@symbo.ls/scratch 3.8.8 → 3.14.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/README.md +2 -2
- package/dist/cjs/defaultConfig/class.js +1 -2
- package/dist/cjs/defaultConfig/font-family.js +6 -6
- package/dist/cjs/defaultConfig/icons.js +2 -2
- package/dist/cjs/defaultConfig/svg.js +2 -2
- package/dist/cjs/defaultConfig/timing.js +1 -1
- package/dist/cjs/factory.js +72 -12
- package/dist/cjs/index.js +6 -4
- package/dist/cjs/set.js +113 -52
- package/dist/cjs/system/color.js +72 -12
- package/dist/cjs/system/document.js +3 -3
- package/dist/cjs/system/font.js +14 -14
- package/dist/cjs/system/reset.js +34 -7
- package/dist/cjs/system/shadow.js +4 -3
- package/dist/cjs/system/spacing.js +18 -18
- package/dist/cjs/system/svg.js +34 -7
- package/dist/cjs/system/theme.js +51 -50
- package/dist/cjs/system/timing.js +6 -6
- package/dist/cjs/system/typography.js +12 -3
- package/dist/cjs/transforms/index.js +4 -4
- package/dist/cjs/utils/color.js +1 -1
- package/dist/cjs/utils/font.js +3 -1
- package/dist/cjs/utils/sequence.js +35 -16
- package/dist/cjs/utils/sprite.js +11 -4
- package/dist/cjs/utils/var.js +23 -9
- package/dist/esm/defaultConfig/class.js +1 -2
- package/dist/esm/defaultConfig/font-family.js +6 -6
- package/dist/esm/defaultConfig/icons.js +2 -2
- package/dist/esm/defaultConfig/svg.js +2 -2
- package/dist/esm/defaultConfig/timing.js +1 -1
- package/dist/esm/factory.js +72 -12
- package/dist/esm/index.js +6 -4
- package/dist/esm/set.js +114 -53
- package/dist/esm/system/color.js +72 -12
- package/dist/esm/system/document.js +3 -3
- package/dist/esm/system/font.js +5 -5
- package/dist/esm/system/reset.js +34 -7
- package/dist/esm/system/shadow.js +4 -3
- package/dist/esm/system/spacing.js +3 -3
- package/dist/esm/system/svg.js +34 -7
- package/dist/esm/system/theme.js +51 -50
- package/dist/esm/system/timing.js +2 -2
- package/dist/esm/system/typography.js +12 -3
- package/dist/esm/transforms/index.js +4 -4
- package/dist/esm/utils/color.js +1 -1
- package/dist/esm/utils/font.js +3 -1
- package/dist/esm/utils/sequence.js +35 -16
- package/dist/esm/utils/sprite.js +11 -4
- package/dist/esm/utils/var.js +23 -9
- package/dist/iife/index.js +728 -302
- 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 +44 -7
- 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 +15 -4
- package/src/utils/var.js +27 -9
package/src/system/color.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { isObject, isArray, isString } from '@
|
|
3
|
+
import { isObject, isArray, isString } from '@symbo.ls/utils'
|
|
4
4
|
import { getActiveConfig } from '../factory.js'
|
|
5
5
|
|
|
6
6
|
import {
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
getRgbTone,
|
|
9
9
|
isCSSVar,
|
|
10
10
|
parseColorToken
|
|
11
|
-
} from '../utils'
|
|
11
|
+
} from '../utils/index.js'
|
|
12
12
|
|
|
13
13
|
export const getColor = (value, key, config) => {
|
|
14
14
|
const CONFIG = config || getActiveConfig()
|
|
@@ -99,11 +99,21 @@ export const getMediaColor = (value, globalTheme, config) => {
|
|
|
99
99
|
|
|
100
100
|
if (isObj && val.value) return getColor(value, `@${globalTheme}`, config)
|
|
101
101
|
else if (isObj) {
|
|
102
|
+
// Prefer the adaptive var (--color-NAME) when available so runtime theme
|
|
103
|
+
// switches via [data-theme] actually take effect. Without this, setting
|
|
104
|
+
// `globalTheme: 'dark'` in config would lock every color to the dark
|
|
105
|
+
// scheme-specific var (--color-NAME-dark), which never responds to
|
|
106
|
+
// runtime theme toggles.
|
|
107
|
+
if (CONFIG.useVariable && val.var) return `var(${val.var})`
|
|
102
108
|
if (globalTheme) return getColor(value, `@${globalTheme}`, config)
|
|
103
109
|
else {
|
|
110
|
+
// Legacy fallback when adaptive var is unavailable (useVariable: false).
|
|
111
|
+
// Only @-prefixed keys are scheme variants — skip metadata like `var`.
|
|
104
112
|
const obj = {}
|
|
105
113
|
for (const mediaName in val) {
|
|
114
|
+
if (mediaName.charCodeAt(0) !== 64 /* @ */) continue
|
|
106
115
|
const query = CONFIG.media[mediaName.slice(1)]
|
|
116
|
+
if (!query) continue
|
|
107
117
|
const media = '@media ' + (query === 'print' ? `${query}` : `screen and ${query}`)
|
|
108
118
|
obj[media] = getColor(value, mediaName, config)
|
|
109
119
|
}
|
|
@@ -128,7 +138,16 @@ export const setColor = (val, key, suffix) => {
|
|
|
128
138
|
)) {
|
|
129
139
|
// Handle space-separated format: '--colorName alpha' (e.g. '--gray1 1')
|
|
130
140
|
const parts = rawRef.split(' ')
|
|
131
|
-
|
|
141
|
+
let refColor = CONFIG.color[parts[0]]
|
|
142
|
+
// Lazy resolution: composite colors (arrays/objects) often reference
|
|
143
|
+
// primitives by name. If iteration order processed the composite first,
|
|
144
|
+
// the primitive is still its raw input — process it now so this
|
|
145
|
+
// dereference works regardless of key order in CONFIG.color. setEach()
|
|
146
|
+
// also pre-sorts so primitives go first, but this is a safety net.
|
|
147
|
+
if (refColor && !refColor.value && !refColor.rgb && (isString(refColor) || isArray(refColor) || isObject(refColor))) {
|
|
148
|
+
CONFIG.color[parts[0]] = setColor(refColor, parts[0])
|
|
149
|
+
refColor = CONFIG.color[parts[0]]
|
|
150
|
+
}
|
|
132
151
|
if (refColor && refColor.value) {
|
|
133
152
|
let rgb = refColor.rgb
|
|
134
153
|
const alpha = parts[1] !== undefined ? parts[1] : '1'
|
|
@@ -160,11 +179,10 @@ export const setColor = (val, key, suffix) => {
|
|
|
160
179
|
}
|
|
161
180
|
}
|
|
162
181
|
|
|
182
|
+
// Normalize array shorthand `[lightVal, darkVal]` to scheme-keyed object
|
|
183
|
+
// so the multi-scheme branch below handles both cases uniformly.
|
|
163
184
|
if (isArray(val)) {
|
|
164
|
-
|
|
165
|
-
'@light': setColor(val[0], key, 'light'),
|
|
166
|
-
'@dark': setColor(val[1], key, 'dark')
|
|
167
|
-
}
|
|
185
|
+
val = { '@light': val[0], '@dark': val[1] }
|
|
168
186
|
}
|
|
169
187
|
|
|
170
188
|
if (isObject(val)) {
|
|
@@ -176,17 +194,99 @@ export const setColor = (val, key, suffix) => {
|
|
|
176
194
|
variant.slice(0, 1) === '@' ? variant.slice(1) : variant
|
|
177
195
|
)
|
|
178
196
|
}
|
|
197
|
+
|
|
198
|
+
// Generate a single adaptive `--color-${key}` CSS var so consumers can
|
|
199
|
+
// write `border-color: var(--color-${key})` and have it switch via
|
|
200
|
+
// `@media (prefers-color-scheme)` and `[data-theme]` automatically.
|
|
201
|
+
// Scheme-agnostic: works for @light/@dark plus arbitrary custom schemes
|
|
202
|
+
// (@ocean, @sunset, etc). Mirrors generateAutoVars() in system/theme.js.
|
|
203
|
+
//
|
|
204
|
+
// Without this, getMediaColor() falls into the @media-keyed-object branch
|
|
205
|
+
// (when globalTheme === 'auto'), which the CSS engine cannot serialize as
|
|
206
|
+
// a single CSS property value — emitting broken rules like
|
|
207
|
+
// `.classname borderrightcolor { }`.
|
|
208
|
+
if (CONFIG.useVariable) {
|
|
209
|
+
const vp = CONFIG.varPrefix ? CONFIG.varPrefix + '-' : ''
|
|
210
|
+
const adaptiveVar = `--${vp}color-${key}`
|
|
211
|
+
let fallbackValue
|
|
212
|
+
const schemeValues = {}
|
|
213
|
+
|
|
214
|
+
for (const variant in obj) {
|
|
215
|
+
if (variant.charCodeAt(0) !== 64 /* @ */) continue
|
|
216
|
+
const scheme = variant.slice(1)
|
|
217
|
+
const entry = obj[variant]
|
|
218
|
+
const value = entry && (entry.value || entry)
|
|
219
|
+
if (!value || typeof value !== 'string') continue
|
|
220
|
+
schemeValues[scheme] = value
|
|
221
|
+
// Prefer 'light' as the :root fallback; otherwise first resolved scheme.
|
|
222
|
+
if (scheme === 'light' || fallbackValue === undefined) fallbackValue = value
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (fallbackValue !== undefined) {
|
|
226
|
+
CONFIG.cssVars[adaptiveVar] = fallbackValue
|
|
227
|
+
|
|
228
|
+
if (!CONFIG.cssMediaVars) CONFIG.cssMediaVars = {}
|
|
229
|
+
for (const scheme in schemeValues) {
|
|
230
|
+
// [data-theme] selector — works for ANY scheme (including custom ones)
|
|
231
|
+
const sel = `[data-theme="${scheme}"]`
|
|
232
|
+
if (!CONFIG.cssMediaVars[sel]) CONFIG.cssMediaVars[sel] = {}
|
|
233
|
+
CONFIG.cssMediaVars[sel][adaptiveVar] = schemeValues[scheme]
|
|
234
|
+
|
|
235
|
+
// prefers-color-scheme media query — only browsers know light/dark
|
|
236
|
+
if (scheme === 'light' || scheme === 'dark') {
|
|
237
|
+
const mq = `@media (prefers-color-scheme: ${scheme})`
|
|
238
|
+
if (!CONFIG.cssMediaVars[mq]) CONFIG.cssMediaVars[mq] = {}
|
|
239
|
+
CONFIG.cssMediaVars[mq][adaptiveVar] = schemeValues[scheme]
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Expose the adaptive var on the wrapper so getColor() returns it
|
|
244
|
+
// directly when called without an explicit @scheme key.
|
|
245
|
+
obj.var = adaptiveVar
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
179
249
|
return obj
|
|
180
250
|
}
|
|
181
251
|
|
|
182
|
-
const
|
|
183
|
-
const
|
|
252
|
+
const vp = CONFIG.varPrefix ? CONFIG.varPrefix + '-' : ''
|
|
253
|
+
const CSSVar = `--${vp}color-${key}` + (suffix ? `-${suffix}` : '')
|
|
254
|
+
|
|
255
|
+
// Resolve dot notation: 'green.08' → take green color at 8% opacity
|
|
256
|
+
let resolvedVal = val.value || val
|
|
257
|
+
if (isString(resolvedVal) && resolvedVal.includes('.') && !resolvedVal.includes('(')) {
|
|
258
|
+
const [colorRef, alphaStr] = resolvedVal.split('.')
|
|
259
|
+
const refColor = CONFIG.color[colorRef]
|
|
260
|
+
if (refColor && refColor.rgb) {
|
|
261
|
+
resolvedVal = `rgba(${refColor.rgb}, ${parseFloat('0.' + alphaStr) || 1})`
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Resolve token notation: 'gray-168' / 'gray+50' / 'gray=90' → apply tone to base
|
|
266
|
+
if (isString(resolvedVal) && !resolvedVal.includes('(') && !resolvedVal.startsWith('#')) {
|
|
267
|
+
const parsed = parseColorToken(resolvedVal)
|
|
268
|
+
if (parsed && parsed.name && !parsed.passthrough && !parsed.cssVar) {
|
|
269
|
+
const refColor = CONFIG.color[parsed.name]
|
|
270
|
+
if (refColor && !refColor.value && !refColor.rgb && (isString(refColor) || isArray(refColor) || isObject(refColor))) {
|
|
271
|
+
CONFIG.color[parsed.name] = setColor(refColor, parsed.name)
|
|
272
|
+
}
|
|
273
|
+
const baseColor = CONFIG.color[parsed.name]
|
|
274
|
+
if (baseColor && baseColor.rgb) {
|
|
275
|
+
let rgb = baseColor.rgb
|
|
276
|
+
if (parsed.tone) rgb = getRgbTone(rgb, parsed.tone)
|
|
277
|
+
const alphaVal = parsed.alpha ? parseFloat(parsed.alpha) : 1
|
|
278
|
+
resolvedVal = `rgba(${rgb}, ${alphaVal})`
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
const colorArr = colorStringToRgbaArray(resolvedVal)
|
|
184
284
|
const [r, g, b, a = 1] = colorArr
|
|
185
285
|
const alpha = parseFloat(a.toFixed(2))
|
|
186
286
|
const rgb = `${r}, ${g}, ${b}`
|
|
187
287
|
const value = `rgba(${rgb}, ${alpha})`
|
|
188
288
|
|
|
189
|
-
if (CONFIG.useVariable) { CONFIG.
|
|
289
|
+
if (CONFIG.useVariable) { CONFIG.cssVars[CSSVar] = value }
|
|
190
290
|
|
|
191
291
|
return {
|
|
192
292
|
var: CSSVar,
|
|
@@ -213,10 +313,11 @@ export const setGradient = (val, key, suffix) => {
|
|
|
213
313
|
return obj
|
|
214
314
|
}
|
|
215
315
|
|
|
216
|
-
const
|
|
316
|
+
const vp = CONFIG.varPrefix ? CONFIG.varPrefix + '-' : ''
|
|
317
|
+
const CSSVar = `--${vp}gradient-${key}` + (suffix ? `-${suffix}` : '')
|
|
217
318
|
|
|
218
319
|
if (CONFIG.useVariable) {
|
|
219
|
-
CONFIG.
|
|
320
|
+
CONFIG.cssVars[CSSVar] = val.value || val
|
|
220
321
|
}
|
|
221
322
|
|
|
222
323
|
return {
|
package/src/system/document.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
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
|
-
import { getDefaultOrFirstKey } from '../utils'
|
|
5
|
+
import { getDefaultOrFirstKey } from '../utils/index.js'
|
|
6
6
|
|
|
7
7
|
export const applyDocument = () => {
|
|
8
8
|
const CONFIG = getActiveConfig()
|
|
9
|
-
const { document: DOCUMENT,
|
|
9
|
+
const { document: DOCUMENT, fontFamily: FONT_FAMILY, theme: THEME, typography: TYPOGRAPHY } = CONFIG
|
|
10
10
|
return merge(DOCUMENT, {
|
|
11
11
|
theme: THEME.document,
|
|
12
12
|
fontFamily: getDefaultOrFirstKey(FONT_FAMILY),
|
package/src/system/font.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { isObject, isArray } from '@
|
|
4
|
-
import { arrayzeValue } from '@symbo.ls/
|
|
3
|
+
import { isObject, isArray } from '@symbo.ls/utils'
|
|
4
|
+
import { arrayzeValue } from '@symbo.ls/utils'
|
|
5
5
|
import { getActiveConfig } from '../factory.js'
|
|
6
6
|
|
|
7
7
|
import {
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
setCustomFontMedia,
|
|
12
12
|
setFontImport,
|
|
13
13
|
resolveFileUrl
|
|
14
|
-
} from '../utils'
|
|
14
|
+
} from '../utils/index.js'
|
|
15
15
|
|
|
16
16
|
export const setFont = (val, key) => {
|
|
17
17
|
const CONFIG = getActiveConfig()
|
|
@@ -48,13 +48,13 @@ export const setFont = (val, key) => {
|
|
|
48
48
|
|
|
49
49
|
export const getFontFamily = (key, factory) => {
|
|
50
50
|
const CONFIG = getActiveConfig()
|
|
51
|
-
const {
|
|
51
|
+
const { fontFamily: FONT_FAMILY } = CONFIG
|
|
52
52
|
return getDefaultOrFirstKey(factory || FONT_FAMILY, key)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
export const setFontFamily = (val, key) => {
|
|
56
56
|
const CONFIG = getActiveConfig()
|
|
57
|
-
const {
|
|
57
|
+
const { fontFamily: FONT_FAMILY, fontFamilyTypes: FONT_FAMILY_TYPES } = CONFIG
|
|
58
58
|
let { value, type } = val
|
|
59
59
|
if (val.isDefault) FONT_FAMILY.default = key
|
|
60
60
|
|
package/src/system/reset.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { deepMerge, merge, overwriteDeep } from '@
|
|
3
|
+
import { deepMerge, merge, overwriteDeep } from '@symbo.ls/utils'
|
|
4
4
|
import { getActiveConfig } from '../factory.js'
|
|
5
5
|
import { getMediaTheme } from './theme.js'
|
|
6
6
|
|
|
@@ -34,10 +34,31 @@ export const applyReset = (reset = {}) => {
|
|
|
34
34
|
: {}
|
|
35
35
|
if (RESET.html) overwriteDeep(RESET.html, globalTheme)
|
|
36
36
|
|
|
37
|
+
// Generate html fontSize overrides for typography media breakpoints
|
|
38
|
+
if (TYPOGRAPHY.unit) {
|
|
39
|
+
const { media: MEDIA } = CONFIG
|
|
40
|
+
for (const key in TYPOGRAPHY) {
|
|
41
|
+
if (key.charAt(0) !== '@') continue
|
|
42
|
+
const mediaTypo = TYPOGRAPHY[key]
|
|
43
|
+
if (!mediaTypo) continue
|
|
44
|
+
// Only override html fontSize if this media explicitly changes the unit
|
|
45
|
+
if (mediaTypo.unit === TYPOGRAPHY.unit || !mediaTypo.unit) continue
|
|
46
|
+
const mediaUnit = mediaTypo.unit
|
|
47
|
+
const mediaBase = mediaTypo.base || TYPOGRAPHY.base
|
|
48
|
+
const mediaBrowserDefault = mediaTypo.browserDefault || TYPOGRAPHY.browserDefault
|
|
49
|
+
const mediaName = key.slice(1)
|
|
50
|
+
const query = MEDIA[mediaName]
|
|
51
|
+
if (!query) continue
|
|
52
|
+
const mediaKey = '@media ' + (query === 'print' ? query : 'screen and ' + query)
|
|
53
|
+
if (!RESET[mediaKey]) RESET[mediaKey] = {}
|
|
54
|
+
if (!RESET[mediaKey].html) RESET[mediaKey].html = {}
|
|
55
|
+
RESET[mediaKey].html.fontSize = (mediaBase / mediaBrowserDefault) + mediaUnit
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
37
59
|
return deepMerge(merge(RESET, reset), {
|
|
38
60
|
html: {
|
|
39
61
|
position: 'absolute',
|
|
40
|
-
// overflow: 'hidden',
|
|
41
62
|
width: '100%',
|
|
42
63
|
height: '100%',
|
|
43
64
|
top: '0',
|
|
@@ -48,7 +69,9 @@ export const applyReset = (reset = {}) => {
|
|
|
48
69
|
|
|
49
70
|
...globalTheme,
|
|
50
71
|
|
|
51
|
-
fontSize: TYPOGRAPHY.
|
|
72
|
+
fontSize: TYPOGRAPHY.unit
|
|
73
|
+
? (TYPOGRAPHY.base / TYPOGRAPHY.browserDefault) + TYPOGRAPHY.unit
|
|
74
|
+
: TYPOGRAPHY.browserDefault + 'px',
|
|
52
75
|
|
|
53
76
|
fontFamily: DOCUMENT.fontFamily,
|
|
54
77
|
lineHeight: DOCUMENT.lineHeight
|
|
@@ -71,15 +94,25 @@ export const applyReset = (reset = {}) => {
|
|
|
71
94
|
color: 'currentColor'
|
|
72
95
|
},
|
|
73
96
|
|
|
74
|
-
|
|
97
|
+
button: {
|
|
98
|
+
color: 'inherit',
|
|
99
|
+
font: 'inherit',
|
|
100
|
+
background: 'transparent',
|
|
101
|
+
border: 'none',
|
|
102
|
+
cursor: 'pointer',
|
|
103
|
+
appearance: 'none',
|
|
104
|
+
WebkitAppearance: 'none'
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
'input, select, textarea': {
|
|
108
|
+
color: 'inherit',
|
|
109
|
+
font: 'inherit'
|
|
110
|
+
},
|
|
111
|
+
|
|
75
112
|
fieldset: {
|
|
76
113
|
border: 0,
|
|
77
114
|
padding: 0,
|
|
78
115
|
margin: 0
|
|
79
|
-
},
|
|
80
|
-
|
|
81
|
-
'select, input': {
|
|
82
|
-
fontFamily: DOCUMENT.fontFamily
|
|
83
116
|
}
|
|
84
117
|
})
|
|
85
118
|
}
|
package/src/system/shadow.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
isObject,
|
|
10
10
|
isString,
|
|
11
11
|
isArray
|
|
12
|
-
} from '@
|
|
12
|
+
} from '@symbo.ls/utils'
|
|
13
13
|
|
|
14
14
|
export const setShadow = (value, key, suffix, prefers) => {
|
|
15
15
|
const CONFIG = getActiveConfig()
|
|
@@ -53,9 +53,10 @@ export const setShadow = (value, key, suffix, prefers) => {
|
|
|
53
53
|
}).join(', ')
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
const
|
|
56
|
+
const vp = CONFIG.varPrefix ? CONFIG.varPrefix + '-' : ''
|
|
57
|
+
const CSSVar = `--${vp}shadow-${key}` + (suffix ? `-${suffix}` : '')
|
|
57
58
|
|
|
58
|
-
if (CONFIG.useVariable) { CONFIG.
|
|
59
|
+
if (CONFIG.useVariable) { CONFIG.cssVars[CSSVar] = value }
|
|
59
60
|
|
|
60
61
|
return {
|
|
61
62
|
var: CSSVar,
|
package/src/system/spacing.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { arrayzeValue } from '@symbo.ls/
|
|
4
|
-
import { isArray, isString, merge } from '@
|
|
3
|
+
import { arrayzeValue } from '@symbo.ls/utils'
|
|
4
|
+
import { isArray, isString, merge } from '@symbo.ls/utils'
|
|
5
5
|
|
|
6
6
|
import { getActiveConfig } from '../factory.js'
|
|
7
7
|
import {
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
generateSequence,
|
|
12
12
|
getFnPrefixAndValue,
|
|
13
13
|
getSequenceValuePropertyPair
|
|
14
|
-
} from '../utils'
|
|
14
|
+
} from '../utils/index.js'
|
|
15
15
|
|
|
16
16
|
const runThroughMedia = (FACTORY) => {
|
|
17
17
|
for (const prop in FACTORY) {
|
package/src/system/svg.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
import { document } from '@
|
|
4
|
-
import { generateSprite, convertSvgToSymbol } from '../utils'
|
|
3
|
+
import { document } from '@symbo.ls/utils'
|
|
4
|
+
import { generateSprite, convertSvgToSymbol } from '../utils/index.js'
|
|
5
5
|
import { getActiveConfig } from '../factory.js'
|
|
6
6
|
|
|
7
7
|
const DEF_OPTIONS = {
|
|
@@ -23,14 +23,14 @@ export const appendSVGSprite = (LIBRARY, options = DEF_OPTIONS) => {
|
|
|
23
23
|
const CONFIG = getActiveConfig()
|
|
24
24
|
|
|
25
25
|
const lib = Object.keys(LIBRARY).length ? {} : CONFIG.svg
|
|
26
|
-
for (const key in LIBRARY) lib[key] =
|
|
26
|
+
for (const key in LIBRARY) lib[key] = LIBRARY[key]
|
|
27
27
|
|
|
28
28
|
appendSVG(lib, options)
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
export const setSvgIcon = (val, key) => {
|
|
32
32
|
const CONFIG = getActiveConfig()
|
|
33
|
-
if (CONFIG.useIconSprite && !CONFIG.
|
|
33
|
+
if (CONFIG.useIconSprite && !CONFIG.semanticIcons?.[key]) {
|
|
34
34
|
return setSVG(val, key)
|
|
35
35
|
} return val
|
|
36
36
|
}
|
|
@@ -39,7 +39,7 @@ export const appendSvgIconsSprite = (LIBRARY, options = DEF_OPTIONS) => {
|
|
|
39
39
|
const CONFIG = getActiveConfig()
|
|
40
40
|
|
|
41
41
|
const lib = Object.keys(LIBRARY).length ? {} : CONFIG.icons
|
|
42
|
-
for (const key in LIBRARY) lib[key] =
|
|
42
|
+
for (const key in LIBRARY) lib[key] = LIBRARY[key]
|
|
43
43
|
|
|
44
44
|
appendSVG(lib, options)
|
|
45
45
|
}
|
|
@@ -57,6 +57,32 @@ const createSVGSpriteElement = (doc, options = { isRoot: true }) => {
|
|
|
57
57
|
return svgElem
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
// Parse SVG sprite string using XML parser to correctly handle self-closing tags.
|
|
61
|
+
// HTML parser treats <line .../> as <line ...> (ignores /), nesting siblings.
|
|
62
|
+
const parseSVGSprite = (doc, svgString) => {
|
|
63
|
+
const DOMParserCtor = (typeof DOMParser !== 'undefined') ? DOMParser : null
|
|
64
|
+
if (DOMParserCtor) {
|
|
65
|
+
const wrapped = `<svg xmlns="http://www.w3.org/2000/svg">${svgString}</svg>`
|
|
66
|
+
const parser = new DOMParserCtor()
|
|
67
|
+
const parsed = parser.parseFromString(wrapped, 'image/svg+xml')
|
|
68
|
+
// Check for parse errors — if the SVG is malformed, fall back to innerHTML
|
|
69
|
+
if (parsed.querySelector('parsererror')) return null
|
|
70
|
+
return parsed.documentElement
|
|
71
|
+
}
|
|
72
|
+
return null
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Move all children from a parsed SVG element into a target element.
|
|
76
|
+
// Uses importNode to cross document boundaries, then removes the source child
|
|
77
|
+
// so the loop terminates.
|
|
78
|
+
const moveChildren = (doc, from, to) => {
|
|
79
|
+
while (from.firstChild) {
|
|
80
|
+
const child = from.firstChild
|
|
81
|
+
to.appendChild(doc.importNode(child, true))
|
|
82
|
+
child.remove()
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
60
86
|
const appendSVG = (lib, options = DEF_OPTIONS) => {
|
|
61
87
|
const CONFIG = getActiveConfig()
|
|
62
88
|
const doc = options.document || document
|
|
@@ -73,8 +99,12 @@ const appendSVG = (lib, options = DEF_OPTIONS) => {
|
|
|
73
99
|
|
|
74
100
|
const spriteHtml = `<svg aria-hidden="true" width="0" height="0" style="position:absolute" id="svgSprite">${SVGsprite}</svg>`
|
|
75
101
|
|
|
102
|
+
const parsed = parseSVGSprite(doc, SVGsprite)
|
|
103
|
+
|
|
76
104
|
if (exists) {
|
|
77
|
-
if (
|
|
105
|
+
if (parsed) {
|
|
106
|
+
moveChildren(doc, parsed, exists)
|
|
107
|
+
} else if (doc.body.insertAdjacentHTML) {
|
|
78
108
|
exists.insertAdjacentHTML('beforeend', SVGsprite)
|
|
79
109
|
} else {
|
|
80
110
|
const tempSVG = createSVGSpriteElement(doc, { isRoot: false })
|
|
@@ -82,7 +112,13 @@ const appendSVG = (lib, options = DEF_OPTIONS) => {
|
|
|
82
112
|
exists.append(...tempSVG.children)
|
|
83
113
|
}
|
|
84
114
|
} else {
|
|
85
|
-
if (
|
|
115
|
+
if (parsed) {
|
|
116
|
+
const svgSpriteDOM = createSVGSpriteElement(doc)
|
|
117
|
+
if (svgSpriteDOM && svgSpriteDOM.nodeType) {
|
|
118
|
+
moveChildren(doc, parsed, svgSpriteDOM)
|
|
119
|
+
doc.body.prepend(svgSpriteDOM)
|
|
120
|
+
}
|
|
121
|
+
} else if (doc.body.insertAdjacentHTML) {
|
|
86
122
|
doc.body.insertAdjacentHTML('afterbegin', spriteHtml)
|
|
87
123
|
} else {
|
|
88
124
|
const svgSpriteDOM = createSVGSpriteElement(doc)
|
|
@@ -92,4 +128,5 @@ const appendSVG = (lib, options = DEF_OPTIONS) => {
|
|
|
92
128
|
}
|
|
93
129
|
}
|
|
94
130
|
}
|
|
131
|
+
|
|
95
132
|
}
|