@symbo.ls/scratch 3.14.0 → 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.
Files changed (95) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/defaultConfig/animation.js +4 -2
  3. package/dist/cjs/defaultConfig/cases.js +4 -2
  4. package/dist/cjs/defaultConfig/class.js +5 -2
  5. package/dist/cjs/defaultConfig/color.js +6 -9
  6. package/dist/cjs/defaultConfig/document.js +4 -2
  7. package/dist/cjs/defaultConfig/font-family.js +8 -12
  8. package/dist/cjs/defaultConfig/font.js +4 -11
  9. package/dist/cjs/defaultConfig/grid.js +5 -3
  10. package/dist/cjs/defaultConfig/icons.js +6 -4
  11. package/dist/cjs/defaultConfig/index.js +200 -24
  12. package/dist/cjs/defaultConfig/media.js +4 -2
  13. package/dist/cjs/defaultConfig/responsive.js +6 -4
  14. package/dist/cjs/defaultConfig/sequence.js +4 -2
  15. package/dist/cjs/defaultConfig/shadow.js +4 -2
  16. package/dist/cjs/defaultConfig/spacing.js +56 -7
  17. package/dist/cjs/defaultConfig/svg.js +6 -4
  18. package/dist/cjs/defaultConfig/templates.js +4 -2
  19. package/dist/cjs/defaultConfig/theme.js +4 -14
  20. package/dist/cjs/defaultConfig/timing.js +36 -5
  21. package/dist/cjs/defaultConfig/typography.js +36 -5
  22. package/dist/cjs/defaultConfig/unit.js +4 -2
  23. package/dist/cjs/factory.js +345 -104
  24. package/dist/cjs/index.js +6333 -13
  25. package/dist/cjs/package.json +4 -0
  26. package/dist/cjs/set.js +5609 -214
  27. package/dist/cjs/system/color.js +4487 -170
  28. package/dist/cjs/system/document.js +4371 -11
  29. package/dist/cjs/system/font.js +4401 -28
  30. package/dist/cjs/system/index.js +5748 -11
  31. package/dist/cjs/system/reset.js +4449 -52
  32. package/dist/cjs/system/shadow.js +4834 -44
  33. package/dist/cjs/system/spacing.js +4752 -39
  34. package/dist/cjs/system/svg.js +4437 -74
  35. package/dist/cjs/system/theme.js +4526 -336
  36. package/dist/cjs/system/timing.js +4695 -19
  37. package/dist/cjs/system/typography.js +4755 -42
  38. package/dist/cjs/tests/index.js +4 -2
  39. package/dist/cjs/transforms/index.js +5019 -134
  40. package/dist/cjs/utils/color.js +47 -66
  41. package/dist/cjs/utils/font.js +25 -48
  42. package/dist/cjs/utils/index.js +5068 -8
  43. package/dist/cjs/utils/sequence.js +4436 -67
  44. package/dist/cjs/utils/sprite.js +353 -19
  45. package/dist/cjs/utils/theme.js +3 -1
  46. package/dist/cjs/utils/unit.js +4 -2
  47. package/dist/cjs/utils/var.js +4391 -57
  48. package/package.json +1 -1
  49. package/src/utils/sprite.js +29 -12
  50. package/dist/esm/defaultConfig/animation.js +0 -4
  51. package/dist/esm/defaultConfig/cases.js +0 -4
  52. package/dist/esm/defaultConfig/class.js +0 -4
  53. package/dist/esm/defaultConfig/color.js +0 -11
  54. package/dist/esm/defaultConfig/document.js +0 -4
  55. package/dist/esm/defaultConfig/font-family.js +0 -18
  56. package/dist/esm/defaultConfig/font.js +0 -13
  57. package/dist/esm/defaultConfig/grid.js +0 -5
  58. package/dist/esm/defaultConfig/icons.js +0 -6
  59. package/dist/esm/defaultConfig/index.js +0 -25
  60. package/dist/esm/defaultConfig/media.js +0 -9
  61. package/dist/esm/defaultConfig/responsive.js +0 -30
  62. package/dist/esm/defaultConfig/sequence.js +0 -29
  63. package/dist/esm/defaultConfig/shadow.js +0 -4
  64. package/dist/esm/defaultConfig/spacing.js +0 -18
  65. package/dist/esm/defaultConfig/svg.js +0 -6
  66. package/dist/esm/defaultConfig/templates.js +0 -4
  67. package/dist/esm/defaultConfig/theme.js +0 -16
  68. package/dist/esm/defaultConfig/timing.js +0 -17
  69. package/dist/esm/defaultConfig/typography.js +0 -21
  70. package/dist/esm/defaultConfig/unit.js +0 -6
  71. package/dist/esm/factory.js +0 -120
  72. package/dist/esm/index.js +0 -14
  73. package/dist/esm/set.js +0 -280
  74. package/dist/esm/system/color.js +0 -253
  75. package/dist/esm/system/document.js +0 -16
  76. package/dist/esm/system/font.js +0 -58
  77. package/dist/esm/system/index.js +0 -10
  78. package/dist/esm/system/reset.js +0 -94
  79. package/dist/esm/system/shadow.js +0 -92
  80. package/dist/esm/system/spacing.js +0 -121
  81. package/dist/esm/system/svg.js +0 -113
  82. package/dist/esm/system/theme.js +0 -481
  83. package/dist/esm/system/timing.js +0 -32
  84. package/dist/esm/system/typography.js +0 -94
  85. package/dist/esm/tests/index.js +0 -8
  86. package/dist/esm/transforms/index.js +0 -216
  87. package/dist/esm/utils/color.js +0 -192
  88. package/dist/esm/utils/font.js +0 -94
  89. package/dist/esm/utils/index.js +0 -7
  90. package/dist/esm/utils/sequence.js +0 -322
  91. package/dist/esm/utils/sprite.js +0 -72
  92. package/dist/esm/utils/theme.js +0 -9
  93. package/dist/esm/utils/unit.js +0 -59
  94. package/dist/esm/utils/var.js +0 -96
  95. package/dist/iife/index.js +0 -3630
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@symbo.ls/scratch",
3
3
  "description": "Φ / CSS framework and methodology.",
4
4
  "author": "symbo.ls",
5
- "version": "3.14.0",
5
+ "version": "3.14.1",
6
6
  "files": [
7
7
  "dist",
8
8
  "*.js",
@@ -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 idRegex = /id="([^"]*)"/
47
- const urlRegex = /url\(#([^)]*)\)/g
48
- const matches = code.match(/id="([^"]*)"/g)
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
- if (isArray(matches)) {
51
- matches.forEach(() => {
52
- const randomKey = Math.floor(Math.random() * 100000)
53
- replacedCode = code
54
- .replace(idRegex, `id="${key}-${randomKey}"`)
55
- .replace(urlRegex, `url(#${key}-${randomKey})`)
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
  }
@@ -1,4 +0,0 @@
1
- const animation = {};
2
- export {
3
- animation
4
- };
@@ -1,4 +0,0 @@
1
- const cases = {};
2
- export {
3
- cases
4
- };
@@ -1,4 +0,0 @@
1
- const defaultProps = {};
2
- export {
3
- defaultProps as class
4
- };
@@ -1,11 +0,0 @@
1
- var proto = {
2
- // eslint-disable-line
3
- name: "",
4
- value: ""
5
- };
6
- const color = {};
7
- const gradient = {};
8
- export {
9
- color,
10
- gradient
11
- };
@@ -1,4 +0,0 @@
1
- const document = {};
2
- export {
3
- document
4
- };
@@ -1,18 +0,0 @@
1
- var defaultFont = {
2
- // eslint-disable-line
3
- name: "",
4
- family: "",
5
- type: ""
6
- };
7
- const fontFamily = {};
8
- const fontFamilyTypes = {
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 fontFace = {};
14
- export {
15
- fontFace,
16
- fontFamily,
17
- fontFamilyTypes
18
- };
@@ -1,13 +0,0 @@
1
- var defFont = {
2
- // eslint-disable-line
3
- name: "",
4
- url: "",
5
- fontStyle: "",
6
- fontWeight: 500,
7
- fontStretch: "normal",
8
- fontOpticalSizing: "auto"
9
- };
10
- const font = {};
11
- export {
12
- font
13
- };
@@ -1,5 +0,0 @@
1
- const defaultProps = {};
2
- const grid = defaultProps;
3
- export {
4
- grid
5
- };
@@ -1,6 +0,0 @@
1
- const icons = {};
2
- const semanticIcons = {};
3
- export {
4
- icons,
5
- semanticIcons
6
- };
@@ -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,9 +0,0 @@
1
- const media = {
2
- tv: "(min-width: 2780px)",
3
- light: "(prefers-color-scheme: light)",
4
- dark: "(prefers-color-scheme: dark)",
5
- print: "print"
6
- };
7
- export {
8
- media
9
- };
@@ -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
- };
@@ -1,4 +0,0 @@
1
- const shadow = {};
2
- export {
3
- shadow
4
- };
@@ -1,18 +0,0 @@
1
- import { sequence } from "./sequence.js";
2
- import { typography } from "./typography.js";
3
- const defaultProps = {
4
- base: typography.base,
5
- type: "spacing",
6
- ratio: sequence.phi,
7
- range: [-5, 15],
8
- subSequence: true,
9
- mediaRegenerate: false,
10
- unit: "em",
11
- sequence: {},
12
- scales: {},
13
- vars: {}
14
- };
15
- const spacing = defaultProps;
16
- export {
17
- spacing
18
- };
@@ -1,6 +0,0 @@
1
- const svg = {};
2
- const svgData = {};
3
- export {
4
- svg,
5
- svgData
6
- };
@@ -1,4 +0,0 @@
1
- const templates = {};
2
- export {
3
- templates
4
- };
@@ -1,16 +0,0 @@
1
- const themeA = {
2
- // eslint-disable-line no-unused-vars
3
- text: "blue",
4
- background: "white",
5
- border: "black",
6
- // .opacity(0.2),
7
- active: {},
8
- helpers: [],
9
- themes: {},
10
- inverse: {}
11
- // schemeAInverse
12
- };
13
- const theme = {};
14
- export {
15
- theme
16
- };
@@ -1,17 +0,0 @@
1
- import { sequence } from "./sequence.js";
2
- const defaultProps = {
3
- default: 150,
4
- base: 150,
5
- type: "timing",
6
- ratio: sequence["perfect-fourth"],
7
- range: [-3, 12],
8
- mediaRegenerate: false,
9
- unit: "ms",
10
- sequence: {},
11
- scales: {},
12
- vars: {}
13
- };
14
- const timing = defaultProps;
15
- export {
16
- timing
17
- };
@@ -1,21 +0,0 @@
1
- import { sequence } from "./sequence.js";
2
- const defaultProps = {
3
- browserDefault: 16,
4
- base: 16,
5
- type: "font-size",
6
- ratio: sequence["minor-third"],
7
- range: [-3, 12],
8
- h1Matches: 6,
9
- lineHeight: 1.5,
10
- subSequence: true,
11
- mediaRegenerate: false,
12
- unit: "em",
13
- templates: {},
14
- sequence: {},
15
- scales: {},
16
- vars: {}
17
- };
18
- const typography = defaultProps;
19
- export {
20
- typography
21
- };
@@ -1,6 +0,0 @@
1
- const unit = {
2
- default: "em"
3
- };
4
- export {
5
- unit
6
- };
@@ -1,120 +0,0 @@
1
- import {
2
- deepClone,
3
- deepMerge,
4
- isDefined,
5
- isObject
6
- } from "@symbo.ls/utils";
7
- import * as CONF from "./defaultConfig/index.js";
8
- const cssVars = {};
9
- const cssMediaVars = {};
10
- const _CONF = CONF;
11
- const _confLower = {};
12
- const toCamel = (s) => s.replace(/_([a-z])/g, (_, c) => c.toUpperCase());
13
- for (const key in _CONF) {
14
- const lower = key.toLowerCase();
15
- _confLower[lower] = _CONF[key];
16
- const camel = toCamel(lower);
17
- if (camel !== lower) _confLower[camel] = _CONF[key];
18
- if (lower !== key) _confLower[key] = _CONF[key];
19
- }
20
- const CONFIG = {
21
- verbose: false,
22
- useVariable: true,
23
- useReset: true,
24
- globalTheme: "auto",
25
- cssVars,
26
- cssMediaVars,
27
- CSS_VARS: cssVars,
28
- CSS_MEDIA_VARS: cssMediaVars,
29
- _scratchConfig: true,
30
- ..._confLower
31
- };
32
- const cachedConfig = deepClone(CONFIG);
33
- const FACTORY = {
34
- active: "0",
35
- 0: CONFIG
36
- };
37
- const activateConfig = (def) => {
38
- if (isDefined(def)) {
39
- FACTORY.active = def;
40
- }
41
- return FACTORY[def || FACTORY.active];
42
- };
43
- const configStack = [];
44
- const pushConfig = (config) => {
45
- if (config && config._scratchConfig) configStack.push(config);
46
- };
47
- const popConfig = () => {
48
- configStack.pop();
49
- };
50
- const getActiveConfig = (def) => {
51
- if (configStack.length) return configStack[configStack.length - 1];
52
- return FACTORY[def || FACTORY.active] || CONFIG;
53
- };
54
- const setActiveConfig = (newConfig) => {
55
- if (!isObject(newConfig)) return;
56
- FACTORY.active = "1";
57
- FACTORY["1"] = deepMerge(newConfig, deepClone(cachedConfig));
58
- return newConfig;
59
- };
60
- const APP_FLAGS = [
61
- "useReset",
62
- "useVariable",
63
- "useFontImport",
64
- "useIconSprite",
65
- "useSvgSprite",
66
- "useDocumentTheme",
67
- "useDefaultIcons",
68
- "useDefaultConfig",
69
- "verbose",
70
- "globalTheme"
71
- ];
72
- const ALIAS_GROUPS = [
73
- ["fontfamily", "fontFamily", "font_family"],
74
- ["fontfamilytypes", "fontFamilyTypes"],
75
- ["semanticicons", "semanticIcons"],
76
- ["svgdata", "svgData"]
77
- ];
78
- const aliasCaseVariants = (cfg) => {
79
- for (const vs of ALIAS_GROUPS) {
80
- let merged;
81
- for (const v of vs) {
82
- const val = cfg[v];
83
- if (!isObject(val)) continue;
84
- merged = merged ? deepMerge(val, merged) : val;
85
- }
86
- if (!merged) continue;
87
- for (const v of vs) if (isObject(cfg[v])) cfg[v] = merged;
88
- }
89
- };
90
- const createConfig = (name, overrides, { cleanBase = false } = {}) => {
91
- const activeBase = cleanBase ? null : getActiveConfig();
92
- const base = deepClone(
93
- !cleanBase && activeBase && activeBase._scratchConfig ? activeBase : cachedConfig
94
- );
95
- for (const flag of APP_FLAGS) {
96
- delete base[flag];
97
- }
98
- const cfg = deepMerge(overrides || {}, base);
99
- cfg.cssVars = {};
100
- cfg.cssMediaVars = {};
101
- cfg.CSS_VARS = cfg.cssVars;
102
- cfg.CSS_MEDIA_VARS = cfg.cssMediaVars;
103
- cfg._scratchConfig = true;
104
- aliasCaseVariants(cfg);
105
- if (name) FACTORY[name] = cfg;
106
- return cfg;
107
- };
108
- export {
109
- CONFIG,
110
- FACTORY,
111
- activateConfig,
112
- createConfig,
113
- cssMediaVars,
114
- cssVars,
115
- getActiveConfig,
116
- popConfig,
117
- pushConfig,
118
- setActiveConfig,
119
- toCamel
120
- };
package/dist/esm/index.js DELETED
@@ -1,14 +0,0 @@
1
- import * as scratchUtils from "./utils/index.js";
2
- import * as scratchSystem from "./system/index.js";
3
- import * as scratchDefaultConfig from "./defaultConfig/index.js";
4
- export * from "./factory.js";
5
- export * from "./defaultConfig/index.js";
6
- export * from "./system/index.js";
7
- export * from "./utils/index.js";
8
- export * from "./transforms/index.js";
9
- export * from "./set.js";
10
- export {
11
- scratchDefaultConfig,
12
- scratchSystem,
13
- scratchUtils
14
- };