@symbo.ls/scratch 0.4.3 → 0.6.0
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/document.js +0 -10
- package/src/config/index.js +1 -1
- package/src/config/spacing.js +0 -90
- package/src/config/timing.js +0 -14
- package/src/config/typography.js +1 -64
- package/src/index.js +0 -1
- package/src/set.js +14 -7
- package/src/system/color.js +83 -10
- package/src/system/document.js +11 -0
- package/src/system/index.js +5 -0
- package/src/{reset.js → system/reset.js} +4 -4
- package/src/system/spacing.js +93 -0
- package/src/system/theme.js +84 -17
- package/src/system/timing.js +21 -0
- package/src/system/typography.js +72 -0
package/package.json
CHANGED
package/src/config/document.js
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { FONT_FAMILY, THEME, TYPOGRAPHY } from '.'
|
|
4
|
-
import { getDefaultOrFirstKey, merge } from '../utils'
|
|
5
|
-
|
|
6
3
|
export const DOCUMENT = {}
|
|
7
|
-
|
|
8
|
-
export const applyDocument = () => merge(DOCUMENT, {
|
|
9
|
-
theme: THEME.document,
|
|
10
|
-
fontFamily: getDefaultOrFirstKey(FONT_FAMILY),
|
|
11
|
-
fontSize: TYPOGRAPHY.base,
|
|
12
|
-
lineHeight: TYPOGRAPHY.lineHeight
|
|
13
|
-
})
|
package/src/config/index.js
CHANGED
package/src/config/spacing.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
import { SEQUENCE, TYPOGRAPHY } from '.'
|
|
4
|
-
import { Arrayize, getSequenceValue, generateSequence, applySequenceVars, merge } from '../utils'
|
|
5
4
|
|
|
6
5
|
const defaultProps = {
|
|
7
6
|
base: TYPOGRAPHY.base,
|
|
@@ -15,93 +14,4 @@ const defaultProps = {
|
|
|
15
14
|
vars: {}
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
const runThroughMedia = props => {
|
|
19
|
-
for (const prop in props) {
|
|
20
|
-
const mediaProps = props[prop]
|
|
21
|
-
if (prop.slice(0, 1) === '@') {
|
|
22
|
-
const { type, base, ratio, range, subSequence, h1Matches, unit } = props
|
|
23
|
-
|
|
24
|
-
merge(mediaProps, {
|
|
25
|
-
type,
|
|
26
|
-
base,
|
|
27
|
-
ratio,
|
|
28
|
-
range,
|
|
29
|
-
subSequence,
|
|
30
|
-
h1Matches,
|
|
31
|
-
unit,
|
|
32
|
-
sequence: {},
|
|
33
|
-
scales: {},
|
|
34
|
-
styles: {},
|
|
35
|
-
vars: {}
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
generateSequence(mediaProps)
|
|
39
|
-
|
|
40
|
-
const mediaName = prop.slice(1)
|
|
41
|
-
applySequenceVars(mediaProps, mediaName)
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export const applySpacingSequence = () => {
|
|
47
|
-
generateSequence(defaultProps)
|
|
48
|
-
applySequenceVars(defaultProps)
|
|
49
|
-
runThroughMedia(defaultProps)
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const getSequence = (props) => {
|
|
53
|
-
if (!props) return
|
|
54
|
-
const hasGenerated = Object.keys(props.sequence).length > 0
|
|
55
|
-
return hasGenerated ? props : generateSequence(props)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export const getSpacingByKey = (val, property = 'padding', props, unit) => {
|
|
59
|
-
const prefix = '--spacing-'
|
|
60
|
-
|
|
61
|
-
const generatedSequence = getSequence(props)
|
|
62
|
-
const type = (generatedSequence || defaultProps).sequence
|
|
63
|
-
|
|
64
|
-
const stack = Arrayize(val)
|
|
65
|
-
if (!stack) return
|
|
66
|
-
|
|
67
|
-
const length = stack.length
|
|
68
|
-
|
|
69
|
-
const wrapSequenceItem = (prop, i) => getSequenceValue({
|
|
70
|
-
type,
|
|
71
|
-
prop,
|
|
72
|
-
val: stack[i],
|
|
73
|
-
prefix,
|
|
74
|
-
unit
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
let suffix = ''
|
|
78
|
-
if (property === 'borderWidth') {
|
|
79
|
-
property = 'border'
|
|
80
|
-
suffix = 'Width'
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
if (length === 2) {
|
|
84
|
-
return [
|
|
85
|
-
wrapSequenceItem(property + 'Block' + suffix, 0),
|
|
86
|
-
wrapSequenceItem(property + 'Inline' + suffix, 1)
|
|
87
|
-
]
|
|
88
|
-
}
|
|
89
|
-
if (length === 3) {
|
|
90
|
-
return [
|
|
91
|
-
wrapSequenceItem(property + 'BlockStart' + suffix, 0),
|
|
92
|
-
wrapSequenceItem(property + 'Inline' + suffix, 1),
|
|
93
|
-
wrapSequenceItem(property + 'BlockEnd' + suffix, 2)
|
|
94
|
-
]
|
|
95
|
-
} else if (length === 4) {
|
|
96
|
-
return [
|
|
97
|
-
wrapSequenceItem(property + 'BlockStart' + suffix, 0),
|
|
98
|
-
wrapSequenceItem(property + 'InlineStart' + suffix, 3),
|
|
99
|
-
wrapSequenceItem(property + 'BlockEnd' + suffix, 2),
|
|
100
|
-
wrapSequenceItem(property + 'InlineEnd' + suffix, 1)
|
|
101
|
-
]
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return getSequenceValue({ type, prop: property, val, prefix, unit })
|
|
105
|
-
}
|
|
106
|
-
|
|
107
17
|
export const SPACING = defaultProps
|
package/src/config/timing.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
import { SEQUENCE } from '.'
|
|
4
|
-
import { applySequenceVars, generateSequence, getSequenceValue } from '../utils'
|
|
5
4
|
|
|
6
5
|
const defaultProps = {
|
|
7
6
|
default: 150,
|
|
@@ -15,17 +14,4 @@ const defaultProps = {
|
|
|
15
14
|
vars: {}
|
|
16
15
|
}
|
|
17
16
|
|
|
18
|
-
export const applyTimingSequence = () => {
|
|
19
|
-
generateSequence(defaultProps)
|
|
20
|
-
applySequenceVars(defaultProps)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export const getTimingByKey = val => getSequenceValue({
|
|
24
|
-
type: defaultProps.sequence,
|
|
25
|
-
prop: 'duration',
|
|
26
|
-
val,
|
|
27
|
-
unit: 'ms',
|
|
28
|
-
prefix: '--duration-'
|
|
29
|
-
})
|
|
30
|
-
|
|
31
17
|
export const TIMING = defaultProps
|
package/src/config/typography.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { SEQUENCE, MEDIA } from '.'
|
|
5
|
-
import { getSequenceValue, generateSequence, findHeadings, merge, applySequenceVars } from '../utils'
|
|
3
|
+
import { SEQUENCE } from './sequence'
|
|
6
4
|
|
|
7
5
|
const defaultProps = {
|
|
8
6
|
browserDefault: 16,
|
|
@@ -19,65 +17,4 @@ const defaultProps = {
|
|
|
19
17
|
vars: {}
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
const runThroughMedia = props => {
|
|
23
|
-
for (const prop in props) {
|
|
24
|
-
const mediaProps = props[prop]
|
|
25
|
-
if (prop.slice(0, 1) === '@') {
|
|
26
|
-
const { type, base, ratio, range, subSequence, h1Matches, unit } = props
|
|
27
|
-
|
|
28
|
-
merge(mediaProps, {
|
|
29
|
-
type,
|
|
30
|
-
base,
|
|
31
|
-
ratio,
|
|
32
|
-
range,
|
|
33
|
-
subSequence,
|
|
34
|
-
h1Matches,
|
|
35
|
-
unit,
|
|
36
|
-
sequence: {},
|
|
37
|
-
scales: {},
|
|
38
|
-
styles: {},
|
|
39
|
-
vars: {}
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
generateSequence(mediaProps)
|
|
43
|
-
|
|
44
|
-
const mediaName = prop.slice(1)
|
|
45
|
-
applySequenceVars(mediaProps, mediaName)
|
|
46
|
-
|
|
47
|
-
const query = MEDIA[mediaName]
|
|
48
|
-
defaultProps.styles[`@media screen and ${query}`] = {
|
|
49
|
-
fontSize: mediaProps.base / defaultProps.browserDefault + unit
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const applyHeadings = (props) => {
|
|
56
|
-
if (props.h1Matches) {
|
|
57
|
-
const unit = props.unit
|
|
58
|
-
const HEADINGS = findHeadings(props)
|
|
59
|
-
const { styles } = props
|
|
60
|
-
for (const k in HEADINGS) {
|
|
61
|
-
styles[`h${parseInt(k) + 1}`] = {
|
|
62
|
-
fontSize: CONFIG.useVariable ? `var(${HEADINGS[k].variable})` : `${HEADINGS[k].scaling}${unit}`
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export const applyTypographySequence = () => {
|
|
69
|
-
generateSequence(defaultProps)
|
|
70
|
-
applyHeadings(defaultProps)
|
|
71
|
-
applySequenceVars(defaultProps)
|
|
72
|
-
runThroughMedia(defaultProps)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export const getFontSizeByKey = val => getSequenceValue({
|
|
76
|
-
type: defaultProps.sequence,
|
|
77
|
-
prop: 'fontSize',
|
|
78
|
-
val,
|
|
79
|
-
unit: defaultProps.unit,
|
|
80
|
-
prefix: '--font-size-'
|
|
81
|
-
})
|
|
82
|
-
|
|
83
20
|
export const TYPOGRAPHY = defaultProps
|
package/src/index.js
CHANGED
package/src/set.js
CHANGED
|
@@ -1,13 +1,20 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { applyDocument, applySpacingSequence, applyTimingSequence, applyTypographySequence } from './config'
|
|
4
3
|
import { CONFIG, CSS_VARS } from './factory' // eslint-disable-line no-unused-vars
|
|
5
|
-
import { applyReset } from './reset'
|
|
6
|
-
import { setColor, setGradient, setFont, setFontFamily, setTheme } from './system'
|
|
7
4
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
5
|
+
setColor,
|
|
6
|
+
setGradient,
|
|
7
|
+
setFont,
|
|
8
|
+
setFontFamily,
|
|
9
|
+
setTheme,
|
|
10
|
+
applyTypographySequence,
|
|
11
|
+
applySpacingSequence,
|
|
12
|
+
applyReset,
|
|
13
|
+
applyTimingSequence,
|
|
14
|
+
applyDocument
|
|
15
|
+
} from './system'
|
|
16
|
+
|
|
17
|
+
import { isFunction } from './utils'
|
|
11
18
|
|
|
12
19
|
const ENV = process.env.NODE_ENV
|
|
13
20
|
|
|
@@ -52,7 +59,7 @@ export const setValue = (FACTORY_NAME, value, key) => {
|
|
|
52
59
|
}
|
|
53
60
|
|
|
54
61
|
FACTORY[key] = result
|
|
55
|
-
setVariables(result, key)
|
|
62
|
+
// setVariables(result, key)
|
|
56
63
|
|
|
57
64
|
return FACTORY
|
|
58
65
|
}
|
package/src/system/color.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
+
import { MEDIA } from '../config'
|
|
3
4
|
import { CONFIG, CSS_VARS } from '../factory' // eslint-disable-line
|
|
4
5
|
|
|
5
6
|
import {
|
|
@@ -10,26 +11,34 @@ import {
|
|
|
10
11
|
hexToRgbArray,
|
|
11
12
|
rgbArrayToHex,
|
|
12
13
|
hslToRgb,
|
|
13
|
-
getColorShade
|
|
14
|
+
getColorShade,
|
|
15
|
+
isObject
|
|
14
16
|
} from '../utils'
|
|
15
17
|
|
|
16
18
|
const ENV = process.env.NODE_ENV
|
|
17
19
|
|
|
18
|
-
export const getColor = value => {
|
|
20
|
+
export const getColor = (value, key) => {
|
|
19
21
|
if (!isString(value)) {
|
|
20
22
|
if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose) console.warn(value, '- type for color is not valid')
|
|
21
23
|
return
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
if (key && value[key]) value = value[key]
|
|
24
27
|
const [name, alpha, tone] = isArray(value) ? value : value.split(' ')
|
|
25
28
|
const { COLOR, GRADIENT } = CONFIG
|
|
26
|
-
|
|
29
|
+
|
|
30
|
+
let val = (COLOR[name] || GRADIENT[name])
|
|
27
31
|
|
|
28
32
|
if (!val) {
|
|
29
33
|
if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose) console.warn('Can\'t find color', name)
|
|
30
34
|
return value
|
|
31
35
|
}
|
|
32
36
|
|
|
37
|
+
if (key) {
|
|
38
|
+
if (val[key]) val = val[key]
|
|
39
|
+
else if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose) console.warn(value, ' - does not have ', key)
|
|
40
|
+
}
|
|
41
|
+
|
|
33
42
|
// TODO: support variables
|
|
34
43
|
// if (alpha) return `rgba(var(${val[shade || ''].var}), ${modifier})`
|
|
35
44
|
|
|
@@ -51,19 +60,63 @@ export const getColor = value => {
|
|
|
51
60
|
} else rgb = val[tone].rgb
|
|
52
61
|
}
|
|
53
62
|
if (alpha) return `rgba(${rgb}, ${alpha})`
|
|
54
|
-
return `rgb(${rgb})`
|
|
55
|
-
} else return val.value
|
|
63
|
+
return CONFIG.useVariable ? `var(${val.var})` : `rgb(${rgb})`
|
|
64
|
+
} else return CONFIG.useVariable ? `var(${val.var})` : val.value
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const getMediaColor = (value, param) => {
|
|
68
|
+
if (!isString(value)) {
|
|
69
|
+
if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose) console.warn(value, '- type for color is not valid')
|
|
70
|
+
return
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const [name] = isArray(value) ? value : value.split(' ')
|
|
74
|
+
|
|
75
|
+
const { COLOR, GRADIENT } = CONFIG
|
|
76
|
+
const val = COLOR[name] || GRADIENT[name]
|
|
77
|
+
|
|
78
|
+
const isObj = isObject(val)
|
|
79
|
+
if (isObj && val.value) return { [param]: getColor(value) }
|
|
80
|
+
else if (isObj) {
|
|
81
|
+
const obj = {}
|
|
82
|
+
|
|
83
|
+
for (const mediaName in val) {
|
|
84
|
+
const query = MEDIA[mediaName.slice(1)]
|
|
85
|
+
const media = `@media screen and ${query}`
|
|
86
|
+
obj[media] = { [param]: getColor(value, mediaName) }
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return obj
|
|
90
|
+
} else {
|
|
91
|
+
if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose) console.warn('Can\'t find color', value)
|
|
92
|
+
return { [param]: value }
|
|
93
|
+
}
|
|
56
94
|
}
|
|
57
95
|
|
|
58
|
-
export const setColor = (val, key) => {
|
|
59
|
-
if (val.slice(0, 2) === '--') val = getColor(val.slice(2))
|
|
96
|
+
export const setColor = (val, key, suffix) => {
|
|
97
|
+
if (isString(val) && val.slice(0, 2) === '--') val = getColor(val.slice(2))
|
|
98
|
+
|
|
99
|
+
if (isArray(val)) {
|
|
100
|
+
return {
|
|
101
|
+
'@light': setColor(val[0], key, 'light'),
|
|
102
|
+
'@dark': setColor(val[0], key, 'dark')
|
|
103
|
+
}
|
|
104
|
+
}
|
|
60
105
|
|
|
61
|
-
|
|
106
|
+
if (isObject(val)) {
|
|
107
|
+
const obj = {}
|
|
108
|
+
for (const variant in val) obj[variant] = setColor(val[variant], key, variant.slice(0, 1) === '@' ? variant.slice(1) : variant)
|
|
109
|
+
return obj
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const CSSVar = `--color-${key}` + (suffix ? `-${suffix}` : '')
|
|
62
113
|
const [r, g, b, a = 1] = colorStringToRgbaArray(val.value || val)
|
|
63
114
|
const alpha = parseFloat(a.toFixed(2))
|
|
64
115
|
const rgb = `${r}, ${g}, ${b}`
|
|
65
116
|
const value = `rgba(${rgb}, ${alpha})`
|
|
66
117
|
|
|
118
|
+
if (CONFIG.useVariable) { CSS_VARS[CSSVar] = value }
|
|
119
|
+
|
|
67
120
|
return {
|
|
68
121
|
var: CSSVar,
|
|
69
122
|
rgb,
|
|
@@ -72,8 +125,28 @@ export const setColor = (val, key) => {
|
|
|
72
125
|
}
|
|
73
126
|
}
|
|
74
127
|
|
|
75
|
-
export const setGradient = (val, key) => {
|
|
76
|
-
|
|
128
|
+
export const setGradient = (val, key, suffix) => {
|
|
129
|
+
if (isString(val) && val.slice(0, 2) === '--') val = getColor(val.slice(2))
|
|
130
|
+
|
|
131
|
+
if (isArray(val)) {
|
|
132
|
+
return {
|
|
133
|
+
'@light': setGradient(val[0], key, 'light'),
|
|
134
|
+
'@dark': setGradient(val[0], key, 'dark')
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (isObject(val)) {
|
|
139
|
+
const obj = {}
|
|
140
|
+
for (const variant in val) obj[variant] = setGradient(val[variant], key, variant.slice(0, 1) === '@' ? variant.slice(1) : variant)
|
|
141
|
+
return obj
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const CSSVar = `--gradient-${key}` + (suffix ? `-${suffix}` : '')
|
|
145
|
+
|
|
146
|
+
if (CONFIG.useVariable) {
|
|
147
|
+
CSS_VARS[CSSVar] = val.value || val
|
|
148
|
+
}
|
|
149
|
+
|
|
77
150
|
return {
|
|
78
151
|
var: CSSVar,
|
|
79
152
|
value: val.value || val
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { DOCUMENT, FONT_FAMILY, THEME, TYPOGRAPHY } from '../config'
|
|
4
|
+
import { getDefaultOrFirstKey, merge } from '../utils'
|
|
5
|
+
|
|
6
|
+
export const applyDocument = () => merge(DOCUMENT, {
|
|
7
|
+
theme: THEME.document,
|
|
8
|
+
fontFamily: getDefaultOrFirstKey(FONT_FAMILY),
|
|
9
|
+
fontSize: TYPOGRAPHY.base,
|
|
10
|
+
lineHeight: TYPOGRAPHY.lineHeight
|
|
11
|
+
})
|
package/src/system/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import * as CONFIG from '
|
|
4
|
-
import { CSS_VARS } from '
|
|
5
|
-
import { getTheme } from '
|
|
6
|
-
import { deepMerge, merge } from '
|
|
3
|
+
import * as CONFIG from '../config'
|
|
4
|
+
import { CSS_VARS } from '../factory'
|
|
5
|
+
import { getTheme } from '.'
|
|
6
|
+
import { deepMerge, merge } from '../utils'
|
|
7
7
|
|
|
8
8
|
export const applyReset = (reset = {}) => {
|
|
9
9
|
return deepMerge(merge(CONFIG.RESET, reset), {
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { SPACING } from '../config'
|
|
4
|
+
import { applySequenceVars, Arrayize, generateSequence, getSequenceValue, merge } from '../utils'
|
|
5
|
+
|
|
6
|
+
const runThroughMedia = props => {
|
|
7
|
+
for (const prop in props) {
|
|
8
|
+
const mediaProps = props[prop]
|
|
9
|
+
if (prop.slice(0, 1) === '@') {
|
|
10
|
+
const { type, base, ratio, range, subSequence, h1Matches, unit } = props
|
|
11
|
+
|
|
12
|
+
merge(mediaProps, {
|
|
13
|
+
type,
|
|
14
|
+
base,
|
|
15
|
+
ratio,
|
|
16
|
+
range,
|
|
17
|
+
subSequence,
|
|
18
|
+
h1Matches,
|
|
19
|
+
unit,
|
|
20
|
+
sequence: {},
|
|
21
|
+
scales: {},
|
|
22
|
+
styles: {},
|
|
23
|
+
vars: {}
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
generateSequence(mediaProps)
|
|
27
|
+
|
|
28
|
+
const mediaName = prop.slice(1)
|
|
29
|
+
applySequenceVars(mediaProps, mediaName)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const applySpacingSequence = () => {
|
|
35
|
+
generateSequence(SPACING)
|
|
36
|
+
applySequenceVars(SPACING)
|
|
37
|
+
runThroughMedia(SPACING)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const getSequence = (props) => {
|
|
41
|
+
if (!props) return
|
|
42
|
+
const hasGenerated = Object.keys(props.sequence).length > 0
|
|
43
|
+
return hasGenerated ? props : generateSequence(props)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const getSpacingByKey = (val, property = 'padding', props, unit) => {
|
|
47
|
+
const prefix = '--spacing-'
|
|
48
|
+
|
|
49
|
+
const generatedSequence = getSequence(props)
|
|
50
|
+
const type = (generatedSequence || SPACING).sequence
|
|
51
|
+
|
|
52
|
+
const stack = Arrayize(val)
|
|
53
|
+
if (!stack) return
|
|
54
|
+
|
|
55
|
+
const length = stack.length
|
|
56
|
+
|
|
57
|
+
const wrapSequenceItem = (prop, i) => getSequenceValue({
|
|
58
|
+
type,
|
|
59
|
+
prop,
|
|
60
|
+
val: stack[i],
|
|
61
|
+
prefix,
|
|
62
|
+
unit
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
let suffix = ''
|
|
66
|
+
if (property === 'borderWidth') {
|
|
67
|
+
property = 'border'
|
|
68
|
+
suffix = 'Width'
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
if (length === 2) {
|
|
72
|
+
return [
|
|
73
|
+
wrapSequenceItem(property + 'Block' + suffix, 0),
|
|
74
|
+
wrapSequenceItem(property + 'Inline' + suffix, 1)
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
if (length === 3) {
|
|
78
|
+
return [
|
|
79
|
+
wrapSequenceItem(property + 'BlockStart' + suffix, 0),
|
|
80
|
+
wrapSequenceItem(property + 'Inline' + suffix, 1),
|
|
81
|
+
wrapSequenceItem(property + 'BlockEnd' + suffix, 2)
|
|
82
|
+
]
|
|
83
|
+
} else if (length === 4) {
|
|
84
|
+
return [
|
|
85
|
+
wrapSequenceItem(property + 'BlockStart' + suffix, 0),
|
|
86
|
+
wrapSequenceItem(property + 'InlineStart' + suffix, 3),
|
|
87
|
+
wrapSequenceItem(property + 'BlockEnd' + suffix, 2),
|
|
88
|
+
wrapSequenceItem(property + 'InlineEnd' + suffix, 1)
|
|
89
|
+
]
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return getSequenceValue({ type, prop: property, val, prefix, unit })
|
|
93
|
+
}
|
package/src/system/theme.js
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { getColor } from './color'
|
|
3
|
+
import { getColor, getMediaColor } from './color'
|
|
4
4
|
import { CONFIG, CSS_VARS } from '../factory' // eslint-disable-line
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
7
|
isObject,
|
|
8
8
|
isString,
|
|
9
|
-
isObjectLike
|
|
9
|
+
isObjectLike,
|
|
10
|
+
merge,
|
|
11
|
+
isArray
|
|
10
12
|
} from '../utils'
|
|
11
13
|
|
|
12
14
|
const ENV = process.env.NODE_ENV
|
|
13
15
|
|
|
14
16
|
const setThemeValue = theme => {
|
|
15
17
|
const value = {}
|
|
16
|
-
const { state,
|
|
18
|
+
const { state, media, helpers, ...rest } = theme
|
|
17
19
|
const keys = Object.keys(rest)
|
|
18
20
|
keys.map(key => {
|
|
19
21
|
const conditions = ['color', 'Color', 'background', 'border']
|
|
@@ -30,6 +32,7 @@ const getThemeValue = theme => {
|
|
|
30
32
|
}
|
|
31
33
|
|
|
32
34
|
export const getTheme = (value, modifier) => {
|
|
35
|
+
if (CONFIG.useVariable) return getMediaTheme(value, modifier)
|
|
33
36
|
const { THEME } = CONFIG
|
|
34
37
|
|
|
35
38
|
if (isString(value)) {
|
|
@@ -44,9 +47,9 @@ export const getTheme = (value, modifier) => {
|
|
|
44
47
|
if (isObjectLike(value) && value[1]) {
|
|
45
48
|
const themeName = value[0]
|
|
46
49
|
const subThemeName = value[1]
|
|
47
|
-
const { helpers,
|
|
50
|
+
const { helpers, media, state } = THEME[themeName]
|
|
48
51
|
|
|
49
|
-
if (
|
|
52
|
+
if (media && media[subThemeName]) return getThemeValue(media[subThemeName])
|
|
50
53
|
if (helpers && helpers[subThemeName]) return getThemeValue(helpers[subThemeName])
|
|
51
54
|
if (state && state[subThemeName]) return getThemeValue(state[subThemeName])
|
|
52
55
|
} else if (isObject(value)) return setThemeValue(value)
|
|
@@ -74,7 +77,7 @@ const setPseudo = (theme, key, variant, themeValue) => {
|
|
|
74
77
|
if (isObject(variant) && !variant.value) variant.value = result
|
|
75
78
|
}
|
|
76
79
|
|
|
77
|
-
const
|
|
80
|
+
const setSelectors = (theme, value) => {
|
|
78
81
|
const { state } = theme
|
|
79
82
|
if (!state) return
|
|
80
83
|
const keys = Object.keys(state)
|
|
@@ -92,12 +95,12 @@ const setPrefersScheme = (theme, key, variant, themeValue) => {
|
|
|
92
95
|
if (isObject(variant) && !variant.value) variant.value = result
|
|
93
96
|
}
|
|
94
97
|
|
|
95
|
-
const
|
|
96
|
-
const {
|
|
97
|
-
if (!
|
|
98
|
-
const keys = Object.keys(
|
|
98
|
+
const setMedia = (theme, value) => {
|
|
99
|
+
const { media } = theme
|
|
100
|
+
if (!media) return
|
|
101
|
+
const keys = Object.keys(media)
|
|
99
102
|
keys.map(key => {
|
|
100
|
-
const variant =
|
|
103
|
+
const variant = media[key]
|
|
101
104
|
if (key === 'dark' || key === 'light') setPrefersScheme(theme, key, variant, value)
|
|
102
105
|
if (key === 'inverse') setInverseTheme(theme, variant, value)
|
|
103
106
|
return theme
|
|
@@ -105,7 +108,7 @@ const goThroughVariants = (theme, value) => {
|
|
|
105
108
|
return theme
|
|
106
109
|
}
|
|
107
110
|
|
|
108
|
-
const
|
|
111
|
+
const setHelpers = (theme, value) => {
|
|
109
112
|
const { helpers } = theme
|
|
110
113
|
if (!helpers) return
|
|
111
114
|
const keys = Object.keys(helpers)
|
|
@@ -119,13 +122,77 @@ const goThroughHelpers = (theme, value) => {
|
|
|
119
122
|
}
|
|
120
123
|
|
|
121
124
|
export const setTheme = (val, key) => {
|
|
122
|
-
|
|
125
|
+
if (CONFIG.useVariable) return setMediaTheme(val, key)
|
|
126
|
+
|
|
127
|
+
const { state, media, helpers } = val
|
|
123
128
|
const value = setThemeValue(val, key)
|
|
124
129
|
const CSSvar = `--theme-${key}`
|
|
125
130
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
131
|
+
setSelectors(val, value)
|
|
132
|
+
setMedia(val, value)
|
|
133
|
+
setHelpers(val, value)
|
|
134
|
+
|
|
135
|
+
return { var: CSSvar, value, state, media, helpers }
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const keySetters = { // eslint-disable-line
|
|
139
|
+
'@': (theme, value) => setMedia(theme, value),
|
|
140
|
+
':': (theme, value) => setSelectors(theme, value),
|
|
141
|
+
'.': (theme, value) => setHelpers(theme, value)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export const setMediaTheme = (val, key, suffix, prefers) => {
|
|
145
|
+
const theme = {}
|
|
146
|
+
|
|
147
|
+
if (isObject(val)) {
|
|
148
|
+
for (const param in val) {
|
|
149
|
+
const symb = param.slice(0, 1)
|
|
150
|
+
const value = val[param]
|
|
151
|
+
if (symb === '@' || symb === ':' || symb === '.') {
|
|
152
|
+
const hasPrefers = symb === '@' && param
|
|
153
|
+
theme[param] = setMediaTheme(value, key, param, prefers || hasPrefers)
|
|
154
|
+
} else {
|
|
155
|
+
const color = getColor(value, prefers)
|
|
156
|
+
const metaSuffixes = [...new Set([prefers, suffix].filter(v => v).map(v => v.slice(1)))]
|
|
157
|
+
const varmetaSuffixName = metaSuffixes.length ? '-' + metaSuffixes.join('-') : ''
|
|
158
|
+
const CSSVar = `--theme-${key}${varmetaSuffixName}-${param}`
|
|
159
|
+
if (CONFIG.useVariable) {
|
|
160
|
+
CSS_VARS[CSSVar] = color
|
|
161
|
+
theme[param] = `var(${CSSVar})`
|
|
162
|
+
} else {
|
|
163
|
+
theme[param] = color
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
129
168
|
|
|
130
|
-
return
|
|
169
|
+
return theme
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const recursiveTheme = val => {
|
|
173
|
+
const obj = {}
|
|
174
|
+
for (const param in val) {
|
|
175
|
+
const symb = param.slice(0, 1)
|
|
176
|
+
if (isObject(val[param])) {
|
|
177
|
+
if (symb === '@') {
|
|
178
|
+
const query = CONFIG.MEDIA[param.slice(1)]
|
|
179
|
+
const media = `@media screen and ${query}`
|
|
180
|
+
obj[media] = recursiveTheme(val[param])
|
|
181
|
+
} else if (symb === ':') {
|
|
182
|
+
obj[`&${param}`] = recursiveTheme(val[param])
|
|
183
|
+
}
|
|
184
|
+
} else obj[param] = val[param]
|
|
185
|
+
}
|
|
186
|
+
return obj
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export const getMediaTheme = (val, key, themeObj) => {
|
|
190
|
+
if (!isString(val)) {
|
|
191
|
+
if ((ENV === 'test' || ENV === 'development') && CONFIG.verbose) console.warn(val, '- type for color is not valid')
|
|
192
|
+
return
|
|
193
|
+
}
|
|
194
|
+
const [name, modifier] = isArray(val) ? val : val.split(' ')
|
|
195
|
+
let value = CONFIG.THEME[name]
|
|
196
|
+
if (modifier && value[modifier]) value = value[modifier]
|
|
197
|
+
return recursiveTheme(value)
|
|
131
198
|
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { TIMING } from '../config'
|
|
4
|
+
import {
|
|
5
|
+
applySequenceVars,
|
|
6
|
+
generateSequence,
|
|
7
|
+
getSequenceValue
|
|
8
|
+
} from '../utils'
|
|
9
|
+
|
|
10
|
+
export const applyTimingSequence = () => {
|
|
11
|
+
generateSequence(TIMING)
|
|
12
|
+
applySequenceVars(TIMING)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const getTimingByKey = val => getSequenceValue({
|
|
16
|
+
type: TIMING.sequence,
|
|
17
|
+
prop: 'duration',
|
|
18
|
+
val,
|
|
19
|
+
unit: 'ms',
|
|
20
|
+
prefix: '--duration-'
|
|
21
|
+
})
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
import { MEDIA, TYPOGRAPHY } from '../config'
|
|
4
|
+
import { CONFIG } from '../factory'
|
|
5
|
+
import {
|
|
6
|
+
applySequenceVars,
|
|
7
|
+
findHeadings,
|
|
8
|
+
generateSequence,
|
|
9
|
+
getSequenceValue,
|
|
10
|
+
merge
|
|
11
|
+
} from '../utils'
|
|
12
|
+
|
|
13
|
+
export const runThroughMedia = props => {
|
|
14
|
+
for (const prop in props) {
|
|
15
|
+
const mediaProps = props[prop]
|
|
16
|
+
if (prop.slice(0, 1) === '@') {
|
|
17
|
+
const { type, base, ratio, range, subSequence, h1Matches, unit } = props
|
|
18
|
+
|
|
19
|
+
merge(mediaProps, {
|
|
20
|
+
type,
|
|
21
|
+
base,
|
|
22
|
+
ratio,
|
|
23
|
+
range,
|
|
24
|
+
subSequence,
|
|
25
|
+
h1Matches,
|
|
26
|
+
unit,
|
|
27
|
+
sequence: {},
|
|
28
|
+
scales: {},
|
|
29
|
+
styles: {},
|
|
30
|
+
vars: {}
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
generateSequence(mediaProps)
|
|
34
|
+
|
|
35
|
+
const mediaName = prop.slice(1)
|
|
36
|
+
applySequenceVars(mediaProps, mediaName)
|
|
37
|
+
|
|
38
|
+
const query = MEDIA[mediaName]
|
|
39
|
+
TYPOGRAPHY.styles[`@media screen and ${query}`] = {
|
|
40
|
+
fontSize: mediaProps.base / TYPOGRAPHY.browserDefault + unit
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export const applyHeadings = (props) => {
|
|
47
|
+
if (props.h1Matches) {
|
|
48
|
+
const unit = props.unit
|
|
49
|
+
const HEADINGS = findHeadings(props)
|
|
50
|
+
const { styles } = props
|
|
51
|
+
for (const k in HEADINGS) {
|
|
52
|
+
styles[`h${parseInt(k) + 1}`] = {
|
|
53
|
+
fontSize: CONFIG.useVariable ? `var(${HEADINGS[k].variable})` : `${HEADINGS[k].scaling}${unit}`
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const applyTypographySequence = () => {
|
|
60
|
+
generateSequence(TYPOGRAPHY)
|
|
61
|
+
applyHeadings(TYPOGRAPHY)
|
|
62
|
+
applySequenceVars(TYPOGRAPHY)
|
|
63
|
+
runThroughMedia(TYPOGRAPHY)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const getFontSizeByKey = val => getSequenceValue({
|
|
67
|
+
type: TYPOGRAPHY.sequence,
|
|
68
|
+
prop: 'fontSize',
|
|
69
|
+
val,
|
|
70
|
+
unit: TYPOGRAPHY.unit,
|
|
71
|
+
prefix: '--font-size-'
|
|
72
|
+
})
|