Created
June 26, 2019 08:49
-
-
Save dariye/2fa113f84658284811cb7006e957ed9a to your computer and use it in GitHub Desktop.
theme.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { darken, parseToHsl, hsl, getLuminance } from "polished"; | |
const addAliases = (arr: (string | number)[], aliases: string[]) => | |
aliases.forEach((key, i) => | |
Object.defineProperty(arr, key, { | |
enumerable: false, | |
get() { | |
return this[i]; | |
} | |
}) | |
); | |
const createMediaQuery = (n: number) => `@media screen and (min-width:${n}em)`; | |
const aliases = ["sm", "md", "lg", "xl"]; | |
// Breakpoints | |
export const breakpoints = [32, 48, 64, 75]; | |
export const mediaQueries = breakpoints.map(createMediaQuery); | |
addAliases(breakpoints, aliases); | |
addAliases(mediaQueries, aliases); | |
// Spacing | |
export const space = [0, 4, 8, 16, 22, 28, 32, 64, 128, 256, 512]; | |
// Typography | |
export const fonts = { | |
sans: "'Inter UI', 'Open Sans', arial, system-ui, sans-serif", | |
system: | |
"-apple-system,BlinkMacSystemFont,Segoe UI',Roboto,Oxygen-Sans,Ubuntu,Cantarell,'Helvetica Neue', sans-serif", | |
serif: "'Courier New', monospace, serif", | |
mono: | |
"'Lucida Console', 'Lucida Sans Typewriter', monaco, 'Bitstream Vera Sans Mono', monospace" | |
}; | |
export const fontSizes = [12, 14, 16, 20, 24, 32, 48]; | |
export const thin = 300; | |
export const regular = 400; | |
export const medium = 500; | |
export const semibold = 600; | |
export const bold = 700; | |
export const bolder = 900; | |
export const fontWeights = { | |
thin, | |
regular, | |
medium, | |
semibold, | |
bold, | |
bolder | |
}; | |
export const lineHeights = { | |
normal: 1, | |
body: 1.5, | |
title: 1.25 | |
}; | |
const letterSpacings = { | |
normal: "normal", | |
tracked: "0.1em", | |
tight: "-0.05em", | |
mega: "0.025em" | |
}; | |
// Border radius | |
export const radii = [0, "2px", "6px", "8px", "12px", "22px", "999px", "100%"]; | |
// Borders | |
export const borderWidths = [0, "1px", "2px", "7px"]; | |
// Max container | |
export const maxContainerWidth = "1329px"; | |
// Colors | |
const names = [ | |
"red", // 0 | |
"orange", // 30 | |
"yellow", // 60 | |
"lime", // 90 | |
"green", // 120 | |
"teal", // 150 | |
"cyan", // 180 | |
"blue", // 210 | |
"indigo", // 240 | |
"violet", // 270 | |
"fuchsia", // 300 | |
"pink", // 330 | |
"red" // 360 | |
]; | |
const palette = { | |
"shade-900": "#000000", | |
"shade-700": "#222222", | |
"shade-600": "#333333", | |
"shade-500": "#676D70", | |
"shade-400": "#838C91", | |
"shade-300": "#BEC3C6", | |
"shade-200": "#E2E4E6", | |
"shade-100": "#EEEEEE", | |
"shade-50": "#FAFAFA", | |
"shade-0": "#FFFFFF", | |
"pink-900": "#801933", | |
"pink-800": "#B32447", | |
"pink-700": "#CC2952", | |
"pink-600": "#E62E5C", | |
"pink-500": "#FF3366", | |
"pink-400": "#FF3769", | |
"pink-300": "#FF98B2", | |
"pink-200": "#FFC1D1", | |
"pink-100": "#FFD6E0", | |
"pink-50": "#FFF5F8", | |
"blue-900": "#285180", | |
"blue-800": "#2F6199", | |
"blue-700": "#3771B3", | |
"blue-600": "#3F81CC", | |
"blue-500": "#4790E5", | |
"blue-400": "#4FA1FF", | |
"blue-300": "#91BCEF", | |
"blue-200": "#B5D3F5", | |
"blue-100": "#DAE9FA", | |
"blue-50": "#F2F7FD", | |
"green-900": "#2E804C", | |
"green-800": "#37995B", | |
"green-700": "#40B36A", | |
"green-600": "#49CC79", | |
"green-500": "#53E588", | |
"green-400": "#5CFF98", | |
"green-300": "#BAF5CF", | |
"green-200": "#CBF7DB", | |
"green-100": "#DDFAE7", | |
"green-50": "#F3FDF7", | |
"red-900": "#751616", | |
"red-800": "#8F1B1B", | |
"red-700": "#A82020", | |
"red-600": "#C22525", | |
"red-500": "#DB2929", | |
"red-400": "#DB2929", | |
"red-300": "#F1A9A9", | |
"red-200": "#F4BEBE", | |
"red-100": "#F8D4D", | |
"red-50": "#FCF0F0", | |
"yellow-900": "#99710B", | |
"yellow-800": "#B3830C", | |
"yellow-700": "#CC960E", | |
"yellow-600": "#E6A910", | |
"yellow-500": "#FFBB11", | |
"yellow-400": "#F9D34B", | |
"yellow-300": "#FFE4A0", | |
"yellow-200": "#FFEAB7", | |
"yellow-100": "#FFF1CF", | |
"yellow-50": "#FFFAEE" | |
}; | |
const baseColors = { | |
...palette, | |
white: "#FFFFFF", | |
black: "#000000", | |
grey: palette["shade-500"], | |
pink: palette["pink-500"], | |
blue: palette["blue-500"], | |
green: palette["green-500"], | |
red: palette["red-500"], | |
yellow: palette["yellow-500"] | |
}; | |
const hueName = (h: number) => { | |
const i = Math.round((h - 2) / 30); | |
const name = names[i]; | |
return name; | |
}; | |
const createHues = (h: number) => | |
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map(n => | |
Math.floor((h + (n * 360) / 12) % 360) | |
); | |
export const createColors = (base: string) => { | |
const colors = { | |
...baseColors, | |
// Old colors | |
error: baseColors.red, | |
success: baseColors.green, | |
warning: baseColors.yellow, | |
border: baseColors["shade-100"], | |
"dark-text": palette["shade-600"], | |
"darker-grey": baseColors.grey, | |
"dark-grey": baseColors["shade-300"], | |
"neutral-grey": baseColors["shade-300"], | |
"light-grey": baseColors["shade-100"], | |
"white-gray": baseColors["shade-50"], | |
"off-white": baseColors["shade-100"], | |
"page-background": baseColors["shade-100"], | |
"page-background-overlay": darken(0.2, baseColors["shade-100"]), | |
"drop-shadow": baseColors["shade-300"], | |
"brand-pink": baseColors.pink, | |
"brand-pink-hover": baseColors["pink-600"], | |
"brand-pink-light": baseColors["pink-200"], | |
"brand-blue": baseColors["blue-500"], | |
"brand-blue-alpha": baseColors["blue-50"], | |
"brand-blue-hover": baseColors["blue-600"], | |
"brand-blue-light": baseColors["blue-200"], | |
"brand-white": baseColors["shade-0"], | |
"text-color-lighter": baseColors["shade-400"], | |
"text-color-light": baseColors.grey, | |
"text-color-dark": baseColors["shade-600"], | |
"text-color-positive": baseColors.green, | |
"input-neutral": baseColors["shade-100"], | |
"input-focus": baseColors.blue, | |
"input-unfocus": baseColors["shade-300"], | |
backdrop: baseColors["shade-400"], | |
"border-light-grey": baseColors["shade-100"], | |
"table-header-light": baseColors["shade-0"], | |
"table-header-dark": baseColors["shade-100"], | |
"dark-blue": baseColors["shade-600"] | |
}; | |
const { hue, saturation, lightness } = parseToHsl(base); | |
const hues = createHues(hue); | |
hues.forEach((h: number) => { | |
const name = hueName(h); | |
colors[name] = hsl(h, saturation, lightness); | |
}); | |
return colors; | |
}; | |
export const invertLuminance = (base: string) => { | |
const luminance = getLuminance(base); | |
const { hue, saturation } = parseToHsl(base); | |
return hsl(hue, saturation, 1 - luminance); | |
}; | |
export const colors = createColors(baseColors.pink); | |
export const boxShadows = [ | |
`0 0 2px 0 rgba(0,0,0,.08),0 1px 4px 0 rgba(0,0,0,.16)`, | |
`0 0 2px 0 rgba(0,0,0,.08),0 2px 8px 0 rgba(0,0,0,.16)`, | |
`0 0 2px 0 rgba(0,0,0,.08),0 4px 16px 0 rgba(0,0,0,.16)`, | |
`0 0 2px 0 rgba(0,0,0,.08),0 8px 32px 0 rgba(0,0,0,.16)` | |
]; | |
// // Duration | |
export const duration = { | |
fast: `150ms`, | |
normal: `300ms`, | |
slow: `450ms`, | |
slowest: `600ms` | |
}; | |
// // Timing | |
const easeInOut = "cubic-bezier(0.5, 0, 0.25, 1)"; | |
const easeOut = "cubic-bezier(0, 0, 0.25, 1)"; | |
const easeIn = "cubic-bezier(0.5, 0, 1, 1)"; | |
const timingFunctions = { | |
easeInOut, | |
easeOut, | |
easeIn | |
}; | |
// // Delay | |
const transitionDelays = { | |
small: `60ms`, | |
medium: `160ms`, | |
large: `260ms`, | |
xLarge: `360ms` | |
}; | |
// Default component styles | |
const Text = { | |
fontFamily: fonts.sans, | |
lineHeight: lineHeights.body, | |
fontSize: fontSizes[2] | |
}; | |
// variants | |
const texts = { | |
body: {}, | |
strong: {} | |
}; | |
const Heading = { | |
fontFamily: fonts.sans, | |
lineHeight: lineHeights.title, | |
fontSize: fontSizes[4] | |
}; | |
// variants | |
const headings = { | |
h1: {}, | |
h2: {}, | |
h3: {}, | |
h4: {}, | |
h5: {}, | |
h6: {} | |
}; | |
const Button = { | |
height: "40px", | |
borderRadius: radii[5], | |
paddingLeft: 30, | |
paddingRight: 30, | |
paddingTop: 0, | |
paddingBottom: 0, | |
fontSize: fontSizes[2], | |
fontWeight: fontWeights.regular, | |
fill: "currentColor" | |
}; | |
// variants | |
const buttons = { | |
default: { | |
color: colors.grey, | |
background: "#ebeff3", | |
boxShadow: "inset 0 0 0 3px #f0f4f6", | |
"&:hover": { | |
boxShadow: "inset 0 0 0 3px #ddd" | |
} | |
}, | |
link: { | |
paddingLeft: 0, | |
paddingRight: 0, | |
paddingTop: 0, | |
paddingBottom: 0, | |
margin: 0, | |
border: 0, | |
color: colors.blue, | |
textDecoration: "none", | |
verticalAlign: "middle", | |
cursor: "pointer", | |
background: "none", | |
boxShadow: "none" | |
}, | |
disabled: { | |
color: "#B3B4C2", | |
cursor: "not-allowed", | |
bg: "#B3B4C2" | |
}, | |
rounded: { | |
borderRadius: radii[4] | |
}, | |
transparent: { | |
background: "transparent", | |
border: `1px solid ${colors["light-grey"]}` | |
} | |
}; | |
const Link = { | |
color: colors.blue | |
}; | |
// variants | |
const links = {}; | |
const Image = {}; | |
// variants | |
const images = { | |
avatar: { | |
borderRadius: radii[7], | |
height: 32, | |
width: 32 | |
}, | |
loading: { | |
opacity: 0 | |
}, | |
square: { | |
borderRadius: radii[1] | |
}, | |
fallback: { | |
color: colors["brand-white"], | |
border: "none" | |
} | |
}; | |
const Card = {}; | |
// variants | |
const cards = {}; | |
export const lightTheme = { | |
name: "light", | |
breakpoints, | |
mediaQueries, | |
space, | |
fonts, | |
fontSizes, | |
fontWeights, | |
lineHeights, | |
letterSpacings, | |
thin, | |
regular, | |
medium, | |
semibold, | |
bold, | |
bolder, | |
colors, | |
radii, | |
borderWidths, | |
maxContainerWidth, | |
boxShadows, | |
duration, | |
timingFunctions, | |
transitionDelays, | |
Text, | |
texts, | |
Heading, | |
headings, | |
Button, | |
buttons, | |
Link, | |
links, | |
Image, | |
images, | |
Card, | |
cards | |
}; | |
export const darkTheme = { | |
...lightTheme, | |
name: "dark", | |
colors: { | |
...colors, | |
"page-background": colors.black | |
} | |
}; | |
export default { light: lightTheme, dark: darkTheme }; | |
// Todo: | |
// Web | |
// Shadows | |
// Mobile themes | |
// padding: 22 / 28 | |
// colors | |
// border-radius | |
// margin | |
// shadows // elevated // color | |
// flex // width | |
// fontSize |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment