@symbo.ls/scratch 3.8.9 → 3.14.1
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/README.md +2 -2
- package/dist/cjs/defaultConfig/animation.js +4 -2
- package/dist/cjs/defaultConfig/cases.js +4 -2
- package/dist/cjs/defaultConfig/class.js +4 -2
- package/dist/cjs/defaultConfig/color.js +6 -9
- package/dist/cjs/defaultConfig/document.js +4 -2
- package/dist/cjs/defaultConfig/font-family.js +8 -12
- package/dist/cjs/defaultConfig/font.js +4 -11
- package/dist/cjs/defaultConfig/grid.js +5 -3
- package/dist/cjs/defaultConfig/icons.js +6 -4
- package/dist/cjs/defaultConfig/index.js +200 -24
- package/dist/cjs/defaultConfig/media.js +4 -2
- package/dist/cjs/defaultConfig/responsive.js +6 -4
- package/dist/cjs/defaultConfig/sequence.js +4 -2
- package/dist/cjs/defaultConfig/shadow.js +4 -2
- package/dist/cjs/defaultConfig/spacing.js +56 -7
- package/dist/cjs/defaultConfig/svg.js +6 -4
- package/dist/cjs/defaultConfig/templates.js +4 -2
- package/dist/cjs/defaultConfig/theme.js +4 -14
- package/dist/cjs/defaultConfig/timing.js +36 -5
- package/dist/cjs/defaultConfig/typography.js +36 -5
- package/dist/cjs/defaultConfig/unit.js +4 -2
- package/dist/cjs/factory.js +341 -40
- package/dist/cjs/index.js +6333 -11
- package/dist/cjs/package.json +4 -0
- package/dist/cjs/set.js +5614 -158
- package/dist/cjs/system/color.js +4481 -104
- package/dist/cjs/system/document.js +4371 -11
- package/dist/cjs/system/font.js +4401 -28
- package/dist/cjs/system/index.js +5748 -11
- package/dist/cjs/system/reset.js +4445 -21
- package/dist/cjs/system/shadow.js +4832 -41
- package/dist/cjs/system/spacing.js +4752 -39
- package/dist/cjs/system/svg.js +4437 -47
- package/dist/cjs/system/theme.js +4526 -335
- package/dist/cjs/system/timing.js +4695 -19
- package/dist/cjs/system/typography.js +4755 -33
- package/dist/cjs/tests/index.js +4 -2
- package/dist/cjs/transforms/index.js +5019 -134
- package/dist/cjs/utils/color.js +47 -66
- package/dist/cjs/utils/font.js +25 -46
- package/dist/cjs/utils/index.js +5068 -8
- package/dist/cjs/utils/sequence.js +4423 -35
- package/dist/cjs/utils/sprite.js +353 -12
- package/dist/cjs/utils/theme.js +3 -1
- package/dist/cjs/utils/unit.js +4 -2
- package/dist/cjs/utils/var.js +4390 -42
- package/index.js +1 -0
- package/package.json +11 -14
- package/src/defaultConfig/class.js +2 -1
- package/src/defaultConfig/font-family.js +3 -3
- package/src/defaultConfig/icons.js +1 -1
- package/src/defaultConfig/svg.js +1 -1
- package/src/defaultConfig/timing.js +1 -1
- package/src/factory.js +85 -13
- package/src/index.js +16 -5
- package/src/set.js +156 -63
- package/src/system/color.js +113 -12
- package/src/system/document.js +3 -3
- package/src/system/font.js +5 -5
- package/src/system/reset.js +41 -8
- package/src/system/shadow.js +4 -3
- package/src/system/spacing.js +3 -3
- package/src/system/svg.js +42 -5
- package/src/system/theme.js +87 -64
- package/src/system/timing.js +2 -2
- package/src/system/typography.js +12 -3
- package/src/transforms/index.js +4 -4
- package/src/utils/color.js +2 -1
- package/src/utils/font.js +7 -1
- package/src/utils/sequence.js +46 -29
- package/src/utils/sprite.js +44 -16
- package/src/utils/var.js +27 -9
- package/dist/esm/defaultConfig/animation.js +0 -4
- package/dist/esm/defaultConfig/cases.js +0 -4
- package/dist/esm/defaultConfig/class.js +0 -5
- package/dist/esm/defaultConfig/color.js +0 -11
- package/dist/esm/defaultConfig/document.js +0 -4
- package/dist/esm/defaultConfig/font-family.js +0 -18
- package/dist/esm/defaultConfig/font.js +0 -13
- package/dist/esm/defaultConfig/grid.js +0 -5
- package/dist/esm/defaultConfig/icons.js +0 -6
- package/dist/esm/defaultConfig/index.js +0 -25
- package/dist/esm/defaultConfig/media.js +0 -9
- package/dist/esm/defaultConfig/responsive.js +0 -30
- package/dist/esm/defaultConfig/sequence.js +0 -29
- package/dist/esm/defaultConfig/shadow.js +0 -4
- package/dist/esm/defaultConfig/spacing.js +0 -18
- package/dist/esm/defaultConfig/svg.js +0 -6
- package/dist/esm/defaultConfig/templates.js +0 -4
- package/dist/esm/defaultConfig/theme.js +0 -16
- package/dist/esm/defaultConfig/timing.js +0 -17
- package/dist/esm/defaultConfig/typography.js +0 -21
- package/dist/esm/defaultConfig/unit.js +0 -6
- package/dist/esm/factory.js +0 -60
- package/dist/esm/index.js +0 -12
- package/dist/esm/set.js +0 -219
- package/dist/esm/system/color.js +0 -193
- package/dist/esm/system/document.js +0 -16
- package/dist/esm/system/font.js +0 -58
- package/dist/esm/system/index.js +0 -10
- package/dist/esm/system/reset.js +0 -67
- package/dist/esm/system/shadow.js +0 -91
- package/dist/esm/system/spacing.js +0 -121
- package/dist/esm/system/svg.js +0 -86
- package/dist/esm/system/theme.js +0 -480
- package/dist/esm/system/timing.js +0 -32
- package/dist/esm/system/typography.js +0 -85
- package/dist/esm/tests/index.js +0 -8
- package/dist/esm/transforms/index.js +0 -216
- package/dist/esm/utils/color.js +0 -192
- package/dist/esm/utils/font.js +0 -92
- package/dist/esm/utils/index.js +0 -7
- package/dist/esm/utils/sequence.js +0 -303
- package/dist/esm/utils/sprite.js +0 -65
- package/dist/esm/utils/theme.js +0 -9
- package/dist/esm/utils/unit.js +0 -59
- package/dist/esm/utils/var.js +0 -82
- package/dist/iife/index.js +0 -3204
package/src/system/timing.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { toCamelCase } from '@symbo.ls/
|
|
3
|
+
import { toCamelCase } from '@symbo.ls/utils'
|
|
4
4
|
import { getActiveConfig } from '../factory.js'
|
|
5
5
|
import {
|
|
6
6
|
applySequenceVars,
|
|
7
7
|
generateSequence,
|
|
8
8
|
getSequenceValuePropertyPair
|
|
9
|
-
} from '../utils'
|
|
9
|
+
} from '../utils/index.js'
|
|
10
10
|
|
|
11
11
|
export const applyTimingSequence = () => {
|
|
12
12
|
const CONFIG = getActiveConfig()
|
package/src/system/typography.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { merge } from '@
|
|
3
|
+
import { merge } from '@symbo.ls/utils'
|
|
4
4
|
import { getActiveConfig } from '../factory.js'
|
|
5
5
|
|
|
6
6
|
import {
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
findHeadings,
|
|
10
10
|
generateSequence,
|
|
11
11
|
getSequenceValuePropertyPair
|
|
12
|
-
} from '../utils'
|
|
12
|
+
} from '../utils/index.js'
|
|
13
13
|
|
|
14
14
|
export const runThroughMedia = FACTORY => {
|
|
15
15
|
const CONFIG = getActiveConfig()
|
|
@@ -35,14 +35,23 @@ export const runThroughMedia = FACTORY => {
|
|
|
35
35
|
unit
|
|
36
36
|
})
|
|
37
37
|
|
|
38
|
+
const VIEWPORT_UNITS = new Set(['vw', 'vh', 'vmin', 'vmax', 'svw', 'svh', 'lvw', 'lvh', 'dvw', 'dvh'])
|
|
39
|
+
const inheritedUnit = mediaValue.unit || unit
|
|
40
|
+
const mediaUnit = (!mediaValue.unit && VIEWPORT_UNITS.has(unit)) ? 'rem' : inheritedUnit
|
|
38
41
|
const query = MEDIA[mediaName]
|
|
39
42
|
const media =
|
|
40
43
|
'@media ' + (query === 'print' ? `${query}` : `screen and ${query}`)
|
|
41
44
|
TYPOGRAPHY.templates[media] = {
|
|
42
|
-
fontSize: mediaValue.base / TYPOGRAPHY.browserDefault +
|
|
45
|
+
fontSize: mediaValue.base / TYPOGRAPHY.browserDefault + mediaUnit
|
|
43
46
|
}
|
|
44
47
|
|
|
45
48
|
if (!mediaRegenerate) {
|
|
49
|
+
merge(mediaValue, {
|
|
50
|
+
sequence: {},
|
|
51
|
+
scales: {},
|
|
52
|
+
vars: {}
|
|
53
|
+
})
|
|
54
|
+
generateSequence(mediaValue)
|
|
46
55
|
applyMediaSequenceVars(FACTORY, prop)
|
|
47
56
|
continue
|
|
48
57
|
}
|
package/src/transforms/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { isString, isObject, exec } from '@
|
|
4
|
-
import { getActiveConfig } from '../factory'
|
|
3
|
+
import { isString, isObject, exec } from '@symbo.ls/utils'
|
|
4
|
+
import { getActiveConfig } from '../factory.js'
|
|
5
5
|
import {
|
|
6
6
|
getSpacingByKey,
|
|
7
7
|
getColor,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
getSpacingBasedOnRatio,
|
|
13
13
|
checkIfBoxSize,
|
|
14
14
|
splitSpacedValue
|
|
15
|
-
} from '../system'
|
|
15
|
+
} from '../system/index.js'
|
|
16
16
|
import {
|
|
17
17
|
getFnPrefixAndValue,
|
|
18
18
|
isResolvedColor,
|
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
CSS_NATIVE_COLOR_REGEX,
|
|
21
21
|
splitTopLevelCommas,
|
|
22
22
|
parseColorToken
|
|
23
|
-
} from '../utils'
|
|
23
|
+
} from '../utils/index.js'
|
|
24
24
|
|
|
25
25
|
const BORDER_STYLES = new Set([
|
|
26
26
|
'none', 'hidden', 'dotted', 'dashed', 'solid', 'double',
|
package/src/utils/color.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
isString,
|
|
7
7
|
isNumber,
|
|
8
8
|
isNotProduction
|
|
9
|
-
} from '@
|
|
9
|
+
} from '@symbo.ls/utils'
|
|
10
10
|
|
|
11
11
|
export const colorStringToRgbaArray = color => {
|
|
12
12
|
if (color === '') return [0, 0, 0, 0]
|
|
@@ -175,6 +175,7 @@ export const isCSSVar = (v) => v.charCodeAt(0) === 45 && v.charCodeAt(1) === 45
|
|
|
175
175
|
export const CSS_NATIVE_COLOR_REGEX = /(?:rgba?\(|hsla?\(|#[0-9a-fA-F]{3,8}\b)/
|
|
176
176
|
|
|
177
177
|
// Regex for Symbols color token: colorName[.opacity][+/-/=tone]
|
|
178
|
+
// Supports hyphenated names like 'highlight-reversed', 'canvas-card', 'line-highlight'
|
|
178
179
|
// +N or -N = relative shade, =N = absolute lightness percentage
|
|
179
180
|
const COLOR_TOKEN_REGEX = /^([a-zA-Z]\w*)(?:\.(\d+))?(?:([+-]\d+|=\d+))?$/
|
|
180
181
|
|
package/src/utils/font.js
CHANGED
|
@@ -16,6 +16,9 @@ export const getDefaultOrFirstKey = (LIBRARY, key) => {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
export const getFontFormat = (url) => {
|
|
19
|
+
// Tolerate missing urls — a font weight entry without a `url` should produce
|
|
20
|
+
// no `format(...)` hint rather than crashing the entire CSS pipeline.
|
|
21
|
+
if (typeof url !== 'string' || !url) return null
|
|
19
22
|
const ext = url.split(/[#?]/)[0].split('.').pop().trim()
|
|
20
23
|
if (['woff2', 'woff', 'ttf', 'otf', 'eot'].includes(ext)) return ext
|
|
21
24
|
return null
|
|
@@ -30,7 +33,10 @@ export const setFontImport = (url) => `@import url('${url}');`
|
|
|
30
33
|
export const setInCustomFontMedia = (str) => `@font-face { ${str} }`
|
|
31
34
|
|
|
32
35
|
export const setCustomFont = (name, url, weight, options = {}) => {
|
|
33
|
-
|
|
36
|
+
// Filter out undefined / empty entries so a missing weight URL doesn't
|
|
37
|
+
// emit a broken `url('undefined')` rule or crash on .split downstream.
|
|
38
|
+
const rawUrls = Array.isArray(url) ? url : [url]
|
|
39
|
+
const urls = rawUrls.filter((u) => typeof u === 'string' && u)
|
|
34
40
|
const srcList = urls.map((u) => {
|
|
35
41
|
const format = getFontFormat(u)
|
|
36
42
|
const formatStr = format ? ` format('${format}')` : ''
|
package/src/utils/sequence.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { isString } from '@
|
|
4
|
-
import { toDashCase } from '@symbo.ls/
|
|
3
|
+
import { isString } from '@symbo.ls/utils'
|
|
4
|
+
import { toDashCase } from '@symbo.ls/utils'
|
|
5
5
|
import { getActiveConfig } from '../factory.js'
|
|
6
6
|
import { CSS_UNITS, isScalingUnit } from './unit.js'
|
|
7
7
|
import { isCSSVar } from './color.js'
|
|
@@ -47,7 +47,8 @@ const setSequenceValue = (props, sequenceProps) => {
|
|
|
47
47
|
variable
|
|
48
48
|
}
|
|
49
49
|
sequenceProps.scales[key] = scaling
|
|
50
|
-
sequenceProps.
|
|
50
|
+
const varUnit = VIEWPORT_UNITS.has(sequenceProps.unit) ? 'rem' : sequenceProps.unit
|
|
51
|
+
sequenceProps.vars[variable] = scaling + varUnit
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
export const getFnPrefixAndValue = (val) => {
|
|
@@ -57,14 +58,18 @@ export const getFnPrefixAndValue = (val) => {
|
|
|
57
58
|
return [prefix, value]
|
|
58
59
|
}
|
|
59
60
|
|
|
61
|
+
const VIEWPORT_UNITS = new Set(['vw', 'vh', 'vmin', 'vmax', 'svw', 'svh', 'lvw', 'lvh', 'dvw', 'dvh'])
|
|
62
|
+
|
|
60
63
|
export const setScalingVar = (key, sequenceProps) => {
|
|
61
|
-
const { base, type, unit } = sequenceProps
|
|
64
|
+
const { base, type, unit: rawUnit } = sequenceProps
|
|
65
|
+
const unit = VIEWPORT_UNITS.has(rawUnit) ? 'rem' : rawUnit
|
|
62
66
|
|
|
63
67
|
const defaultVal = (isScalingUnit(unit) ? 1 : base) + unit
|
|
64
68
|
|
|
65
69
|
if (key === 0) return defaultVal
|
|
66
70
|
|
|
67
|
-
const
|
|
71
|
+
const vp = sequenceProps.varPrefix ? sequenceProps.varPrefix + '-' : ''
|
|
72
|
+
const prefix = '--' + vp + (type && type.replace('.', '-'))
|
|
68
73
|
const ratioVar = `${prefix}-ratio`
|
|
69
74
|
|
|
70
75
|
if (key > 0) {
|
|
@@ -73,6 +78,15 @@ export const setScalingVar = (key, sequenceProps) => {
|
|
|
73
78
|
}
|
|
74
79
|
if (key < 0) {
|
|
75
80
|
const nextLetterKey = numToLetterMap[key + 1]
|
|
81
|
+
const absKey = Math.abs(key)
|
|
82
|
+
const phiPow = Math.pow(PHI, 2 * absKey)
|
|
83
|
+
const prevAscKey = numToLetterMap[absKey]
|
|
84
|
+
// Clamp: max(current / ratio, normalized * ratio^n / phi^2n)
|
|
85
|
+
// current chain: A / ratio^n
|
|
86
|
+
// normalized: A * ratio^n / phi^(2n) = ASC mirror / phi^(2n)
|
|
87
|
+
if (prevAscKey) {
|
|
88
|
+
return `max(calc(var(${prefix}-${nextLetterKey}) / var(${ratioVar})), calc(var(${prefix}-${prevAscKey}) / ${phiPow.toFixed(4)}))`
|
|
89
|
+
}
|
|
76
90
|
return `calc(var(${prefix}-${nextLetterKey}) / var(${ratioVar}))`
|
|
77
91
|
}
|
|
78
92
|
}
|
|
@@ -82,7 +96,8 @@ export const setSubScalingVar = (index, arr, variable, sequenceProps) => {
|
|
|
82
96
|
const skipMiddle = index === 2 && arr.length === 2
|
|
83
97
|
const indexMapWithLength = skipMiddle ? index + 1 : index
|
|
84
98
|
|
|
85
|
-
const
|
|
99
|
+
const vp = sequenceProps.varPrefix ? sequenceProps.varPrefix + '-' : ''
|
|
100
|
+
const prefix = '--' + vp + (type && type.replace('.', '-'))
|
|
86
101
|
const subRatioVarPrefix = `${prefix}-sub-ratio-`
|
|
87
102
|
|
|
88
103
|
return `calc(var(${variable}) * var(${subRatioVarPrefix + indexMapWithLength}))`
|
|
@@ -136,24 +151,25 @@ export const generateSubSequence = (props, sequenceProps) => {
|
|
|
136
151
|
})
|
|
137
152
|
}
|
|
138
153
|
|
|
154
|
+
const PHI = 1.618
|
|
155
|
+
|
|
139
156
|
const switchSequenceOnNegative = (key, base, ratio) => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
//
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
// if (key < 0) return base * Math.pow(avg, key)
|
|
150
|
-
return base * Math.pow(ratio, key)
|
|
157
|
+
if (key >= 0) return base * Math.pow(ratio, key)
|
|
158
|
+
|
|
159
|
+
// DESC: clamp between current and normalized to preserve proportions
|
|
160
|
+
// Below golden ratio: use current (1/ratio^n) — nothing changes
|
|
161
|
+
// Above golden ratio: use normalized (ratio^n / phi^2n) — proportion stays constant
|
|
162
|
+
const absKey = Math.abs(key)
|
|
163
|
+
const current = base * Math.pow(ratio, key) // base / ratio^n
|
|
164
|
+
const normalized = base * Math.pow(ratio, absKey) / Math.pow(PHI, 2 * absKey) // base * ratio^n / phi^(2n)
|
|
165
|
+
return Math.max(current, normalized)
|
|
151
166
|
}
|
|
152
167
|
|
|
153
168
|
export const generateSequence = (sequenceProps) => {
|
|
154
169
|
const { type, base, ratio, range, subSequence } = sequenceProps
|
|
155
170
|
const n = Math.abs(range[0]) + Math.abs(range[1])
|
|
156
|
-
const
|
|
171
|
+
const vp = sequenceProps.varPrefix ? sequenceProps.varPrefix + '-' : ''
|
|
172
|
+
const prefix = '--' + vp + (type && type.replace('.', '-')) + '-'
|
|
157
173
|
|
|
158
174
|
for (let i = 0; i <= n; i++) {
|
|
159
175
|
const key = range[1] - i
|
|
@@ -204,7 +220,8 @@ export const generateSequencePosition = (sequenceProps, position = 0) => {
|
|
|
204
220
|
|
|
205
221
|
const value = base * Math.pow(ratio, index)
|
|
206
222
|
const scaling = ~~((value / base) * 100) / 100
|
|
207
|
-
const
|
|
223
|
+
const vp = sequenceProps.varPrefix ? sequenceProps.varPrefix + '-' : ''
|
|
224
|
+
const prefix = '--' + vp + (type && type.replace('.', '-')) + '-'
|
|
208
225
|
const variable = prefix + letterKey
|
|
209
226
|
const scalingVariable = setScalingVar(index, sequenceProps)
|
|
210
227
|
|
|
@@ -256,7 +273,8 @@ export const getSequenceValue = (value = 'A', sequenceProps) => {
|
|
|
256
273
|
]
|
|
257
274
|
if (skipArr.includes(value)) return value
|
|
258
275
|
|
|
259
|
-
const
|
|
276
|
+
const vp = sequenceProps.varPrefix ? sequenceProps.varPrefix + '-' : ''
|
|
277
|
+
const prefix = `--${vp}${toDashCase(sequenceProps.type.replace('.', '-'))}-`
|
|
260
278
|
const letterVal = value.toUpperCase()
|
|
261
279
|
const isNegative = letterVal.slice(0, 1) === '-' ? '-' : ''
|
|
262
280
|
let absValue = isNegative ? letterVal.slice(1) : letterVal
|
|
@@ -316,15 +334,14 @@ export const getSequenceValueBySymbols = (value, sequenceProps) => {
|
|
|
316
334
|
)
|
|
317
335
|
if (!mathArr.length) return value
|
|
318
336
|
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
.join('')
|
|
337
|
+
// Tokenize the expression preserving all operators, then resolve each token
|
|
338
|
+
const symbolRegex = /(\s*[+\-*/,]\s*)/
|
|
339
|
+
const tokens = value.split(symbolRegex)
|
|
340
|
+
return tokens.map((token) => {
|
|
341
|
+
const trimmed = token.trim()
|
|
342
|
+
if (!trimmed || ['+', '-', '*', '/', ','].includes(trimmed)) return token
|
|
343
|
+
return getSequenceValue(trimmed, sequenceProps)
|
|
344
|
+
}).join('')
|
|
328
345
|
}
|
|
329
346
|
|
|
330
347
|
export const getSequenceValuePropertyPair = (
|
package/src/utils/sprite.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { isArray, isNotProduction, isString } from '@
|
|
4
|
-
import { getActiveConfig } from '../factory'
|
|
3
|
+
import { isArray, isNotProduction, isString } from '@symbo.ls/utils'
|
|
4
|
+
import { getActiveConfig } from '../factory.js'
|
|
5
5
|
|
|
6
6
|
const isDev = isNotProduction()
|
|
7
7
|
|
|
@@ -11,8 +11,8 @@ export const generateSprite = (icons) => {
|
|
|
11
11
|
let sprite = ''
|
|
12
12
|
|
|
13
13
|
for (const key in icons) {
|
|
14
|
-
if (CONFIG.
|
|
15
|
-
else CONFIG.
|
|
14
|
+
if (CONFIG.__svgCache[key]) continue
|
|
15
|
+
else CONFIG.__svgCache[key] = true
|
|
16
16
|
sprite += icons[key]
|
|
17
17
|
}
|
|
18
18
|
|
|
@@ -20,10 +20,10 @@ export const generateSprite = (icons) => {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
const parseRootAttributes = (htmlString) => {
|
|
23
|
-
const val = htmlString.default || htmlString
|
|
23
|
+
const val = htmlString && (htmlString.default || htmlString)
|
|
24
24
|
if (!isString(val)) {
|
|
25
25
|
if (isDev) console.warn('parseRootAttributes:', val, 'is not a string')
|
|
26
|
-
return
|
|
26
|
+
return {} // empty attrs — caller destructures `width`/`height`, must not crash
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
const match = val.match(/<svg\s+(.*?)>/)
|
|
@@ -35,6 +35,7 @@ const parseRootAttributes = (htmlString) => {
|
|
|
35
35
|
const attrs = attrString.match(
|
|
36
36
|
/(\S+)=["']?((?:.(?!["']?\s+(?:\S+)=|\s*\/?[>"']))+.)["']?/gm
|
|
37
37
|
)
|
|
38
|
+
if (!attrs) return {} // attr regex sometimes returns null on minimal SVG; same safety
|
|
38
39
|
return attrs.reduce((acc, attr) => {
|
|
39
40
|
const [key, value] = attr.split('=')
|
|
40
41
|
acc[key] = value.replace(/['"]/g, '')
|
|
@@ -42,18 +43,34 @@ const parseRootAttributes = (htmlString) => {
|
|
|
42
43
|
}, {})
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
// Rewrite every internal id="…" + url(#…) reference inside an SVG body
|
|
47
|
+
// with a deterministic suffix derived from the symbol key + the original
|
|
48
|
+
// id. Same input SVG + same key → same output, every render.
|
|
49
|
+
//
|
|
50
|
+
// Previous behavior had three bugs that compounded:
|
|
51
|
+
// 1. `idRegex` had no `g` flag, so `.replace(idRegex, …)` only swapped
|
|
52
|
+
// the FIRST `id="…"` match. SVGs with multiple ids (filters,
|
|
53
|
+
// gradients, masks, clipPaths) lost references.
|
|
54
|
+
// 2. `Math.random()` was the per-iteration suffix, so the same SVG got
|
|
55
|
+
// different ids on every call → SSR-rendered DOM never matched the
|
|
56
|
+
// hydrate pass and one symbol's filter could fail to match its url().
|
|
57
|
+
// 3. Each iteration reset `replacedCode = code` (instead of chaining),
|
|
58
|
+
// so even though the loop ran N times it only ever produced one
|
|
59
|
+
// single-id swap.
|
|
45
60
|
const replaceIdsAndUrls = (code, key) => {
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
61
|
+
const ids = []
|
|
62
|
+
code.replace(/id="([^"]*)"/g, (_, id) => { ids.push(id); return _ })
|
|
63
|
+
if (!ids.length) return code
|
|
64
|
+
|
|
49
65
|
let replacedCode = code
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
66
|
+
for (const origId of ids) {
|
|
67
|
+
const escaped = origId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
68
|
+
const newId = `${key}-${origId}`
|
|
69
|
+
replacedCode = replacedCode
|
|
70
|
+
.replace(new RegExp(`id="${escaped}"`, 'g'), `id="${newId}"`)
|
|
71
|
+
.replace(new RegExp(`url\\(#${escaped}\\)`, 'g'), `url(#${newId})`)
|
|
72
|
+
.replace(new RegExp(`xlink:href="#${escaped}"`, 'g'), `xlink:href="#${newId}"`)
|
|
73
|
+
.replace(new RegExp(`href="#${escaped}"`, 'g'), `href="#${newId}"`)
|
|
57
74
|
}
|
|
58
75
|
return replacedCode
|
|
59
76
|
}
|
|
@@ -75,5 +92,16 @@ export const convertSvgToSymbol = (key, code) => {
|
|
|
75
92
|
symbol = symbol.replace(/width="[^"]*"/, '')
|
|
76
93
|
symbol = symbol.replace(/height="[^"]*"/, '')
|
|
77
94
|
symbol = symbol.replace('</svg', '</symbol')
|
|
95
|
+
symbol = expandSvgSelfClosing(symbol)
|
|
78
96
|
return symbol
|
|
79
97
|
}
|
|
98
|
+
|
|
99
|
+
// SVG elements that are void in SVG but not in HTML.
|
|
100
|
+
// HTML parser treats <line .../> as <line ...> (ignores /), nesting siblings.
|
|
101
|
+
// Fix: expand self-closing tags to explicit open+close for HTML parser compat.
|
|
102
|
+
const SVG_VOID_TAGS = 'line|circle|ellipse|rect|polyline|polygon|path|stop|use|image'
|
|
103
|
+
const SVG_SELF_CLOSING_RE = new RegExp(
|
|
104
|
+
`<(${SVG_VOID_TAGS})\\b([^>]*?)\\s*/>`,
|
|
105
|
+
'g'
|
|
106
|
+
)
|
|
107
|
+
const expandSvgSelfClosing = (str) => str.replace(SVG_SELF_CLOSING_RE, '<$1$2></$1>')
|
package/src/utils/var.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { isObjectLike } from '@
|
|
3
|
+
import { isObjectLike } from '@symbo.ls/utils'
|
|
4
4
|
import { getActiveConfig } from '../factory.js'
|
|
5
5
|
import { getSubratio } from './sequence.js'
|
|
6
6
|
import { isScalingUnit } from './unit.js'
|
|
7
7
|
|
|
8
8
|
export const setVariables = (result, key) => {
|
|
9
9
|
const CONFIG = getActiveConfig()
|
|
10
|
-
const { CSS_VARS } = CONFIG
|
|
10
|
+
const { cssVars: CSS_VARS } = CONFIG
|
|
11
11
|
if (isObjectLike(result.value)) {
|
|
12
12
|
// TODO: handle nested object variables
|
|
13
13
|
} else {
|
|
@@ -20,7 +20,8 @@ export const applySequenceGlobalVars = (vars, obj, options) => {
|
|
|
20
20
|
const { unit: UNIT } = CONFIG
|
|
21
21
|
const unit = obj.unit || UNIT.default
|
|
22
22
|
const { base, ratio, type } = obj
|
|
23
|
-
const
|
|
23
|
+
const vp = obj.varPrefix ? obj.varPrefix + '-' : ''
|
|
24
|
+
const prefix = '--' + vp + (type && type.replace('.', '-'))
|
|
24
25
|
vars[`${prefix}-base`] = base
|
|
25
26
|
vars[`${prefix}-unit`] = unit
|
|
26
27
|
const ratioVar = `${prefix}-ratio`
|
|
@@ -36,11 +37,15 @@ export const applySequenceGlobalVars = (vars, obj, options) => {
|
|
|
36
37
|
// vars[`${prefix}-sub-ratio-3`] = second
|
|
37
38
|
}
|
|
38
39
|
|
|
40
|
+
// Viewport units are applied to root fontSize only; tokens use 'rem' instead
|
|
41
|
+
const VIEWPORT_UNITS = new Set(['vw', 'vh', 'vmin', 'vmax', 'svw', 'svh', 'lvw', 'lvh', 'dvw', 'dvh'])
|
|
42
|
+
|
|
39
43
|
export const applySequenceVars = (FACTORY, options = {}) => {
|
|
40
44
|
const CONFIG = getActiveConfig()
|
|
41
|
-
const { unit: UNIT, timing: TIMING, CSS_VARS } = CONFIG
|
|
45
|
+
const { unit: UNIT, timing: TIMING, cssVars: CSS_VARS } = CONFIG
|
|
42
46
|
|
|
43
|
-
const
|
|
47
|
+
const rawUnit = FACTORY.unit || UNIT.default
|
|
48
|
+
const unit = VIEWPORT_UNITS.has(rawUnit) ? 'rem' : rawUnit
|
|
44
49
|
const { mediaRegenerate, sequence, scales } = FACTORY
|
|
45
50
|
|
|
46
51
|
if (!mediaRegenerate) {
|
|
@@ -72,13 +77,15 @@ export const applySequenceVars = (FACTORY, options = {}) => {
|
|
|
72
77
|
|
|
73
78
|
export const applyMediaSequenceVars = (FACTORY, media, options = {}) => {
|
|
74
79
|
const CONFIG = getActiveConfig()
|
|
75
|
-
const { unit: UNIT, media: MEDIA, CSS_VARS } = CONFIG
|
|
80
|
+
const { unit: UNIT, media: MEDIA, cssVars: CSS_VARS } = CONFIG
|
|
76
81
|
|
|
77
82
|
const mediaName = media.slice(1)
|
|
78
83
|
|
|
79
|
-
const
|
|
84
|
+
const mediaConfig = FACTORY[media]
|
|
85
|
+
const rawMediaUnit = mediaConfig.unit || FACTORY.unit || UNIT.default
|
|
86
|
+
const unit = VIEWPORT_UNITS.has(rawMediaUnit) ? 'rem' : rawMediaUnit
|
|
80
87
|
const { mediaRegenerate } = FACTORY
|
|
81
|
-
const { sequence, scales } =
|
|
88
|
+
const { sequence, scales } = mediaConfig
|
|
82
89
|
|
|
83
90
|
const query = MEDIA[mediaName]
|
|
84
91
|
if (!query && CONFIG.verbose) console.warn('Can\'t find media query ', query)
|
|
@@ -88,7 +95,18 @@ export const applyMediaSequenceVars = (FACTORY, media, options = {}) => {
|
|
|
88
95
|
if (!mediaRegenerate) {
|
|
89
96
|
let underMediaQuery = CSS_VARS[`@media ${query}`]
|
|
90
97
|
if (!underMediaQuery) underMediaQuery = CSS_VARS[`@media ${query}`] = {}
|
|
91
|
-
applySequenceGlobalVars(underMediaQuery,
|
|
98
|
+
applySequenceGlobalVars(underMediaQuery, mediaConfig, options)
|
|
99
|
+
|
|
100
|
+
// If unit changed, override token vars with new unit values
|
|
101
|
+
const parentUnit = FACTORY.unit || UNIT.default
|
|
102
|
+
if (unit !== parentUnit && sequence) {
|
|
103
|
+
for (const key in sequence) {
|
|
104
|
+
const item = sequence[key]
|
|
105
|
+
const value = scales[key] + unit
|
|
106
|
+
underMediaQuery[item.variable + '_default'] = value
|
|
107
|
+
underMediaQuery[item.variable] = value
|
|
108
|
+
}
|
|
109
|
+
}
|
|
92
110
|
return
|
|
93
111
|
}
|
|
94
112
|
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
var defaultFont = {
|
|
2
|
-
// eslint-disable-line
|
|
3
|
-
name: "",
|
|
4
|
-
family: "",
|
|
5
|
-
type: ""
|
|
6
|
-
};
|
|
7
|
-
const font_family = {};
|
|
8
|
-
const font_family_types = {
|
|
9
|
-
"sans-serif": "Helvetica, Arial, sans-serif, --system-default",
|
|
10
|
-
serif: "Times New Roman, Georgia, serif, --system-default",
|
|
11
|
-
monospace: "Courier New, monospace, --system-default"
|
|
12
|
-
};
|
|
13
|
-
const font_face = {};
|
|
14
|
-
export {
|
|
15
|
-
font_face,
|
|
16
|
-
font_family,
|
|
17
|
-
font_family_types
|
|
18
|
-
};
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
export * from "./sequence.js";
|
|
2
|
-
export * from "./unit.js";
|
|
3
|
-
export * from "./typography.js";
|
|
4
|
-
export * from "./font.js";
|
|
5
|
-
export * from "./font-family.js";
|
|
6
|
-
export * from "./media.js";
|
|
7
|
-
export * from "./spacing.js";
|
|
8
|
-
export * from "./color.js";
|
|
9
|
-
export * from "./theme.js";
|
|
10
|
-
export * from "./shadow.js";
|
|
11
|
-
export * from "./icons.js";
|
|
12
|
-
export * from "./timing.js";
|
|
13
|
-
export * from "./document.js";
|
|
14
|
-
export * from "./responsive.js";
|
|
15
|
-
export * from "./animation.js";
|
|
16
|
-
export * from "./svg.js";
|
|
17
|
-
export * from "./templates.js";
|
|
18
|
-
export * from "./grid.js";
|
|
19
|
-
export * from "./class.js";
|
|
20
|
-
const reset = {};
|
|
21
|
-
const vars = {};
|
|
22
|
-
export {
|
|
23
|
-
reset,
|
|
24
|
-
vars
|
|
25
|
-
};
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
const breakpoints = {
|
|
2
|
-
screenL: 1920,
|
|
3
|
-
screenM: 1680,
|
|
4
|
-
screenS: 1440,
|
|
5
|
-
tabletL: 1366,
|
|
6
|
-
tabletM: 1280,
|
|
7
|
-
tabletS: 1024,
|
|
8
|
-
mobileL: 768,
|
|
9
|
-
mobileM: 560,
|
|
10
|
-
mobileS: 480,
|
|
11
|
-
mobileXS: 375
|
|
12
|
-
};
|
|
13
|
-
const devices = {
|
|
14
|
-
screenXXL: [2560, 1440],
|
|
15
|
-
screenXL: [2240, 1260],
|
|
16
|
-
screenL: [1920, 1024],
|
|
17
|
-
screenM: [1680, 1024],
|
|
18
|
-
screenS: [1440, 720],
|
|
19
|
-
tabletL: [1366, 926],
|
|
20
|
-
tabletM: [1280, 768],
|
|
21
|
-
tabletS: [1024, 768],
|
|
22
|
-
mobileL: [768, 375],
|
|
23
|
-
mobileM: [560, 768],
|
|
24
|
-
mobileS: [480, 768],
|
|
25
|
-
mobileXS: [375, 768]
|
|
26
|
-
};
|
|
27
|
-
export {
|
|
28
|
-
breakpoints,
|
|
29
|
-
devices
|
|
30
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
const sequence = {
|
|
2
|
-
"minor-second": 1.067,
|
|
3
|
-
"major-second": 1.125,
|
|
4
|
-
"minor-third": 1.2,
|
|
5
|
-
"major-third": 1.25,
|
|
6
|
-
"perfect-fourth": 1.333,
|
|
7
|
-
"augmented-fourth": 1.414,
|
|
8
|
-
"perfect-fifth": 1.5,
|
|
9
|
-
"minor-sixth": 1.6,
|
|
10
|
-
phi: 1.618,
|
|
11
|
-
// golden-ratio
|
|
12
|
-
"major-sixth": 1.667,
|
|
13
|
-
"square-root-3": 1.732,
|
|
14
|
-
// theodorus
|
|
15
|
-
"minor-seventh": 1.778,
|
|
16
|
-
"major-seventh": 1.875,
|
|
17
|
-
octave: 2,
|
|
18
|
-
"square-root-5": 2.23,
|
|
19
|
-
// pythagoras
|
|
20
|
-
"major-tenth": 2.5,
|
|
21
|
-
"major-eleventh": 2.667,
|
|
22
|
-
"major-twelfth": 3,
|
|
23
|
-
pi: 3.14,
|
|
24
|
-
// archimedes
|
|
25
|
-
"double-octave": 4
|
|
26
|
-
};
|
|
27
|
-
export {
|
|
28
|
-
sequence
|
|
29
|
-
};
|