@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/esm/headless-ui.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import React, { forwardRef, createElement } from
|
|
2
|
-
|
|
1
|
+
import React, { forwardRef, createElement } from "react";
|
|
3
2
|
/**
|
|
4
3
|
* @file headless-ui.tsx
|
|
5
4
|
* @description Headless UI / shadcn/ui compatibility layer for @nice2dev/icons
|
|
@@ -27,393 +26,283 @@ import React, { forwardRef, createElement } from 'react';
|
|
|
27
26
|
* @since 2026-03
|
|
28
27
|
* @license MIT
|
|
29
28
|
*/
|
|
30
|
-
/* ────────────────────────────────────────────────────────────────────────────
|
|
31
|
-
SLOT IMPLEMENTATION
|
|
32
|
-
───────────────────────────────────────────────────────────────────────────── */
|
|
33
|
-
/**
|
|
34
|
-
* Simple Slot implementation for asChild pattern.
|
|
35
|
-
* Compatible with Radix UI's Slot component behavior.
|
|
36
|
-
*/
|
|
37
29
|
const Slot = /* @__PURE__ */ Object.assign(
|
|
38
|
-
/* @__PURE__ */ forwardRef(
|
|
39
|
-
|
|
30
|
+
/* @__PURE__ */ forwardRef(
|
|
31
|
+
({ children, ...props }, forwardedRef) => {
|
|
32
|
+
if (!React.isValidElement(children)) {
|
|
40
33
|
return null;
|
|
41
|
-
|
|
42
|
-
|
|
34
|
+
}
|
|
35
|
+
return React.cloneElement(children, {
|
|
43
36
|
...props,
|
|
44
37
|
...children.props,
|
|
45
|
-
ref: forwardedRef
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Wraps a NtdIcon component with forwardRef for Headless UI / Radix compatibility.
|
|
53
|
-
* Supports the asChild pattern used by shadcn/ui and Radix primitives.
|
|
54
|
-
*
|
|
55
|
-
* @param IconComponent - The NtdIcon component to wrap
|
|
56
|
-
* @param displayName - Optional display name for debugging
|
|
57
|
-
* @returns A forwardRef-wrapped icon component
|
|
58
|
-
*
|
|
59
|
-
* @example
|
|
60
|
-
* ```tsx
|
|
61
|
-
* import { NtdUser, NtdSettings } from '@nice2dev/icons';
|
|
62
|
-
* import { forwardRefIcon } from '@nice2dev/icons/headless-ui';
|
|
63
|
-
*
|
|
64
|
-
* // Create ref-compatible versions
|
|
65
|
-
* const UserIcon = forwardRefIcon(NtdUser);
|
|
66
|
-
* const SettingsIcon = forwardRefIcon(NtdSettings, 'SettingsIcon');
|
|
67
|
-
*
|
|
68
|
-
* // Use with Radix UI / shadcn
|
|
69
|
-
* <DropdownMenu.Trigger asChild>
|
|
70
|
-
* <SettingsIcon className="h-5 w-5" />
|
|
71
|
-
* </DropdownMenu.Trigger>
|
|
72
|
-
* ```
|
|
73
|
-
*/
|
|
38
|
+
ref: forwardedRef
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
),
|
|
42
|
+
{ displayName: "Slot" }
|
|
43
|
+
);
|
|
74
44
|
function forwardRefIcon(IconComponent, displayName) {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
45
|
+
const WrappedIcon = forwardRef(
|
|
46
|
+
({ asChild, children, ...props }, ref) => {
|
|
47
|
+
if (asChild && React.isValidElement(children)) {
|
|
48
|
+
return createElement(Slot, { ref, ...props }, children);
|
|
49
|
+
}
|
|
50
|
+
return createElement(IconComponent, { ...props, ref });
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
WrappedIcon.displayName = displayName || IconComponent.displayName || "NtdIcon";
|
|
54
|
+
return WrappedIcon;
|
|
83
55
|
}
|
|
84
|
-
/* ────────────────────────────────────────────────────────────────────────────
|
|
85
|
-
SHADCN/UI PRESET
|
|
86
|
-
───────────────────────────────────────────────────────────────────────────── */
|
|
87
|
-
/**
|
|
88
|
-
* shadcn/ui icon size presets matching their button sizes
|
|
89
|
-
*/
|
|
90
56
|
const SHADCN_ICON_SIZES = {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
57
|
+
default: "1rem",
|
|
58
|
+
// 16px - matches default button text
|
|
59
|
+
sm: "0.875rem",
|
|
60
|
+
// 14px - matches sm button
|
|
61
|
+
lg: "1.125rem",
|
|
62
|
+
// 18px - matches lg button
|
|
63
|
+
icon: "1rem"
|
|
64
|
+
// 16px - for icon-only buttons
|
|
95
65
|
};
|
|
96
|
-
/**
|
|
97
|
-
* shadcn/ui color tokens mapping.
|
|
98
|
-
*
|
|
99
|
-
* These names belong to the host application: shadcn declares them on :root as
|
|
100
|
-
* HSL triplets (`--primary: 222 47% 11%`), which is why every value wraps them
|
|
101
|
-
* in `hsl()`. They are deliberately not `--nice-*` tokens — ours hold hex, so
|
|
102
|
-
* `hsl(#3b82f6)` would be invalid and the colour would be dropped. The token
|
|
103
|
-
* audit skips this file for the same reason.
|
|
104
|
-
*/
|
|
105
66
|
const SHADCN_COLOR_TOKENS = {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
67
|
+
foreground: "hsl(var(--foreground))",
|
|
68
|
+
mutedForeground: "hsl(var(--muted-foreground))",
|
|
69
|
+
primary: "hsl(var(--primary))",
|
|
70
|
+
primaryForeground: "hsl(var(--primary-foreground))",
|
|
71
|
+
secondary: "hsl(var(--secondary))",
|
|
72
|
+
secondaryForeground: "hsl(var(--secondary-foreground))",
|
|
73
|
+
accent: "hsl(var(--accent))",
|
|
74
|
+
accentForeground: "hsl(var(--accent-foreground))",
|
|
75
|
+
destructive: "hsl(var(--destructive))",
|
|
76
|
+
destructiveForeground: "hsl(var(--destructive-foreground))"
|
|
116
77
|
};
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
ghost: SHADCN_COLOR_TOKENS.foreground,
|
|
131
|
-
link: SHADCN_COLOR_TOKENS.primary,
|
|
132
|
-
};
|
|
133
|
-
return {
|
|
134
|
-
size: SHADCN_ICON_SIZES[size],
|
|
135
|
-
color: colorMap[variant] || SHADCN_COLOR_TOKENS.foreground,
|
|
136
|
-
};
|
|
78
|
+
function getShadcnIconProps(variant = "default", size = "default") {
|
|
79
|
+
const colorMap = {
|
|
80
|
+
default: SHADCN_COLOR_TOKENS.primaryForeground,
|
|
81
|
+
destructive: SHADCN_COLOR_TOKENS.destructiveForeground,
|
|
82
|
+
outline: SHADCN_COLOR_TOKENS.foreground,
|
|
83
|
+
secondary: SHADCN_COLOR_TOKENS.secondaryForeground,
|
|
84
|
+
ghost: SHADCN_COLOR_TOKENS.foreground,
|
|
85
|
+
link: SHADCN_COLOR_TOKENS.primary
|
|
86
|
+
};
|
|
87
|
+
return {
|
|
88
|
+
size: SHADCN_ICON_SIZES[size],
|
|
89
|
+
color: colorMap[variant] || SHADCN_COLOR_TOKENS.foreground
|
|
90
|
+
};
|
|
137
91
|
}
|
|
138
|
-
/**
|
|
139
|
-
* Preset shadcn/ui className utilities for icons
|
|
140
|
-
*/
|
|
141
92
|
const shadcnIconClasses = {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
93
|
+
/** Standard icon in button */
|
|
94
|
+
button: "h-4 w-4",
|
|
95
|
+
/** Icon with right margin (before text) */
|
|
96
|
+
buttonLeft: "mr-2 h-4 w-4",
|
|
97
|
+
/** Icon with left margin (after text) */
|
|
98
|
+
buttonRight: "ml-2 h-4 w-4",
|
|
99
|
+
/** Small icon */
|
|
100
|
+
sm: "h-3.5 w-3.5",
|
|
101
|
+
/** Large icon */
|
|
102
|
+
lg: "h-5 w-5",
|
|
103
|
+
/** Icon-only button */
|
|
104
|
+
iconOnly: "h-4 w-4",
|
|
105
|
+
/** Navigation menu icon */
|
|
106
|
+
nav: "h-4 w-4 shrink-0",
|
|
107
|
+
/** Dropdown menu icon */
|
|
108
|
+
dropdown: "mr-2 h-4 w-4",
|
|
109
|
+
/** Alert/toast icon */
|
|
110
|
+
alert: "h-4 w-4",
|
|
111
|
+
/** Badge icon */
|
|
112
|
+
badge: "h-3 w-3",
|
|
113
|
+
/** Card header icon */
|
|
114
|
+
card: "h-5 w-5 text-muted-foreground",
|
|
115
|
+
/** Spinner/loading */
|
|
116
|
+
spinner: "h-4 w-4 animate-spin"
|
|
166
117
|
};
|
|
167
|
-
/* ────────────────────────────────────────────────────────────────────────────
|
|
168
|
-
RADIX UI HELPERS
|
|
169
|
-
───────────────────────────────────────────────────────────────────────────── */
|
|
170
|
-
/**
|
|
171
|
-
* Creates an icon component compatible with Radix UI primitives.
|
|
172
|
-
* Automatically handles ref forwarding and asChild pattern.
|
|
173
|
-
*
|
|
174
|
-
* @param IconComponent - The NtdIcon component
|
|
175
|
-
* @param defaultProps - Default props to apply
|
|
176
|
-
* @returns Radix-compatible icon component
|
|
177
|
-
*
|
|
178
|
-
* @example
|
|
179
|
-
* ```tsx
|
|
180
|
-
* import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
|
|
181
|
-
* import { NtdChevronDown } from '@nice2dev/icons';
|
|
182
|
-
* import { createRadixIcon } from '@nice2dev/icons/headless-ui';
|
|
183
|
-
*
|
|
184
|
-
* const ChevronIcon = createRadixIcon(NtdChevronDown, {
|
|
185
|
-
* className: 'h-4 w-4 text-muted-foreground'
|
|
186
|
-
* });
|
|
187
|
-
*
|
|
188
|
-
* <DropdownMenu.Trigger>
|
|
189
|
-
* Options <ChevronIcon />
|
|
190
|
-
* </DropdownMenu.Trigger>
|
|
191
|
-
* ```
|
|
192
|
-
*/
|
|
193
118
|
function createRadixIcon(IconComponent, defaultProps = {}) {
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
119
|
+
const RadixIcon = forwardRef((props, ref) => {
|
|
120
|
+
const mergedProps = { ...defaultProps, ...props };
|
|
121
|
+
return createElement(IconComponent, { ...mergedProps, ref });
|
|
122
|
+
});
|
|
123
|
+
RadixIcon.displayName = `Radix${IconComponent.displayName || "Icon"}`;
|
|
124
|
+
return RadixIcon;
|
|
200
125
|
}
|
|
201
|
-
/**
|
|
202
|
-
* HOC that adds Radix UI state-based styling to icons.
|
|
203
|
-
* Supports data-state attributes for open/closed states.
|
|
204
|
-
*
|
|
205
|
-
* @param IconComponent - The icon component to enhance
|
|
206
|
-
* @returns Enhanced icon with state-aware styling
|
|
207
|
-
*
|
|
208
|
-
* @example
|
|
209
|
-
* ```tsx
|
|
210
|
-
* const StateAwareChevron = withRadixState(NtdChevronDown);
|
|
211
|
-
*
|
|
212
|
-
* // Automatically rotates when parent has data-state="open"
|
|
213
|
-
* <Collapsible.Trigger>
|
|
214
|
-
* <StateAwareChevron />
|
|
215
|
-
* </Collapsible.Trigger>
|
|
216
|
-
* ```
|
|
217
|
-
*/
|
|
218
126
|
function withRadixState(IconComponent) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
|
|
127
|
+
const StateIcon = forwardRef(
|
|
128
|
+
({ className, style, ...props }, ref) => {
|
|
129
|
+
const stateStyles = {
|
|
130
|
+
transition: "transform 200ms ease",
|
|
131
|
+
...style
|
|
132
|
+
};
|
|
133
|
+
const stateClassName = `${className || ""} data-[state=open]:rotate-180`.trim();
|
|
134
|
+
return createElement(IconComponent, {
|
|
135
|
+
...props,
|
|
136
|
+
ref,
|
|
137
|
+
className: stateClassName,
|
|
138
|
+
style: stateStyles
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
);
|
|
142
|
+
StateIcon.displayName = `StateAware${IconComponent.displayName || "Icon"}`;
|
|
143
|
+
return StateIcon;
|
|
235
144
|
}
|
|
236
|
-
/* ────────────────────────────────────────────────────────────────────────────
|
|
237
|
-
HEADLESS UI HELPERS
|
|
238
|
-
───────────────────────────────────────────────────────────────────────────── */
|
|
239
|
-
/**
|
|
240
|
-
* Transition presets for Headless UI Transition component with icons.
|
|
241
|
-
*/
|
|
242
145
|
const headlessTransitions = {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
146
|
+
/** Fade in/out */
|
|
147
|
+
fade: {
|
|
148
|
+
enter: "transition-opacity duration-150 ease-out",
|
|
149
|
+
enterFrom: "opacity-0",
|
|
150
|
+
enterTo: "opacity-100",
|
|
151
|
+
leave: "transition-opacity duration-100 ease-in",
|
|
152
|
+
leaveFrom: "opacity-100",
|
|
153
|
+
leaveTo: "opacity-0"
|
|
154
|
+
},
|
|
155
|
+
/** Scale up/down */
|
|
156
|
+
scale: {
|
|
157
|
+
enter: "transition-transform duration-150 ease-out",
|
|
158
|
+
enterFrom: "scale-75",
|
|
159
|
+
enterTo: "scale-100",
|
|
160
|
+
leave: "transition-transform duration-100 ease-in",
|
|
161
|
+
leaveFrom: "scale-100",
|
|
162
|
+
leaveTo: "scale-75"
|
|
163
|
+
},
|
|
164
|
+
/** Rotate */
|
|
165
|
+
rotate: {
|
|
166
|
+
enter: "transition-transform duration-200 ease-out",
|
|
167
|
+
enterFrom: "rotate-0",
|
|
168
|
+
enterTo: "rotate-180",
|
|
169
|
+
leave: "transition-transform duration-200 ease-in",
|
|
170
|
+
leaveFrom: "rotate-180",
|
|
171
|
+
leaveTo: "rotate-0"
|
|
172
|
+
},
|
|
173
|
+
/** Spin (for loading) */
|
|
174
|
+
spin: {
|
|
175
|
+
enter: "animate-spin",
|
|
176
|
+
enterFrom: "",
|
|
177
|
+
enterTo: "",
|
|
178
|
+
leave: "",
|
|
179
|
+
leaveFrom: "",
|
|
180
|
+
leaveTo: ""
|
|
181
|
+
}
|
|
279
182
|
};
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
};
|
|
296
|
-
HeadlessIcon.displayName = `Headless${IconComponent.displayName || 'Icon'}`;
|
|
297
|
-
return HeadlessIcon;
|
|
183
|
+
function createHeadlessIcon(IconComponent, transition = "fade") {
|
|
184
|
+
const HeadlessIcon = ({
|
|
185
|
+
show = true,
|
|
186
|
+
className,
|
|
187
|
+
...props
|
|
188
|
+
}) => {
|
|
189
|
+
const t = headlessTransitions[transition];
|
|
190
|
+
const transitionClass = show ? `${t.enter} ${t.enterTo}` : `${t.leave} ${t.leaveTo}`;
|
|
191
|
+
return createElement(IconComponent, {
|
|
192
|
+
...props,
|
|
193
|
+
className: `${className || ""} ${transitionClass}`.trim()
|
|
194
|
+
});
|
|
195
|
+
};
|
|
196
|
+
HeadlessIcon.displayName = `Headless${IconComponent.displayName || "Icon"}`;
|
|
197
|
+
return HeadlessIcon;
|
|
298
198
|
}
|
|
299
|
-
/* ────────────────────────────────────────────────────────────────────────────
|
|
300
|
-
ICON BUTTON PRESETS
|
|
301
|
-
───────────────────────────────────────────────────────────────────────────── */
|
|
302
|
-
/**
|
|
303
|
-
* Props generator for common icon button patterns in shadcn/ui.
|
|
304
|
-
*/
|
|
305
199
|
const iconButtonPresets = {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
200
|
+
/**
|
|
201
|
+
* Close button (X icon)
|
|
202
|
+
*/
|
|
203
|
+
close: {
|
|
204
|
+
className: "rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground",
|
|
205
|
+
size: 16
|
|
206
|
+
},
|
|
207
|
+
/**
|
|
208
|
+
* Chevron (accordion, collapsible)
|
|
209
|
+
*/
|
|
210
|
+
chevron: {
|
|
211
|
+
className: "h-4 w-4 shrink-0 transition-transform duration-200",
|
|
212
|
+
"data-chevron": true
|
|
213
|
+
},
|
|
214
|
+
/**
|
|
215
|
+
* Menu trigger
|
|
216
|
+
*/
|
|
217
|
+
menuTrigger: {
|
|
218
|
+
className: "h-5 w-5",
|
|
219
|
+
strokeWidth: 1.5
|
|
220
|
+
},
|
|
221
|
+
/**
|
|
222
|
+
* Navigation item icon
|
|
223
|
+
*/
|
|
224
|
+
navItem: {
|
|
225
|
+
className: "mr-2 h-4 w-4 shrink-0"
|
|
226
|
+
},
|
|
227
|
+
/**
|
|
228
|
+
* Sidebar icon
|
|
229
|
+
*/
|
|
230
|
+
sidebar: {
|
|
231
|
+
className: "h-4 w-4",
|
|
232
|
+
strokeWidth: 2
|
|
233
|
+
},
|
|
234
|
+
/**
|
|
235
|
+
* Toast icon
|
|
236
|
+
*/
|
|
237
|
+
toast: {
|
|
238
|
+
className: "h-5 w-5"
|
|
239
|
+
},
|
|
240
|
+
/**
|
|
241
|
+
* Dialog icon
|
|
242
|
+
*/
|
|
243
|
+
dialog: {
|
|
244
|
+
className: "h-4 w-4 opacity-70"
|
|
245
|
+
}
|
|
352
246
|
};
|
|
353
|
-
/* ────────────────────────────────────────────────────────────────────────────
|
|
354
|
-
UTILITY FUNCTIONS
|
|
355
|
-
───────────────────────────────────────────────────────────────────────────── */
|
|
356
|
-
/**
|
|
357
|
-
* Merges icon props with shadcn/ui defaults.
|
|
358
|
-
*
|
|
359
|
-
* @param props - User-provided props
|
|
360
|
-
* @param preset - Preset name from iconButtonPresets
|
|
361
|
-
* @returns Merged props
|
|
362
|
-
*/
|
|
363
247
|
function mergeIconProps(props, preset) {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
248
|
+
const presetProps = iconButtonPresets[preset];
|
|
249
|
+
return {
|
|
250
|
+
...presetProps,
|
|
251
|
+
...props,
|
|
252
|
+
className: `${presetProps.className || ""} ${props.className || ""}`.trim()
|
|
253
|
+
};
|
|
370
254
|
}
|
|
371
|
-
/**
|
|
372
|
-
* Creates a className string for icons based on variant and size.
|
|
373
|
-
*
|
|
374
|
-
* @param options - Styling options
|
|
375
|
-
* @returns Tailwind className string
|
|
376
|
-
*/
|
|
377
255
|
function getIconClassName(options = {}) {
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
256
|
+
const { variant = "default", size = "md", interactive = false, spinning = false } = options;
|
|
257
|
+
const sizeMap = {
|
|
258
|
+
xs: "h-3 w-3",
|
|
259
|
+
sm: "h-3.5 w-3.5",
|
|
260
|
+
md: "h-4 w-4",
|
|
261
|
+
lg: "h-5 w-5",
|
|
262
|
+
xl: "h-6 w-6"
|
|
263
|
+
};
|
|
264
|
+
const variantMap = {
|
|
265
|
+
default: "",
|
|
266
|
+
muted: "text-muted-foreground",
|
|
267
|
+
primary: "text-primary",
|
|
268
|
+
destructive: "text-destructive"
|
|
269
|
+
};
|
|
270
|
+
const classes = [
|
|
271
|
+
sizeMap[size],
|
|
272
|
+
variantMap[variant],
|
|
273
|
+
interactive && "transition-colors hover:text-foreground cursor-pointer",
|
|
274
|
+
spinning && "animate-spin"
|
|
275
|
+
].filter(Boolean);
|
|
276
|
+
return classes.join(" ");
|
|
399
277
|
}
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
278
|
+
const headlessUi = {
|
|
279
|
+
forwardRefIcon,
|
|
280
|
+
createRadixIcon,
|
|
281
|
+
withRadixState,
|
|
282
|
+
createHeadlessIcon,
|
|
283
|
+
getShadcnIconProps,
|
|
284
|
+
mergeIconProps,
|
|
285
|
+
getIconClassName,
|
|
286
|
+
Slot,
|
|
287
|
+
SHADCN_ICON_SIZES,
|
|
288
|
+
SHADCN_COLOR_TOKENS,
|
|
289
|
+
shadcnIconClasses,
|
|
290
|
+
headlessTransitions,
|
|
291
|
+
iconButtonPresets
|
|
292
|
+
};
|
|
293
|
+
export {
|
|
294
|
+
SHADCN_COLOR_TOKENS,
|
|
295
|
+
SHADCN_ICON_SIZES,
|
|
296
|
+
Slot,
|
|
297
|
+
createHeadlessIcon,
|
|
298
|
+
createRadixIcon,
|
|
299
|
+
headlessUi as default,
|
|
300
|
+
forwardRefIcon,
|
|
301
|
+
getIconClassName,
|
|
302
|
+
getShadcnIconProps,
|
|
303
|
+
headlessTransitions,
|
|
304
|
+
iconButtonPresets,
|
|
305
|
+
mergeIconProps,
|
|
306
|
+
shadcnIconClasses,
|
|
307
|
+
withRadixState
|
|
417
308
|
};
|
|
418
|
-
|
|
419
|
-
export { SHADCN_COLOR_TOKENS, SHADCN_ICON_SIZES, Slot, createHeadlessIcon, createRadixIcon, headlessUi as default, forwardRefIcon, getIconClassName, getShadcnIconProps, headlessTransitions, iconButtonPresets, mergeIconProps, shadcnIconClasses, withRadixState };
|