@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/types.js
CHANGED
|
@@ -1,83 +1,57 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Default colors for semantic color variants.
|
|
5
|
-
* These are used when CSS variables are not defined.
|
|
6
|
-
*/
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
3
|
const SEMANTIC_COLOR_DEFAULTS = {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
4
|
+
success: "#22c55e",
|
|
5
|
+
// Green 500
|
|
6
|
+
warning: "#f59e0b",
|
|
7
|
+
// Amber 500
|
|
8
|
+
error: "#ef4444",
|
|
9
|
+
// Red 500
|
|
10
|
+
info: "#3b82f6",
|
|
11
|
+
// Blue 500
|
|
12
|
+
muted: "#6b7280",
|
|
13
|
+
// Gray 500
|
|
14
|
+
primary: "#6366f1",
|
|
15
|
+
// Indigo 500
|
|
16
|
+
secondary: "#8b5cf6",
|
|
17
|
+
// Violet 500
|
|
18
|
+
accent: "#ec4899"
|
|
19
|
+
// Pink 500
|
|
16
20
|
};
|
|
17
|
-
/**
|
|
18
|
-
* CSS variable names for semantic colors.
|
|
19
|
-
* Define these in your CSS to customize icon colors globally.
|
|
20
|
-
*
|
|
21
|
-
* @example
|
|
22
|
-
* ```css
|
|
23
|
-
* :root {
|
|
24
|
-
* --ntd-icon-success: #10b981;
|
|
25
|
-
* --ntd-icon-error: #dc2626;
|
|
26
|
-
* }
|
|
27
|
-
* ```
|
|
28
|
-
*/
|
|
29
21
|
const SEMANTIC_COLOR_VARS = {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
22
|
+
success: "--ntd-icon-success",
|
|
23
|
+
warning: "--ntd-icon-warning",
|
|
24
|
+
error: "--ntd-icon-error",
|
|
25
|
+
info: "--ntd-icon-info",
|
|
26
|
+
muted: "--ntd-icon-muted",
|
|
27
|
+
primary: "--ntd-icon-primary",
|
|
28
|
+
secondary: "--ntd-icon-secondary",
|
|
29
|
+
accent: "--ntd-icon-accent"
|
|
38
30
|
};
|
|
39
|
-
/** Gradient preset color stops. */
|
|
40
31
|
const GRADIENT_PRESETS = {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
32
|
+
sunset: ["#ff6b6b", "#feca57", "#ff9ff3"],
|
|
33
|
+
ocean: ["#0652DD", "#1B9CFC", "#38ada9"],
|
|
34
|
+
forest: ["#0a3d0a", "#1e8449", "#58D68D"],
|
|
35
|
+
fire: ["#e74c3c", "#f39c12", "#f1c40f"],
|
|
36
|
+
ice: ["#74b9ff", "#a29bfe", "#dfe6e9"],
|
|
37
|
+
neon: ["#6c5ce7", "#fd79a8", "#00cec9"],
|
|
38
|
+
gold: ["#f9ca24", "#f0932b", "#e17055"],
|
|
39
|
+
"purple-haze": ["#6c5ce7", "#a55eea", "#e056a0"],
|
|
40
|
+
aurora: ["#00b894", "#00cec9", "#0984e3", "#6c5ce7"],
|
|
41
|
+
midnight: ["#0c0c1d", "#1e3a5f", "#2c3e50"],
|
|
42
|
+
candy: ["#ff6b81", "#ffa502", "#2ed573"],
|
|
43
|
+
steel: ["#636e72", "#b2bec3", "#dfe6e9"]
|
|
53
44
|
};
|
|
54
|
-
/**
|
|
55
|
-
* Map of named size presets to their pixel values.
|
|
56
|
-
*
|
|
57
|
-
* Used internally by {@link createIcon} to resolve `IconSize` strings to numbers.
|
|
58
|
-
*
|
|
59
|
-
* | Key | Value |
|
|
60
|
-
* |--------|-------|
|
|
61
|
-
* | `xs` | 12 |
|
|
62
|
-
* | `sm` | 16 |
|
|
63
|
-
* | `md` | 24 |
|
|
64
|
-
* | `lg` | 32 |
|
|
65
|
-
* | `xl` | 48 |
|
|
66
|
-
* | `2xl` | 64 |
|
|
67
|
-
* | `xxl` | 96 |
|
|
68
|
-
* | `xxxl` | 128 |
|
|
69
|
-
*/
|
|
70
45
|
const SIZE_MAP = {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
46
|
+
xs: 12,
|
|
47
|
+
sm: 16,
|
|
48
|
+
md: 24,
|
|
49
|
+
lg: 32,
|
|
50
|
+
xl: 48,
|
|
51
|
+
"2xl": 64,
|
|
52
|
+
xxl: 96,
|
|
53
|
+
xxxl: 128
|
|
79
54
|
};
|
|
80
|
-
|
|
81
55
|
exports.GRADIENT_PRESETS = GRADIENT_PRESETS;
|
|
82
56
|
exports.SEMANTIC_COLOR_DEFAULTS = SEMANTIC_COLOR_DEFAULTS;
|
|
83
57
|
exports.SEMANTIC_COLOR_VARS = SEMANTIC_COLOR_VARS;
|
package/dist/cjs/utilities.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
var React = require('react');
|
|
6
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } });
|
|
3
|
+
const React = require("react");
|
|
7
4
|
/**
|
|
8
5
|
* @file utilities.ts
|
|
9
6
|
* @description Utility hooks and functions for @nice2dev/icons
|
|
@@ -32,361 +29,203 @@ var React = require('react');
|
|
|
32
29
|
* @since 2026-03
|
|
33
30
|
* @license MIT
|
|
34
31
|
*/
|
|
35
|
-
/*
|
|
36
|
-
ICON REGISTRY
|
|
37
|
-
───────────────────────────────────────────────────────────────────────────── */
|
|
38
|
-
/**
|
|
39
|
-
* Global icon cache for dynamic loading
|
|
40
|
-
*/
|
|
41
|
-
const iconRegistry = new Map();
|
|
42
|
-
/**
|
|
43
|
-
* Registers an icon in the global registry
|
|
44
|
-
*/
|
|
32
|
+
const iconRegistry = /* @__PURE__ */ new Map();
|
|
45
33
|
function registerIcon(name, component) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
34
|
+
iconRegistry.set(name, {
|
|
35
|
+
component,
|
|
36
|
+
loadedAt: Date.now()
|
|
37
|
+
});
|
|
50
38
|
}
|
|
51
|
-
/**
|
|
52
|
-
* Gets an icon from the registry
|
|
53
|
-
*/
|
|
54
39
|
function getIconFromRegistry(name) {
|
|
55
|
-
|
|
56
|
-
return (_a = iconRegistry.get(name)) === null || _a === void 0 ? void 0 : _a.component;
|
|
40
|
+
return iconRegistry.get(name)?.component;
|
|
57
41
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Clears the icon registry
|
|
60
|
-
*/
|
|
61
42
|
function clearIconRegistry() {
|
|
62
|
-
|
|
43
|
+
iconRegistry.clear();
|
|
63
44
|
}
|
|
64
|
-
/**
|
|
65
|
-
* Gets all registered icon names
|
|
66
|
-
*/
|
|
67
45
|
function getRegisteredIconNames() {
|
|
68
|
-
|
|
46
|
+
return Array.from(iconRegistry.keys());
|
|
69
47
|
}
|
|
70
|
-
/* ────────────────────────────────────────────────────────────────────────────
|
|
71
|
-
USE ICON HOOK
|
|
72
|
-
───────────────────────────────────────────────────────────────────────────── */
|
|
73
|
-
/**
|
|
74
|
-
* Hook for dynamically loading icons by name.
|
|
75
|
-
*
|
|
76
|
-
* @param iconName - Name of the icon to load (e.g., 'NtdHome')
|
|
77
|
-
* @param options - Loading options
|
|
78
|
-
* @returns Icon component, loading state, and error
|
|
79
|
-
*
|
|
80
|
-
* @example
|
|
81
|
-
* ```tsx
|
|
82
|
-
* function DynamicIcon({ name }: { name: string }) {
|
|
83
|
-
* const { Icon, isLoading, error } = useIcon(name);
|
|
84
|
-
*
|
|
85
|
-
* if (isLoading) return <Spinner />;
|
|
86
|
-
* if (error || !Icon) return <FallbackIcon />;
|
|
87
|
-
*
|
|
88
|
-
* return <Icon size="md" />;
|
|
89
|
-
* }
|
|
90
|
-
* ```
|
|
91
|
-
*/
|
|
92
48
|
function useIcon(iconName, options = {}) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
49
|
+
const { fallback, cache = true } = options;
|
|
50
|
+
const [state, setState] = React.useState({
|
|
51
|
+
Icon: iconName ? getIconFromRegistry(iconName) || null : null,
|
|
52
|
+
isLoading: false,
|
|
53
|
+
error: null
|
|
54
|
+
});
|
|
55
|
+
React.useEffect(() => {
|
|
56
|
+
if (!iconName) {
|
|
57
|
+
setState({ Icon: null, isLoading: false, error: null });
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
const cached = getIconFromRegistry(iconName);
|
|
61
|
+
if (cached) {
|
|
62
|
+
setState({ Icon: cached, isLoading: false, error: null });
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
setState((prev) => ({ ...prev, isLoading: true, error: null }));
|
|
66
|
+
const loadIcon = async () => {
|
|
67
|
+
try {
|
|
68
|
+
const module2 = await Promise.resolve().then(() => require("./icons/index.js"));
|
|
69
|
+
const IconComponent = module2[iconName];
|
|
70
|
+
if (IconComponent) {
|
|
71
|
+
if (cache) {
|
|
72
|
+
registerIcon(iconName, IconComponent);
|
|
73
|
+
}
|
|
74
|
+
setState({ Icon: IconComponent, isLoading: false, error: null });
|
|
75
|
+
} else {
|
|
76
|
+
throw new Error(`Icon "${iconName}" not found`);
|
|
109
77
|
}
|
|
110
|
-
|
|
111
|
-
setState(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
setState({ Icon: IconComponent, isLoading: false, error: null });
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
throw new Error(`Icon "${iconName}" not found`);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
catch (err) {
|
|
129
|
-
setState({
|
|
130
|
-
Icon: fallback || null,
|
|
131
|
-
isLoading: false,
|
|
132
|
-
error: err instanceof Error ? err : new Error('Failed to load icon'),
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
loadIcon();
|
|
137
|
-
}, [iconName, cache, fallback]);
|
|
138
|
-
return state;
|
|
78
|
+
} catch (err) {
|
|
79
|
+
setState({
|
|
80
|
+
Icon: fallback || null,
|
|
81
|
+
isLoading: false,
|
|
82
|
+
error: err instanceof Error ? err : new Error("Failed to load icon")
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
loadIcon();
|
|
87
|
+
}, [iconName, cache, fallback]);
|
|
88
|
+
return state;
|
|
139
89
|
}
|
|
140
|
-
/* ────────────────────────────────────────────────────────────────────────────
|
|
141
|
-
USE REDUCED MOTION
|
|
142
|
-
───────────────────────────────────────────────────────────────────────────── */
|
|
143
|
-
/**
|
|
144
|
-
* Subscribes to prefers-reduced-motion media query.
|
|
145
|
-
*/
|
|
146
90
|
function subscribeToReducedMotion(callback) {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
91
|
+
if (typeof window === "undefined") {
|
|
92
|
+
return () => {
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
const mediaQuery = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
96
|
+
const handler = () => callback();
|
|
97
|
+
mediaQuery.addEventListener("change", handler);
|
|
98
|
+
return () => mediaQuery.removeEventListener("change", handler);
|
|
154
99
|
}
|
|
155
|
-
/**
|
|
156
|
-
* Gets current reduced motion preference.
|
|
157
|
-
*/
|
|
158
100
|
function getReducedMotionSnapshot() {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
101
|
+
if (typeof window === "undefined") {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
|
|
163
105
|
}
|
|
164
|
-
/**
|
|
165
|
-
* Server snapshot for SSR (assumes no reduced motion preference).
|
|
166
|
-
*/
|
|
167
106
|
function getReducedMotionServerSnapshot() {
|
|
168
|
-
|
|
107
|
+
return false;
|
|
169
108
|
}
|
|
170
|
-
/**
|
|
171
|
-
* Hook that returns true if user prefers reduced motion.
|
|
172
|
-
* Uses useSyncExternalStore for SSR compatibility.
|
|
173
|
-
*
|
|
174
|
-
* @returns Whether the user prefers reduced motion
|
|
175
|
-
*
|
|
176
|
-
* @example
|
|
177
|
-
* ```tsx
|
|
178
|
-
* function AnimatedIcon() {
|
|
179
|
-
* const prefersReducedMotion = useReducedMotion();
|
|
180
|
-
*
|
|
181
|
-
* return (
|
|
182
|
-
* <NtdHeart
|
|
183
|
-
* animation={prefersReducedMotion ? undefined : 'pulse'}
|
|
184
|
-
* />
|
|
185
|
-
* );
|
|
186
|
-
* }
|
|
187
|
-
* ```
|
|
188
|
-
*/
|
|
189
109
|
function useReducedMotion() {
|
|
190
|
-
|
|
110
|
+
return React.useSyncExternalStore(
|
|
111
|
+
subscribeToReducedMotion,
|
|
112
|
+
getReducedMotionSnapshot,
|
|
113
|
+
getReducedMotionServerSnapshot
|
|
114
|
+
);
|
|
191
115
|
}
|
|
192
|
-
/* ────────────────────────────────────────────────────────────────────────────
|
|
193
|
-
PRELOAD ICONS
|
|
194
|
-
───────────────────────────────────────────────────────────────────────────── */
|
|
195
|
-
/**
|
|
196
|
-
* Preloads icons into the registry for instant access.
|
|
197
|
-
*
|
|
198
|
-
* @param iconNames - Array of icon names to preload
|
|
199
|
-
* @returns Promise that resolves when all icons are loaded
|
|
200
|
-
*
|
|
201
|
-
* @example
|
|
202
|
-
* ```tsx
|
|
203
|
-
* // Preload critical icons at app startup
|
|
204
|
-
* useEffect(() => {
|
|
205
|
-
* preloadIcons(['NtdHome', 'NtdSearch', 'NtdUser', 'NtdMenu']);
|
|
206
|
-
* }, []);
|
|
207
|
-
* ```
|
|
208
|
-
*/
|
|
209
116
|
async function preloadIcons(iconNames) {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
catch (error) {
|
|
222
|
-
console.warn('Failed to preload icons:', error);
|
|
117
|
+
const results = /* @__PURE__ */ new Map();
|
|
118
|
+
try {
|
|
119
|
+
const module2 = await Promise.resolve().then(() => require("./icons/index.js"));
|
|
120
|
+
for (const name of iconNames) {
|
|
121
|
+
const IconComponent = module2[name];
|
|
122
|
+
if (IconComponent) {
|
|
123
|
+
registerIcon(name, IconComponent);
|
|
124
|
+
results.set(name, IconComponent);
|
|
125
|
+
}
|
|
223
126
|
}
|
|
224
|
-
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.warn("Failed to preload icons:", error);
|
|
129
|
+
}
|
|
130
|
+
return results;
|
|
225
131
|
}
|
|
226
|
-
/**
|
|
227
|
-
* Creates a preloader component that preloads icons on mount.
|
|
228
|
-
*
|
|
229
|
-
* @param iconNames - Icons to preload
|
|
230
|
-
* @returns React component that preloads icons
|
|
231
|
-
*
|
|
232
|
-
* @example
|
|
233
|
-
* ```tsx
|
|
234
|
-
* const IconPreloader = createIconPreloader(['NtdHome', 'NtdSearch']);
|
|
235
|
-
*
|
|
236
|
-
* function App() {
|
|
237
|
-
* return (
|
|
238
|
-
* <>
|
|
239
|
-
* <IconPreloader />
|
|
240
|
-
* <MainContent />
|
|
241
|
-
* </>
|
|
242
|
-
* );
|
|
243
|
-
* }
|
|
244
|
-
* ```
|
|
245
|
-
*/
|
|
246
132
|
function createIconPreloader(iconNames) {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
133
|
+
return function IconPreloader() {
|
|
134
|
+
React.useEffect(() => {
|
|
135
|
+
preloadIcons(iconNames);
|
|
136
|
+
}, []);
|
|
137
|
+
return null;
|
|
138
|
+
};
|
|
253
139
|
}
|
|
254
|
-
/* ────────────────────────────────────────────────────────────────────────────
|
|
255
|
-
ICON PROPS HELPERS
|
|
256
|
-
───────────────────────────────────────────────────────────────────────────── */
|
|
257
|
-
/**
|
|
258
|
-
* Creates props with animation disabled if user prefers reduced motion.
|
|
259
|
-
*
|
|
260
|
-
* @param props - Original icon props
|
|
261
|
-
* @param prefersReducedMotion - Whether user prefers reduced motion
|
|
262
|
-
* @returns Props with animation conditionally disabled
|
|
263
|
-
*/
|
|
264
140
|
function withReducedMotionProps(props, prefersReducedMotion) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
141
|
+
if (!prefersReducedMotion) {
|
|
142
|
+
return props;
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
...props,
|
|
146
|
+
animation: void 0,
|
|
147
|
+
animationDuration: void 0,
|
|
148
|
+
gradientAnimation: void 0
|
|
149
|
+
};
|
|
274
150
|
}
|
|
275
|
-
/**
|
|
276
|
-
* Creates accessible icon props based on context.
|
|
277
|
-
*
|
|
278
|
-
* @param options - Accessibility options
|
|
279
|
-
* @returns Icon props for accessibility
|
|
280
|
-
*/
|
|
281
151
|
function createAccessibleIconProps(options) {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
return {
|
|
285
|
-
'aria-hidden': true,
|
|
286
|
-
role: 'presentation',
|
|
287
|
-
};
|
|
288
|
-
}
|
|
152
|
+
const { label, isDecorative = !label, role } = options;
|
|
153
|
+
if (isDecorative) {
|
|
289
154
|
return {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
title: label,
|
|
155
|
+
"aria-hidden": true,
|
|
156
|
+
role: "presentation"
|
|
293
157
|
};
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
"aria-label": label,
|
|
161
|
+
role: role || "img",
|
|
162
|
+
title: label
|
|
163
|
+
};
|
|
294
164
|
}
|
|
295
|
-
/* ────────────────────────────────────────────────────────────────────────────
|
|
296
|
-
ICON TYPE GUARDS
|
|
297
|
-
───────────────────────────────────────────────────────────────────────────── */
|
|
298
|
-
/**
|
|
299
|
-
* Checks if a value is a valid icon component.
|
|
300
|
-
* Handles both regular components and forwardRef components.
|
|
301
|
-
*/
|
|
302
165
|
function isIconComponent(value) {
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
return typeof displayName === 'string' && displayName.startsWith('Ntd');
|
|
166
|
+
if (value == null) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
const isValidComponent = typeof value === "function" || typeof value === "object" && "$$typeof" in value;
|
|
170
|
+
if (!isValidComponent) {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
const displayName = value.displayName;
|
|
174
|
+
return typeof displayName === "string" && displayName.startsWith("Ntd");
|
|
313
175
|
}
|
|
314
|
-
/**
|
|
315
|
-
* Checks if an icon name is valid.
|
|
316
|
-
*/
|
|
317
176
|
function isValidIconName(name) {
|
|
318
|
-
|
|
177
|
+
return /^Ntd[A-Z][a-zA-Z0-9]*$/.test(name);
|
|
319
178
|
}
|
|
320
|
-
/**
|
|
321
|
-
* Creates a function that renders multiple icons efficiently.
|
|
322
|
-
*
|
|
323
|
-
* @param configs - Array of icon configurations
|
|
324
|
-
* @returns Function that renders all configured icons
|
|
325
|
-
*
|
|
326
|
-
* @example
|
|
327
|
-
* ```tsx
|
|
328
|
-
* const renderNavIcons = createBatchIconRenderer([
|
|
329
|
-
* { name: 'NtdHome', props: { size: 'md' } },
|
|
330
|
-
* { name: 'NtdSearch', props: { size: 'md' } },
|
|
331
|
-
* { name: 'NtdUser', props: { size: 'md' } },
|
|
332
|
-
* ]);
|
|
333
|
-
*
|
|
334
|
-
* // In component
|
|
335
|
-
* const icons = renderNavIcons();
|
|
336
|
-
* ```
|
|
337
|
-
*/
|
|
338
179
|
function useBatchIcons(configs) {
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
setIsLoading(false);
|
|
350
|
-
};
|
|
351
|
-
loadIcons();
|
|
352
|
-
}, [namesKey]);
|
|
353
|
-
const renderIcon = React.useCallback((name, additionalProps) => {
|
|
354
|
-
const Icon = icons.get(name);
|
|
355
|
-
const config = configs.find((c) => c.name === name);
|
|
356
|
-
if (!Icon) {
|
|
357
|
-
return null;
|
|
358
|
-
}
|
|
359
|
-
const mergedProps = {
|
|
360
|
-
...config === null || config === void 0 ? void 0 : config.props,
|
|
361
|
-
...additionalProps,
|
|
362
|
-
};
|
|
363
|
-
return React.createElement(Icon, mergedProps);
|
|
364
|
-
}, [icons, configs]);
|
|
365
|
-
return {
|
|
366
|
-
renderIcon,
|
|
367
|
-
isLoading,
|
|
368
|
-
icons,
|
|
180
|
+
const [icons, setIcons] = React.useState(/* @__PURE__ */ new Map());
|
|
181
|
+
const [isLoading, setIsLoading] = React.useState(true);
|
|
182
|
+
const namesKey = configs.map((c) => c.name).join(",");
|
|
183
|
+
React.useEffect(() => {
|
|
184
|
+
const loadIcons = async () => {
|
|
185
|
+
setIsLoading(true);
|
|
186
|
+
const names = namesKey ? namesKey.split(",") : [];
|
|
187
|
+
const loadedIcons = await preloadIcons(names);
|
|
188
|
+
setIcons(loadedIcons);
|
|
189
|
+
setIsLoading(false);
|
|
369
190
|
};
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
191
|
+
loadIcons();
|
|
192
|
+
}, [namesKey]);
|
|
193
|
+
const renderIcon = React.useCallback(
|
|
194
|
+
(name, additionalProps) => {
|
|
195
|
+
const Icon = icons.get(name);
|
|
196
|
+
const config = configs.find((c) => c.name === name);
|
|
197
|
+
if (!Icon) {
|
|
198
|
+
return null;
|
|
199
|
+
}
|
|
200
|
+
const mergedProps = {
|
|
201
|
+
...config?.props,
|
|
202
|
+
...additionalProps
|
|
203
|
+
};
|
|
204
|
+
return React.createElement(Icon, mergedProps);
|
|
205
|
+
},
|
|
206
|
+
[icons, configs]
|
|
207
|
+
);
|
|
208
|
+
return {
|
|
209
|
+
renderIcon,
|
|
210
|
+
isLoading,
|
|
211
|
+
icons
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
const utilities = {
|
|
215
|
+
useIcon,
|
|
216
|
+
useReducedMotion,
|
|
217
|
+
preloadIcons,
|
|
218
|
+
createIconPreloader,
|
|
219
|
+
registerIcon,
|
|
220
|
+
getIconFromRegistry,
|
|
221
|
+
clearIconRegistry,
|
|
222
|
+
getRegisteredIconNames,
|
|
223
|
+
withReducedMotionProps,
|
|
224
|
+
createAccessibleIconProps,
|
|
225
|
+
isIconComponent,
|
|
226
|
+
isValidIconName,
|
|
227
|
+
useBatchIcons
|
|
388
228
|
};
|
|
389
|
-
|
|
390
229
|
exports.clearIconRegistry = clearIconRegistry;
|
|
391
230
|
exports.createAccessibleIconProps = createAccessibleIconProps;
|
|
392
231
|
exports.createIconPreloader = createIconPreloader;
|