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