@symbo.ls/scratch 0.3.20 → 0.3.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +17 -9
- package/src/config/document.js +2 -2
- package/src/config/index.js +1 -0
- package/src/config/spacing.js +1 -1
- package/src/index.js +1 -1
- package/src/reset.js +43 -39
- package/src/set.js +8 -222
- package/src/system/color.js +81 -0
- package/src/system/font.js +30 -0
- package/src/system/index.js +5 -0
- package/src/system/theme.js +134 -0
- package/src/utils/font.js +14 -7
- package/src/utils/object.js +2 -0
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbo.ls/scratch",
|
|
3
3
|
"description": "Φ / CSS framework and methodology.",
|
|
4
|
-
"author": "
|
|
5
|
-
"version": "0.3.
|
|
4
|
+
"author": "symbo.ls",
|
|
5
|
+
"version": "0.3.23",
|
|
6
6
|
"files": [
|
|
7
7
|
"src"
|
|
8
8
|
],
|
|
9
|
-
"repository": "https://github.com/
|
|
9
|
+
"repository": "https://github.com/symbo-ls/scratch",
|
|
10
|
+
"source": "src/index.js",
|
|
10
11
|
"main": "src/index.js",
|
|
11
12
|
"publishConfig": {},
|
|
12
13
|
"dependencies": {
|
|
@@ -19,19 +20,21 @@
|
|
|
19
20
|
"bump": "npx np"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
22
|
-
"@babel/core": "^7.0.0-0",
|
|
23
23
|
"@babel/preset-env": "^7.18.9",
|
|
24
|
-
"babel-eslint": "^10.0.3",
|
|
25
24
|
"babel-jest": "^27.0.2",
|
|
26
25
|
"babel-preset-env": "^1.7.0",
|
|
27
26
|
"coveralls": "^3.0.5",
|
|
28
|
-
"eslint": "^7.12.1",
|
|
29
27
|
"eslint-plugin-jest": "^24.1.0",
|
|
30
28
|
"jest": "^27.0.6",
|
|
31
29
|
"nodemon": "^2.0.6",
|
|
32
30
|
"np": "^7.2.0",
|
|
33
|
-
"
|
|
34
|
-
"
|
|
31
|
+
"@babel/core": "^7.11.5",
|
|
32
|
+
"@emotion/css": "^11.5.0",
|
|
33
|
+
"babel-eslint": "^10.0.3",
|
|
34
|
+
"eslint": "^6.1.0",
|
|
35
|
+
"parcel-bundler": "^1.12.3",
|
|
36
|
+
"parcel-plugin-svg-sprite": "^1.4.1",
|
|
37
|
+
"standard": "^13.1.0"
|
|
35
38
|
},
|
|
36
39
|
"jest": {
|
|
37
40
|
"collectCoverageFrom": [
|
|
@@ -47,5 +50,10 @@
|
|
|
47
50
|
"browserslist": [
|
|
48
51
|
"> 1%",
|
|
49
52
|
"ie >= 9"
|
|
50
|
-
]
|
|
53
|
+
],
|
|
54
|
+
"targets": {
|
|
55
|
+
"context": "browser",
|
|
56
|
+
"outputFormat": "commonjs",
|
|
57
|
+
"includeNodeModules": true
|
|
58
|
+
}
|
|
51
59
|
}
|
package/src/config/document.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
import { FONT_FAMILY, THEME, TYPOGRAPHY } from '.'
|
|
4
|
-
import { merge } from '../utils'
|
|
4
|
+
import { getDefaultOrFirstKey, merge } from '../utils'
|
|
5
5
|
|
|
6
6
|
export const DOCUMENT = {}
|
|
7
7
|
|
|
8
8
|
export const applyDocument = () => merge(DOCUMENT, {
|
|
9
9
|
theme: THEME.document,
|
|
10
|
-
fontFamily:
|
|
10
|
+
fontFamily: getDefaultOrFirstKey(FONT_FAMILY),
|
|
11
11
|
fontSize: TYPOGRAPHY.base,
|
|
12
12
|
lineHeight: TYPOGRAPHY.styles.lineHeight
|
|
13
13
|
})
|
package/src/config/index.js
CHANGED
package/src/config/spacing.js
CHANGED
package/src/index.js
CHANGED
package/src/reset.js
CHANGED
|
@@ -1,44 +1,48 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
import * as CONFIG from './config'
|
|
4
|
-
import { getTheme } from './
|
|
4
|
+
import { getTheme } from './system'
|
|
5
5
|
import { deepMerge, merge } from './utils'
|
|
6
6
|
|
|
7
|
-
export const
|
|
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
|
-
|
|
7
|
+
export const applyReset = (reset = {}) => {
|
|
8
|
+
return deepMerge(merge(CONFIG.RESET, reset), {
|
|
9
|
+
html: {
|
|
10
|
+
position: 'absolute',
|
|
11
|
+
overflow: 'hidden',
|
|
12
|
+
width: '100%',
|
|
13
|
+
height: '100%',
|
|
14
|
+
top: '0',
|
|
15
|
+
left: '0',
|
|
16
|
+
margin: '0',
|
|
17
|
+
WebkitFontSmoothing: 'antialiased',
|
|
18
|
+
transform: 'translate3d(0, 0, 1px)',
|
|
19
|
+
scrollBehavior: 'smooth',
|
|
20
|
+
|
|
21
|
+
fontFamily: CONFIG.DOCUMENT.fontFamily,
|
|
22
|
+
fontSize: CONFIG.DOCUMENT.fontSize / CONFIG.TYPOGRAPHY.default + CONFIG.UNIT.default,
|
|
23
|
+
lineHeight: CONFIG.DOCUMENT.lineHeight
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
body: {
|
|
27
|
+
boxSizing: 'border-box',
|
|
28
|
+
height: '100%',
|
|
29
|
+
margin: 0,
|
|
30
|
+
fontFamily: CONFIG.DOCUMENT.fontFamily,
|
|
31
|
+
|
|
32
|
+
...getTheme('document')
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
...CONFIG.TYPOGRAPHY.styles,
|
|
36
|
+
|
|
37
|
+
// form elements
|
|
38
|
+
fieldset: {
|
|
39
|
+
border: 0,
|
|
40
|
+
padding: 0,
|
|
41
|
+
margin: 0
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
'select, input': {
|
|
45
|
+
fontFamily: CONFIG.DOCUMENT.fontFamily
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
}
|
package/src/set.js
CHANGED
|
@@ -3,233 +3,17 @@
|
|
|
3
3
|
import { applyDocument, applySpacingSequence, applyTimingSequence, applyTypographySequence } from './config'
|
|
4
4
|
import CONFIG, { CSS_VARS } from './factory'
|
|
5
5
|
import { applyReset } from './reset'
|
|
6
|
+
import { setColor, setGradient, setFont, setFontFamily, setTheme } from './system'
|
|
6
7
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
isObject,
|
|
10
|
-
isString,
|
|
11
|
-
isObjectLike,
|
|
12
|
-
rgbToHSL,
|
|
13
|
-
hexToRgbArray,
|
|
14
|
-
rgbArrayToHex,
|
|
15
|
-
getDefaultOrFirstKey,
|
|
16
|
-
getFontFaceEach,
|
|
17
|
-
hslToRgb,
|
|
18
|
-
getColorShade,
|
|
19
|
-
setVariables
|
|
8
|
+
setVariables,
|
|
9
|
+
isFunction
|
|
20
10
|
} from './utils'
|
|
21
11
|
|
|
22
12
|
const ENV = process.env.NODE_ENV
|
|
23
13
|
|
|
24
|
-
export const getColor = value => {
|
|
25
|
-
if (!isString(value)) {
|
|
26
|
-
if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose) console.warn(value, '- type for color is not valid')
|
|
27
|
-
return
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const [name, alpha, tone] = isArray(value) ? value : value.split(' ')
|
|
31
|
-
const { COLOR, GRADIENT } = CONFIG
|
|
32
|
-
const val = COLOR[name] || GRADIENT[name]
|
|
33
|
-
|
|
34
|
-
if (!val) {
|
|
35
|
-
if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose) console.warn('Can\'t find color', name)
|
|
36
|
-
return value
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// TODO: support variables
|
|
40
|
-
// if (alpha) return `rgba(var(${val[shade || ''].var}), ${modifier})`
|
|
41
|
-
|
|
42
|
-
let rgb = val.rgb
|
|
43
|
-
if (rgb) {
|
|
44
|
-
if (tone) {
|
|
45
|
-
if (!val[tone]) {
|
|
46
|
-
const toHex = rgbArrayToHex(rgb.split(', ').map(v => parseFloat(v)))
|
|
47
|
-
if (tone.slice(0, 1) === '-' || tone.slice(0, 1) === '+') {
|
|
48
|
-
rgb = hexToRgbArray(getColorShade(toHex, parseFloat(tone))).join(', ')
|
|
49
|
-
} else {
|
|
50
|
-
const [r, g, b] = [...rgb.split(', ').map(v => parseInt(v))]
|
|
51
|
-
const hsl = rgbToHSL(r, g, b)
|
|
52
|
-
const [h, s, l] = hsl // eslint-disable-line
|
|
53
|
-
const newRgb = hslToRgb(h, s, parseFloat(tone) / 100 * 255)
|
|
54
|
-
rgb = newRgb
|
|
55
|
-
}
|
|
56
|
-
val[tone] = { rgb, var: `${val.var}-${tone}` }
|
|
57
|
-
} else rgb = val[tone].rgb
|
|
58
|
-
}
|
|
59
|
-
if (alpha) return `rgba(${rgb}, ${alpha})`
|
|
60
|
-
return `rgb(${rgb})`
|
|
61
|
-
} else return val.value
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const setColor = (val, key) => {
|
|
65
|
-
if (val.slice(0, 2) === '--') val = getColor(val.slice(2))
|
|
66
|
-
|
|
67
|
-
const CSSVar = `--color-${key}`
|
|
68
|
-
const [r, g, b, a = 1] = colorStringToRgbaArray(val.value || val)
|
|
69
|
-
const alpha = parseFloat(a.toFixed(2))
|
|
70
|
-
const rgb = `${r}, ${g}, ${b}`
|
|
71
|
-
const value = `rgba(${rgb}, ${alpha})`
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
var: CSSVar,
|
|
75
|
-
rgb,
|
|
76
|
-
alpha,
|
|
77
|
-
value
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const setGradient = (val, key) => {
|
|
82
|
-
const CSSVar = `--gradient-${key}`
|
|
83
|
-
return {
|
|
84
|
-
var: CSSVar,
|
|
85
|
-
value: val.value || val
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const setThemeValue = theme => {
|
|
90
|
-
const value = {}
|
|
91
|
-
const { state, variants, helpers, ...rest } = theme
|
|
92
|
-
const keys = Object.keys(rest)
|
|
93
|
-
keys.map(key => {
|
|
94
|
-
const conditions = ['color', 'Color', 'background', 'border']
|
|
95
|
-
const isColor = conditions.some(k => key.includes(k))
|
|
96
|
-
return (value[key] = isColor ? getColor(theme[key]) : theme[key])
|
|
97
|
-
})
|
|
98
|
-
return value
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const getThemeValue = theme => {
|
|
102
|
-
if (theme.value) return theme.value
|
|
103
|
-
theme.value = setThemeValue(theme)
|
|
104
|
-
return theme.value
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export const getTheme = value => {
|
|
108
|
-
const { THEME } = CONFIG
|
|
109
|
-
|
|
110
|
-
if (isString(value)) {
|
|
111
|
-
const [theme, subtheme] = value.split(' ')
|
|
112
|
-
const isOurTheme = THEME[theme]
|
|
113
|
-
if (isOurTheme) {
|
|
114
|
-
if (!subtheme) return getThemeValue(isOurTheme)
|
|
115
|
-
value = [theme, subtheme]
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (isObjectLike(value) && value[1]) {
|
|
120
|
-
const themeName = value[0]
|
|
121
|
-
const subThemeName = value[1]
|
|
122
|
-
const { helpers, variants, state } = THEME[themeName]
|
|
123
|
-
|
|
124
|
-
if (variants && variants[subThemeName]) return getThemeValue(variants[subThemeName])
|
|
125
|
-
if (helpers && helpers[subThemeName]) return getThemeValue(helpers[subThemeName])
|
|
126
|
-
if (state && state[subThemeName]) return getThemeValue(state[subThemeName])
|
|
127
|
-
} else if (isObject(value)) return setThemeValue(value)
|
|
128
|
-
|
|
129
|
-
if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose) console.warn('Can\'t find theme', value)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const setInverseTheme = (theme, variant, value) => {
|
|
133
|
-
if (isObject(variant)) {
|
|
134
|
-
theme.variants.inverse.value = setThemeValue(variant)
|
|
135
|
-
} else if (variant === true) {
|
|
136
|
-
const { color, background } = value
|
|
137
|
-
theme.variants.inverse = {
|
|
138
|
-
value: {
|
|
139
|
-
color: background,
|
|
140
|
-
background: color
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const setPseudo = (theme, key, variant, themeValue) => {
|
|
147
|
-
const result = getTheme(variant)
|
|
148
|
-
themeValue[`&:${key}`] = result
|
|
149
|
-
if (isObject(variant) && !variant.value) variant.value = result
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
const goThroughInteractiveStates = (theme, value) => {
|
|
153
|
-
const { state } = theme
|
|
154
|
-
if (!state) return
|
|
155
|
-
const keys = Object.keys(state)
|
|
156
|
-
keys.map(key => {
|
|
157
|
-
const variant = state[key]
|
|
158
|
-
setPseudo(theme, key, variant, value)
|
|
159
|
-
return theme
|
|
160
|
-
})
|
|
161
|
-
return theme
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
const setPrefersScheme = (theme, key, variant, themeValue) => {
|
|
165
|
-
const result = getTheme(variant)
|
|
166
|
-
// console.log(variant)
|
|
167
|
-
themeValue[`@media (prefers-color-scheme: ${key})`] = result
|
|
168
|
-
if (isObject(variant) && !variant.value) variant.value = result
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
const goThroughVariants = (theme, value) => {
|
|
172
|
-
const { variants } = theme
|
|
173
|
-
if (!variants) return
|
|
174
|
-
const keys = Object.keys(variants)
|
|
175
|
-
keys.map(key => {
|
|
176
|
-
const variant = variants[key]
|
|
177
|
-
// console.log('=========')
|
|
178
|
-
// console.log(theme, key, variant, value)
|
|
179
|
-
if (key === 'dark' || key === 'light') setPrefersScheme(theme, key, variant, value)
|
|
180
|
-
if (key === 'inverse') setInverseTheme(theme, variant, value)
|
|
181
|
-
return theme
|
|
182
|
-
})
|
|
183
|
-
return theme
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const goThroughHelpers = (theme, value) => {
|
|
187
|
-
const { helpers } = theme
|
|
188
|
-
if (!helpers) return
|
|
189
|
-
const keys = Object.keys(helpers)
|
|
190
|
-
keys.map(key => {
|
|
191
|
-
const helper = helpers[key]
|
|
192
|
-
if (isString(helper)) helpers[key] = CONFIG.THEME[helper]
|
|
193
|
-
else getThemeValue(helpers[key])
|
|
194
|
-
return theme
|
|
195
|
-
})
|
|
196
|
-
return theme
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const setTheme = (val, key) => {
|
|
200
|
-
const { state, variants, helpers } = val
|
|
201
|
-
const value = setThemeValue(val, key)
|
|
202
|
-
const CSSvar = `--theme-${key}`
|
|
203
|
-
|
|
204
|
-
goThroughInteractiveStates(val, value)
|
|
205
|
-
goThroughVariants(val, value)
|
|
206
|
-
goThroughHelpers(val, value)
|
|
207
|
-
|
|
208
|
-
return { var: CSSvar, value, state, variants, helpers }
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
const setFont = (val, key) => {
|
|
212
|
-
const CSSvar = `--font-${key}`
|
|
213
|
-
const fontFace = getFontFaceEach(key, val)
|
|
214
|
-
return { var: CSSvar, value: val, fontFace }
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
export const getFontFamily = (LIBRARY, key) => {
|
|
218
|
-
return getDefaultOrFirstKey(LIBRARY, key)
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const setFontFamily = (val, key) => {
|
|
222
|
-
const { FONT_FAMILY, FONT_FAMILY_TYPES } = CONFIG
|
|
223
|
-
const { value, type } = val
|
|
224
|
-
if (val.default) FONT_FAMILY.default = key
|
|
225
|
-
|
|
226
|
-
const CSSvar = `--font-family-${key}`
|
|
227
|
-
const str = `${value.join(', ')}, ${FONT_FAMILY_TYPES[type]}`
|
|
228
|
-
return { var: CSSvar, value: str, arr: value, type }
|
|
229
|
-
}
|
|
230
|
-
|
|
231
14
|
const setCases = (val, key) => {
|
|
232
|
-
return val()
|
|
15
|
+
if (isFunction(val)) return val()
|
|
16
|
+
return val
|
|
233
17
|
}
|
|
234
18
|
|
|
235
19
|
const setSameValue = (val, key) => val
|
|
@@ -296,10 +80,12 @@ export const set = recivedConfig => {
|
|
|
296
80
|
// apply generic configs
|
|
297
81
|
applyTypographySequence()
|
|
298
82
|
applySpacingSequence()
|
|
299
|
-
applyDocument()
|
|
300
83
|
applyTimingSequence()
|
|
84
|
+
applyDocument()
|
|
301
85
|
applyReset()
|
|
302
86
|
|
|
303
87
|
CONFIG.VARS = CSS_VARS
|
|
304
88
|
return CONFIG
|
|
305
89
|
}
|
|
90
|
+
|
|
91
|
+
export * from './system'
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import CONFIG, { CSS_VARS } from '../factory' // eslint-disable-line
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
isArray,
|
|
7
|
+
colorStringToRgbaArray,
|
|
8
|
+
isString,
|
|
9
|
+
rgbToHSL,
|
|
10
|
+
hexToRgbArray,
|
|
11
|
+
rgbArrayToHex,
|
|
12
|
+
hslToRgb,
|
|
13
|
+
getColorShade
|
|
14
|
+
} from '../utils'
|
|
15
|
+
|
|
16
|
+
const ENV = process.env.NODE_ENV
|
|
17
|
+
|
|
18
|
+
export const getColor = value => {
|
|
19
|
+
if (!isString(value)) {
|
|
20
|
+
if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose) console.warn(value, '- type for color is not valid')
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const [name, alpha, tone] = isArray(value) ? value : value.split(' ')
|
|
25
|
+
const { COLOR, GRADIENT } = CONFIG
|
|
26
|
+
const val = COLOR[name] || GRADIENT[name]
|
|
27
|
+
|
|
28
|
+
if (!val) {
|
|
29
|
+
if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose) console.warn('Can\'t find color', name)
|
|
30
|
+
return value
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// TODO: support variables
|
|
34
|
+
// if (alpha) return `rgba(var(${val[shade || ''].var}), ${modifier})`
|
|
35
|
+
|
|
36
|
+
let rgb = val.rgb
|
|
37
|
+
if (rgb) {
|
|
38
|
+
if (tone) {
|
|
39
|
+
if (!val[tone]) {
|
|
40
|
+
const toHex = rgbArrayToHex(rgb.split(', ').map(v => parseFloat(v)))
|
|
41
|
+
if (tone.slice(0, 1) === '-' || tone.slice(0, 1) === '+') {
|
|
42
|
+
rgb = hexToRgbArray(getColorShade(toHex, parseFloat(tone))).join(', ')
|
|
43
|
+
} else {
|
|
44
|
+
const [r, g, b] = [...rgb.split(', ').map(v => parseInt(v))]
|
|
45
|
+
const hsl = rgbToHSL(r, g, b)
|
|
46
|
+
const [h, s, l] = hsl // eslint-disable-line
|
|
47
|
+
const newRgb = hslToRgb(h, s, parseFloat(tone) / 100 * 255)
|
|
48
|
+
rgb = newRgb
|
|
49
|
+
}
|
|
50
|
+
val[tone] = { rgb, var: `${val.var}-${tone}` }
|
|
51
|
+
} else rgb = val[tone].rgb
|
|
52
|
+
}
|
|
53
|
+
if (alpha) return `rgba(${rgb}, ${alpha})`
|
|
54
|
+
return `rgb(${rgb})`
|
|
55
|
+
} else return val.value
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export const setColor = (val, key) => {
|
|
59
|
+
if (val.slice(0, 2) === '--') val = getColor(val.slice(2))
|
|
60
|
+
|
|
61
|
+
const CSSVar = `--color-${key}`
|
|
62
|
+
const [r, g, b, a = 1] = colorStringToRgbaArray(val.value || val)
|
|
63
|
+
const alpha = parseFloat(a.toFixed(2))
|
|
64
|
+
const rgb = `${r}, ${g}, ${b}`
|
|
65
|
+
const value = `rgba(${rgb}, ${alpha})`
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
var: CSSVar,
|
|
69
|
+
rgb,
|
|
70
|
+
alpha,
|
|
71
|
+
value
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export const setGradient = (val, key) => {
|
|
76
|
+
const CSSVar = `--gradient-${key}`
|
|
77
|
+
return {
|
|
78
|
+
var: CSSVar,
|
|
79
|
+
value: val.value || val
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import CONFIG, { CSS_VARS } from '../factory' // eslint-disable-line
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
getDefaultOrFirstKey,
|
|
7
|
+
getFontFaceEach
|
|
8
|
+
} from '../utils'
|
|
9
|
+
|
|
10
|
+
// const ENV = process.env.NODE_ENV
|
|
11
|
+
|
|
12
|
+
export const setFont = (val, key) => {
|
|
13
|
+
const CSSvar = `--font-${key}`
|
|
14
|
+
const fontFace = getFontFaceEach(key, val)
|
|
15
|
+
return { var: CSSvar, value: val, fontFace }
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const getFontFamily = (LIBRARY, key) => {
|
|
19
|
+
return getDefaultOrFirstKey(LIBRARY, key)
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const setFontFamily = (val, key) => {
|
|
23
|
+
const { FONT_FAMILY, FONT_FAMILY_TYPES } = CONFIG
|
|
24
|
+
const { value, type } = val
|
|
25
|
+
if (val.isDefault) FONT_FAMILY.default = key
|
|
26
|
+
|
|
27
|
+
const CSSvar = `--font-family-${key}`
|
|
28
|
+
const str = `${value.join(', ')}, ${FONT_FAMILY_TYPES[type]}`
|
|
29
|
+
return { var: CSSvar, value: str, arr: value, type }
|
|
30
|
+
}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { getColor } from './color'
|
|
4
|
+
import CONFIG, { CSS_VARS } from '../factory' // eslint-disable-line
|
|
5
|
+
|
|
6
|
+
import {
|
|
7
|
+
isObject,
|
|
8
|
+
isString,
|
|
9
|
+
isObjectLike
|
|
10
|
+
} from '../utils'
|
|
11
|
+
|
|
12
|
+
const ENV = process.env.NODE_ENV
|
|
13
|
+
|
|
14
|
+
const setThemeValue = theme => {
|
|
15
|
+
const value = {}
|
|
16
|
+
const { state, variants, helpers, ...rest } = theme
|
|
17
|
+
const keys = Object.keys(rest)
|
|
18
|
+
keys.map(key => {
|
|
19
|
+
const conditions = ['color', 'Color', 'background', 'border']
|
|
20
|
+
const isColor = conditions.some(k => key.includes(k))
|
|
21
|
+
return (value[key] = isColor ? getColor(theme[key]) : theme[key])
|
|
22
|
+
})
|
|
23
|
+
return value
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const getThemeValue = theme => {
|
|
27
|
+
if (theme.value) return theme.value
|
|
28
|
+
theme.value = setThemeValue(theme)
|
|
29
|
+
return theme.value
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const getTheme = (value, modifier) => {
|
|
33
|
+
const { THEME } = CONFIG
|
|
34
|
+
|
|
35
|
+
if (isString(value)) {
|
|
36
|
+
const [theme, subtheme] = value.split(' ')
|
|
37
|
+
const isOurTheme = THEME[theme]
|
|
38
|
+
if (isOurTheme) {
|
|
39
|
+
if (!subtheme && !modifier) return getThemeValue(isOurTheme)
|
|
40
|
+
value = [theme, subtheme || modifier]
|
|
41
|
+
}
|
|
42
|
+
} // else value = [value, modifier]
|
|
43
|
+
|
|
44
|
+
if (isObjectLike(value) && value[1]) {
|
|
45
|
+
const themeName = value[0]
|
|
46
|
+
const subThemeName = value[1]
|
|
47
|
+
const { helpers, variants, state } = THEME[themeName]
|
|
48
|
+
|
|
49
|
+
if (variants && variants[subThemeName]) return getThemeValue(variants[subThemeName])
|
|
50
|
+
if (helpers && helpers[subThemeName]) return getThemeValue(helpers[subThemeName])
|
|
51
|
+
if (state && state[subThemeName]) return getThemeValue(state[subThemeName])
|
|
52
|
+
} else if (isObject(value)) return setThemeValue(value)
|
|
53
|
+
|
|
54
|
+
if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose) console.warn('Can\'t find theme', value)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const setInverseTheme = (theme, variant, value) => {
|
|
58
|
+
if (isObject(variant)) {
|
|
59
|
+
theme.variants.inverse.value = setThemeValue(variant)
|
|
60
|
+
} else if (variant === true) {
|
|
61
|
+
const { color, background } = value
|
|
62
|
+
theme.variants.inverse = {
|
|
63
|
+
value: {
|
|
64
|
+
color: background,
|
|
65
|
+
background: color
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const setPseudo = (theme, key, variant, themeValue) => {
|
|
72
|
+
const result = getTheme(variant)
|
|
73
|
+
themeValue[`&:${key}`] = result
|
|
74
|
+
if (isObject(variant) && !variant.value) variant.value = result
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const goThroughInteractiveStates = (theme, value) => {
|
|
78
|
+
const { state } = theme
|
|
79
|
+
if (!state) return
|
|
80
|
+
const keys = Object.keys(state)
|
|
81
|
+
keys.map(key => {
|
|
82
|
+
const variant = state[key]
|
|
83
|
+
setPseudo(theme, key, variant, value)
|
|
84
|
+
return theme
|
|
85
|
+
})
|
|
86
|
+
return theme
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const setPrefersScheme = (theme, key, variant, themeValue) => {
|
|
90
|
+
const result = getTheme(variant)
|
|
91
|
+
// console.log(variant)
|
|
92
|
+
themeValue[`@media (prefers-color-scheme: ${key})`] = result
|
|
93
|
+
if (isObject(variant) && !variant.value) variant.value = result
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const goThroughVariants = (theme, value) => {
|
|
97
|
+
const { variants } = theme
|
|
98
|
+
if (!variants) return
|
|
99
|
+
const keys = Object.keys(variants)
|
|
100
|
+
keys.map(key => {
|
|
101
|
+
const variant = variants[key]
|
|
102
|
+
// console.log('=========')
|
|
103
|
+
// console.log(theme, key, variant, value)
|
|
104
|
+
if (key === 'dark' || key === 'light') setPrefersScheme(theme, key, variant, value)
|
|
105
|
+
if (key === 'inverse') setInverseTheme(theme, variant, value)
|
|
106
|
+
return theme
|
|
107
|
+
})
|
|
108
|
+
return theme
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const goThroughHelpers = (theme, value) => {
|
|
112
|
+
const { helpers } = theme
|
|
113
|
+
if (!helpers) return
|
|
114
|
+
const keys = Object.keys(helpers)
|
|
115
|
+
keys.map(key => {
|
|
116
|
+
const helper = helpers[key]
|
|
117
|
+
if (isString(helper)) helpers[key] = CONFIG.THEME[helper]
|
|
118
|
+
else getThemeValue(helpers[key])
|
|
119
|
+
return theme
|
|
120
|
+
})
|
|
121
|
+
return theme
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export const setTheme = (val, key) => {
|
|
125
|
+
const { state, variants, helpers } = val
|
|
126
|
+
const value = setThemeValue(val, key)
|
|
127
|
+
const CSSvar = `--theme-${key}`
|
|
128
|
+
|
|
129
|
+
goThroughInteractiveStates(val, value)
|
|
130
|
+
goThroughVariants(val, value)
|
|
131
|
+
goThroughHelpers(val, value)
|
|
132
|
+
|
|
133
|
+
return { var: CSSvar, value, state, variants, helpers }
|
|
134
|
+
}
|
package/src/utils/font.js
CHANGED
|
@@ -2,32 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
export const getDefaultOrFirstKey = (LIBRARY, key) => {
|
|
4
4
|
if (LIBRARY[key]) return LIBRARY[key].value
|
|
5
|
-
if (LIBRARY.
|
|
5
|
+
if (LIBRARY.default) return LIBRARY[LIBRARY.default].value
|
|
6
6
|
const hasValue = Object.keys(LIBRARY)[0]
|
|
7
7
|
return hasValue && LIBRARY[hasValue] && LIBRARY[hasValue].value
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export const getFontFormat = url => url.split(/[#?]/)[0].split('.').pop().trim()
|
|
11
11
|
|
|
12
|
-
export const setCustomFont = (name, weight, url) =>
|
|
12
|
+
export const setCustomFont = (name, weight, url) => `
|
|
13
13
|
font-family: '${name}';
|
|
14
14
|
font-style: normal;
|
|
15
15
|
font-weight: ${weight};
|
|
16
|
-
src: url('${url}') format('${getFontFormat(url)}')
|
|
16
|
+
src: url('${url}') format('${getFontFormat(url)}');`
|
|
17
|
+
|
|
18
|
+
export const setCustomFontMedia = (name, weight, url) => `@font-face {
|
|
19
|
+
${setCustomFont((name, weight, url))}
|
|
17
20
|
}`
|
|
18
21
|
// src: url('${url}') format('${getFontFormat(url)}');
|
|
19
22
|
|
|
20
23
|
export const getFontFaceEach = (name, weightsObject) => {
|
|
21
24
|
const keys = Object.keys(weightsObject)
|
|
22
|
-
|
|
25
|
+
return keys.map(key => {
|
|
23
26
|
const { fontWeight, url } = weightsObject[key]
|
|
24
27
|
return setCustomFont(name, fontWeight, url)
|
|
25
28
|
})
|
|
26
|
-
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const getFontFaceEachString = (name, weightsObject) => {
|
|
32
|
+
return getFontFaceEach(name, weightsObject).join('\n')
|
|
27
33
|
}
|
|
28
34
|
|
|
29
35
|
export const getFontFace = LIBRARY => {
|
|
30
36
|
const keys = Object.keys(LIBRARY)
|
|
31
|
-
|
|
32
|
-
return fontsJoint.join('\n')
|
|
37
|
+
return keys.map(key => getFontFaceEach(key, LIBRARY[key].value))
|
|
33
38
|
}
|
|
39
|
+
|
|
40
|
+
export const getFontFaceString = LIBRARY => getFontFace(LIBRARY).join('\n')
|