-
Notifications
You must be signed in to change notification settings - Fork 667
Expand file tree
/
Copy pathto-theme.js
More file actions
127 lines (110 loc) · 3.03 KB
/
to-theme.js
File metadata and controls
127 lines (110 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// custom implementation of typography.js for use in theme-ui
import verticalRhythm from 'compass-vertical-rhythm'
import ms from 'modularscale'
import styles from './styles'
// - uses unitless values
// - creates base theme object
// - uses a static theme.styles object for consumption in theme-ui
// - ignores overrideThemeStyles
// - does not include color styles
// - should be mostly compatible with existing typography.js themes
const defaults = {
baseFontSize: 16,
baseLineHeight: 1.45,
headerLineHeight: 1.1,
scaleRatio: 2,
googleFonts: [],
headerFontFamily: [
'-apple-system',
'BlinkMacSystemFont',
'Segoe UI',
'Roboto',
'Oxygen',
'Ubuntu',
'Cantarell',
'Fira Sans',
'Droid Sans',
'Helvetica Neue',
'sans-serif',
],
bodyFontFamily: ['georgia', 'serif'],
headerWeight: 'bold',
bodyWeight: 'normal',
boldWeight: 'bold',
includeNormalize: true,
blockMarginBottom: 1,
}
export const toUnitless = val => parseFloat(val)
export const getScale = opts => value =>
ms(value, opts.scaleRatio) * opts.baseFontSize
export const getSpace = (result, opts) => {
const n = toUnitless(result.rhythm(opts.blockMarginBottom))
return [0, 1 / 4, 1 / 2, 1, 2, 4, 8].map(v => v * n)
}
// genericFontFamilies, wrapFontFamily adapted from typography.js
// Wrap font names in quotes, unless the font name is actually a keyword.
// See https://stackoverflow.com/a/13752149 and https://www.w3.org/TR/CSS2/fonts.html#font-family-prop
const genericFontFamilies = [
'inherit',
'default',
'serif',
'sans-serif',
'monospace',
'fantasy',
'cursive',
'-apple-system',
'system-ui',
]
const wrapFontFamily = fontFamily =>
genericFontFamilies.includes(fontFamily) ? fontFamily : `'${fontFamily}'`
const stackFonts = fonts => fonts.map(wrapFontFamily).join(', ')
export const getFonts = (result, opts) => {
const body = stackFonts(opts.bodyFontFamily)
const heading = stackFonts(opts.headerFontFamily)
return {
body,
heading,
}
}
export const getFontSizes = (result, opts) => {
const scale = getScale(opts)
return [-1.5 / 5, -1 / 5, 0, 2 / 5, 3 / 5, 1].map(scale)
}
export const getLineHeights = (result, opts) => {
const body = opts.baseLineHeight
const heading = opts.headerLineHeight
return {
body,
heading,
}
}
export const getFontWeights = (result, opts) => {
const body = opts.bodyWeight
const bold = opts.boldWeight
const heading = opts.headerWeight
return {
body,
bold,
heading,
}
}
export const toTheme = (_opts = {}) => {
const opts = { ...defaults, ..._opts }
// enforce unitless values
opts.baseFontSize = toUnitless(opts.baseFontSize)
opts.rhythmUnit = 'px'
const typo = verticalRhythm(opts)
const theme = {}
typo.options = opts
theme.space = getSpace(typo, opts)
theme.fonts = getFonts(typo, opts)
theme.fontSizes = getFontSizes(typo, opts)
theme.fontWeights = getFontWeights(typo, opts)
theme.lineHeights = getLineHeights(typo, opts)
return {
...theme,
styles,
typography: typo,
}
}
export default toTheme