@nice2dev/icons 1.3.15 → 1.3.16

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/NiceDesktopIconExporter.js +688 -599
  3. package/dist/cjs/NiceFaviconGenerator.js +603 -417
  4. package/dist/cjs/NiceIconPicker.js +788 -508
  5. package/dist/cjs/NiceIconPreview.js +246 -188
  6. package/dist/cjs/NiceIconSetCreator.js +683 -552
  7. package/dist/cjs/NiceIconStacker.js +547 -171
  8. package/dist/cjs/NiceIconValue.js +27 -35
  9. package/dist/cjs/NtdIconBadge.js +384 -360
  10. package/dist/cjs/NtdIconMorph.js +419 -354
  11. package/dist/cjs/NtdStateMorph.js +150 -147
  12. package/dist/cjs/advancedIconSearch.js +373 -510
  13. package/dist/cjs/animationControls.js +518 -642
  14. package/dist/cjs/client.js +12 -15
  15. package/dist/cjs/createIcon.js +349 -251
  16. package/dist/cjs/design-tokens.js +324 -390
  17. package/dist/cjs/figmaExport.js +162 -257
  18. package/dist/cjs/figmaSync.js +234 -316
  19. package/dist/cjs/headless-ui.js +240 -368
  20. package/dist/cjs/iconAnalytics.js +337 -393
  21. package/dist/cjs/iconHtml.js +64 -86
  22. package/dist/cjs/iconMetadata.js +392 -472
  23. package/dist/cjs/iconParts.js +120 -90
  24. package/dist/cjs/iconStack.js +136 -155
  25. package/dist/cjs/iconStyles.js +1609 -504
  26. package/dist/cjs/iconValue.js +359 -430
  27. package/dist/cjs/icons/accessibility.js +1119 -134
  28. package/dist/cjs/icons/actions.js +1290 -330
  29. package/dist/cjs/icons/ai.js +1424 -144
  30. package/dist/cjs/icons/brand.js +1344 -172
  31. package/dist/cjs/icons/business.js +903 -193
  32. package/dist/cjs/icons/devtech.js +1656 -227
  33. package/dist/cjs/icons/ecommerce.js +802 -111
  34. package/dist/cjs/icons/education.js +1345 -199
  35. package/dist/cjs/icons/files.js +1597 -328
  36. package/dist/cjs/icons/fintech.js +793 -104
  37. package/dist/cjs/icons/food.js +1507 -153
  38. package/dist/cjs/icons/fun.js +786 -109
  39. package/dist/cjs/icons/gaming.js +916 -170
  40. package/dist/cjs/icons/health.js +623 -112
  41. package/dist/cjs/icons/index.js +32 -35
  42. package/dist/cjs/icons/input.js +282 -83
  43. package/dist/cjs/icons/legal.js +1065 -122
  44. package/dist/cjs/icons/media.js +1061 -267
  45. package/dist/cjs/icons/navigation.js +387 -122
  46. package/dist/cjs/icons/omniverk.js +747 -90
  47. package/dist/cjs/icons/realestate.js +1520 -193
  48. package/dist/cjs/icons/saas.js +867 -98
  49. package/dist/cjs/icons/science.js +1451 -202
  50. package/dist/cjs/icons/shapes.js +1316 -308
  51. package/dist/cjs/icons/smarthome.js +786 -90
  52. package/dist/cjs/icons/social.js +591 -59
  53. package/dist/cjs/icons/sports.js +1225 -133
  54. package/dist/cjs/icons/sustainability.js +1211 -139
  55. package/dist/cjs/icons/travel.js +1470 -148
  56. package/dist/cjs/icons/ui.js +1508 -315
  57. package/dist/cjs/icons/weather.js +1160 -173
  58. package/dist/cjs/index.js +566 -568
  59. package/dist/cjs/lottieIntegration.js +261 -266
  60. package/dist/cjs/nicetodev-icons.css +1 -1
  61. package/dist/cjs/particleEffects.js +270 -251
  62. package/dist/cjs/resolver.js +229 -284
  63. package/dist/cjs/rsc.js +175 -193
  64. package/dist/cjs/sharpen.js +73 -130
  65. package/dist/cjs/smilAnimations.js +371 -165
  66. package/dist/cjs/stacking.js +87 -122
  67. package/dist/cjs/tailwind-plugin.js +280 -320
  68. package/dist/cjs/types.js +46 -72
  69. package/dist/cjs/utilities.js +163 -324
  70. package/dist/cjs/variantProps.js +12 -52
  71. package/dist/esm/NiceDesktopIconExporter.js +671 -598
  72. package/dist/esm/NiceFaviconGenerator.js +583 -416
  73. package/dist/esm/NiceIconPicker.js +789 -507
  74. package/dist/esm/NiceIconPreview.js +247 -187
  75. package/dist/esm/NiceIconSetCreator.js +685 -551
  76. package/dist/esm/NiceIconStacker.js +549 -170
  77. package/dist/esm/NiceIconValue.js +29 -34
  78. package/dist/esm/NtdIconBadge.js +388 -359
  79. package/dist/esm/NtdIconMorph.js +423 -353
  80. package/dist/esm/NtdStateMorph.js +152 -146
  81. package/dist/esm/advancedIconSearch.js +391 -509
  82. package/dist/esm/animationControls.js +527 -641
  83. package/dist/esm/client.js +48 -10
  84. package/dist/esm/createIcon.js +350 -250
  85. package/dist/esm/design-tokens.js +334 -387
  86. package/dist/esm/figmaExport.js +170 -256
  87. package/dist/esm/figmaSync.js +237 -315
  88. package/dist/esm/headless-ui.js +254 -365
  89. package/dist/esm/iconAnalytics.js +342 -392
  90. package/dist/esm/iconHtml.js +67 -85
  91. package/dist/esm/iconMetadata.js +404 -471
  92. package/dist/esm/iconParts.js +125 -89
  93. package/dist/esm/iconStack.js +145 -154
  94. package/dist/esm/iconStyles.js +1620 -503
  95. package/dist/esm/iconValue.js +361 -429
  96. package/dist/esm/icons/accessibility.js +1133 -133
  97. package/dist/esm/icons/actions.js +1320 -329
  98. package/dist/esm/icons/ai.js +1441 -143
  99. package/dist/esm/icons/brand.js +1351 -171
  100. package/dist/esm/icons/business.js +931 -201
  101. package/dist/esm/icons/devtech.js +1687 -226
  102. package/dist/esm/icons/ecommerce.js +816 -110
  103. package/dist/esm/icons/education.js +1364 -198
  104. package/dist/esm/icons/files.js +1628 -327
  105. package/dist/esm/icons/fintech.js +807 -103
  106. package/dist/esm/icons/food.js +1524 -152
  107. package/dist/esm/icons/fun.js +801 -108
  108. package/dist/esm/icons/gaming.js +933 -169
  109. package/dist/esm/icons/health.js +636 -111
  110. package/dist/esm/icons/index.js +596 -32
  111. package/dist/esm/icons/input.js +326 -82
  112. package/dist/esm/icons/legal.js +1079 -121
  113. package/dist/esm/icons/media.js +1086 -266
  114. package/dist/esm/icons/navigation.js +401 -121
  115. package/dist/esm/icons/omniverk.js +759 -89
  116. package/dist/esm/icons/realestate.js +1544 -198
  117. package/dist/esm/icons/saas.js +880 -97
  118. package/dist/esm/icons/science.js +1477 -208
  119. package/dist/esm/icons/shapes.js +1343 -307
  120. package/dist/esm/icons/smarthome.js +799 -89
  121. package/dist/esm/icons/social.js +599 -58
  122. package/dist/esm/icons/sports.js +1240 -132
  123. package/dist/esm/icons/sustainability.js +1226 -138
  124. package/dist/esm/icons/travel.js +1486 -147
  125. package/dist/esm/icons/ui.js +1540 -314
  126. package/dist/esm/icons/weather.js +1181 -172
  127. package/dist/esm/index.js +756 -58
  128. package/dist/esm/lottieIntegration.js +264 -265
  129. package/dist/esm/nicetodev-icons.css +1 -1
  130. package/dist/esm/particleEffects.js +271 -250
  131. package/dist/esm/resolver.js +231 -283
  132. package/dist/esm/rsc.js +182 -192
  133. package/dist/esm/sharpen.js +78 -129
  134. package/dist/esm/smilAnimations.js +376 -164
  135. package/dist/esm/stacking.js +99 -121
  136. package/dist/esm/tailwind-plugin.js +282 -319
  137. package/dist/esm/types.js +50 -71
  138. package/dist/esm/utilities.js +177 -321
  139. package/dist/esm/variantProps.js +23 -52
  140. package/package.json +15 -22
@@ -1,470 +1,402 @@
1
- import { parseIconHtml } from './iconHtml.js';
2
- import { iconDisplayName, stackChildrenOf } from './iconStack.js';
3
-
4
- /**
5
- * An icon — or a stack of icons — kept as short text (1.3.10): what NiceIconPicker stores with
6
- * `valueFormat="name"` (the default) or `"json"`, as short as a database value can be and still be
7
- * read by people.
8
- *
9
- * **The code** (`'name'`) — a plain icon is its name (`NtdFolder`); a stack nests like a function
10
- * call, the parent first, each setting behind a sign of its own:
11
- *
12
- * ```
13
- * Folder(Star@tr) a star in the folder's top-right corner
14
- * Bell(Circle@tr'3') a circle with "3" in the bell's corner
15
- * Folder(Star@tr%40^15,Lock@bl) two icons in the folder: 40 %, turned 15°; a lock
16
- * User:o(Circle@br#2a2{count}'5'#fff) an outline user, a green circle bound to `count`
17
- * ```
18
- *
19
- * | sign | meaning | example |
20
- * |---|---|---|
21
- * | `( , )` | what sits in the icon, side by side | `Folder(Star,Lock)` |
22
- * | `:` | variant — `so` solid, `sh` sharp, `o` outline, `w` wireframe, `d` duotone, `c` cutout, `r` rounded, `m` mini, `3d`, `v` vivid | `:o` |
23
- * | `@` | position in the parent — `c t b l r tl tr bl br`, `h…` halfway (`ht`, `hbr`…); the parent's own spot when absent | `@tr` |
24
- * | `%` | size, percent of the parent | `%40` |
25
- * | `^` | turn, degrees clockwise | `^-30` |
26
- * | `~` | nudge right / down, percent of the parent | `~5/-3` |
27
- * | `#` | colours: primary, secondary, accent (`##0f0` — secondary only) | `#2a2` |
28
- * | `'…'` | text; `#` and `%` after it are the text's colour and size | `'3'#fff%60` |
29
- * | `{…}` | the value the text is bound to (the text after it is a sample) | `{count}'5'` |
30
- *
31
- * Names drop `Ntd` inside a stack. A name or colour holding any of the signs goes in backticks
32
- * (`` `fa:home` ``); `\` escapes inside quotes.
33
- *
34
- * **JSON** (`'json'`) — the same tree as JsonML: `["Folder",["Star",{"a":"tr"}]]`, a node being
35
- * `[name, {settings}?, ...nodes, "text"?]` with the settings `v a s r x y p sc ac b tc ts` written
36
- * as in the code; a plain icon is its name as a JSON string.
37
- */
1
+ import { parseIconHtml } from "./iconHtml.js";
2
+ import { iconDisplayName, stackChildrenOf } from "./iconStack.js";
38
3
  const VARIANT_CODE = {
39
- solid: 'so',
40
- sharp: 'sh',
41
- outline: 'o',
42
- wireframe: 'w',
43
- duotone: 'd',
44
- cutout: 'c',
45
- rounded: 'r',
46
- mini: 'm',
47
- '3d': '3d',
48
- vivid: 'v',
4
+ solid: "so",
5
+ sharp: "sh",
6
+ outline: "o",
7
+ wireframe: "w",
8
+ duotone: "d",
9
+ cutout: "c",
10
+ rounded: "r",
11
+ mini: "m",
12
+ "3d": "3d",
13
+ vivid: "v"
49
14
  };
50
15
  const ALIGN_CODE = {
51
- center: 'c',
52
- top: 't',
53
- bottom: 'b',
54
- left: 'l',
55
- right: 'r',
56
- 'top-left': 'tl',
57
- 'top-right': 'tr',
58
- 'bottom-left': 'bl',
59
- 'bottom-right': 'br',
60
- 'half-top': 'ht',
61
- 'half-bottom': 'hb',
62
- 'half-left': 'hl',
63
- 'half-right': 'hr',
64
- 'half-top-left': 'htl',
65
- 'half-top-right': 'htr',
66
- 'half-bottom-left': 'hbl',
67
- 'half-bottom-right': 'hbr',
16
+ center: "c",
17
+ top: "t",
18
+ bottom: "b",
19
+ left: "l",
20
+ right: "r",
21
+ "top-left": "tl",
22
+ "top-right": "tr",
23
+ "bottom-left": "bl",
24
+ "bottom-right": "br",
25
+ "half-top": "ht",
26
+ "half-bottom": "hb",
27
+ "half-left": "hl",
28
+ "half-right": "hr",
29
+ "half-top-left": "htl",
30
+ "half-top-right": "htr",
31
+ "half-bottom-left": "hbl",
32
+ "half-bottom-right": "hbr"
68
33
  };
69
- /** A code or a full name → the value; an unknown one (a newer writer's) reads as unset. */
70
34
  function reverse(codes) {
71
- const map = new Map();
72
- for (const [full, code] of Object.entries(codes)) {
73
- map.set(code, full);
74
- map.set(full, full);
75
- }
76
- return map;
35
+ const map = /* @__PURE__ */ new Map();
36
+ for (const [full, code] of Object.entries(codes)) {
37
+ map.set(code, full);
38
+ map.set(full, full);
39
+ }
40
+ return map;
77
41
  }
78
42
  const VARIANTS = reverse(VARIANT_CODE);
79
- const ALIGNS = reverse({ ...ALIGN_CODE, perfect: 'p' });
80
- /** The signs of the code; a name or colour holding one of them goes in backticks. */
81
- const SIGNS = new Set(['(', ')', ',', ':', '@', '%', '^', '~', '#', "'", '{', '}', '`', '\\']);
82
- /** A plain icon: one layer and nothing set on it but its name. */
43
+ const ALIGNS = reverse({ ...ALIGN_CODE, perfect: "p" });
44
+ const SIGNS = /* @__PURE__ */ new Set(["(", ")", ",", ":", "@", "%", "^", "~", "#", "'", "{", "}", "`", "\\"]);
83
45
  function isPlain(layers) {
84
- return (layers.length === 1 &&
85
- Object.entries(layers[0]).every(([key, value]) => key === 'id' || key === 'icon' || value === undefined));
46
+ return layers.length === 1 && Object.entries(layers[0]).every(
47
+ ([key, value]) => key === "id" || key === "icon" || value === void 0
48
+ );
86
49
  }
87
50
  function quote(text, mark) {
88
- return mark + text.replace(/[\\`']/g, (c) => (c === mark || c === '\\' ? `\\${c}` : c)) + mark;
51
+ return mark + text.replace(/[\\`']/g, (c) => c === mark || c === "\\" ? `\\${c}` : c) + mark;
89
52
  }
90
53
  function writeName(name) {
91
- const needsQuotes = name === '' ||
92
- name !== name.trim() ||
93
- [...name].some((c) => SIGNS.has(c)) ||
94
- /^["[<]/.test(name);
95
- return needsQuotes ? quote(name, '`') : name;
54
+ const needsQuotes = name === "" || name !== name.trim() || [...name].some((c) => SIGNS.has(c)) || /^["[<]/.test(name);
55
+ return needsQuotes ? quote(name, "`") : name;
96
56
  }
97
57
  function writeNumber(n) {
98
- return String(Math.round(n * 1000) / 1000);
58
+ return String(Math.round(n * 1e3) / 1e3);
99
59
  }
100
- /** `#22aa22` → `2a2`, any other hex as is; another colour (`var(--x)`) in backticks. */
101
60
  function writeColor(color) {
102
- if (!color) {
103
- return '';
104
- }
105
- const hex = /^#([0-9a-f]{3,8})$/i.exec(color);
106
- if (!hex) {
107
- return quote(color, '`');
108
- }
109
- const h = hex[1].toLowerCase();
110
- return h.length === 6 && h[0] === h[1] && h[2] === h[3] && h[4] === h[5] ? h[0] + h[2] + h[4] : h;
61
+ if (!color) {
62
+ return "";
63
+ }
64
+ const hex = /^#([0-9a-f]{3,8})$/i.exec(color);
65
+ if (!hex) {
66
+ return quote(color, "`");
67
+ }
68
+ const h = hex[1].toLowerCase();
69
+ return h.length === 6 && h[0] === h[1] && h[2] === h[3] && h[4] === h[5] ? h[0] + h[2] + h[4] : h;
111
70
  }
112
71
  function writeCode(layers, shortName) {
113
- const write = (layer, isBase) => {
114
- var _a, _b, _c, _d;
115
- let out = writeName(shortName(layer.icon));
116
- if (layer.variant) {
117
- out += `:${(_a = VARIANT_CODE[layer.variant]) !== null && _a !== void 0 ? _a : layer.variant}`;
118
- }
119
- if (!isBase) {
120
- if (layer.align && layer.align !== 'perfect') {
121
- out += `@${(_b = ALIGN_CODE[layer.align]) !== null && _b !== void 0 ? _b : layer.align}`;
122
- }
123
- if (layer.size !== undefined) {
124
- out += `%${writeNumber(layer.size * 100)}`;
125
- }
126
- if (layer.rotation !== undefined) {
127
- out += `^${writeNumber(layer.rotation)}`;
128
- }
129
- if (layer.offsetX || layer.offsetY) {
130
- out += `~${writeNumber((_c = layer.offsetX) !== null && _c !== void 0 ? _c : 0)}`;
131
- if (layer.offsetY) {
132
- out += `/${writeNumber(layer.offsetY)}`;
133
- }
134
- }
135
- }
136
- const colors = [layer.primaryColor, layer.secondaryColor, layer.accentColor];
137
- const lastColor = colors.reduce((last, c, i) => (c ? i : last), -1);
138
- for (let i = 0; i <= lastColor; i++) {
139
- out += `#${writeColor(colors[i])}`;
140
- }
141
- const bound = !!layer.textBinding && /^[A-Za-z_$][\w$]*$/.test(layer.textBinding);
142
- if (bound) {
143
- out += `{${layer.textBinding}}`;
144
- }
145
- // text settings need a text part to follow; an empty text carries them
146
- if (layer.text || (!bound && (layer.textColor || layer.textSize !== undefined))) {
147
- out += quote((_d = layer.text) !== null && _d !== void 0 ? _d : '', "'");
148
- }
149
- if (layer.textColor) {
150
- out += `#${writeColor(layer.textColor)}`;
151
- }
152
- if (layer.textSize !== undefined) {
153
- out += `%${writeNumber(layer.textSize)}`;
154
- }
155
- const inner = stackChildrenOf(layers, layer.id);
156
- return inner.length > 0 ? `${out}(${inner.map((l) => write(l, false)).join(',')})` : out;
157
- };
158
- return write(layers[0], true);
72
+ const write = (layer, isBase) => {
73
+ let out = writeName(shortName(layer.icon));
74
+ if (layer.variant) {
75
+ out += `:${VARIANT_CODE[layer.variant] ?? layer.variant}`;
76
+ }
77
+ if (!isBase) {
78
+ if (layer.align && layer.align !== "perfect") {
79
+ out += `@${ALIGN_CODE[layer.align] ?? layer.align}`;
80
+ }
81
+ if (layer.size !== void 0) {
82
+ out += `%${writeNumber(layer.size * 100)}`;
83
+ }
84
+ if (layer.rotation !== void 0) {
85
+ out += `^${writeNumber(layer.rotation)}`;
86
+ }
87
+ if (layer.offsetX || layer.offsetY) {
88
+ out += `~${writeNumber(layer.offsetX ?? 0)}`;
89
+ if (layer.offsetY) {
90
+ out += `/${writeNumber(layer.offsetY)}`;
91
+ }
92
+ }
93
+ }
94
+ const colors = [layer.primaryColor, layer.secondaryColor, layer.accentColor];
95
+ const lastColor = colors.reduce((last, c, i) => c ? i : last, -1);
96
+ for (let i = 0; i <= lastColor; i++) {
97
+ out += `#${writeColor(colors[i])}`;
98
+ }
99
+ const bound = !!layer.textBinding && /^[A-Za-z_$][\w$]*$/.test(layer.textBinding);
100
+ if (bound) {
101
+ out += `{${layer.textBinding}}`;
102
+ }
103
+ if (layer.text || !bound && (layer.textColor || layer.textSize !== void 0)) {
104
+ out += quote(layer.text ?? "", "'");
105
+ }
106
+ if (layer.textColor) {
107
+ out += `#${writeColor(layer.textColor)}`;
108
+ }
109
+ if (layer.textSize !== void 0) {
110
+ out += `%${writeNumber(layer.textSize)}`;
111
+ }
112
+ const inner = stackChildrenOf(layers, layer.id);
113
+ return inner.length > 0 ? `${out}(${inner.map((l) => write(l, false)).join(",")})` : out;
114
+ };
115
+ return write(layers[0], true);
159
116
  }
160
117
  function writeJson(layers, shortName) {
161
- const write = (layer, isBase) => {
162
- var _a, _b;
163
- const s = {};
164
- const set = (key, value) => {
165
- if (value !== undefined && value !== '' && value !== 0) {
166
- s[key] = value;
167
- }
168
- };
169
- set('v', layer.variant && ((_a = VARIANT_CODE[layer.variant]) !== null && _a !== void 0 ? _a : layer.variant));
170
- if (!isBase) {
171
- if (layer.align && layer.align !== 'perfect') {
172
- set('a', (_b = ALIGN_CODE[layer.align]) !== null && _b !== void 0 ? _b : layer.align);
173
- }
174
- if (layer.size !== undefined) {
175
- s.s = Math.round(layer.size * 100000) / 1000;
176
- }
177
- if (layer.rotation !== undefined) {
178
- s.r = layer.rotation;
179
- }
180
- set('x', layer.offsetX);
181
- set('y', layer.offsetY);
182
- }
183
- set('p', layer.primaryColor);
184
- set('sc', layer.secondaryColor);
185
- set('ac', layer.accentColor);
186
- set('b', layer.textBinding);
187
- set('tc', layer.textColor);
188
- if (layer.textSize !== undefined) {
189
- s.ts = layer.textSize;
190
- }
191
- const node = [shortName(layer.icon)];
192
- if (Object.keys(s).length > 0) {
193
- node.push(s);
194
- }
195
- for (const child of stackChildrenOf(layers, layer.id)) {
196
- node.push(write(child, false));
197
- }
198
- if (layer.text) {
199
- node.push(layer.text);
200
- }
201
- return node;
118
+ const write = (layer, isBase) => {
119
+ const s = {};
120
+ const set = (key, value) => {
121
+ if (value !== void 0 && value !== "" && value !== 0) {
122
+ s[key] = value;
123
+ }
202
124
  };
203
- return write(layers[0], true);
125
+ set("v", layer.variant && (VARIANT_CODE[layer.variant] ?? layer.variant));
126
+ if (!isBase) {
127
+ if (layer.align && layer.align !== "perfect") {
128
+ set("a", ALIGN_CODE[layer.align] ?? layer.align);
129
+ }
130
+ if (layer.size !== void 0) {
131
+ s.s = Math.round(layer.size * 1e5) / 1e3;
132
+ }
133
+ if (layer.rotation !== void 0) {
134
+ s.r = layer.rotation;
135
+ }
136
+ set("x", layer.offsetX);
137
+ set("y", layer.offsetY);
138
+ }
139
+ set("p", layer.primaryColor);
140
+ set("sc", layer.secondaryColor);
141
+ set("ac", layer.accentColor);
142
+ set("b", layer.textBinding);
143
+ set("tc", layer.textColor);
144
+ if (layer.textSize !== void 0) {
145
+ s.ts = layer.textSize;
146
+ }
147
+ const node = [shortName(layer.icon)];
148
+ if (Object.keys(s).length > 0) {
149
+ node.push(s);
150
+ }
151
+ for (const child of stackChildrenOf(layers, layer.id)) {
152
+ node.push(write(child, false));
153
+ }
154
+ if (layer.text) {
155
+ node.push(layer.text);
156
+ }
157
+ return node;
158
+ };
159
+ return write(layers[0], true);
204
160
  }
205
- /**
206
- * Writes an icon or a stack as short text (1.3.10): `'name'` — a plain icon's name, a stack's code
207
- * (`Folder(Star@tr)`) — or `'json'` (`["Folder",["Star",{"a":"tr"}]]`). Empty for no layers.
208
- * `parseIconValue` reads it back; the ids of the layers are not kept.
209
- */
210
- function formatIconValue(layers, format = 'name', { shortName = iconDisplayName } = {}) {
211
- if (layers.length === 0) {
212
- return '';
213
- }
214
- if (isPlain(layers)) {
215
- return format === 'json' ? JSON.stringify(layers[0].icon) : layers[0].icon;
216
- }
217
- return format === 'json'
218
- ? JSON.stringify(writeJson(layers, shortName))
219
- : writeCode(layers, shortName);
161
+ function formatIconValue(layers, format = "name", { shortName = iconDisplayName } = {}) {
162
+ if (layers.length === 0) {
163
+ return "";
164
+ }
165
+ if (isPlain(layers)) {
166
+ return format === "json" ? JSON.stringify(layers[0].icon) : layers[0].icon;
167
+ }
168
+ return format === "json" ? JSON.stringify(writeJson(layers, shortName)) : writeCode(layers, shortName);
220
169
  }
221
- /* ─── Reading ─── */
222
170
  class IconValueError extends Error {
223
171
  }
224
- /** Collects the layers in document order, ids `'1'`, `'2'`…; what sits in the base has no parent. */
225
172
  class LayerSink {
226
- constructor() {
227
- this.layers = [];
228
- }
229
- add(layer, parent, isBase) {
230
- const data = isBase
231
- ? // where a layer sits means nothing for the base
232
- { ...layer, align: undefined, size: undefined, rotation: undefined }
233
- : layer;
234
- if (isBase || !data.offsetX) {
235
- data.offsetX = undefined;
236
- }
237
- if (isBase || !data.offsetY) {
238
- data.offsetY = undefined;
239
- }
240
- if (data.align === 'perfect') {
241
- data.align = undefined;
242
- }
243
- const id = String(this.layers.length + 1);
244
- const clean = Object.fromEntries(Object.entries(data).filter(([, v]) => v !== undefined && v !== ''));
245
- this.layers.push({ id, ...clean, ...(parent && parent !== '1' ? { parent } : {}) });
246
- return id;
173
+ constructor() {
174
+ this.layers = [];
175
+ }
176
+ add(layer, parent, isBase) {
177
+ const data = isBase ? (
178
+ // where a layer sits means nothing for the base
179
+ { ...layer, align: void 0, size: void 0, rotation: void 0 }
180
+ ) : layer;
181
+ if (isBase || !data.offsetX) {
182
+ data.offsetX = void 0;
183
+ }
184
+ if (isBase || !data.offsetY) {
185
+ data.offsetY = void 0;
186
+ }
187
+ if (data.align === "perfect") {
188
+ data.align = void 0;
247
189
  }
190
+ const id = String(this.layers.length + 1);
191
+ const clean = Object.fromEntries(
192
+ Object.entries(data).filter(([, v]) => v !== void 0 && v !== "")
193
+ );
194
+ this.layers.push({ id, ...clean, ...parent && parent !== "1" ? { parent } : {} });
195
+ return id;
196
+ }
248
197
  }
249
198
  function readCode(code) {
250
- const sink = new LayerSink();
251
- let i = 0;
252
- const peek = () => code[i];
253
- const skipSpaces = () => {
254
- while (i < code.length && /\s/.test(code[i])) {
255
- i++;
256
- }
257
- };
258
- const quoted = (mark) => {
199
+ const sink = new LayerSink();
200
+ let i = 0;
201
+ const peek = () => code[i];
202
+ const skipSpaces = () => {
203
+ while (i < code.length && /\s/.test(code[i])) {
204
+ i++;
205
+ }
206
+ };
207
+ const quoted = (mark) => {
208
+ i++;
209
+ let out = "";
210
+ while (i < code.length && code[i] !== mark) {
211
+ if (code[i] === "\\" && i + 1 < code.length) {
259
212
  i++;
260
- let out = '';
261
- while (i < code.length && code[i] !== mark) {
262
- if (code[i] === '\\' && i + 1 < code.length) {
263
- i++;
264
- }
265
- out += code[i];
266
- i++;
267
- }
268
- if (code[i] !== mark) {
269
- throw new IconValueError('unclosed quote');
270
- }
213
+ }
214
+ out += code[i];
215
+ i++;
216
+ }
217
+ if (code[i] !== mark) {
218
+ throw new IconValueError("unclosed quote");
219
+ }
220
+ i++;
221
+ return out;
222
+ };
223
+ const name = () => {
224
+ skipSpaces();
225
+ if (peek() === "`") {
226
+ return quoted("`");
227
+ }
228
+ const start = i;
229
+ while (i < code.length && !SIGNS.has(code[i])) {
230
+ i++;
231
+ }
232
+ const out = code.slice(start, i).trim();
233
+ if (!out) {
234
+ throw new IconValueError("name expected");
235
+ }
236
+ return out;
237
+ };
238
+ const word = () => {
239
+ const hit = /^[A-Za-z0-9-]*/.exec(code.slice(i))?.[0] ?? "";
240
+ i += hit.length;
241
+ return hit;
242
+ };
243
+ const number = () => {
244
+ const hit = /^-?(?:\d+(?:\.\d*)?|\.\d+)/.exec(code.slice(i))?.[0];
245
+ if (!hit) {
246
+ throw new IconValueError("number expected");
247
+ }
248
+ i += hit.length;
249
+ return Number(hit);
250
+ };
251
+ const color = () => {
252
+ if (peek() === "`") {
253
+ return quoted("`");
254
+ }
255
+ const hit = /^[0-9a-fA-F]{0,8}/.exec(code.slice(i))?.[0] ?? "";
256
+ i += hit.length;
257
+ return hit ? `#${hit.toLowerCase()}` : void 0;
258
+ };
259
+ const node = (parent, isBase) => {
260
+ const layer = { icon: name() };
261
+ const colors = [];
262
+ let settings = true;
263
+ while (settings) {
264
+ const sign = peek();
265
+ if (sign === ":" || sign === "@" || sign === "%" || sign === "^" || sign === "~" || sign === "#") {
271
266
  i++;
272
- return out;
273
- };
274
- const name = () => {
275
- skipSpaces();
276
- if (peek() === '`') {
277
- return quoted('`');
278
- }
279
- const start = i;
280
- while (i < code.length && !SIGNS.has(code[i])) {
281
- i++;
282
- }
283
- const out = code.slice(start, i).trim();
284
- if (!out) {
285
- throw new IconValueError('name expected');
286
- }
287
- return out;
288
- };
289
- const word = () => {
290
- var _a, _b;
291
- const hit = (_b = (_a = /^[A-Za-z0-9-]*/.exec(code.slice(i))) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : '';
292
- i += hit.length;
293
- return hit;
294
- };
295
- const number = () => {
296
- var _a;
297
- const hit = (_a = /^-?(?:\d+(?:\.\d*)?|\.\d+)/.exec(code.slice(i))) === null || _a === void 0 ? void 0 : _a[0];
298
- if (!hit) {
299
- throw new IconValueError('number expected');
300
- }
301
- i += hit.length;
302
- return Number(hit);
303
- };
304
- const color = () => {
305
- var _a, _b;
306
- if (peek() === '`') {
307
- return quoted('`');
308
- }
309
- const hit = (_b = (_a = /^[0-9a-fA-F]{0,8}/.exec(code.slice(i))) === null || _a === void 0 ? void 0 : _a[0]) !== null && _b !== void 0 ? _b : '';
310
- i += hit.length;
311
- return hit ? `#${hit.toLowerCase()}` : undefined;
312
- };
313
- const node = (parent, isBase) => {
314
- const layer = { icon: name() };
315
- const colors = [];
316
- let settings = true;
317
- while (settings) {
318
- const sign = peek();
319
- if (sign === ':' ||
320
- sign === '@' ||
321
- sign === '%' ||
322
- sign === '^' ||
323
- sign === '~' ||
324
- sign === '#') {
325
- i++;
326
- }
327
- if (sign === ':') {
328
- layer.variant = VARIANTS.get(word());
329
- }
330
- else if (sign === '@') {
331
- layer.align = ALIGNS.get(word());
332
- }
333
- else if (sign === '%') {
334
- layer.size = Math.round(number() * 1000) / 100000;
335
- }
336
- else if (sign === '^') {
337
- layer.rotation = number();
338
- }
339
- else if (sign === '~') {
340
- layer.offsetX = number();
341
- if (peek() === '/') {
342
- i++;
343
- layer.offsetY = number();
344
- }
345
- }
346
- else if (sign === '#') {
347
- colors.push(color());
348
- }
349
- else {
350
- settings = false;
351
- }
352
- }
353
- [layer.primaryColor, layer.secondaryColor, layer.accentColor] = colors;
354
- if (peek() === '{') {
355
- const end = code.indexOf('}', i);
356
- if (end < 0) {
357
- throw new IconValueError('unclosed binding');
358
- }
359
- layer.textBinding = code.slice(i + 1, end).trim();
360
- i = end + 1;
361
- }
362
- if (peek() === "'") {
363
- layer.text = quoted("'");
364
- }
365
- if (layer.text !== undefined || layer.textBinding) {
366
- for (let sign = peek(); sign === '#' || sign === '%'; sign = peek()) {
367
- i++;
368
- if (sign === '#') {
369
- layer.textColor = color();
370
- }
371
- else {
372
- layer.textSize = number();
373
- }
374
- }
267
+ }
268
+ if (sign === ":") {
269
+ layer.variant = VARIANTS.get(word());
270
+ } else if (sign === "@") {
271
+ layer.align = ALIGNS.get(word());
272
+ } else if (sign === "%") {
273
+ layer.size = Math.round(number() * 1e3) / 1e5;
274
+ } else if (sign === "^") {
275
+ layer.rotation = number();
276
+ } else if (sign === "~") {
277
+ layer.offsetX = number();
278
+ if (peek() === "/") {
279
+ i++;
280
+ layer.offsetY = number();
281
+ }
282
+ } else if (sign === "#") {
283
+ colors.push(color());
284
+ } else {
285
+ settings = false;
286
+ }
287
+ }
288
+ [layer.primaryColor, layer.secondaryColor, layer.accentColor] = colors;
289
+ if (peek() === "{") {
290
+ const end = code.indexOf("}", i);
291
+ if (end < 0) {
292
+ throw new IconValueError("unclosed binding");
293
+ }
294
+ layer.textBinding = code.slice(i + 1, end).trim();
295
+ i = end + 1;
296
+ }
297
+ if (peek() === "'") {
298
+ layer.text = quoted("'");
299
+ }
300
+ if (layer.text !== void 0 || layer.textBinding) {
301
+ for (let sign = peek(); sign === "#" || sign === "%"; sign = peek()) {
302
+ i++;
303
+ if (sign === "#") {
304
+ layer.textColor = color();
305
+ } else {
306
+ layer.textSize = number();
375
307
  }
376
- const id = sink.add(layer, parent, isBase);
308
+ }
309
+ }
310
+ const id = sink.add(layer, parent, isBase);
311
+ skipSpaces();
312
+ if (peek() === "(") {
313
+ i++;
314
+ let more = true;
315
+ while (more) {
316
+ node(id, false);
377
317
  skipSpaces();
378
- if (peek() === '(') {
379
- i++;
380
- let more = true;
381
- while (more) {
382
- node(id, false);
383
- skipSpaces();
384
- more = peek() === ',';
385
- if (more) {
386
- i++;
387
- }
388
- }
389
- if (peek() !== ')') {
390
- throw new IconValueError(') expected');
391
- }
392
- i++;
393
- skipSpaces();
394
- }
395
- };
396
- node(undefined, true);
397
- if (i < code.length) {
398
- throw new IconValueError('unexpected text');
318
+ more = peek() === ",";
319
+ if (more) {
320
+ i++;
321
+ }
322
+ }
323
+ if (peek() !== ")") {
324
+ throw new IconValueError(") expected");
325
+ }
326
+ i++;
327
+ skipSpaces();
399
328
  }
400
- return sink.layers;
329
+ };
330
+ node(void 0, true);
331
+ if (i < code.length) {
332
+ throw new IconValueError("unexpected text");
333
+ }
334
+ return sink.layers;
401
335
  }
402
336
  function readJson(json) {
403
- const parsed = JSON.parse(json);
404
- if (typeof parsed === 'string') {
405
- return parsed.trim() ? [{ id: '1', icon: parsed }] : null;
406
- }
407
- const sink = new LayerSink();
408
- const str = (v) => (typeof v === 'string' ? v : undefined);
409
- const num = (v) => (typeof v === 'number' && Number.isFinite(v) ? v : undefined);
410
- const node = (value, parent, isBase) => {
411
- var _a, _b;
412
- if (!Array.isArray(value) || typeof value[0] !== 'string' || !value[0]) {
413
- throw new IconValueError('node expected');
414
- }
415
- const [icon, ...rest] = value;
416
- const first = rest[0];
417
- const s = (first && typeof first === 'object' && !Array.isArray(first) ? rest.shift() : {});
418
- const text = rest.filter((v) => typeof v === 'string').join('');
419
- const size = num(s.s);
420
- const id = sink.add({
421
- icon,
422
- variant: VARIANTS.get((_a = str(s.v)) !== null && _a !== void 0 ? _a : ''),
423
- align: ALIGNS.get((_b = str(s.a)) !== null && _b !== void 0 ? _b : ''),
424
- size: size === undefined ? undefined : Math.round(size * 1000) / 100000,
425
- rotation: num(s.r),
426
- offsetX: num(s.x),
427
- offsetY: num(s.y),
428
- primaryColor: str(s.p),
429
- secondaryColor: str(s.sc),
430
- accentColor: str(s.ac),
431
- text: text || undefined,
432
- textBinding: str(s.b),
433
- textColor: str(s.tc),
434
- textSize: num(s.ts),
435
- }, parent, isBase);
436
- for (const child of rest) {
437
- if (Array.isArray(child)) {
438
- node(child, id, false);
439
- }
440
- }
441
- };
442
- node(parsed, undefined, true);
443
- return sink.layers;
337
+ const parsed = JSON.parse(json);
338
+ if (typeof parsed === "string") {
339
+ return parsed.trim() ? [{ id: "1", icon: parsed }] : null;
340
+ }
341
+ const sink = new LayerSink();
342
+ const str = (v) => typeof v === "string" ? v : void 0;
343
+ const num = (v) => typeof v === "number" && Number.isFinite(v) ? v : void 0;
344
+ const node = (value, parent, isBase) => {
345
+ if (!Array.isArray(value) || typeof value[0] !== "string" || !value[0]) {
346
+ throw new IconValueError("node expected");
347
+ }
348
+ const [icon, ...rest] = value;
349
+ const first = rest[0];
350
+ const s = first && typeof first === "object" && !Array.isArray(first) ? rest.shift() : {};
351
+ const text = rest.filter((v) => typeof v === "string").join("");
352
+ const size = num(s.s);
353
+ const id = sink.add(
354
+ {
355
+ icon,
356
+ variant: VARIANTS.get(str(s.v) ?? ""),
357
+ align: ALIGNS.get(str(s.a) ?? ""),
358
+ size: size === void 0 ? void 0 : Math.round(size * 1e3) / 1e5,
359
+ rotation: num(s.r),
360
+ offsetX: num(s.x),
361
+ offsetY: num(s.y),
362
+ primaryColor: str(s.p),
363
+ secondaryColor: str(s.sc),
364
+ accentColor: str(s.ac),
365
+ text: text || void 0,
366
+ textBinding: str(s.b),
367
+ textColor: str(s.tc),
368
+ textSize: num(s.ts)
369
+ },
370
+ parent,
371
+ isBase
372
+ );
373
+ for (const child of rest) {
374
+ if (Array.isArray(child)) {
375
+ node(child, id, false);
376
+ }
377
+ }
378
+ };
379
+ node(parsed, void 0, true);
380
+ return sink.layers;
444
381
  }
445
- /**
446
- * Reads an icon kept as text (1.3.10) — a name, the code (`Folder(Star@tr)`), JSON or the HTML of
447
- * NiceIconPicker 1.3.9 — into stack layers (ids `'1'`, `'2'`… in document order). `null` for empty
448
- * or unreadable text. Names stay as written: `renderIconStack` resolves `Star` to `NtdStar`.
449
- */
450
382
  function parseIconValue(value) {
451
- var _a, _b;
452
- const text = value === null || value === void 0 ? void 0 : value.trim();
453
- if (!text) {
454
- return null;
455
- }
456
- try {
457
- if (text.startsWith('<')) {
458
- return (_b = (_a = parseIconHtml(text)) === null || _a === void 0 ? void 0 : _a.layers) !== null && _b !== void 0 ? _b : null;
459
- }
460
- if (text.startsWith('[') || text.startsWith('"')) {
461
- return readJson(text);
462
- }
463
- return readCode(text);
383
+ const text = value?.trim();
384
+ if (!text) {
385
+ return null;
386
+ }
387
+ try {
388
+ if (text.startsWith("<")) {
389
+ return parseIconHtml(text)?.layers ?? null;
464
390
  }
465
- catch (_c) {
466
- return null;
391
+ if (text.startsWith("[") || text.startsWith('"')) {
392
+ return readJson(text);
467
393
  }
394
+ return readCode(text);
395
+ } catch {
396
+ return null;
397
+ }
468
398
  }
469
-
470
- export { formatIconValue, parseIconValue };
399
+ export {
400
+ formatIconValue,
401
+ parseIconValue
402
+ };