@symbo.ls/scratch 0.3.15 → 0.3.18
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 +1 -1
- package/src/config/cases.js +3 -0
- package/src/config/icons.js +3 -0
- package/src/config/index.js +4 -6
- package/src/config/media.js +15 -0
- package/src/config/responsive.js +1 -1
- package/src/config/timing.js +25 -2
- package/src/index.js +1 -1
- package/src/reset.js +4 -1
- package/src/{methods/set.js → set.js} +75 -40
- package/src/utils/color.js +148 -0
- package/src/utils/font.js +32 -0
- package/src/utils/index.js +5 -363
- package/src/utils/object.js +46 -0
- package/src/utils/sequence.js +117 -0
- package/src/utils/setVariables.js +18 -0
- package/src/methods/create.js +0 -9
- package/src/methods/generate.js +0 -40
- package/src/methods/index.js +0 -3
- package/src/methods/inject.js +0 -5
package/package.json
CHANGED
package/src/config/index.js
CHANGED
|
@@ -2,16 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
export * from './sequence'
|
|
4
4
|
export * from './unit'
|
|
5
|
-
|
|
6
5
|
export * from './typography'
|
|
7
6
|
export * from './font'
|
|
8
7
|
export * from './font-family'
|
|
9
|
-
|
|
8
|
+
export * from './media'
|
|
10
9
|
export * from './spacing'
|
|
11
|
-
|
|
12
10
|
export * from './color'
|
|
13
11
|
export * from './theme'
|
|
14
|
-
|
|
15
|
-
export * from './
|
|
16
|
-
|
|
12
|
+
export * from './icons'
|
|
13
|
+
export * from './timing'
|
|
17
14
|
export * from './document'
|
|
15
|
+
export * from './cases'
|
package/src/config/media.js
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
export const MEDIA = {
|
|
4
|
+
screenL: '(max-width: 1920px)',
|
|
5
|
+
screenD: '(max-width: 1680px)',
|
|
6
|
+
screenS: '(max-width: 1440px)',
|
|
7
|
+
tabletL: '(max-width: 1366px)',
|
|
8
|
+
tabletM: '(max-width: 1280px)',
|
|
9
|
+
tabletS: '(max-width: 1024px)',
|
|
10
|
+
mobileL: '(max-width: 768px)',
|
|
11
|
+
mobileM: '(max-width: 560px)',
|
|
12
|
+
mobileS: '(max-width: 480px)',
|
|
13
|
+
|
|
14
|
+
light: '(prefers-color-scheme: light)'
|
|
15
|
+
}
|
package/src/config/responsive.js
CHANGED
package/src/config/timing.js
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import { SEQUENCE } from '.'
|
|
4
|
+
import { fallBack, generateSequence } from '../utils'
|
|
5
|
+
|
|
6
|
+
const defaultProps = {
|
|
7
|
+
default: 150,
|
|
8
|
+
base: 150,
|
|
9
|
+
type: 'timing',
|
|
10
|
+
ratio: SEQUENCE['minor-third'],
|
|
11
|
+
range: [-3, +12],
|
|
12
|
+
sequence: {},
|
|
13
|
+
scales: {}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const applyTimingSequence = () => {
|
|
17
|
+
generateSequence(defaultProps)
|
|
5
18
|
}
|
|
19
|
+
|
|
20
|
+
export const mapTiming = val => fallBack({
|
|
21
|
+
type: defaultProps.sequence,
|
|
22
|
+
prop: 'timing',
|
|
23
|
+
val,
|
|
24
|
+
unit: 'ms',
|
|
25
|
+
prefix: '--duration-'
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
export const TIMING = defaultProps
|
package/src/index.js
CHANGED
package/src/reset.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
import * as CONFIG from './config'
|
|
4
|
+
import { getTheme } from './set'
|
|
4
5
|
import { deepMerge, merge } from './utils'
|
|
5
6
|
|
|
6
7
|
export const RESET = {}
|
|
@@ -27,7 +28,9 @@ export const applyReset = (reset = {}) => deepMerge(merge(RESET, reset), {
|
|
|
27
28
|
body: {
|
|
28
29
|
boxSizing: 'border-box',
|
|
29
30
|
height: '100%',
|
|
30
|
-
margin: 0
|
|
31
|
+
margin: 0,
|
|
32
|
+
|
|
33
|
+
...getTheme('document')
|
|
31
34
|
},
|
|
32
35
|
|
|
33
36
|
...CONFIG.TYPOGRAPHY.styles,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { applyDocument, applySpacingSequence, applyTypographySequence } from '
|
|
4
|
-
import CONFIG, { CSS_VARS } from '
|
|
3
|
+
import { applyDocument, applySpacingSequence, applyTimingSequence, applyTypographySequence } from './config'
|
|
4
|
+
import CONFIG, { CSS_VARS } from './factory'
|
|
5
|
+
import { applyReset } from './reset'
|
|
5
6
|
import {
|
|
6
7
|
isArray,
|
|
7
8
|
colorStringToRgbaArray,
|
|
@@ -14,8 +15,9 @@ import {
|
|
|
14
15
|
getDefaultOrFirstKey,
|
|
15
16
|
getFontFaceEach,
|
|
16
17
|
hslToRgb,
|
|
17
|
-
getColorShade
|
|
18
|
-
|
|
18
|
+
getColorShade,
|
|
19
|
+
setVariables
|
|
20
|
+
} from './utils'
|
|
19
21
|
|
|
20
22
|
const ENV = process.env.NODE_ENV
|
|
21
23
|
|
|
@@ -45,7 +47,7 @@ export const getColor = value => {
|
|
|
45
47
|
if (tone.slice(0, 1) === '-' || tone.slice(0, 1) === '+') {
|
|
46
48
|
rgb = hexToRgbArray(getColorShade(toHex, parseFloat(tone))).join(', ')
|
|
47
49
|
} else {
|
|
48
|
-
const [r, g, b] = [...rgb.split(', ').map(v =>
|
|
50
|
+
const [r, g, b] = [...rgb.split(', ').map(v => parseInt(v))]
|
|
49
51
|
const hsl = rgbToHSL(r, g, b)
|
|
50
52
|
const [h, s, l] = hsl // eslint-disable-line
|
|
51
53
|
const newRgb = hslToRgb(h, s, parseFloat(tone) / 100 * 255)
|
|
@@ -104,26 +106,29 @@ const getThemeValue = theme => {
|
|
|
104
106
|
|
|
105
107
|
export const getTheme = value => {
|
|
106
108
|
const { THEME } = CONFIG
|
|
107
|
-
|
|
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
|
+
|
|
108
119
|
if (isObjectLike(value) && value[1]) {
|
|
109
120
|
const themeName = value[0]
|
|
110
121
|
const subThemeName = value[1]
|
|
111
122
|
const { helpers, variants, state } = THEME[themeName]
|
|
123
|
+
|
|
112
124
|
if (variants && variants[subThemeName]) return getThemeValue(variants[subThemeName])
|
|
113
125
|
if (helpers && helpers[subThemeName]) return getThemeValue(helpers[subThemeName])
|
|
114
126
|
if (state && state[subThemeName]) return getThemeValue(state[subThemeName])
|
|
115
127
|
} else if (isObject(value)) return setThemeValue(value)
|
|
116
|
-
else if (isString(value) && THEME[value]) return getThemeValue(THEME[value])
|
|
117
128
|
|
|
118
129
|
if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose) console.warn('Can\'t find theme', value)
|
|
119
130
|
}
|
|
120
131
|
|
|
121
|
-
const setPrefersScheme = (theme, key, variant, themeValue) => {
|
|
122
|
-
const result = getTheme(variant)
|
|
123
|
-
themeValue[`@media (prefers-color-scheme: ${key})`] = result
|
|
124
|
-
if (isObject(variant) && !variant.value) variant.value = result
|
|
125
|
-
}
|
|
126
|
-
|
|
127
132
|
const setInverseTheme = (theme, variant, value) => {
|
|
128
133
|
if (isObject(variant)) {
|
|
129
134
|
theme.variants.inverse.value = setThemeValue(variant)
|
|
@@ -138,25 +143,39 @@ const setInverseTheme = (theme, variant, value) => {
|
|
|
138
143
|
}
|
|
139
144
|
}
|
|
140
145
|
|
|
141
|
-
const
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
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)
|
|
145
156
|
keys.map(key => {
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
else getThemeValue(helpers[key])
|
|
157
|
+
const variant = state[key]
|
|
158
|
+
setPseudo(theme, key, variant, value)
|
|
149
159
|
return theme
|
|
150
160
|
})
|
|
151
161
|
return theme
|
|
152
162
|
}
|
|
153
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
|
+
|
|
154
171
|
const goThroughVariants = (theme, value) => {
|
|
155
172
|
const { variants } = theme
|
|
156
173
|
if (!variants) return
|
|
157
174
|
const keys = Object.keys(variants)
|
|
158
175
|
keys.map(key => {
|
|
159
176
|
const variant = variants[key]
|
|
177
|
+
// console.log('=========')
|
|
178
|
+
// console.log(theme, key, variant, value)
|
|
160
179
|
if (key === 'dark' || key === 'light') setPrefersScheme(theme, key, variant, value)
|
|
161
180
|
if (key === 'inverse') setInverseTheme(theme, variant, value)
|
|
162
181
|
return theme
|
|
@@ -164,19 +183,14 @@ const goThroughVariants = (theme, value) => {
|
|
|
164
183
|
return theme
|
|
165
184
|
}
|
|
166
185
|
|
|
167
|
-
const
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const goThroughInteractiveStates = (theme, value) => {
|
|
174
|
-
const { state } = theme
|
|
175
|
-
if (!state) return
|
|
176
|
-
const keys = Object.keys(state)
|
|
186
|
+
const goThroughHelpers = (theme, value) => {
|
|
187
|
+
const { helpers } = theme
|
|
188
|
+
if (!helpers) return
|
|
189
|
+
const keys = Object.keys(helpers)
|
|
177
190
|
keys.map(key => {
|
|
178
|
-
const
|
|
179
|
-
|
|
191
|
+
const helper = helpers[key]
|
|
192
|
+
if (isString(helper)) helpers[key] = CONFIG.THEME[helper]
|
|
193
|
+
else getThemeValue(helpers[key])
|
|
180
194
|
return theme
|
|
181
195
|
})
|
|
182
196
|
return theme
|
|
@@ -214,6 +228,10 @@ const setFontFamily = (val, key) => {
|
|
|
214
228
|
return { var: CSSvar, value: str, arr: value, type }
|
|
215
229
|
}
|
|
216
230
|
|
|
231
|
+
const setCases = (val, key) => {
|
|
232
|
+
return val()
|
|
233
|
+
}
|
|
234
|
+
|
|
217
235
|
const setSameValue = (val, key) => val
|
|
218
236
|
|
|
219
237
|
export const SETTERS = {
|
|
@@ -223,8 +241,12 @@ export const SETTERS = {
|
|
|
223
241
|
font_family: setFontFamily,
|
|
224
242
|
theme: setTheme,
|
|
225
243
|
typography: setSameValue,
|
|
244
|
+
cases: setCases,
|
|
226
245
|
spacing: setSameValue,
|
|
227
|
-
|
|
246
|
+
media: setSameValue,
|
|
247
|
+
timing: setSameValue,
|
|
248
|
+
icons: setSameValue,
|
|
249
|
+
reset: setSameValue
|
|
228
250
|
}
|
|
229
251
|
|
|
230
252
|
/**
|
|
@@ -238,8 +260,15 @@ export const setValue = (FACTORY_NAME, value, key) => {
|
|
|
238
260
|
const factoryName = FACTORY_NAME.toLowerCase()
|
|
239
261
|
const FACTORY = CONFIG[FACTORY_NAME]
|
|
240
262
|
const result = SETTERS[factoryName](value, key)
|
|
263
|
+
|
|
264
|
+
// console.log(CONFIG.verbose)
|
|
265
|
+
if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose && FACTORY[key]) {
|
|
266
|
+
// console.warn('Replacing ', key, ' as ', FACTORY[key], ' in ', factoryName)
|
|
267
|
+
}
|
|
268
|
+
|
|
241
269
|
FACTORY[key] = result
|
|
242
|
-
|
|
270
|
+
setVariables(result, key)
|
|
271
|
+
|
|
243
272
|
return FACTORY
|
|
244
273
|
}
|
|
245
274
|
|
|
@@ -252,7 +281,15 @@ export const setEach = (factoryName, props) => {
|
|
|
252
281
|
}
|
|
253
282
|
|
|
254
283
|
export const set = recivedConfig => {
|
|
255
|
-
const { version, verbose, ...config } = recivedConfig
|
|
284
|
+
const { version, verbose, useVariable, ...config } = recivedConfig
|
|
285
|
+
|
|
286
|
+
// console.log('=========')
|
|
287
|
+
// console.log(verbose)
|
|
288
|
+
CONFIG.verbose = verbose
|
|
289
|
+
CONFIG.useVariable = useVariable
|
|
290
|
+
// console.log(recivedConfig)
|
|
291
|
+
if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose) console.log(CONFIG)
|
|
292
|
+
|
|
256
293
|
const keys = Object.keys(config)
|
|
257
294
|
keys.map(key => setEach(key, config[key]))
|
|
258
295
|
|
|
@@ -260,11 +297,9 @@ export const set = recivedConfig => {
|
|
|
260
297
|
applyTypographySequence()
|
|
261
298
|
applySpacingSequence()
|
|
262
299
|
applyDocument()
|
|
300
|
+
applyTimingSequence()
|
|
301
|
+
applyReset()
|
|
263
302
|
|
|
264
|
-
CONFIG.
|
|
265
|
-
|
|
266
|
-
console.log(CONFIG)
|
|
303
|
+
CONFIG.VARS = CSS_VARS
|
|
267
304
|
return CONFIG
|
|
268
305
|
}
|
|
269
|
-
|
|
270
|
-
export default set
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const ENV = process.env.NODE_ENV
|
|
4
|
+
|
|
5
|
+
export const colorStringToRgbaArray = color => {
|
|
6
|
+
if (color === '') return
|
|
7
|
+
if (color.toLowerCase() === 'transparent') return [0, 0, 0, 0]
|
|
8
|
+
|
|
9
|
+
// convert #RGB and #RGBA to #RRGGBB and #RRGGBBAA
|
|
10
|
+
if (color[0] === '#') {
|
|
11
|
+
if (color.length < 7) {
|
|
12
|
+
color = '#' + color[1] + color[1] + color[2] + color[2] + color[3] + color[3] + (color.length > 4 ? color[4] + color[4] : '')
|
|
13
|
+
} return [parseInt(color.substr(1, 2), 16),
|
|
14
|
+
parseInt(color.substr(3, 2), 16),
|
|
15
|
+
parseInt(color.substr(5, 2), 16),
|
|
16
|
+
color.length > 7 ? parseInt(color.substr(7, 2), 16) / 255 : 1]
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// convert named colors
|
|
20
|
+
if (color.indexOf('rgb') === -1) {
|
|
21
|
+
// intentionally use unknown tag to lower chances of css rule override with !important
|
|
22
|
+
const elem = document.body.appendChild(document.createElement('fictum'))
|
|
23
|
+
// this flag tested on chrome 59, ff 53, ie9, ie10, ie11, edge 14
|
|
24
|
+
const flag = 'rgb(1, 2, 3)'
|
|
25
|
+
elem.style.color = flag
|
|
26
|
+
// color set failed - some monstrous css rule is probably taking over the color of our object
|
|
27
|
+
if (elem.style.color !== flag) return
|
|
28
|
+
elem.style.color = color
|
|
29
|
+
if (elem.style.color === flag || elem.style.color === '') return // color parse failed
|
|
30
|
+
color = window.getComputedStyle(elem).color
|
|
31
|
+
document.body.removeChild(elem)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// convert 'rgb(R,G,B)' to 'rgb(R,G,B,A)' which looks awful but will pass the regxep below
|
|
35
|
+
if (color.indexOf('rgb') === 0) {
|
|
36
|
+
if (color.indexOf('rgba') === -1) color = `${color}, 1`
|
|
37
|
+
return color.match(/[\.\d]+/g).map(a => +a) // eslint-disable-line
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const mixTwoColors = (colorA, colorB, range = 0.5) => {
|
|
42
|
+
colorA = colorStringToRgbaArray(colorA)
|
|
43
|
+
colorB = colorStringToRgbaArray(colorB)
|
|
44
|
+
return mixTwoRgba(colorA, colorB, range)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export const hexToRgb = (hex, alpha = 1) => {
|
|
48
|
+
const [r, g, b] = hex.match(/\w\w/g).map(x => parseInt(x, 16))
|
|
49
|
+
return `rgb(${r},${g},${b})`
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const hexToRgbArray = (hex, alpha = 1) => {
|
|
53
|
+
const [r, g, b] = hex.match(/\w\w/g).map(x => parseInt(x, 16))
|
|
54
|
+
return [r, g, b]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export const rgbToHex = (r, g, b) => {
|
|
58
|
+
return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export const rgbArrayToHex = ([r, g, b]) => {
|
|
62
|
+
return ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export const hexToRgba = (hex, alpha = 1) => {
|
|
66
|
+
const [r, g, b] = hex.match(/\w\w/g).map(x => parseInt(x, 16))
|
|
67
|
+
return `rgba(${r},${g},${b},${alpha})`
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const mixTwoRgb = (colorA, colorB, range = 0.5) => {
|
|
71
|
+
const arr = []
|
|
72
|
+
for (let i = 0; i < 3; i++) {
|
|
73
|
+
arr[i] = Math.round(
|
|
74
|
+
colorA[i] + (
|
|
75
|
+
(colorB[i] - colorA[i]) * range
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
return `rgb(${arr})`
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export const changeLightness = (delta, hsl) => {
|
|
83
|
+
const [hue, saturation, lightness] = hsl
|
|
84
|
+
|
|
85
|
+
const newLightness = Math.max(
|
|
86
|
+
0,
|
|
87
|
+
Math.min(100, lightness + parseFloat(delta))
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
return [hue, saturation, newLightness]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export const rgbToHSL = (r, g, b) => {
|
|
94
|
+
const a = Math.max(r, g, b); const n = a - Math.min(r, g, b); const f = (1 - Math.abs(a + a - n - 1))
|
|
95
|
+
const h = n && ((a == r) ? (g - b) / n : ((a == g) ? 2 + (b - r) / n : 4 + (r - g) / n)) //eslint-disable-line
|
|
96
|
+
return [60 * (h < 0 ? h + 6 : h), f ? n / f : 0, (a + a - n) / 2]
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export const hslToRgb = (h, s, l,
|
|
100
|
+
a = s * Math.min(l, 1 - l),
|
|
101
|
+
f = (n, k = (n + h / 30) % 12) => l - a * Math.max(
|
|
102
|
+
Math.min(k - 3, 9 - k, 1), -1
|
|
103
|
+
)
|
|
104
|
+
) => [f(0), f(8), f(4)]
|
|
105
|
+
|
|
106
|
+
export const getColorShade = (col, amt) => {
|
|
107
|
+
const num = parseInt(col, 16)
|
|
108
|
+
|
|
109
|
+
let r = (num >> 16) + amt
|
|
110
|
+
|
|
111
|
+
if (r > 255) r = 255
|
|
112
|
+
else if (r < 0) r = 0
|
|
113
|
+
|
|
114
|
+
let b = ((num >> 8) & 0x00FF) + amt
|
|
115
|
+
|
|
116
|
+
if (b > 255) b = 255
|
|
117
|
+
else if (b < 0) b = 0
|
|
118
|
+
|
|
119
|
+
let g = (num & 0x0000FF) + amt
|
|
120
|
+
|
|
121
|
+
if (g > 255) g = 255
|
|
122
|
+
else if (g < 0) g = 0
|
|
123
|
+
|
|
124
|
+
return (g | (b << 8) | (r << 16)).toString(16)
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export const mixTwoRgba = (colorA, colorB, range = 0.5) => {
|
|
128
|
+
const arr = []
|
|
129
|
+
for (let i = 0; i < 4; i++) {
|
|
130
|
+
const round = (i === 3) ? x => x : Math.round
|
|
131
|
+
arr[i] = round(
|
|
132
|
+
(colorA[i] + (
|
|
133
|
+
(colorB[i] - colorA[i]) * range
|
|
134
|
+
))
|
|
135
|
+
)
|
|
136
|
+
}
|
|
137
|
+
return `rgba(${arr})`
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export const opacify = (color, opacity) => {
|
|
141
|
+
const arr = colorStringToRgbaArray(color)
|
|
142
|
+
if (!arr) {
|
|
143
|
+
if (ENV === 'test' || ENV === 'development') console.warn(color + 'color is not rgba')
|
|
144
|
+
return
|
|
145
|
+
}
|
|
146
|
+
arr[3] = opacity
|
|
147
|
+
return `rgba(${arr})`
|
|
148
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
export const getDefaultOrFirstKey = (LIBRARY, key) => {
|
|
4
|
+
if (LIBRARY[key]) return LIBRARY[key].value
|
|
5
|
+
if (LIBRARY.default) return LIBRARY[LIBRARY.default].value
|
|
6
|
+
return LIBRARY[Object.keys(LIBRARY)[0]].value
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const getFontFormat = url => url.split(/[#?]/)[0].split('.').pop().trim()
|
|
10
|
+
|
|
11
|
+
export const setCustomFont = (name, weight, url) => `@font-face {
|
|
12
|
+
font-family: '${name}';
|
|
13
|
+
font-style: normal;
|
|
14
|
+
font-weight: ${weight};
|
|
15
|
+
src: url('${url}') format('${getFontFormat(url)}');
|
|
16
|
+
}`
|
|
17
|
+
// src: url('${url}') format('${getFontFormat(url)}');
|
|
18
|
+
|
|
19
|
+
export const getFontFaceEach = (name, weightsObject) => {
|
|
20
|
+
const keys = Object.keys(weightsObject)
|
|
21
|
+
const weightsJoint = keys.map(key => {
|
|
22
|
+
const { fontWeight, url } = weightsObject[key]
|
|
23
|
+
return setCustomFont(name, fontWeight, url)
|
|
24
|
+
})
|
|
25
|
+
return weightsJoint.join('\n')
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const getFontFace = LIBRARY => {
|
|
29
|
+
const keys = Object.keys(LIBRARY)
|
|
30
|
+
const fontsJoint = keys.map(key => getFontFaceEach(key, LIBRARY[key].value))
|
|
31
|
+
return fontsJoint.join('\n')
|
|
32
|
+
}
|
package/src/utils/index.js
CHANGED
|
@@ -1,365 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export
|
|
8
|
-
|
|
9
|
-
export const isArray = arg => Array.isArray(arg)
|
|
10
|
-
|
|
11
|
-
export const isObject = arg => {
|
|
12
|
-
if (arg === null) return false
|
|
13
|
-
return (typeof arg === 'object') && (arg.constructor === Object)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const isObjectLike = arg => {
|
|
17
|
-
if (arg === null) return false
|
|
18
|
-
return (typeof arg === 'object')
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const merge = (obj, original) => {
|
|
22
|
-
for (const e in original) {
|
|
23
|
-
const objProp = obj[e]
|
|
24
|
-
const originalProp = original[e]
|
|
25
|
-
if (objProp === undefined) {
|
|
26
|
-
obj[e] = originalProp
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return obj
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export const deepMerge = (obj, obj2) => {
|
|
33
|
-
for (const e in obj2) {
|
|
34
|
-
const objProp = obj[e]
|
|
35
|
-
const obj2Prop = obj2[e]
|
|
36
|
-
if (objProp === undefined) {
|
|
37
|
-
obj[e] = obj2Prop
|
|
38
|
-
} else if (isObjectLike(objProp) && isObject(obj2Prop)) {
|
|
39
|
-
deepMerge(objProp, obj2Prop)
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return obj
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export const colorStringToRgbaArray = color => {
|
|
46
|
-
if (color === '') return
|
|
47
|
-
if (color.toLowerCase() === 'transparent') return [0, 0, 0, 0]
|
|
48
|
-
|
|
49
|
-
// convert #RGB and #RGBA to #RRGGBB and #RRGGBBAA
|
|
50
|
-
if (color[0] === '#') {
|
|
51
|
-
if (color.length < 7) {
|
|
52
|
-
color = '#' + color[1] + color[1] + color[2] + color[2] + color[3] + color[3] + (color.length > 4 ? color[4] + color[4] : '')
|
|
53
|
-
} return [parseInt(color.substr(1, 2), 16),
|
|
54
|
-
parseInt(color.substr(3, 2), 16),
|
|
55
|
-
parseInt(color.substr(5, 2), 16),
|
|
56
|
-
color.length > 7 ? parseInt(color.substr(7, 2), 16) / 255 : 1]
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// convert named colors
|
|
60
|
-
if (color.indexOf('rgb') === -1) {
|
|
61
|
-
// intentionally use unknown tag to lower chances of css rule override with !important
|
|
62
|
-
const elem = document.body.appendChild(document.createElement('fictum'))
|
|
63
|
-
// this flag tested on chrome 59, ff 53, ie9, ie10, ie11, edge 14
|
|
64
|
-
const flag = 'rgb(1, 2, 3)'
|
|
65
|
-
elem.style.color = flag
|
|
66
|
-
// color set failed - some monstrous css rule is probably taking over the color of our object
|
|
67
|
-
if (elem.style.color !== flag) return
|
|
68
|
-
elem.style.color = color
|
|
69
|
-
if (elem.style.color === flag || elem.style.color === '') return // color parse failed
|
|
70
|
-
color = window.getComputedStyle(elem).color
|
|
71
|
-
document.body.removeChild(elem)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// convert 'rgb(R,G,B)' to 'rgb(R,G,B,A)' which looks awful but will pass the regxep below
|
|
75
|
-
if (color.indexOf('rgb') === 0) {
|
|
76
|
-
if (color.indexOf('rgba') === -1) color = `${color}, 1`
|
|
77
|
-
return color.match(/[\.\d]+/g).map(a => +a) // eslint-disable-line
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export const mixTwoColors = (colorA, colorB, range = 0.5) => {
|
|
82
|
-
colorA = colorStringToRgbaArray(colorA)
|
|
83
|
-
colorB = colorStringToRgbaArray(colorB)
|
|
84
|
-
return mixTwoRgba(colorA, colorB, range)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export const hexToRgb = (hex, alpha = 1) => {
|
|
88
|
-
const [r, g, b] = hex.match(/\w\w/g).map(x => parseInt(x, 16))
|
|
89
|
-
return `rgb(${r},${g},${b})`
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export const hexToRgbArray = (hex, alpha = 1) => {
|
|
93
|
-
const [r, g, b] = hex.match(/\w\w/g).map(x => parseInt(x, 16))
|
|
94
|
-
return [r, g, b]
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export const rgbToHex = (r, g, b) => {
|
|
98
|
-
return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export const rgbArrayToHex = ([r, g, b]) => {
|
|
102
|
-
return ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export const hexToRgba = (hex, alpha = 1) => {
|
|
106
|
-
const [r, g, b] = hex.match(/\w\w/g).map(x => parseInt(x, 16))
|
|
107
|
-
return `rgba(${r},${g},${b},${alpha})`
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
export const mixTwoRgb = (colorA, colorB, range = 0.5) => {
|
|
111
|
-
const arr = []
|
|
112
|
-
for (let i = 0; i < 3; i++) {
|
|
113
|
-
arr[i] = Math.round(
|
|
114
|
-
colorA[i] + (
|
|
115
|
-
(colorB[i] - colorA[i]) * range
|
|
116
|
-
)
|
|
117
|
-
)
|
|
118
|
-
}
|
|
119
|
-
return `rgb(${arr})`
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// export const rgbToHSL = (r, g, b) => {
|
|
123
|
-
// console.log(r, g, b)
|
|
124
|
-
// r /= 255
|
|
125
|
-
// g /= 255
|
|
126
|
-
// b /= 255
|
|
127
|
-
// const l = Math.max(r, g, b)
|
|
128
|
-
// const s = l - Math.min(r, g, b)
|
|
129
|
-
// const h = s
|
|
130
|
-
// ? l === r
|
|
131
|
-
// ? (g - b) / s
|
|
132
|
-
// : l === g
|
|
133
|
-
// ? 2 + (b - r) / s
|
|
134
|
-
// : 4 + (r - g) / s
|
|
135
|
-
// : 0
|
|
136
|
-
// return [
|
|
137
|
-
// 60 * h < 0 ? 60 * h + 360 : 60 * h,
|
|
138
|
-
// 100 * (s ? (l <= 0.5 ? s / (2 * l - s) : s / (2 - (2 * l - s))) : 0),
|
|
139
|
-
// (100 * (2 * l - s)) / 2
|
|
140
|
-
// ]
|
|
141
|
-
// }
|
|
142
|
-
|
|
143
|
-
// export const hslToRgb = (h, s, l) => {
|
|
144
|
-
// console.log(h, s, l)
|
|
145
|
-
// const a = s * Math.min(l, 1 - l)
|
|
146
|
-
// const f = (n, k = (n + h / 30) % 12) => l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)
|
|
147
|
-
// return [f(0), f(8), f(4)].map(v => v * 1000)
|
|
148
|
-
// }
|
|
149
|
-
|
|
150
|
-
export const changeLightness = (delta, hsl) => {
|
|
151
|
-
const [hue, saturation, lightness] = hsl
|
|
152
|
-
|
|
153
|
-
const newLightness = Math.max(
|
|
154
|
-
0,
|
|
155
|
-
Math.min(100, lightness + parseFloat(delta))
|
|
156
|
-
)
|
|
157
|
-
|
|
158
|
-
return [hue, saturation, newLightness]
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export const rgbToHSL = (r, g, b) => {
|
|
162
|
-
const a = Math.max(r, g, b); const n = a - Math.min(r, g, b); const f = (1 - Math.abs(a + a - n - 1))
|
|
163
|
-
const h = n && ((a == r) ? (g - b) / n : ((a == g) ? 2 + (b - r) / n : 4 + (r - g) / n)) //eslint-disable-line
|
|
164
|
-
return [60 * (h < 0 ? h + 6 : h), f ? n / f : 0, (a + a - n) / 2]
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export const hslToRgb = (h, s, l,
|
|
168
|
-
a = s * Math.min(l, 1 - l),
|
|
169
|
-
f = (n, k = (n + h / 30) % 12) => l - a * Math.max(
|
|
170
|
-
Math.min(k - 3, 9 - k, 1), -1
|
|
171
|
-
)
|
|
172
|
-
) => [f(0), f(8), f(4)]
|
|
173
|
-
|
|
174
|
-
export const getColorShade = (col, amt) => {
|
|
175
|
-
const num = parseInt(col, 16)
|
|
176
|
-
|
|
177
|
-
let r = (num >> 16) + amt
|
|
178
|
-
|
|
179
|
-
if (r > 255) r = 255
|
|
180
|
-
else if (r < 0) r = 0
|
|
181
|
-
|
|
182
|
-
let b = ((num >> 8) & 0x00FF) + amt
|
|
183
|
-
|
|
184
|
-
if (b > 255) b = 255
|
|
185
|
-
else if (b < 0) b = 0
|
|
186
|
-
|
|
187
|
-
let g = (num & 0x0000FF) + amt
|
|
188
|
-
|
|
189
|
-
if (g > 255) g = 255
|
|
190
|
-
else if (g < 0) g = 0
|
|
191
|
-
|
|
192
|
-
return (g | (b << 8) | (r << 16)).toString(16)
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
export const mixTwoRgba = (colorA, colorB, range = 0.5) => {
|
|
196
|
-
const arr = []
|
|
197
|
-
for (let i = 0; i < 4; i++) {
|
|
198
|
-
const round = (i === 3) ? x => x : Math.round
|
|
199
|
-
arr[i] = round(
|
|
200
|
-
(colorA[i] + (
|
|
201
|
-
(colorB[i] - colorA[i]) * range
|
|
202
|
-
))
|
|
203
|
-
)
|
|
204
|
-
}
|
|
205
|
-
return `rgba(${arr})`
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
export const opacify = (color, opacity) => {
|
|
209
|
-
const arr = colorStringToRgbaArray(color)
|
|
210
|
-
if (!arr) {
|
|
211
|
-
if (ENV === 'test' || ENV === 'development') console.warn(color + 'color is not rgba')
|
|
212
|
-
return
|
|
213
|
-
}
|
|
214
|
-
arr[3] = opacity
|
|
215
|
-
return `rgba(${arr})`
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
export const getDefaultOrFirstKey = (LIBRARY, key) => {
|
|
219
|
-
if (LIBRARY[key]) return LIBRARY[key].value
|
|
220
|
-
if (LIBRARY.default) return LIBRARY[LIBRARY.default].value
|
|
221
|
-
return LIBRARY[Object.keys(LIBRARY)[0]].value
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
export const getFontFormat = url => url.split(/[#?]/)[0].split('.').pop().trim()
|
|
225
|
-
|
|
226
|
-
export const setCustomFont = (name, weight, url) => `@font-face {
|
|
227
|
-
font-family: '${name}';
|
|
228
|
-
font-style: normal;
|
|
229
|
-
font-weight: ${weight};
|
|
230
|
-
src: url('${url}') format('${getFontFormat(url)}');
|
|
231
|
-
}`
|
|
232
|
-
// src: url('${url}') format('${getFontFormat(url)}');
|
|
233
|
-
|
|
234
|
-
export const getFontFaceEach = (name, weightsObject) => {
|
|
235
|
-
const keys = Object.keys(weightsObject)
|
|
236
|
-
const weightsJoint = keys.map(key => {
|
|
237
|
-
const { fontWeight, url } = weightsObject[key]
|
|
238
|
-
return setCustomFont(name, fontWeight, url)
|
|
239
|
-
})
|
|
240
|
-
return weightsJoint.join('\n')
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
export const getFontFace = LIBRARY => {
|
|
244
|
-
const keys = Object.keys(LIBRARY)
|
|
245
|
-
const fontsJoint = keys.map(key => getFontFaceEach(key, LIBRARY[key].value))
|
|
246
|
-
return fontsJoint.join('\n')
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
export const numToLetterMap = {
|
|
250
|
-
'-6': 'U',
|
|
251
|
-
'-5': 'V',
|
|
252
|
-
'-4': 'W',
|
|
253
|
-
'-3': 'X',
|
|
254
|
-
'-2': 'Y',
|
|
255
|
-
'-1': 'Z',
|
|
256
|
-
0: 'A',
|
|
257
|
-
1: 'B',
|
|
258
|
-
2: 'C',
|
|
259
|
-
3: 'D',
|
|
260
|
-
4: 'E',
|
|
261
|
-
5: 'F',
|
|
262
|
-
6: 'G',
|
|
263
|
-
7: 'H',
|
|
264
|
-
8: 'I',
|
|
265
|
-
9: 'J',
|
|
266
|
-
10: 'K',
|
|
267
|
-
11: 'L',
|
|
268
|
-
12: 'M',
|
|
269
|
-
13: 'N',
|
|
270
|
-
14: 'O',
|
|
271
|
-
15: 'P'
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
const setSequenceValue = ({ key, variable, value, scaling, state, index }) => {
|
|
275
|
-
state.sequence[variable] = {
|
|
276
|
-
key,
|
|
277
|
-
decimal: Math.round(value * 100) / 100,
|
|
278
|
-
val: Math.round(value),
|
|
279
|
-
scaling,
|
|
280
|
-
index
|
|
281
|
-
}
|
|
282
|
-
state.scales[variable] = scaling
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
export const generateSubSequence = ({ key, base, value, ratio, variable, state, index }) => {
|
|
286
|
-
const next = value * ratio
|
|
287
|
-
const smallscale = (next - value) / ratio
|
|
288
|
-
|
|
289
|
-
const valueRounded = Math.round(value)
|
|
290
|
-
const nextRounded = Math.round(next)
|
|
291
|
-
const diffRounded = nextRounded - valueRounded
|
|
292
|
-
|
|
293
|
-
let arr = []
|
|
294
|
-
const first = next - smallscale
|
|
295
|
-
const second = value + smallscale
|
|
296
|
-
const middle = (first + second) / 2
|
|
297
|
-
if (diffRounded > 100) arr = [first, middle, second]
|
|
298
|
-
else arr = [first, second]
|
|
299
|
-
// else if (diffRounded > 2) arr = [first, second]
|
|
300
|
-
// else if (diffRounded > 1) arr = [middle]
|
|
301
|
-
|
|
302
|
-
arr.map((v, k) => {
|
|
303
|
-
const scaling = Math.round(v / base * 1000) / 1000
|
|
304
|
-
const newVar = variable + (k + 1)
|
|
305
|
-
|
|
306
|
-
return setSequenceValue({ key: key + (k + 1), variable: newVar, value: v, scaling, state, index: index + (k + 1) / 10 })
|
|
307
|
-
})
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
export const generateSequence = ({ type, base, ratio, range, subSequence, ...state }) => {
|
|
311
|
-
const n = Math.abs(range[0]) + Math.abs(range[1])
|
|
312
|
-
const prefix = '--' + type + '-'
|
|
313
|
-
for (let i = 0; i <= n; i++) {
|
|
314
|
-
const key = range[1] - i
|
|
315
|
-
const letterKey = numToLetterMap[key]
|
|
316
|
-
const value = base * Math.pow(ratio, key)
|
|
317
|
-
const scaling = Math.round(value / base * 1000) / 1000
|
|
318
|
-
const variable = prefix + letterKey
|
|
319
|
-
|
|
320
|
-
setSequenceValue({ key: letterKey, variable, value, scaling, state, index: key })
|
|
321
|
-
|
|
322
|
-
if (subSequence) generateSubSequence({ key: letterKey, base, value, ratio, variable, state, index: key })
|
|
323
|
-
}
|
|
324
|
-
return state
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
export const fallBack = ({ type, prop, val = 'A', prefix = '--font-size-', unit = UNIT.default }) => {
|
|
328
|
-
if (typeof val !== 'string') console.warn(prop, val, 'is not a string')
|
|
329
|
-
|
|
330
|
-
if (val === '-' || val === '') return ({ })
|
|
331
|
-
if (val === 'none' || val === 'auto' || val === 'fit-content' || val === 'min-content' || val === 'max-content') return ({ [prop]: val })
|
|
332
|
-
|
|
333
|
-
// const startsWithLetterRegex = /^[a-zA-Z]/i
|
|
334
|
-
const startsWithLetterRegex = /^-?[a-zA-Z]/i
|
|
335
|
-
// const hasLetter = /[A-Za-z]+/.test(val)
|
|
336
|
-
const startsWithLetter = startsWithLetterRegex.test(val)
|
|
337
|
-
if (!startsWithLetter) return ({ [prop]: val })
|
|
338
|
-
|
|
339
|
-
const letterVal = val.toUpperCase()
|
|
340
|
-
const isNegative = letterVal.slice(0, 1) === '-' ? '-' : ''
|
|
341
|
-
const simplyLetterVal = isNegative ? letterVal.slice(1) : letterVal
|
|
342
|
-
|
|
343
|
-
const value = type ? type[prefix + simplyLetterVal] : null
|
|
344
|
-
if (!value) return console.warn('can\'t find', type, prefix + simplyLetterVal, simplyLetterVal)
|
|
345
|
-
|
|
346
|
-
return ({
|
|
347
|
-
[prop]: isNegative + value.val + value.unit,
|
|
348
|
-
[prop]: isNegative + value.scaling + 'em'
|
|
349
|
-
})
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
export const Arrayize = val => {
|
|
353
|
-
const isString = typeof val === 'string'
|
|
354
|
-
if (isString) return val.split(' ')
|
|
355
|
-
if (isObject(val)) return Object.keys(val).map(v => val[v])
|
|
356
|
-
if (isArray(val)) return val
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
export const findHeadings = (TYPOGRAPHY) => {
|
|
360
|
-
const { h1Matches, type, sequence } = TYPOGRAPHY
|
|
361
|
-
return new Array(6).fill(null).map((_, i) => {
|
|
362
|
-
const findLetter = numToLetterMap[h1Matches - i]
|
|
363
|
-
return sequence[`--${type}-${findLetter}`]
|
|
364
|
-
})
|
|
365
|
-
}
|
|
3
|
+
export * from './object'
|
|
4
|
+
export * from './color'
|
|
5
|
+
export * from './font'
|
|
6
|
+
export * from './sequence'
|
|
7
|
+
export * from './setVariables'
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
export const isString = arg => typeof arg === 'string'
|
|
4
|
+
|
|
5
|
+
export const isArray = arg => Array.isArray(arg)
|
|
6
|
+
|
|
7
|
+
export const isObject = arg => {
|
|
8
|
+
if (arg === null) return false
|
|
9
|
+
return (typeof arg === 'object') && (arg.constructor === Object)
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const isObjectLike = arg => {
|
|
13
|
+
if (arg === null) return false
|
|
14
|
+
return (typeof arg === 'object')
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const merge = (obj, original) => {
|
|
18
|
+
for (const e in original) {
|
|
19
|
+
const objProp = obj[e]
|
|
20
|
+
const originalProp = original[e]
|
|
21
|
+
if (objProp === undefined) {
|
|
22
|
+
obj[e] = originalProp
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return obj
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const deepMerge = (obj, obj2) => {
|
|
29
|
+
for (const e in obj2) {
|
|
30
|
+
const objProp = obj[e]
|
|
31
|
+
const obj2Prop = obj2[e]
|
|
32
|
+
if (objProp === undefined) {
|
|
33
|
+
obj[e] = obj2Prop
|
|
34
|
+
} else if (isObjectLike(objProp) && isObject(obj2Prop)) {
|
|
35
|
+
deepMerge(objProp, obj2Prop)
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return obj
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const Arrayize = val => {
|
|
42
|
+
const isString = typeof val === 'string'
|
|
43
|
+
if (isString) return val.split(' ')
|
|
44
|
+
if (isObject(val)) return Object.keys(val).map(v => val[v])
|
|
45
|
+
if (isArray(val)) return val
|
|
46
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { UNIT } from '../config'
|
|
4
|
+
|
|
5
|
+
export const numToLetterMap = {
|
|
6
|
+
'-6': 'U',
|
|
7
|
+
'-5': 'V',
|
|
8
|
+
'-4': 'W',
|
|
9
|
+
'-3': 'X',
|
|
10
|
+
'-2': 'Y',
|
|
11
|
+
'-1': 'Z',
|
|
12
|
+
0: 'A',
|
|
13
|
+
1: 'B',
|
|
14
|
+
2: 'C',
|
|
15
|
+
3: 'D',
|
|
16
|
+
4: 'E',
|
|
17
|
+
5: 'F',
|
|
18
|
+
6: 'G',
|
|
19
|
+
7: 'H',
|
|
20
|
+
8: 'I',
|
|
21
|
+
9: 'J',
|
|
22
|
+
10: 'K',
|
|
23
|
+
11: 'L',
|
|
24
|
+
12: 'M',
|
|
25
|
+
13: 'N',
|
|
26
|
+
14: 'O',
|
|
27
|
+
15: 'P'
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const setSequenceValue = ({ key, variable, value, scaling, state, index }) => {
|
|
31
|
+
state.sequence[variable] = {
|
|
32
|
+
key,
|
|
33
|
+
decimal: Math.round(value * 100) / 100,
|
|
34
|
+
val: Math.round(value),
|
|
35
|
+
scaling,
|
|
36
|
+
index
|
|
37
|
+
}
|
|
38
|
+
state.scales[variable] = scaling
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const generateSubSequence = ({ key, base, value, ratio, variable, state, index }) => {
|
|
42
|
+
const next = value * ratio
|
|
43
|
+
const smallscale = (next - value) / ratio
|
|
44
|
+
|
|
45
|
+
const valueRounded = Math.round(value)
|
|
46
|
+
const nextRounded = Math.round(next)
|
|
47
|
+
const diffRounded = nextRounded - valueRounded
|
|
48
|
+
|
|
49
|
+
let arr = []
|
|
50
|
+
const first = next - smallscale
|
|
51
|
+
const second = value + smallscale
|
|
52
|
+
const middle = (first + second) / 2
|
|
53
|
+
if (diffRounded > 100) arr = [first, middle, second]
|
|
54
|
+
else arr = [first, second]
|
|
55
|
+
// else if (diffRounded > 2) arr = [first, second]
|
|
56
|
+
// else if (diffRounded > 1) arr = [middle]
|
|
57
|
+
|
|
58
|
+
arr.map((v, k) => {
|
|
59
|
+
const scaling = Math.round(v / base * 1000) / 1000
|
|
60
|
+
const newVar = variable + (k + 1)
|
|
61
|
+
|
|
62
|
+
return setSequenceValue({ key: key + (k + 1), variable: newVar, value: v, scaling, state, index: index + (k + 1) / 10 })
|
|
63
|
+
})
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const generateSequence = ({ type, base, ratio, range, subSequence, ...state }) => {
|
|
67
|
+
const n = Math.abs(range[0]) + Math.abs(range[1])
|
|
68
|
+
const prefix = '--' + type + '-'
|
|
69
|
+
for (let i = 0; i <= n; i++) {
|
|
70
|
+
const key = range[1] - i
|
|
71
|
+
const letterKey = numToLetterMap[key]
|
|
72
|
+
const value = base * Math.pow(ratio, key)
|
|
73
|
+
const scaling = Math.round(value / base * 1000) / 1000
|
|
74
|
+
const variable = prefix + letterKey
|
|
75
|
+
|
|
76
|
+
setSequenceValue({ key: letterKey, variable, value, scaling, state, index: key })
|
|
77
|
+
|
|
78
|
+
if (subSequence) generateSubSequence({ key: letterKey, base, value, ratio, variable, state, index: key })
|
|
79
|
+
}
|
|
80
|
+
return state
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const fallBack = ({ type, prop, val = 'A', prefix = '--font-size-', unit = UNIT.default }) => {
|
|
84
|
+
if (typeof val !== 'string') console.warn(prop, val, 'is not a string')
|
|
85
|
+
|
|
86
|
+
if (val === '-' || val === '') return ({ })
|
|
87
|
+
if (val === 'none' || val === 'auto' || val === 'fit-content' || val === 'min-content' || val === 'max-content') return ({ [prop]: val })
|
|
88
|
+
|
|
89
|
+
// const startsWithLetterRegex = /^[a-zA-Z]/i
|
|
90
|
+
const startsWithLetterRegex = /^-?[a-zA-Z]/i
|
|
91
|
+
// const hasLetter = /[A-Za-z]+/.test(val)
|
|
92
|
+
const startsWithLetter = startsWithLetterRegex.test(val)
|
|
93
|
+
if (!startsWithLetter) return ({ [prop]: val })
|
|
94
|
+
|
|
95
|
+
const letterVal = val.toUpperCase()
|
|
96
|
+
const isNegative = letterVal.slice(0, 1) === '-' ? '-' : ''
|
|
97
|
+
const simplyLetterVal = isNegative ? letterVal.slice(1) : letterVal
|
|
98
|
+
|
|
99
|
+
const value = type ? type[prefix + simplyLetterVal] : null
|
|
100
|
+
if (!value) return console.warn('can\'t find', type, prefix + simplyLetterVal, simplyLetterVal)
|
|
101
|
+
|
|
102
|
+
if (unit === 'ms' || unit === 's') {
|
|
103
|
+
return ({ [prop]: isNegative + value.val + value.unit })
|
|
104
|
+
}
|
|
105
|
+
return ({
|
|
106
|
+
[prop]: isNegative + value.val + value.unit,
|
|
107
|
+
[prop]: isNegative + value.scaling + 'em'
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export const findHeadings = (TYPOGRAPHY) => {
|
|
112
|
+
const { h1Matches, type, sequence } = TYPOGRAPHY
|
|
113
|
+
return new Array(6).fill(null).map((_, i) => {
|
|
114
|
+
const findLetter = numToLetterMap[h1Matches - i]
|
|
115
|
+
return sequence[`--${type}-${findLetter}`]
|
|
116
|
+
})
|
|
117
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { CSS_VARS } from '../factory'
|
|
4
|
+
import { isObjectLike } from './object'
|
|
5
|
+
|
|
6
|
+
export const setVariables = (result, key) => {
|
|
7
|
+
// CSS_VARS[result.var] =
|
|
8
|
+
if (isObjectLike(result.value)) {
|
|
9
|
+
// console.group(key)
|
|
10
|
+
// for (const key in result.value) {
|
|
11
|
+
// console.log(key, result.value[key])
|
|
12
|
+
// }
|
|
13
|
+
// console.log(result)
|
|
14
|
+
// console.groupEnd(key)
|
|
15
|
+
} else {
|
|
16
|
+
CSS_VARS[result.var] = result.value
|
|
17
|
+
}
|
|
18
|
+
}
|
package/src/methods/create.js
DELETED
package/src/methods/generate.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
import { themeMap } from '../config/theme'
|
|
4
|
-
|
|
5
|
-
// var pairAsInvert = (scheme, referenced) => cx(scheme, referenced)
|
|
6
|
-
|
|
7
|
-
const mapThemeCSS = scheme => {
|
|
8
|
-
let str = ''
|
|
9
|
-
for (const prop in scheme) {
|
|
10
|
-
const mappedProp = themeMap[prop]
|
|
11
|
-
const value = scheme[prop]
|
|
12
|
-
if (mappedProp && value) {
|
|
13
|
-
str += `${mappedProp}: ${value}`
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
return str
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const generateTheme = scheme => {
|
|
20
|
-
const { helpers, inverse } = scheme
|
|
21
|
-
|
|
22
|
-
let rule = `
|
|
23
|
-
${mapThemeCSS(scheme)}
|
|
24
|
-
`
|
|
25
|
-
|
|
26
|
-
if (inverse) {
|
|
27
|
-
rule += `&.inverse { ${inverse} }`
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (helpers) {
|
|
31
|
-
for (const prop in helpers) {
|
|
32
|
-
const value = helpers[prop]
|
|
33
|
-
rule += `.${prop} { ${value} }`
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return rule
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export default { generateTheme }
|
package/src/methods/index.js
DELETED