@nice2dev/icons 1.3.15 → 1.3.17

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 (153) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/README.md +1 -1
  3. package/dist/cjs/NiceDesktopIconExporter.js +688 -599
  4. package/dist/cjs/NiceFaviconGenerator.js +603 -417
  5. package/dist/cjs/NiceIconPicker.js +788 -508
  6. package/dist/cjs/NiceIconPreview.js +246 -188
  7. package/dist/cjs/NiceIconSetCreator.js +683 -552
  8. package/dist/cjs/NiceIconStacker.js +547 -171
  9. package/dist/cjs/NiceIconValue.js +27 -35
  10. package/dist/cjs/NtdIconBadge.js +384 -360
  11. package/dist/cjs/NtdIconMorph.js +419 -354
  12. package/dist/cjs/NtdStateMorph.js +150 -147
  13. package/dist/cjs/advancedIconSearch.js +373 -510
  14. package/dist/cjs/animationControls.js +518 -642
  15. package/dist/cjs/animationSpeed.js +69 -0
  16. package/dist/cjs/client.js +12 -15
  17. package/dist/cjs/createIcon.js +374 -252
  18. package/dist/cjs/design-tokens.js +324 -390
  19. package/dist/cjs/figmaExport.js +162 -257
  20. package/dist/cjs/figmaSync.js +234 -316
  21. package/dist/cjs/headless-ui.js +240 -368
  22. package/dist/cjs/iconAnalytics.js +337 -393
  23. package/dist/cjs/iconHtml.js +64 -86
  24. package/dist/cjs/iconMetadata.js +392 -472
  25. package/dist/cjs/iconParts.js +120 -90
  26. package/dist/cjs/iconStack.js +136 -155
  27. package/dist/cjs/iconStyles.js +1670 -509
  28. package/dist/cjs/iconValue.js +359 -430
  29. package/dist/cjs/icons/accessibility.js +1119 -134
  30. package/dist/cjs/icons/actions.js +1290 -330
  31. package/dist/cjs/icons/ai.js +1424 -144
  32. package/dist/cjs/icons/brand.js +613 -184
  33. package/dist/cjs/icons/business.js +938 -192
  34. package/dist/cjs/icons/devtech.js +1656 -227
  35. package/dist/cjs/icons/ecommerce.js +802 -111
  36. package/dist/cjs/icons/education.js +1345 -199
  37. package/dist/cjs/icons/files.js +1597 -328
  38. package/dist/cjs/icons/fintech.js +793 -104
  39. package/dist/cjs/icons/food.js +1028 -156
  40. package/dist/cjs/icons/fun.js +804 -109
  41. package/dist/cjs/icons/gaming.js +916 -170
  42. package/dist/cjs/icons/health.js +623 -112
  43. package/dist/cjs/icons/index.js +32 -42
  44. package/dist/cjs/icons/input.js +282 -83
  45. package/dist/cjs/icons/legal.js +1065 -122
  46. package/dist/cjs/icons/media.js +1061 -267
  47. package/dist/cjs/icons/navigation.js +407 -123
  48. package/dist/cjs/icons/omniverk.js +523 -93
  49. package/dist/cjs/icons/realestate.js +1520 -193
  50. package/dist/cjs/icons/saas.js +867 -98
  51. package/dist/cjs/icons/science.js +1344 -202
  52. package/dist/cjs/icons/shapes.js +1316 -308
  53. package/dist/cjs/icons/smarthome.js +786 -90
  54. package/dist/cjs/icons/social.js +591 -59
  55. package/dist/cjs/icons/sports.js +1133 -133
  56. package/dist/cjs/icons/sustainability.js +1211 -139
  57. package/dist/cjs/icons/travel.js +1470 -148
  58. package/dist/cjs/icons/ui.js +1508 -315
  59. package/dist/cjs/icons/weather.js +1160 -173
  60. package/dist/cjs/index.js +559 -568
  61. package/dist/cjs/lottieIntegration.js +261 -266
  62. package/dist/cjs/nicetodev-icons.css +1 -1
  63. package/dist/cjs/particleEffects.js +270 -251
  64. package/dist/cjs/resolver.js +229 -284
  65. package/dist/cjs/rsc.js +175 -193
  66. package/dist/cjs/sharpen.js +73 -130
  67. package/dist/cjs/smilAnimations.js +380 -165
  68. package/dist/cjs/stacking.js +87 -122
  69. package/dist/cjs/tailwind-plugin.js +280 -320
  70. package/dist/cjs/types.js +46 -72
  71. package/dist/cjs/utilities.js +163 -324
  72. package/dist/cjs/variantProps.js +12 -52
  73. package/dist/esm/NiceDesktopIconExporter.js +671 -598
  74. package/dist/esm/NiceFaviconGenerator.js +583 -416
  75. package/dist/esm/NiceIconPicker.js +789 -507
  76. package/dist/esm/NiceIconPreview.js +247 -187
  77. package/dist/esm/NiceIconSetCreator.js +685 -551
  78. package/dist/esm/NiceIconStacker.js +549 -170
  79. package/dist/esm/NiceIconValue.js +29 -34
  80. package/dist/esm/NtdIconBadge.js +388 -359
  81. package/dist/esm/NtdIconMorph.js +423 -353
  82. package/dist/esm/NtdStateMorph.js +152 -146
  83. package/dist/esm/advancedIconSearch.js +391 -509
  84. package/dist/esm/animationControls.js +527 -641
  85. package/dist/esm/animationSpeed.js +69 -0
  86. package/dist/esm/client.js +48 -10
  87. package/dist/esm/createIcon.js +375 -251
  88. package/dist/esm/design-tokens.js +334 -387
  89. package/dist/esm/figmaExport.js +170 -256
  90. package/dist/esm/figmaSync.js +237 -315
  91. package/dist/esm/headless-ui.js +254 -365
  92. package/dist/esm/iconAnalytics.js +342 -392
  93. package/dist/esm/iconHtml.js +67 -85
  94. package/dist/esm/iconMetadata.js +404 -471
  95. package/dist/esm/iconParts.js +125 -89
  96. package/dist/esm/iconStack.js +145 -154
  97. package/dist/esm/iconStyles.js +1681 -508
  98. package/dist/esm/iconValue.js +361 -429
  99. package/dist/esm/icons/accessibility.js +1133 -133
  100. package/dist/esm/icons/actions.js +1320 -329
  101. package/dist/esm/icons/ai.js +1441 -143
  102. package/dist/esm/icons/brand.js +616 -179
  103. package/dist/esm/icons/business.js +957 -191
  104. package/dist/esm/icons/devtech.js +1687 -226
  105. package/dist/esm/icons/ecommerce.js +816 -110
  106. package/dist/esm/icons/education.js +1364 -198
  107. package/dist/esm/icons/files.js +1628 -327
  108. package/dist/esm/icons/fintech.js +807 -103
  109. package/dist/esm/icons/food.js +1043 -153
  110. package/dist/esm/icons/fun.js +819 -108
  111. package/dist/esm/icons/gaming.js +933 -169
  112. package/dist/esm/icons/health.js +636 -111
  113. package/dist/esm/icons/index.js +589 -32
  114. package/dist/esm/icons/input.js +326 -82
  115. package/dist/esm/icons/legal.js +1079 -121
  116. package/dist/esm/icons/media.js +1086 -266
  117. package/dist/esm/icons/navigation.js +421 -122
  118. package/dist/esm/icons/omniverk.js +534 -91
  119. package/dist/esm/icons/realestate.js +1544 -198
  120. package/dist/esm/icons/saas.js +880 -97
  121. package/dist/esm/icons/science.js +1370 -208
  122. package/dist/esm/icons/shapes.js +1343 -307
  123. package/dist/esm/icons/smarthome.js +799 -89
  124. package/dist/esm/icons/social.js +599 -58
  125. package/dist/esm/icons/sports.js +1148 -132
  126. package/dist/esm/icons/sustainability.js +1226 -138
  127. package/dist/esm/icons/travel.js +1486 -147
  128. package/dist/esm/icons/ui.js +1540 -314
  129. package/dist/esm/icons/weather.js +1181 -172
  130. package/dist/esm/index.js +749 -58
  131. package/dist/esm/lottieIntegration.js +264 -265
  132. package/dist/esm/nicetodev-icons.css +1 -1
  133. package/dist/esm/particleEffects.js +271 -250
  134. package/dist/esm/resolver.js +231 -283
  135. package/dist/esm/rsc.js +182 -192
  136. package/dist/esm/sharpen.js +78 -129
  137. package/dist/esm/smilAnimations.js +385 -164
  138. package/dist/esm/stacking.js +99 -121
  139. package/dist/esm/tailwind-plugin.js +282 -319
  140. package/dist/esm/types.js +50 -71
  141. package/dist/esm/utilities.js +177 -321
  142. package/dist/esm/variantProps.js +23 -52
  143. package/dist/types/animationSpeed.d.ts +19 -0
  144. package/dist/types/createIcon.d.ts +6 -0
  145. package/dist/types/iconStyles.d.ts +6 -1
  146. package/dist/types/icons/brand.d.ts +0 -4
  147. package/dist/types/icons/food.d.ts +0 -3
  148. package/dist/types/icons/index.d.ts +3 -3
  149. package/dist/types/icons/omniverk.d.ts +0 -3
  150. package/dist/types/icons/science.d.ts +1 -1
  151. package/dist/types/smilAnimations.d.ts +4 -2
  152. package/dist/types/types.d.ts +7 -0
  153. 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
+ };