@symbo.ls/scratch 3.14.2 → 3.14.3

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.
Files changed (140) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/cjs/index.cjs +1 -0
  3. package/dist/cjs/src/defaultConfig/animation.cjs +1 -0
  4. package/dist/cjs/src/defaultConfig/cases.cjs +1 -0
  5. package/dist/cjs/src/defaultConfig/class.cjs +1 -0
  6. package/dist/cjs/src/defaultConfig/color.cjs +1 -0
  7. package/dist/cjs/src/defaultConfig/document.cjs +1 -0
  8. package/dist/cjs/src/defaultConfig/font-family.cjs +1 -0
  9. package/dist/cjs/src/defaultConfig/font.cjs +1 -0
  10. package/dist/cjs/src/defaultConfig/grid.cjs +1 -0
  11. package/dist/cjs/src/defaultConfig/icons.cjs +1 -0
  12. package/dist/cjs/src/defaultConfig/index.cjs +1 -0
  13. package/dist/cjs/src/defaultConfig/media.cjs +1 -0
  14. package/dist/cjs/src/defaultConfig/responsive.cjs +1 -0
  15. package/dist/cjs/src/defaultConfig/sequence.cjs +1 -0
  16. package/dist/cjs/src/defaultConfig/shadow.cjs +1 -0
  17. package/dist/cjs/src/defaultConfig/spacing.cjs +1 -0
  18. package/dist/cjs/src/defaultConfig/svg.cjs +1 -0
  19. package/dist/cjs/src/defaultConfig/templates.cjs +1 -0
  20. package/dist/cjs/src/defaultConfig/theme.cjs +1 -0
  21. package/dist/cjs/src/defaultConfig/timing.cjs +1 -0
  22. package/dist/cjs/src/defaultConfig/typography.cjs +1 -0
  23. package/dist/cjs/src/defaultConfig/unit.cjs +1 -0
  24. package/dist/cjs/src/factory.cjs +1 -0
  25. package/dist/cjs/src/index.cjs +1 -0
  26. package/dist/cjs/src/set.cjs +1 -0
  27. package/dist/cjs/src/system/color.cjs +1 -0
  28. package/dist/cjs/src/system/document.cjs +1 -0
  29. package/dist/cjs/src/system/font.cjs +1 -0
  30. package/dist/cjs/src/system/index.cjs +1 -0
  31. package/dist/cjs/src/system/reset.cjs +1 -0
  32. package/dist/cjs/src/system/shadow.cjs +1 -0
  33. package/dist/cjs/src/system/spacing.cjs +1 -0
  34. package/dist/cjs/src/system/svg.cjs +1 -0
  35. package/dist/cjs/src/system/theme.cjs +1 -0
  36. package/dist/cjs/src/system/timing.cjs +1 -0
  37. package/dist/cjs/src/system/typography.cjs +1 -0
  38. package/dist/cjs/src/tests/index.cjs +1 -0
  39. package/dist/cjs/src/transforms/index.cjs +1 -0
  40. package/dist/cjs/src/utils/color.cjs +1 -0
  41. package/dist/cjs/src/utils/font.cjs +9 -0
  42. package/dist/cjs/src/utils/index.cjs +1 -0
  43. package/dist/cjs/src/utils/sequence.cjs +1 -0
  44. package/dist/cjs/src/utils/sprite.cjs +1 -0
  45. package/dist/cjs/src/utils/theme.cjs +1 -0
  46. package/dist/cjs/src/utils/unit.cjs +1 -0
  47. package/dist/cjs/src/utils/var.cjs +1 -0
  48. package/dist/esm/index.js +1 -0
  49. package/dist/esm/src/defaultConfig/animation.js +1 -0
  50. package/dist/esm/src/defaultConfig/cases.js +1 -0
  51. package/dist/esm/src/defaultConfig/class.js +1 -0
  52. package/dist/esm/src/defaultConfig/color.js +1 -0
  53. package/dist/esm/src/defaultConfig/document.js +1 -0
  54. package/dist/esm/src/defaultConfig/font-family.js +1 -0
  55. package/dist/esm/src/defaultConfig/font.js +1 -0
  56. package/dist/esm/src/defaultConfig/grid.js +1 -0
  57. package/dist/esm/src/defaultConfig/icons.js +1 -0
  58. package/dist/esm/src/defaultConfig/index.js +1 -0
  59. package/dist/esm/src/defaultConfig/media.js +1 -0
  60. package/dist/esm/src/defaultConfig/responsive.js +1 -0
  61. package/dist/esm/src/defaultConfig/sequence.js +1 -0
  62. package/dist/esm/src/defaultConfig/shadow.js +1 -0
  63. package/dist/esm/src/defaultConfig/spacing.js +1 -0
  64. package/dist/esm/src/defaultConfig/svg.js +1 -0
  65. package/dist/esm/src/defaultConfig/templates.js +1 -0
  66. package/dist/esm/src/defaultConfig/theme.js +1 -0
  67. package/dist/esm/src/defaultConfig/timing.js +1 -0
  68. package/dist/esm/src/defaultConfig/typography.js +1 -0
  69. package/dist/esm/src/defaultConfig/unit.js +1 -0
  70. package/dist/esm/src/factory.js +1 -0
  71. package/dist/esm/src/index.js +1 -0
  72. package/dist/esm/src/set.js +1 -0
  73. package/dist/esm/src/system/color.js +1 -0
  74. package/dist/esm/src/system/document.js +1 -0
  75. package/dist/esm/src/system/font.js +1 -0
  76. package/dist/esm/src/system/index.js +1 -0
  77. package/dist/esm/src/system/reset.js +1 -0
  78. package/dist/esm/src/system/shadow.js +1 -0
  79. package/dist/esm/src/system/spacing.js +1 -0
  80. package/dist/esm/src/system/svg.js +1 -0
  81. package/dist/esm/src/system/theme.js +1 -0
  82. package/dist/esm/src/system/timing.js +1 -0
  83. package/dist/esm/src/system/typography.js +1 -0
  84. package/dist/esm/src/tests/index.js +1 -0
  85. package/dist/esm/src/transforms/index.js +1 -0
  86. package/dist/esm/src/utils/color.js +1 -0
  87. package/dist/esm/src/utils/font.js +9 -0
  88. package/dist/esm/src/utils/index.js +1 -0
  89. package/dist/esm/src/utils/sequence.js +1 -0
  90. package/dist/esm/src/utils/sprite.js +1 -0
  91. package/dist/esm/src/utils/theme.js +1 -0
  92. package/dist/esm/src/utils/unit.js +1 -0
  93. package/dist/esm/src/utils/var.js +1 -0
  94. package/package.json +16 -15
  95. package/index.js +0 -1
  96. package/src/defaultConfig/animation.js +0 -3
  97. package/src/defaultConfig/cases.js +0 -3
  98. package/src/defaultConfig/class.js +0 -6
  99. package/src/defaultConfig/color.js +0 -9
  100. package/src/defaultConfig/document.js +0 -3
  101. package/src/defaultConfig/font-family.js +0 -15
  102. package/src/defaultConfig/font.js +0 -12
  103. package/src/defaultConfig/grid.js +0 -5
  104. package/src/defaultConfig/icons.js +0 -4
  105. package/src/defaultConfig/index.js +0 -24
  106. package/src/defaultConfig/media.js +0 -10
  107. package/src/defaultConfig/responsive.js +0 -29
  108. package/src/defaultConfig/sequence.js +0 -24
  109. package/src/defaultConfig/shadow.js +0 -3
  110. package/src/defaultConfig/spacing.js +0 -19
  111. package/src/defaultConfig/svg.js +0 -4
  112. package/src/defaultConfig/templates.js +0 -3
  113. package/src/defaultConfig/theme.js +0 -13
  114. package/src/defaultConfig/timing.js +0 -18
  115. package/src/defaultConfig/typography.js +0 -22
  116. package/src/defaultConfig/unit.js +0 -5
  117. package/src/factory.js +0 -135
  118. package/src/index.js +0 -24
  119. package/src/set.js +0 -353
  120. package/src/system/color.js +0 -327
  121. package/src/system/document.js +0 -16
  122. package/src/system/font.js +0 -66
  123. package/src/system/index.js +0 -12
  124. package/src/system/reset.js +0 -119
  125. package/src/system/shadow.js +0 -107
  126. package/src/system/spacing.js +0 -152
  127. package/src/system/svg.js +0 -132
  128. package/src/system/theme.js +0 -454
  129. package/src/system/timing.js +0 -32
  130. package/src/system/typography.js +0 -110
  131. package/src/tests/index.js +0 -4
  132. package/src/transforms/index.js +0 -270
  133. package/src/utils/color.js +0 -269
  134. package/src/utils/font.js +0 -116
  135. package/src/utils/index.js +0 -9
  136. package/src/utils/sequence.js +0 -386
  137. package/src/utils/sprite.js +0 -107
  138. package/src/utils/theme.js +0 -8
  139. package/src/utils/unit.js +0 -72
  140. package/src/utils/var.js +0 -129
@@ -1,270 +0,0 @@
1
- 'use strict'
2
-
3
- import { isString, isObject, exec } from '@symbo.ls/utils'
4
- import { getActiveConfig } from '../factory.js'
5
- import {
6
- getSpacingByKey,
7
- getColor,
8
- getShadow,
9
- getMediaColor,
10
- getTimingByKey,
11
- getTimingFunction,
12
- getSpacingBasedOnRatio,
13
- checkIfBoxSize,
14
- splitSpacedValue
15
- } from '../system/index.js'
16
- import {
17
- getFnPrefixAndValue,
18
- isResolvedColor,
19
- isCSSVar,
20
- CSS_NATIVE_COLOR_REGEX,
21
- splitTopLevelCommas,
22
- parseColorToken
23
- } from '../utils/index.js'
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
46
-
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(' ')
66
- }
67
-
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(' ')
84
- }
85
-
86
- export const transformShadow = (sh, globalTheme) => getShadow(sh, globalTheme)
87
-
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
- }
171
-
172
- export const transformBackgroundImage = (backgroundImage, globalTheme) => {
173
- const CONFIG = getActiveConfig()
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(' ')
192
- }
193
-
194
- export const transfromGap = (gap) =>
195
- isString(gap) &&
196
- gap
197
- .split(' ')
198
- .map((v) => getSpacingByKey(v, 'gap').gap)
199
- .join(' ')
200
-
201
- export const transformTransition = (transition) => {
202
- const arr = transition.split(' ')
203
-
204
- if (!arr.length) return transition
205
-
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(' ')
217
- }
218
-
219
- export const transformDuration = (duration, props, propertyName) => {
220
- if (!isString(duration)) return
221
- return duration
222
- .split(',')
223
- .map((v) => getTimingByKey(v).timing || v)
224
- .join(',')
225
- }
226
-
227
- export const splitTransition = (transition) => {
228
- const arr = transition.split(',')
229
- if (!arr.length) return
230
- return arr.map(transformTransition).join(',')
231
- }
232
-
233
- export function transformSize(propertyName, val, props = {}, opts = {}) {
234
- let value = exec.call(this, val || props[propertyName])
235
-
236
- if (value === undefined || value === null) return
237
-
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
- }
246
-
247
- const shouldScaleBoxSize = props.scaleBoxSize
248
- const isBoxSize = checkIfBoxSize(propertyName)
249
- if (!shouldScaleBoxSize && isBoxSize && !opts.ratio) {
250
- value = splitSpacedValue(value)
251
- }
252
- }
253
-
254
- return opts.ratio
255
- ? getSpacingBasedOnRatio(props, propertyName, value, fnPrefix)
256
- : getSpacingByKey(value, propertyName, undefined, fnPrefix)
257
- }
258
-
259
- export const transformSizeRatio = (propertyName, val = null, props) => {
260
- return transformSize(propertyName, val, props, {
261
- ratio: true
262
- })
263
- }
264
-
265
- export const transformBorderRadius = (radius, props, propertyName) => {
266
- if (!isString(radius)) return
267
- return {
268
- borderRadius: radius.split(' ').map((v, k) => getSpacingBasedOnRatio(props, propertyName, v)[propertyName]).join(' ')
269
- }
270
- }
@@ -1,269 +0,0 @@
1
- 'use strict'
2
-
3
- import {
4
- document,
5
- window,
6
- isString,
7
- isNumber,
8
- isNotProduction
9
- } from '@symbo.ls/utils'
10
-
11
- export const colorStringToRgbaArray = color => {
12
- if (color === '') return [0, 0, 0, 0]
13
- if (color.toLowerCase() === 'transparent') return [0, 0, 0, 0]
14
-
15
- // convert #RGB and #RGBA to #RRGGBB and #RRGGBBAA
16
- if (color[0] === '#') {
17
- if (color.length < 7) {
18
- color =
19
- '#' +
20
- color[1] +
21
- color[1] +
22
- color[2] +
23
- color[2] +
24
- color[3] +
25
- color[3] +
26
- (color.length > 4 ? color[4] + color[4] : '')
27
- }
28
- return [
29
- parseInt(color.substr(1, 2), 16),
30
- parseInt(color.substr(3, 2), 16),
31
- parseInt(color.substr(5, 2), 16),
32
- color.length > 7 ? parseInt(color.substr(7, 2), 16) / 255 : 1
33
- ]
34
- }
35
-
36
- // convert named colors
37
- if (color.indexOf('rgb') === -1) {
38
- if (document && window) {
39
- // intentionally use unknown tag to lower chances of css rule override with !important
40
- const elem = document.body.appendChild(document.createElement('fictum'))
41
- // this flag tested on chrome 59, ff 53, ie9, ie10, ie11, edge 14
42
- const flag = 'rgb(1, 2, 3)'
43
- elem.style.color = flag
44
- // color set failed - some monstrous css rule is probably taking over the color of our object
45
- if (elem.style.color !== flag) {
46
- document.body.removeChild(elem)
47
- return
48
- }
49
- elem.style.color = color
50
- if (elem.style.color === flag || elem.style.color === '') {
51
- document.body.removeChild(elem)
52
- return [0, 0, 0, 0] // color parse failed
53
- }
54
- color = window.getComputedStyle(elem).color
55
- document.body.removeChild(elem)
56
- }
57
- }
58
-
59
- // convert 'rgb(R,G,B)' to 'rgb(R,G,B,A)' which looks awful but will pass the regxep below
60
- if (color.indexOf('rgb') === 0) {
61
- if (color.indexOf('rgba') === -1) color = `${color}, 1`
62
- return color.match(/[\.\d]+/g).map(a => +a) // eslint-disable-line
63
- }
64
-
65
- return [0, 0, 0, 0]
66
- }
67
-
68
- export const mixTwoColors = (colorA, colorB, range = 0.5) => {
69
- colorA = colorStringToRgbaArray(colorA)
70
- colorB = colorStringToRgbaArray(colorB)
71
- return mixTwoRgba(colorA, colorB, range)
72
- }
73
-
74
- export const hexToRgb = (hex, alpha = 1) => {
75
- const [r, g, b] = hex.match(/\w\w/g).map(x => parseInt(x, 16))
76
- return `rgb(${r},${g},${b})`
77
- }
78
-
79
- export const hexToRgbArray = (hex, alpha = 1) => {
80
- const [r, g, b] = hex.match(/\w\w/g).map(x => parseInt(x, 16))
81
- return [r, g, b]
82
- }
83
-
84
- export const rgbToHex = (r, g, b) => {
85
- return '#' + ((1 << 24) | (r << 16) | (g << 8) | b).toString(16).slice(1)
86
- }
87
-
88
- export const rgbArrayToHex = ([r, g, b]) => {
89
- return ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)
90
- }
91
-
92
- export const hexToRgba = (hex, alpha = 1) => {
93
- const [r, g, b] = hex.match(/\w\w/g).map(x => parseInt(x, 16))
94
- return `rgba(${r},${g},${b},${alpha})`
95
- }
96
-
97
- export const mixTwoRgb = (colorA, colorB, range = 0.5) => {
98
- const arr = []
99
- for (let i = 0; i < 3; i++) {
100
- arr[i] = ~~(colorA[i] + (colorB[i] - colorA[i]) * range)
101
- }
102
- return `rgb(${arr})`
103
- }
104
-
105
- export const changeLightness = (delta, hsl) => {
106
- const [hue, saturation, lightness] = hsl
107
-
108
- const newLightness = Math.max(0, Math.min(100, lightness + parseFloat(delta)))
109
-
110
- return [hue, saturation, newLightness]
111
- }
112
-
113
- export const rgbToHSL = (r, g, b) => {
114
- const a = Math.max(r, g, b)
115
- const n = a - Math.min(r, g, b)
116
- const f = 1 - Math.abs(a + a - n - 1)
117
- const h =
118
- n && (a == r ? (g - b) / n : a == g ? 2 + (b - r) / n : 4 + (r - g) / n) //eslint-disable-line
119
- return [60 * (h < 0 ? h + 6 : h), f ? n / f : 0, (a + a - n) / 2]
120
- }
121
-
122
- export const hslToRgb = (
123
- h,
124
- s,
125
- l,
126
- a = s * Math.min(l, 1 - l),
127
- f = (n, k = (n + h / 30) % 12) =>
128
- l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)
129
- ) => [f(0), f(8), f(4)]
130
-
131
- export const getColorShade = (col, amt) => {
132
- const num = parseInt(col, 16)
133
-
134
- let r = (num >> 16) + amt
135
-
136
- if (r > 255) r = 255
137
- else if (r < 0) r = 0
138
-
139
- let b = ((num >> 8) & 0x00ff) + amt
140
-
141
- if (b > 255) b = 255
142
- else if (b < 0) b = 0
143
-
144
- let g = (num & 0x0000ff) + amt
145
-
146
- if (g > 255) g = 255
147
- else if (g < 0) g = 0
148
-
149
- return ((g | (b << 8) | (r << 16)) + 0x1000000).toString(16).slice(1)
150
- }
151
-
152
- export const mixTwoRgba = (colorA, colorB, range = 0.5) => {
153
- const arr = []
154
- for (let i = 0; i < 4; i++) {
155
- const round = i === 3 ? x => x : Math.round
156
- arr[i] = round(colorA[i] + (colorB[i] - colorA[i]) * range)
157
- }
158
- return `rgba(${arr})`
159
- }
160
-
161
- export const opacify = (color, opacity) => {
162
- const arr = colorStringToRgbaArray(color)
163
- if (!arr) {
164
- if (isNotProduction()) console.warn(color + ' color is not rgba')
165
- return
166
- }
167
- arr[3] = opacity
168
- return `rgba(${arr})`
169
- }
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
- // Supports hyphenated names like 'highlight-reversed', 'canvas-card', 'line-highlight'
179
- // +N or -N = relative shade, =N = absolute lightness percentage
180
- const COLOR_TOKEN_REGEX = /^([a-zA-Z]\w*)(?:\.(\d+))?(?:([+-]\d+|=\d+))?$/
181
-
182
- /**
183
- * Parse a color token string into its components.
184
- * Returns { name, alpha, tone } for valid tokens,
185
- * { passthrough: value } for CSS native values,
186
- * or null for non-color tokens (e.g. '10px', '0')
187
- *
188
- * Tone prefixes:
189
- * +N relative shade (add N to RGB)
190
- * -N relative shade (subtract N from RGB)
191
- * =N absolute lightness (set HSL lightness to N%)
192
- */
193
- export const parseColorToken = (value) => {
194
- if (!isString(value)) return null
195
-
196
- // CSS native color passthrough
197
- if (CSS_NATIVE_COLOR_REGEX.test(value)) return { passthrough: value }
198
-
199
- // CSS var passthrough
200
- if (isCSSVar(value)) return { cssVar: value }
201
-
202
- const match = value.match(COLOR_TOKEN_REGEX)
203
- if (!match) return null
204
-
205
- const [, name, alphaDigits, rawTone] = match
206
- const alpha = alphaDigits !== undefined ? `0.${alphaDigits}` : undefined
207
- // Strip '=' prefix for absolute tones — getRgbTone handles unsigned values as absolute
208
- const tone = rawTone && rawTone[0] === '=' ? rawTone.slice(1) : rawTone
209
-
210
- return { name, alpha, tone }
211
- }
212
-
213
- /**
214
- * Check if a getColor() result is a resolved CSS color
215
- * (as opposed to the original unresolved value being returned)
216
- */
217
- export const isResolvedColor = (result) => {
218
- return isString(result) && (
219
- result.includes('rgb') ||
220
- result.includes('var(') ||
221
- result.includes('#')
222
- )
223
- }
224
-
225
- /**
226
- * Split a string by commas, respecting parenthesized groups.
227
- * e.g. 'rgba(0,0,0,0.1), white.5 0 A' → ['rgba(0,0,0,0.1)', ' white.5 0 A']
228
- */
229
- export const splitTopLevelCommas = (value) => {
230
- const result = []
231
- let current = ''
232
- let depth = 0
233
-
234
- for (const char of value) {
235
- if (char === '(') depth += 1
236
- else if (char === ')' && depth > 0) depth -= 1
237
-
238
- if (char === ',' && depth === 0) {
239
- result.push(current)
240
- current = ''
241
- continue
242
- }
243
-
244
- current += char
245
- }
246
-
247
- if (current.length || !result.length) result.push(current)
248
- return result
249
- }
250
-
251
- export const getRgbTone = (rgb, tone) => {
252
- if (isString(rgb) && rgb.includes('rgb'))
253
- rgb = colorStringToRgbaArray(rgb).join(', ')
254
- if (isString(rgb)) rgb = rgb.split(',').map(v => parseFloat(v.trim()))
255
- if (isNumber(tone)) tone += ''
256
- const toHex = rgbArrayToHex(rgb)
257
- const abs = tone.slice(0, 1)
258
-
259
- if (abs === '-' || abs === '+') {
260
- const colorShade = getColorShade(toHex, parseFloat(tone))
261
- return hexToRgbArray(colorShade).join(', ')
262
- } else {
263
- const [r, g, b] = rgb
264
- const hsl = rgbToHSL(r, g, b)
265
- const [h, s, l] = hsl // eslint-disable-line
266
- const newRgb = hslToRgb(h, s, (parseFloat(tone) / 100) * 255)
267
- return newRgb
268
- }
269
- }
package/src/utils/font.js DELETED
@@ -1,116 +0,0 @@
1
- 'use strict'
2
-
3
- export const resolveFileUrl = (url, files) => {
4
- if (!url || !files) return null
5
- try { new URL(url); return null } catch (e) { } // expected: src is not an absolute URL, treating as relative path
6
- const file = files[url]
7
- if (file) return file.content && file.content.src
8
- return null
9
- }
10
-
11
- export const getDefaultOrFirstKey = (LIBRARY, key) => {
12
- if (LIBRARY[key]) return LIBRARY[key].value
13
- if (LIBRARY.default) return LIBRARY[LIBRARY.default].value
14
- const hasValue = Object.keys(LIBRARY)[0]
15
- return hasValue && LIBRARY[hasValue] && LIBRARY[hasValue].value
16
- }
17
-
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
22
- const ext = url.split(/[#?]/)[0].split('.').pop().trim()
23
- if (['woff2', 'woff', 'ttf', 'otf', 'eot'].includes(ext)) return ext
24
- return null
25
- }
26
-
27
- export const isGoogleFontsUrl = (url) =>
28
- url &&
29
- (url.includes('fonts.googleapis.com') || url.includes('fonts.gstatic.com'))
30
-
31
- export const setFontImport = (url) => `@import url('${url}');`
32
-
33
- export const setInCustomFontMedia = (str) => `@font-face { ${str} }`
34
-
35
- export const setCustomFont = (name, url, weight, options = {}) => {
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)
40
- const srcList = urls.map((u) => {
41
- const format = getFontFormat(u)
42
- const formatStr = format ? ` format('${format}')` : ''
43
- return `url('${u}')${formatStr}`
44
- }).join(',\n ')
45
- return `
46
- font-family: '${name}';
47
- font-style: ${options.fontStyle || 'normal'};${
48
- weight
49
- ? `
50
- font-weight: ${weight};`
51
- : ''
52
- }${
53
- options.fontStretch
54
- ? `
55
- font-stretch: ${options.fontStretch};`
56
- : ''
57
- }${
58
- options.fontDisplay
59
- ? `
60
- font-display: ${options.fontDisplay};`
61
- : ''
62
- }
63
- src: ${srcList};`
64
- }
65
-
66
- export const setCustomFontMedia = (
67
- name,
68
- url,
69
- weight,
70
- options
71
- ) => `@font-face {${setCustomFont(name, url, weight, options)}
72
- }`
73
-
74
- export const getFontFaceEach = (name, weights, files) => {
75
- const keys = Object.keys(weights)
76
- return keys.map((key) => {
77
- const { url, fontWeight, fontStyle, fontDisplay, fontStretch } = weights[key]
78
- const resolvedUrl = Array.isArray(url)
79
- ? url.map((u) => resolveFileUrl(u, files) || u)
80
- : resolveFileUrl(url, files) || url
81
- return setCustomFont(name, resolvedUrl, fontWeight, { fontStyle, fontDisplay, fontStretch })
82
- })
83
- }
84
-
85
- export const getFontFace = (LIBRARY) => {
86
- const keys = Object.keys(LIBRARY)
87
- return keys.map((key) => getFontFaceEach(key, LIBRARY[key].value))
88
- }
89
-
90
- export const getFontFaceEachString = (name, weights, files) => {
91
- if (weights && weights.isVariable) {
92
- const url = resolveFileUrl(weights.url, files) || weights.url
93
- if (isGoogleFontsUrl(url)) {
94
- return setFontImport(url)
95
- }
96
- return setCustomFontMedia(name, url, weights.fontWeight, {
97
- fontStretch: weights.fontStretch,
98
- fontDisplay: weights.fontDisplay || 'swap'
99
- })
100
- }
101
- const isArr = weights[0]
102
- if (isArr) return getFontFaceEach(name, weights, files).map(setInCustomFontMedia)
103
- const url = Array.isArray(weights.url)
104
- ? weights.url.map((u) => resolveFileUrl(u, files) || u)
105
- : resolveFileUrl(weights.url, files) || weights.url
106
- return setCustomFontMedia(name, url, weights.fontWeight, {
107
- fontStyle: weights.fontStyle,
108
- fontDisplay: weights.fontDisplay,
109
- fontStretch: weights.fontStretch
110
- })
111
- }
112
-
113
- export const getFontFaceString = (LIBRARY, files) => {
114
- const keys = Object.keys(LIBRARY)
115
- return keys.map((key) => getFontFaceEachString(key, LIBRARY[key].value, files))
116
- }
@@ -1,9 +0,0 @@
1
- 'use strict'
2
-
3
- export * from './unit.js'
4
- export * from './color.js'
5
- export * from './theme.js'
6
- export * from './font.js'
7
- export * from './sequence.js'
8
- export * from './var.js'
9
- export * from './sprite.js'