@symbo.ls/scratch 3.2.3 → 3.2.8
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/dist/cjs/factory.js +23 -494
- package/dist/cjs/index.js +11 -2742
- package/dist/cjs/set.js +66 -2060
- package/dist/esm/factory.js +43 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/set.js +148 -0
- package/dist/iife/index.js +2580 -0
- package/package.json +25 -15
- package/src/set.js +22 -7
- package/src/system/color.js +48 -11
- package/src/system/font.js +19 -5
- package/src/system/reset.js +12 -3
- package/src/system/shadow.js +20 -13
- package/src/system/spacing.js +63 -56
- package/src/system/theme.js +4 -3
- package/src/system/timing.js +1 -1
- package/src/transforms/index.js +212 -95
- package/src/utils/color.js +79 -0
- package/src/utils/font.js +54 -14
- package/src/utils/sequence.js +94 -39
- package/src/utils/sprite.js +2 -2
- package/src/utils/unit.js +69 -2
- package/src/utils/var.js +1 -2
- package/dist/cjs/defaultConfig/animation.js +0 -26
- package/dist/cjs/defaultConfig/cases.js +0 -26
- package/dist/cjs/defaultConfig/class.js +0 -27
- package/dist/cjs/defaultConfig/color.js +0 -28
- package/dist/cjs/defaultConfig/document.js +0 -26
- package/dist/cjs/defaultConfig/font-family.js +0 -34
- package/dist/cjs/defaultConfig/font.js +0 -26
- package/dist/cjs/defaultConfig/grid.js +0 -27
- package/dist/cjs/defaultConfig/icons.js +0 -28
- package/dist/cjs/defaultConfig/index.js +0 -222
- package/dist/cjs/defaultConfig/media.js +0 -31
- package/dist/cjs/defaultConfig/responsive.js +0 -52
- package/dist/cjs/defaultConfig/sequence.js +0 -51
- package/dist/cjs/defaultConfig/shadow.js +0 -26
- package/dist/cjs/defaultConfig/spacing.js +0 -87
- package/dist/cjs/defaultConfig/svg.js +0 -28
- package/dist/cjs/defaultConfig/templates.js +0 -26
- package/dist/cjs/defaultConfig/theme.js +0 -26
- package/dist/cjs/defaultConfig/timing.js +0 -68
- package/dist/cjs/defaultConfig/typography.js +0 -72
- package/dist/cjs/defaultConfig/unit.js +0 -28
- package/dist/cjs/package.json +0 -4
- package/dist/cjs/system/color.js +0 -1175
- package/dist/cjs/system/document.js +0 -987
- package/dist/cjs/system/font.js +0 -1009
- package/dist/cjs/system/index.js +0 -2227
- package/dist/cjs/system/reset.js +0 -1099
- package/dist/cjs/system/shadow.js +0 -1384
- package/dist/cjs/system/spacing.js +0 -1338
- package/dist/cjs/system/svg.js +0 -1086
- package/dist/cjs/system/theme.js +0 -1276
- package/dist/cjs/system/timing.js +0 -1213
- package/dist/cjs/system/typography.js +0 -1311
- package/dist/cjs/tests/index.js +0 -30
- package/dist/cjs/transforms/index.js +0 -1613
- package/dist/cjs/utils/color.js +0 -333
- package/dist/cjs/utils/font.js +0 -69
- package/dist/cjs/utils/index.js +0 -1548
- package/dist/cjs/utils/sequence.js +0 -1198
- package/dist/cjs/utils/sprite.js +0 -579
- package/dist/cjs/utils/theme.js +0 -31
- package/dist/cjs/utils/unit.js +0 -28
- package/dist/cjs/utils/var.js +0 -1040
package/src/transforms/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { isString, isObject, exec } from '@domql/utils'
|
|
4
4
|
import { getActiveConfig } from '../factory'
|
|
5
5
|
import {
|
|
6
6
|
getSpacingByKey,
|
|
@@ -9,134 +9,251 @@ import {
|
|
|
9
9
|
getMediaColor,
|
|
10
10
|
getTimingByKey,
|
|
11
11
|
getTimingFunction,
|
|
12
|
-
getSpacingBasedOnRatio
|
|
12
|
+
getSpacingBasedOnRatio,
|
|
13
|
+
checkIfBoxSize,
|
|
14
|
+
splitSpacedValue
|
|
13
15
|
} from '../system'
|
|
16
|
+
import {
|
|
17
|
+
getFnPrefixAndValue,
|
|
18
|
+
isResolvedColor,
|
|
19
|
+
isCSSVar,
|
|
20
|
+
CSS_NATIVE_COLOR_REGEX,
|
|
21
|
+
splitTopLevelCommas,
|
|
22
|
+
parseColorToken
|
|
23
|
+
} from '../utils'
|
|
24
|
+
|
|
25
|
+
const BORDER_STYLES = new Set([
|
|
26
|
+
'none', 'hidden', 'dotted', 'dashed', 'solid', 'double',
|
|
27
|
+
'groove', 'ridge', 'inset', 'outset', 'initial'
|
|
28
|
+
])
|
|
29
|
+
|
|
30
|
+
const GRADIENT_KEYWORDS = new Set([
|
|
31
|
+
'to', 'top', 'bottom', 'left', 'right', 'center', 'at',
|
|
32
|
+
'circle', 'ellipse', 'closest-side', 'farthest-side',
|
|
33
|
+
'closest-corner', 'farthest-corner'
|
|
34
|
+
])
|
|
35
|
+
const isBorderStyle = (str) => BORDER_STYLES.has(str)
|
|
36
|
+
|
|
37
|
+
export const transformBorder = (border) => {
|
|
38
|
+
const str = border + ''
|
|
39
|
+
|
|
40
|
+
// CSS passthrough: native CSS color syntax
|
|
41
|
+
if (CSS_NATIVE_COLOR_REGEX.test(str)) return str
|
|
42
|
+
|
|
43
|
+
// Simple CSS keywords
|
|
44
|
+
const trimmed = str.trim()
|
|
45
|
+
if (trimmed === 'none' || trimmed === '0' || trimmed === 'initial' || trimmed === 'inherit' || trimmed === 'unset') return str
|
|
14
46
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
else if (isBorderStyle(v)) return v || 'solid'
|
|
35
|
-
else if (v.slice(-2) === 'px' || v.slice(-2) === 'em') return v // TODO: add map spacing
|
|
36
|
-
else if (getColor(v).length > 2) return getColor(v)
|
|
37
|
-
return getSpacingByKey(v, 'border').border
|
|
38
|
-
}).join(' ')
|
|
47
|
+
// Space-separated tokens (CSS-like syntax)
|
|
48
|
+
const tokens = str.split(/\s+/)
|
|
49
|
+
|
|
50
|
+
return tokens
|
|
51
|
+
.map((v) => {
|
|
52
|
+
v = v.trim()
|
|
53
|
+
if (!v) return ''
|
|
54
|
+
if (isCSSVar(v)) return `var(${v})`
|
|
55
|
+
if (isBorderStyle(v)) return v
|
|
56
|
+
if (/^\d/.test(v) || v === '0') return v
|
|
57
|
+
// Try color resolution
|
|
58
|
+
const color = getColor(v)
|
|
59
|
+
if (isResolvedColor(color)) return color
|
|
60
|
+
// Try spacing key
|
|
61
|
+
const spacing = getSpacingByKey(v, 'border')
|
|
62
|
+
if (spacing && spacing.border) return spacing.border
|
|
63
|
+
return v
|
|
64
|
+
})
|
|
65
|
+
.join(' ')
|
|
39
66
|
}
|
|
40
67
|
|
|
41
|
-
export const transformTextStroke = stroke => {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
68
|
+
export const transformTextStroke = (stroke) => {
|
|
69
|
+
// CSS passthrough
|
|
70
|
+
if (CSS_NATIVE_COLOR_REGEX.test(stroke)) return stroke
|
|
71
|
+
|
|
72
|
+
return stroke
|
|
73
|
+
.split(/\s+/)
|
|
74
|
+
.map((v) => {
|
|
75
|
+
v = v.trim()
|
|
76
|
+
if (!v) return ''
|
|
77
|
+
if (isCSSVar(v)) return `var(${v})`
|
|
78
|
+
if (/^\d/.test(v) || v.includes('px') || v === '0') return v
|
|
79
|
+
const color = getColor(v)
|
|
80
|
+
if (isResolvedColor(color)) return color
|
|
81
|
+
return v
|
|
82
|
+
})
|
|
83
|
+
.join(' ')
|
|
48
84
|
}
|
|
49
85
|
|
|
50
86
|
export const transformShadow = (sh, globalTheme) => getShadow(sh, globalTheme)
|
|
51
87
|
|
|
52
|
-
export const transformBoxShadow = (shadows, globalTheme) =>
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
88
|
+
export const transformBoxShadow = (shadows, globalTheme) => {
|
|
89
|
+
// CSS passthrough: native CSS color syntax
|
|
90
|
+
if (CSS_NATIVE_COLOR_REGEX.test(shadows)) return shadows
|
|
91
|
+
|
|
92
|
+
// Split multiple shadows by commas (CSS standard), respecting parentheses
|
|
93
|
+
return splitTopLevelCommas(shadows)
|
|
94
|
+
.map((shadow) => {
|
|
95
|
+
shadow = shadow.trim()
|
|
96
|
+
if (!shadow) return ''
|
|
97
|
+
|
|
98
|
+
// Each shadow: space-separated tokens
|
|
99
|
+
return shadow.split(/\s+/)
|
|
100
|
+
.map((v) => {
|
|
101
|
+
v = v.trim()
|
|
102
|
+
if (!v) return ''
|
|
103
|
+
if (isCSSVar(v)) return `var(${v})`
|
|
104
|
+
if (v === 'inset' || v === 'none') return v
|
|
105
|
+
|
|
106
|
+
// Try color resolution
|
|
107
|
+
const color = getColor(v)
|
|
108
|
+
if (isResolvedColor(color)) {
|
|
109
|
+
const mediaColor = getMediaColor(v, globalTheme)
|
|
110
|
+
if (isObject(mediaColor))
|
|
111
|
+
return Object.values(mediaColor).filter((c) =>
|
|
112
|
+
c.includes(': ' + globalTheme)
|
|
113
|
+
)[0]
|
|
114
|
+
return mediaColor
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// CSS unit values
|
|
118
|
+
if (/^\d/.test(v) || v === '0' || v.includes('px') || v.slice(-2) === 'em') return v
|
|
119
|
+
|
|
120
|
+
// Spacing key
|
|
121
|
+
const spacing = getSpacingByKey(v, 'shadow')
|
|
122
|
+
if (spacing && spacing.shadow) return spacing.shadow
|
|
123
|
+
|
|
124
|
+
return v
|
|
125
|
+
})
|
|
126
|
+
.join(' ')
|
|
127
|
+
})
|
|
128
|
+
.join(', ')
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Resolve Symbols color tokens inside a CSS gradient string.
|
|
133
|
+
* e.g. 'linear-gradient(to bottom, white.97 65%, white.0 100%)'
|
|
134
|
+
* → 'linear-gradient(to bottom, rgba(255, 255, 255, 0.97) 65%, rgba(255, 255, 255, 0.0) 100%)'
|
|
135
|
+
*/
|
|
136
|
+
export const resolveColorsInGradient = (gradient, globalTheme) => {
|
|
137
|
+
// Find the opening paren after the gradient type
|
|
138
|
+
const parenStart = gradient.indexOf('(')
|
|
139
|
+
if (parenStart === -1) return gradient
|
|
140
|
+
|
|
141
|
+
const prefix = gradient.slice(0, parenStart + 1)
|
|
142
|
+
const inner = gradient.slice(parenStart + 1, gradient.lastIndexOf(')'))
|
|
143
|
+
const suffix = ')'
|
|
144
|
+
|
|
145
|
+
// Split by top-level commas (respects nested rgba() etc.)
|
|
146
|
+
const segments = splitTopLevelCommas(inner)
|
|
147
|
+
|
|
148
|
+
const resolved = segments.map((segment) => {
|
|
149
|
+
segment = segment.trim()
|
|
150
|
+
// Split segment into space-separated tokens
|
|
151
|
+
const tokens = segment.split(/\s+/)
|
|
152
|
+
|
|
153
|
+
return tokens.map((token) => {
|
|
154
|
+
if (!token) return token
|
|
155
|
+
// Skip CSS values: percentages, degrees, direction keywords, native colors
|
|
156
|
+
if (/^\d/.test(token) || token === '0') return token
|
|
157
|
+
if (GRADIENT_KEYWORDS.has(token)) return token
|
|
158
|
+
if (token === 'transparent') return token
|
|
159
|
+
if (CSS_NATIVE_COLOR_REGEX.test(token)) return token
|
|
160
|
+
|
|
161
|
+
// Try to resolve as a Symbols color token
|
|
162
|
+
const color = getColor(token)
|
|
163
|
+
if (isResolvedColor(color)) return color
|
|
164
|
+
|
|
165
|
+
return token
|
|
166
|
+
}).join(' ')
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
return prefix + resolved.join(', ') + suffix
|
|
170
|
+
}
|
|
67
171
|
|
|
68
172
|
export const transformBackgroundImage = (backgroundImage, globalTheme) => {
|
|
69
173
|
const CONFIG = getActiveConfig()
|
|
70
|
-
return backgroundImage
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
return
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
174
|
+
return backgroundImage
|
|
175
|
+
.split(', ')
|
|
176
|
+
.map((v) => {
|
|
177
|
+
if (isCSSVar(v)) return `var(${v})`
|
|
178
|
+
if (v.includes('url')) return v
|
|
179
|
+
if (v.includes('gradient')) return resolveColorsInGradient(v, globalTheme)
|
|
180
|
+
else if (CONFIG.GRADIENT[backgroundImage]) {
|
|
181
|
+
return {
|
|
182
|
+
backgroundImage: getMediaColor(
|
|
183
|
+
backgroundImage,
|
|
184
|
+
globalTheme || CONFIG.globalTheme
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
} else if (v.includes('/') || v.startsWith('http') || (v.includes('.') && !parseColorToken(v)))
|
|
188
|
+
return `url(${v})`
|
|
189
|
+
return v
|
|
190
|
+
})
|
|
191
|
+
.join(' ')
|
|
80
192
|
}
|
|
81
193
|
|
|
82
|
-
export const transfromGap =
|
|
83
|
-
|
|
84
|
-
|
|
194
|
+
export const transfromGap = (gap) =>
|
|
195
|
+
isString(gap) &&
|
|
196
|
+
gap
|
|
197
|
+
.split(' ')
|
|
198
|
+
.map((v) => getSpacingByKey(v, 'gap').gap)
|
|
199
|
+
.join(' ')
|
|
85
200
|
|
|
86
|
-
export const transformTransition = transition => {
|
|
201
|
+
export const transformTransition = (transition) => {
|
|
87
202
|
const arr = transition.split(' ')
|
|
88
203
|
|
|
89
204
|
if (!arr.length) return transition
|
|
90
205
|
|
|
91
|
-
return arr
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
206
|
+
return arr
|
|
207
|
+
.map((v) => {
|
|
208
|
+
if (isCSSVar(v)) return `var(${v})`
|
|
209
|
+
if (v.length < 3 || v.includes('ms')) {
|
|
210
|
+
const mapWithSequence = getTimingByKey(v)
|
|
211
|
+
return mapWithSequence.timing || v
|
|
212
|
+
}
|
|
213
|
+
if (getTimingFunction(v)) return getTimingFunction(v)
|
|
214
|
+
return v
|
|
215
|
+
})
|
|
216
|
+
.join(' ')
|
|
100
217
|
}
|
|
101
218
|
|
|
102
219
|
export const transformDuration = (duration, props, propertyName) => {
|
|
103
220
|
if (!isString(duration)) return
|
|
104
|
-
return duration
|
|
221
|
+
return duration
|
|
222
|
+
.split(',')
|
|
223
|
+
.map((v) => getTimingByKey(v).timing || v)
|
|
224
|
+
.join(',')
|
|
105
225
|
}
|
|
106
226
|
|
|
107
|
-
export const splitTransition = transition => {
|
|
227
|
+
export const splitTransition = (transition) => {
|
|
108
228
|
const arr = transition.split(',')
|
|
109
229
|
if (!arr.length) return
|
|
110
230
|
return arr.map(transformTransition).join(',')
|
|
111
231
|
}
|
|
112
232
|
|
|
113
|
-
export
|
|
114
|
-
|
|
115
|
-
return (prop.includes('width') || prop.includes('height')) && !prop.includes('border')
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export const transformSize = (propertyName, val, props = {}, opts = {}) => {
|
|
119
|
-
let value = val || props[propertyName]
|
|
233
|
+
export function transformSize(propertyName, val, props = {}, opts = {}) {
|
|
234
|
+
let value = exec.call(this, val || props[propertyName])
|
|
120
235
|
|
|
121
|
-
if (
|
|
236
|
+
if (value === undefined || value === null) return
|
|
122
237
|
|
|
123
|
-
|
|
124
|
-
|
|
238
|
+
let fnPrefix
|
|
239
|
+
if (isString(value)) {
|
|
240
|
+
// has function prefix
|
|
241
|
+
if (value.includes('(')) {
|
|
242
|
+
const fnArr = getFnPrefixAndValue(value)
|
|
243
|
+
fnPrefix = fnArr[0]
|
|
244
|
+
value = fnArr[1]
|
|
245
|
+
}
|
|
125
246
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return v
|
|
132
|
-
}).join(' ')
|
|
247
|
+
const shouldScaleBoxSize = props.scaleBoxSize
|
|
248
|
+
const isBoxSize = checkIfBoxSize(propertyName)
|
|
249
|
+
if (!shouldScaleBoxSize && isBoxSize) {
|
|
250
|
+
value = splitSpacedValue(value)
|
|
251
|
+
}
|
|
133
252
|
}
|
|
134
253
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
return getSpacingByKey(value, propertyName)
|
|
139
|
-
}
|
|
254
|
+
return opts.ratio
|
|
255
|
+
? getSpacingBasedOnRatio(props, propertyName, value, fnPrefix)
|
|
256
|
+
: getSpacingByKey(value, propertyName, undefined, fnPrefix)
|
|
140
257
|
}
|
|
141
258
|
|
|
142
259
|
export const transformSizeRatio = (propertyName, val = null, props) => {
|
package/src/utils/color.js
CHANGED
|
@@ -168,6 +168,85 @@ export const opacify = (color, opacity) => {
|
|
|
168
168
|
return `rgba(${arr})`
|
|
169
169
|
}
|
|
170
170
|
|
|
171
|
+
// Check if value is a CSS custom property reference (starts with --)
|
|
172
|
+
export const isCSSVar = (v) => v.charCodeAt(0) === 45 && v.charCodeAt(1) === 45
|
|
173
|
+
|
|
174
|
+
// Regex for CSS native color values - signals passthrough
|
|
175
|
+
export const CSS_NATIVE_COLOR_REGEX = /(?:rgba?\(|hsla?\(|#[0-9a-fA-F]{3,8}\b)/
|
|
176
|
+
|
|
177
|
+
// Regex for Symbols color token: colorName[.opacity][+/-/=tone]
|
|
178
|
+
// +N or -N = relative shade, =N = absolute lightness percentage
|
|
179
|
+
const COLOR_TOKEN_REGEX = /^([a-zA-Z]\w*)(?:\.(\d+))?(?:([+-]\d+|=\d+))?$/
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Parse a color token string into its components.
|
|
183
|
+
* Returns { name, alpha, tone } for valid tokens,
|
|
184
|
+
* { passthrough: value } for CSS native values,
|
|
185
|
+
* or null for non-color tokens (e.g. '10px', '0')
|
|
186
|
+
*
|
|
187
|
+
* Tone prefixes:
|
|
188
|
+
* +N relative shade (add N to RGB)
|
|
189
|
+
* -N relative shade (subtract N from RGB)
|
|
190
|
+
* =N absolute lightness (set HSL lightness to N%)
|
|
191
|
+
*/
|
|
192
|
+
export const parseColorToken = (value) => {
|
|
193
|
+
if (!isString(value)) return null
|
|
194
|
+
|
|
195
|
+
// CSS native color passthrough
|
|
196
|
+
if (CSS_NATIVE_COLOR_REGEX.test(value)) return { passthrough: value }
|
|
197
|
+
|
|
198
|
+
// CSS var passthrough
|
|
199
|
+
if (isCSSVar(value)) return { cssVar: value }
|
|
200
|
+
|
|
201
|
+
const match = value.match(COLOR_TOKEN_REGEX)
|
|
202
|
+
if (!match) return null
|
|
203
|
+
|
|
204
|
+
const [, name, alphaDigits, rawTone] = match
|
|
205
|
+
const alpha = alphaDigits !== undefined ? `0.${alphaDigits}` : undefined
|
|
206
|
+
// Strip '=' prefix for absolute tones — getRgbTone handles unsigned values as absolute
|
|
207
|
+
const tone = rawTone && rawTone[0] === '=' ? rawTone.slice(1) : rawTone
|
|
208
|
+
|
|
209
|
+
return { name, alpha, tone }
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Check if a getColor() result is a resolved CSS color
|
|
214
|
+
* (as opposed to the original unresolved value being returned)
|
|
215
|
+
*/
|
|
216
|
+
export const isResolvedColor = (result) => {
|
|
217
|
+
return isString(result) && (
|
|
218
|
+
result.includes('rgb') ||
|
|
219
|
+
result.includes('var(') ||
|
|
220
|
+
result.includes('#')
|
|
221
|
+
)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Split a string by commas, respecting parenthesized groups.
|
|
226
|
+
* e.g. 'rgba(0,0,0,0.1), white.5 0 A' → ['rgba(0,0,0,0.1)', ' white.5 0 A']
|
|
227
|
+
*/
|
|
228
|
+
export const splitTopLevelCommas = (value) => {
|
|
229
|
+
const result = []
|
|
230
|
+
let current = ''
|
|
231
|
+
let depth = 0
|
|
232
|
+
|
|
233
|
+
for (const char of value) {
|
|
234
|
+
if (char === '(') depth += 1
|
|
235
|
+
else if (char === ')' && depth > 0) depth -= 1
|
|
236
|
+
|
|
237
|
+
if (char === ',' && depth === 0) {
|
|
238
|
+
result.push(current)
|
|
239
|
+
current = ''
|
|
240
|
+
continue
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
current += char
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
if (current.length || !result.length) result.push(current)
|
|
247
|
+
return result
|
|
248
|
+
}
|
|
249
|
+
|
|
171
250
|
export const getRgbTone = (rgb, tone) => {
|
|
172
251
|
if (isString(rgb) && rgb.includes('rgb'))
|
|
173
252
|
rgb = colorStringToRgbaArray(rgb).join(', ')
|
package/src/utils/font.js
CHANGED
|
@@ -7,41 +7,81 @@ export const getDefaultOrFirstKey = (LIBRARY, key) => {
|
|
|
7
7
|
return hasValue && LIBRARY[hasValue] && LIBRARY[hasValue].value
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export const getFontFormat = url =>
|
|
10
|
+
export const getFontFormat = (url) => {
|
|
11
|
+
const ext = url.split(/[#?]/)[0].split('.').pop().trim()
|
|
12
|
+
if (['woff2', 'woff', 'ttf', 'otf', 'eot'].includes(ext)) return ext
|
|
13
|
+
return null
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const isGoogleFontsUrl = (url) =>
|
|
17
|
+
url &&
|
|
18
|
+
(url.includes('fonts.googleapis.com') || url.includes('fonts.gstatic.com'))
|
|
11
19
|
|
|
12
|
-
export const
|
|
20
|
+
export const setFontImport = (url) => `@import url('${url}');`
|
|
13
21
|
|
|
14
|
-
export const
|
|
22
|
+
export const setInCustomFontMedia = (str) => `@font-face { ${str} }`
|
|
23
|
+
|
|
24
|
+
export const setCustomFont = (name, url, weight, options = {}) => {
|
|
25
|
+
const format = getFontFormat(url)
|
|
26
|
+
const formatStr = format ? ` format('${format}')` : ''
|
|
27
|
+
return `
|
|
15
28
|
font-family: '${name}';
|
|
16
|
-
font-style: normal
|
|
17
|
-
|
|
18
|
-
|
|
29
|
+
font-style: normal;${
|
|
30
|
+
weight
|
|
31
|
+
? `
|
|
32
|
+
font-weight: ${weight};`
|
|
33
|
+
: ''
|
|
34
|
+
}${
|
|
35
|
+
options.fontStretch
|
|
36
|
+
? `
|
|
37
|
+
font-stretch: ${options.fontStretch};`
|
|
38
|
+
: ''
|
|
39
|
+
}${
|
|
40
|
+
options.fontDisplay
|
|
41
|
+
? `
|
|
42
|
+
font-display: ${options.fontDisplay};`
|
|
43
|
+
: ''
|
|
44
|
+
}
|
|
45
|
+
src: url('${url}')${formatStr};`
|
|
46
|
+
}
|
|
19
47
|
|
|
20
|
-
export const setCustomFontMedia = (
|
|
21
|
-
|
|
48
|
+
export const setCustomFontMedia = (
|
|
49
|
+
name,
|
|
50
|
+
url,
|
|
51
|
+
weight,
|
|
52
|
+
options
|
|
53
|
+
) => `@font-face {${setCustomFont(name, url, weight, options)}
|
|
22
54
|
}`
|
|
23
|
-
// src: url('${url}') format('${getFontFormat(url)}');
|
|
24
55
|
|
|
25
56
|
export const getFontFaceEach = (name, weights) => {
|
|
26
57
|
const keys = Object.keys(weights)
|
|
27
|
-
return keys.map(key => {
|
|
58
|
+
return keys.map((key) => {
|
|
28
59
|
const { url, fontWeight } = weights[key]
|
|
29
60
|
return setCustomFont(name, url, fontWeight)
|
|
30
61
|
})
|
|
31
62
|
}
|
|
32
63
|
|
|
33
|
-
export const getFontFace = LIBRARY => {
|
|
64
|
+
export const getFontFace = (LIBRARY) => {
|
|
34
65
|
const keys = Object.keys(LIBRARY)
|
|
35
|
-
return keys.map(key => getFontFaceEach(key, LIBRARY[key].value))
|
|
66
|
+
return keys.map((key) => getFontFaceEach(key, LIBRARY[key].value))
|
|
36
67
|
}
|
|
37
68
|
|
|
38
69
|
export const getFontFaceEachString = (name, weights) => {
|
|
70
|
+
if (weights && weights.isVariable) {
|
|
71
|
+
if (isGoogleFontsUrl(weights.url)) {
|
|
72
|
+
return setFontImport(weights.url)
|
|
73
|
+
}
|
|
74
|
+
return setCustomFontMedia(name, weights.url, weights.fontWeight, {
|
|
75
|
+
fontStretch: weights.fontStretch,
|
|
76
|
+
fontDisplay: weights.fontDisplay || 'swap'
|
|
77
|
+
})
|
|
78
|
+
}
|
|
39
79
|
const isArr = weights[0]
|
|
40
80
|
if (isArr) return getFontFaceEach(name, weights).map(setInCustomFontMedia)
|
|
41
81
|
return setCustomFontMedia(name, weights.url)
|
|
42
82
|
}
|
|
43
83
|
|
|
44
|
-
export const getFontFaceString = LIBRARY => {
|
|
84
|
+
export const getFontFaceString = (LIBRARY) => {
|
|
45
85
|
const keys = Object.keys(LIBRARY)
|
|
46
|
-
return keys.map(key => getFontFaceEachString(key, LIBRARY[key].value))
|
|
86
|
+
return keys.map((key) => getFontFaceEachString(key, LIBRARY[key].value))
|
|
47
87
|
}
|