@nice2dev/icons 1.2.0 → 1.2.1

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 (107) hide show
  1. package/CHANGELOG.md +103 -0
  2. package/dist/cjs/NiceDesktopIconExporter.js +2 -6
  3. package/dist/cjs/NiceFaviconGenerator.js +2 -1
  4. package/dist/cjs/NiceIconPicker.js +15 -20
  5. package/dist/cjs/NiceIconSetCreator.js +6 -29
  6. package/dist/cjs/NtdIconBadge.js +12 -12
  7. package/dist/cjs/NtdIconMorph.js +21 -11
  8. package/dist/cjs/NtdStateMorph.js +3 -3
  9. package/dist/cjs/animationControls.js +10 -3
  10. package/dist/cjs/createIcon.js +5 -2
  11. package/dist/cjs/headless-ui.js +3 -3
  12. package/dist/cjs/iconStyles.js +36 -34
  13. package/dist/cjs/icons/accessibility.js +13 -13
  14. package/dist/cjs/icons/actions.js +37 -25
  15. package/dist/cjs/icons/ai.js +15 -15
  16. package/dist/cjs/icons/brand.js +7 -7
  17. package/dist/cjs/icons/business.js +18 -81
  18. package/dist/cjs/icons/devtech.js +31 -103
  19. package/dist/cjs/icons/ecommerce.js +16 -16
  20. package/dist/cjs/icons/education.js +17 -17
  21. package/dist/cjs/icons/files.js +31 -31
  22. package/dist/cjs/icons/fintech.js +14 -14
  23. package/dist/cjs/icons/food.js +16 -16
  24. package/dist/cjs/icons/fun.js +13 -13
  25. package/dist/cjs/icons/gaming.js +15 -15
  26. package/dist/cjs/icons/health.js +13 -22
  27. package/dist/cjs/icons/index.js +4 -0
  28. package/dist/cjs/icons/legal.js +13 -13
  29. package/dist/cjs/icons/media.js +46 -23
  30. package/dist/cjs/icons/navigation.js +14 -14
  31. package/dist/cjs/icons/omniverk.js +10 -10
  32. package/dist/cjs/icons/realestate.js +17 -17
  33. package/dist/cjs/icons/saas.js +13 -13
  34. package/dist/cjs/icons/science.js +16 -16
  35. package/dist/cjs/icons/shapes.js +22 -22
  36. package/dist/cjs/icons/smarthome.js +13 -13
  37. package/dist/cjs/icons/social.js +8 -98
  38. package/dist/cjs/icons/sports.js +14 -14
  39. package/dist/cjs/icons/sustainability.js +15 -15
  40. package/dist/cjs/icons/travel.js +15 -15
  41. package/dist/cjs/icons/ui.js +39 -28
  42. package/dist/cjs/icons/weather.js +20 -20
  43. package/dist/cjs/index.js +4 -0
  44. package/dist/cjs/lottieIntegration.js +3 -3
  45. package/dist/cjs/nicetodev-icons.css +1 -1
  46. package/dist/cjs/particleEffects.js +11 -4
  47. package/dist/cjs/resolver.js +4 -0
  48. package/dist/esm/NiceDesktopIconExporter.js +2 -6
  49. package/dist/esm/NiceFaviconGenerator.js +2 -1
  50. package/dist/esm/NiceIconPicker.js +16 -21
  51. package/dist/esm/NiceIconSetCreator.js +6 -29
  52. package/dist/esm/NtdIconBadge.js +12 -12
  53. package/dist/esm/NtdIconMorph.js +21 -11
  54. package/dist/esm/NtdStateMorph.js +3 -3
  55. package/dist/esm/animationControls.js +11 -4
  56. package/dist/esm/createIcon.js +6 -3
  57. package/dist/esm/headless-ui.js +3 -3
  58. package/dist/esm/iconStyles.js +36 -34
  59. package/dist/esm/icons/accessibility.js +13 -13
  60. package/dist/esm/icons/actions.js +37 -26
  61. package/dist/esm/icons/ai.js +15 -15
  62. package/dist/esm/icons/brand.js +7 -7
  63. package/dist/esm/icons/business.js +18 -81
  64. package/dist/esm/icons/devtech.js +31 -103
  65. package/dist/esm/icons/ecommerce.js +16 -16
  66. package/dist/esm/icons/education.js +17 -17
  67. package/dist/esm/icons/files.js +31 -31
  68. package/dist/esm/icons/fintech.js +14 -14
  69. package/dist/esm/icons/food.js +16 -16
  70. package/dist/esm/icons/fun.js +13 -13
  71. package/dist/esm/icons/gaming.js +15 -15
  72. package/dist/esm/icons/health.js +13 -22
  73. package/dist/esm/icons/index.js +3 -3
  74. package/dist/esm/icons/legal.js +13 -13
  75. package/dist/esm/icons/media.js +45 -24
  76. package/dist/esm/icons/navigation.js +14 -14
  77. package/dist/esm/icons/omniverk.js +10 -10
  78. package/dist/esm/icons/realestate.js +17 -17
  79. package/dist/esm/icons/saas.js +13 -13
  80. package/dist/esm/icons/science.js +16 -16
  81. package/dist/esm/icons/shapes.js +22 -22
  82. package/dist/esm/icons/smarthome.js +13 -13
  83. package/dist/esm/icons/social.js +8 -98
  84. package/dist/esm/icons/sports.js +14 -14
  85. package/dist/esm/icons/sustainability.js +15 -15
  86. package/dist/esm/icons/travel.js +15 -15
  87. package/dist/esm/icons/ui.js +39 -29
  88. package/dist/esm/icons/weather.js +20 -20
  89. package/dist/esm/index.js +3 -3
  90. package/dist/esm/lottieIntegration.js +3 -3
  91. package/dist/esm/nicetodev-icons.css +1 -1
  92. package/dist/esm/particleEffects.js +11 -4
  93. package/dist/esm/resolver.js +4 -0
  94. package/dist/esm/smilAnimations.js +1 -1
  95. package/dist/types/NiceDesktopIconExporter.d.ts +1 -0
  96. package/dist/types/NtdIconBadge.d.ts +12 -4
  97. package/dist/types/NtdIconMorph.d.ts +9 -3
  98. package/dist/types/NtdStateMorph.d.ts +3 -1
  99. package/dist/types/headless-ui.d.ts +6 -2
  100. package/dist/types/iconStyles.d.ts +33 -11
  101. package/dist/types/icons/actions.d.ts +1 -0
  102. package/dist/types/icons/index.d.ts +3 -3
  103. package/dist/types/icons/media.d.ts +3 -0
  104. package/dist/types/icons/ui.d.ts +2 -0
  105. package/dist/types/lottieIntegration.d.ts +3 -1
  106. package/dist/types/particleEffects.d.ts +3 -1
  107. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,108 @@
1
1
  # @nice2dev/icons — Changelog
2
2
 
3
+ ## 1.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 8c82c30: 1.2.1 — the decisions that waited since 1.2.0, and the debts the CI gates were holding. One API
8
+ change, agreed: `NiceIconSuggestorAI` suggests Nice icons only. Two stylesheets to import if you use
9
+ the packages: `@nice2dev/social/style.css`, `@nice2dev/ui-science/style.css`. Upgrade notes:
10
+ `documentation/omniverk/OMNIVERK_UPGRADE_1.2.1.md`.
11
+
12
+ **Tree-shaking.** An import from a package no longer brings the whole package. Module-level
13
+ statements that may have a side effect — a `displayName` assigned after each component (now
14
+ `Object.assign` inside `/* @__PURE__ */`, or under a development check for plain functions),
15
+ unannotated `forwardRef` / `memo` / `createContext` / icon-factory calls, spreads, registries filled
16
+ at import, `<style>` tags injected at import, a direct `eval` in ui-math — are gone. One import from
17
+ each of 53 packages: 5066.5 kB → 1171.6 kB (`@nice2dev/ui` 1928.2 kB → 12.9 kB, icon packs 48–275 kB
18
+ → 1.6–2.6 kB). `defaultViewRegistry` has the Nice\* input controls from the start, each loading its
19
+ module on first render; sixteen controls add their styles to `<head>` on first render.
20
+
21
+ **Dead code.** 405 source files no entry point imported (never on npm) are deleted;
22
+ `NiceClipboardStack` (`@nice2dev/ui`) and `NiceSampleBrowser` (`@nice2dev/ui-audio`), finished and
23
+ documented, are exported.
24
+
25
+ **ui-mobile draws Nice icons.** New peer `@nice2dev/icons ^1.2.0`; `TabIcons`, `DrawerIcons`,
26
+ `HeaderIcons`, the `NiceSwipeActions` presets and the `NiceInfiniteScroll` states are `Ntd*` icons
27
+ instead of pasted `<svg>`, simple glyphs are CSS marks. `@nice2dev/icons` adds `NtdReply` and
28
+ `NtdInbox`; an icon no longer throws without `window.matchMedia`.
29
+
30
+ **`NiceIconSuggestorAI` (breaking, agreed).** `AIIconLibrary` is `'nice'`; `svgPath` and `unicode`
31
+ left `AISuggestedIcon`; the preview is a `<NiceIcon>`, "Copy SVG" is "Copy JSX".
32
+
33
+ **Peer ranges.** Every internal `@nice2dev/*` peer is `^1.2.0` (was as wide as `^1.0.20`), except
34
+ `@nice2dev/icons ^1.2.1` where a package draws an icon new in 1.2.1: ui-mobile (`NtdReply`,
35
+ `NtdInbox`), ui-audio (`NtdMicrophoneOff`) and ui-security (`NtdBackspace`). ui-security, licensing
36
+ (`^1.2.0`) and templates (`^1.2.0`) gain the `@nice2dev/icons` peer: their glyph icons (`⌫`, `←`,
37
+ `→`, `↑`, `↓`) are Nice icons now. `@nice2dev/icons` adds `NtdBackspace`.
38
+
39
+ **Class names inside components.** 834 class names in library stylesheets had no `nice-` prefix
40
+ (`.tab-button`, `.status-badge`, `.selected`, …) and styled every element of that name on the page.
41
+ They follow `nice-{block}__{element}--{modifier}` now — no change on screen. The class theme hooks
42
+ next to `[data-theme]` on seven controls (`dark` on the AI chart / data grid / code and HTML
43
+ editors / form builder, `light-theme` on `NiceMAM` and `NiceVideoAnnotator`) are `nice-dark` /
44
+ `nice-light`; `NiceLowPowerMode` marks `<html>` with `nice-lpm-no-animations` /
45
+ `nice-lpm-reduced-quality`; the `NiceVideoEditor` of `@nice2dev/ui-video` styles its elements under
46
+ `nice-video-studio`, so they no longer collide with the `NiceVideoEditor` of `@nice2dev/ui`.
47
+ Rules for classes nothing rendered are gone, among them the stylesheet of `NiceGanttChart`, which
48
+ left ui-erp in 1.0.10.
49
+
50
+ **Translations.** About 3,400 UI texts in 32 packages were hard-coded; they go through `t()` now,
51
+ with the English text unchanged and pl / de / fr / es / uk in `@nice2dev/i18n` (ui-diagrams,
52
+ ui-presentations and ui-math in their own dictionaries). In `@nice2dev/events` and
53
+ `@nice2dev/admin` that includes column headers, option labels and the statuses and roles they used
54
+ to print raw (`checked-in`, `no-show`) — English labels for those come from the dictionary. ui-3d and ui-graphics read the app's
55
+ global translator, as ui-audio does since 1.2.0 — their own provider overrides it. ui-audio's
56
+ controls used 631 keys the dictionary did not have (English in every language), and the radio
57
+ player showed raw keys (`search_stations`). Texts that were hard-coded **in Polish** — in
58
+ `NiceSidebarNav`, `NiceNetworkDiscoveryPanel`, the backup and smart-home controls,
59
+ `NiceSavedQueryPanel`, `NiceNotificationPreferences`, the ui-buildings panels, the ui-printing
60
+ template editor and the photo editor — default to English now; Polish is in the dictionary. English
61
+ plurals glued on (`result{s}`) are two keys. `presentationsTranslator(lang)` (ui-presentations)
62
+ translates outside its provider.
63
+
64
+ **List props are optional.** 170 list props (`items`, `columns`, `data`, …) in 15 packages that
65
+ were required without a default are optional, with a stable empty default; every one of those
66
+ controls mounts without data (tested). `NiceStockChart` without data no longer computes NaN
67
+ coordinates.
68
+
69
+ **Unstyled components get stylesheets.** 98 components rendered class names no stylesheet had —
70
+ admin panels, auth forms, events rounds and pickers, the ERP invoice / purchase order / VAT table /
71
+ HR dashboard, the radio player, `NiceInbox`, PWA prompts, `NiceViewRenderer`, shells, smart-home,
72
+ … The fixed layout that sat in inline style objects is in classes now, so an app can override it;
73
+ values that depend on data stay inline. **`@nice2dev/social` and `@nice2dev/ui-science` ship a
74
+ stylesheet — import `@nice2dev/social/style.css` / `@nice2dev/ui-science/style.css`.** ui-science's
75
+ `sideEffects` is `["*.css"]`. Colours, spacing and radii in every stylesheet come from theme tokens
76
+ (visible in dark themes: `NiceRecipe` difficulty badges, transcoder states, warehouse heat map).
77
+
78
+ **Icons only from Nice.** About 130 glyphs (`×`, `→`, `↑`) and 100 pasted `<svg>` used as icons
79
+ are Nice icons; 11 `<svg>` stay as the control's own graphic (logos, spinners, checkbox mark). `NiceIcon`
80
+ gains `pin`, `mic-off`, `log-out`, `chevrons-left`, `chevrons-right`, `zoom-in`, `zoom-out`,
81
+ `navigation`, `refresh-ccw`, `minimize` and `smartphone`; `@nice2dev/icons` gains
82
+ `NtdMicrophoneOff`. The `icon` fields of the module, menu, tab, mode, quick-action, scene and admin
83
+ widget DTOs, notification channels and view toolbar items are rendered through `NiceIcon` — they
84
+ used to be printed as text. `NiceRatings` `thumbs` draws shapes instead of emoji.
85
+
86
+ **Dialogs instead of `window.prompt` / `confirm` / `alert`.** New `useNiceDialogs()` — `prompt`,
87
+ `confirm` and `alert` as promises on `NicePromptDialog` / `NiceConfirmDialog` — and
88
+ `NiceConfirmDialog.showReject`. Seventeen controls asked through the browser's blocking dialogs and
89
+ use the library's now (`NiceFileManager`, `NiceHtmlEditor`, `NiceViewRenderer` action `confirm`, the 3D,
90
+ vector and pixel editors, …). Keys pressed in `NicePromptDialog` / `NiceConfirmDialog` no longer
91
+ reach the page's shortcuts (Escape still closes them), and `NicePromptDialog`'s backdrop covers the
92
+ whole viewport.
93
+
94
+ **Smaller fixes.** `NiceFileManager.items` is optional. `NiceMLStudio` status badges: `draft`,
95
+ `registered`, `archived`, `cancelled` get a neutral colour, deploying / stopped deployments theirs.
96
+ Component docs (`doc.json`) list only props the components have. `NiceMobileTabs`: tabs beyond
97
+ `maxTabs` open from "More" (it only logged). `NiceInventoryManager`: new `onCreatePurchaseOrder`;
98
+ without it the "Create PO" button is gone (it only logged). Keyboard: `NiceNavShell` tabs follow the
99
+ WAI-ARIA tabs pattern, clickable `NiceDeviceTile` / `NiceCardGroup` cards and animated icons with
100
+ `trigger="click"` are focusable. ui-math: `CalculatorService.evaluate` parses instead of running
101
+ `new Function` (`asin`, `sinh`, `ceil`, exponents and `angleUnit` were wrong); `ExpressionParser`
102
+ takes `functions`, `constants`, `ignoreCase` and `strict`, multiplies implicitly (`2x`) and reads `^`
103
+ right to left. `InvoiceLine.vatRate` and `VatRate.rate` are documented as fractions (0.23).
104
+ `AmqpServerBinding` is `Record<string, never>`.
105
+
3
106
  ## 1.2.0
4
107
 
5
108
  ### Minor Changes
@@ -632,14 +632,10 @@ const NiceDesktopIconExporter = ({ icon, initialConfig, onExport, className = ''
632
632
  onExport === null || onExport === void 0 ? void 0 : onExport(icons);
633
633
  };
634
634
  const IconComponent = icon;
635
- return (jsxRuntime.jsxs("div", { className: `nice-desktop-icon-exporter ${className}`, children: [jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__preview", children: [jsxRuntime.jsx("h3", { children: "Preview" }), jsxRuntime.jsx("div", { className: "nice-desktop-icon-exporter__preview-grid", children: [16, 32, 48, 64, 128, 256].map((size) => (jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__preview-item", children: [jsxRuntime.jsx("div", { style: {
635
+ return (jsxRuntime.jsxs("div", { className: `nice-desktop-icon-exporter ${className}`, children: [jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__preview", children: [jsxRuntime.jsx("h3", { children: "Preview" }), jsxRuntime.jsx("div", { className: "nice-desktop-icon-exporter__preview-grid", children: [16, 32, 48, 64, 128, 256].map((size) => (jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__preview-item", children: [jsxRuntime.jsx("div", { className: "nice-desktop-icon-exporter__preview-box", style: {
636
636
  width: Math.min(size, 128),
637
637
  height: Math.min(size, 128),
638
638
  backgroundColor: config.backgroundColor || '#f0f0f0',
639
- display: 'flex',
640
- alignItems: 'center',
641
- justifyContent: 'center',
642
- borderRadius: 4,
643
639
  }, children: jsxRuntime.jsx(IconComponent, { size: Math.min(size, 128) * (1 - config.padding * 2), fill: config.fillColor }) }), jsxRuntime.jsxs("span", { children: [size, "\u00D7", size] })] }, size))) })] }), jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__config", children: [jsxRuntime.jsx("h3", { children: "Configuration" }), jsxRuntime.jsxs("label", { children: ["Icon Name:", jsxRuntime.jsx("input", { type: "text", value: config.name, onChange: (e) => setConfig((c) => ({ ...c, name: e.target.value })) })] }), jsxRuntime.jsxs("label", { children: ["Fill Color:", jsxRuntime.jsx("input", { type: "color", value: config.fillColor, onChange: (e) => setConfig((c) => ({ ...c, fillColor: e.target.value })) })] }), jsxRuntime.jsxs("label", { children: ["Background:", jsxRuntime.jsx("input", { type: "color", value: config.backgroundColor || '#ffffff', onChange: (e) => setConfig((c) => ({ ...c, backgroundColor: e.target.value })) }), jsxRuntime.jsx("button", { onClick: () => setConfig((c) => ({ ...c, backgroundColor: undefined })), children: "Transparent" })] }), jsxRuntime.jsxs("label", { children: ["Padding: ", Math.round(config.padding * 100), "%", jsxRuntime.jsx("input", { type: "range", min: "0", max: "0.3", step: "0.01", value: config.padding, onChange: (e) => setConfig((c) => ({ ...c, padding: parseFloat(e.target.value) })) })] }), jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__platforms", children: [jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.includeWindows, onChange: (e) => setConfig((c) => ({ ...c, includeWindows: e.target.checked })) }), "Windows (.ico)"] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.includeMacOS, onChange: (e) => setConfig((c) => ({ ...c, includeMacOS: e.target.checked })) }), "macOS (.iconset)"] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.includeLinux, onChange: (e) => setConfig((c) => ({ ...c, includeLinux: e.target.checked })) }), "Linux (hicolor)"] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.includeRetina, onChange: (e) => setConfig((c) => ({ ...c, includeRetina: e.target.checked })) }), "HiDPI/Retina (@2x, @3x)"] })] }), jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__sizes", children: [jsxRuntime.jsx("h4", { children: "Sizes:" }), DESKTOP_ICON_SIZES.map(({ size, label }) => (jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.sizes.includes(size), onChange: (e) => {
644
640
  setConfig((c) => ({
645
641
  ...c,
@@ -647,7 +643,7 @@ const NiceDesktopIconExporter = ({ icon, initialConfig, onExport, className = ''
647
643
  ? [...c.sizes, size].sort((a, b) => a - b)
648
644
  : c.sizes.filter((s) => s !== size),
649
645
  }));
650
- } }), label] }, size)))] })] }), jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__actions", children: [jsxRuntime.jsx("button", { onClick: handleExport, disabled: isExporting, children: isExporting ? `Exporting... ${Math.round(progress)}%` : 'Generate Icons' }), jsxRuntime.jsx("button", { onClick: downloadAll, disabled: isExporting || icons.length === 0, children: "Download All (ZIP)" })] }), icons.length > 0 && (jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__results", children: [jsxRuntime.jsxs("h3", { children: ["Generated Icons (", icons.length, ")"] }), jsxRuntime.jsx("div", { className: "nice-desktop-icon-exporter__results-grid", children: icons.map((exportedIcon) => (jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__result-item", children: [jsxRuntime.jsx("img", { src: exportedIcon.dataUrl, alt: exportedIcon.filename, style: { maxWidth: 64, maxHeight: 64 } }), jsxRuntime.jsx("span", { children: exportedIcon.filename }), jsxRuntime.jsx("button", { onClick: () => downloadSingle(exportedIcon), children: "Download" })] }, exportedIcon.filename))) })] }))] }));
646
+ } }), label] }, size)))] })] }), jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__actions", children: [jsxRuntime.jsx("button", { onClick: handleExport, disabled: isExporting, children: isExporting ? `Exporting... ${Math.round(progress)}%` : 'Generate Icons' }), jsxRuntime.jsx("button", { onClick: downloadAll, disabled: isExporting || icons.length === 0, children: "Download All (ZIP)" })] }), icons.length > 0 && (jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__results", children: [jsxRuntime.jsxs("h3", { children: ["Generated Icons (", icons.length, ")"] }), jsxRuntime.jsx("div", { className: "nice-desktop-icon-exporter__results-grid", children: icons.map((exportedIcon) => (jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__result-item", children: [jsxRuntime.jsx("img", { src: exportedIcon.dataUrl, alt: exportedIcon.filename }), jsxRuntime.jsx("span", { children: exportedIcon.filename }), jsxRuntime.jsx("button", { onClick: () => downloadSingle(exportedIcon), children: "Download" })] }, exportedIcon.filename))) })] }))] }));
651
647
  };
652
648
 
653
649
  exports.DESKTOP_ICON_SIZES = DESKTOP_ICON_SIZES;
@@ -2,6 +2,7 @@
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var React = require('react');
5
+ var actions = require('./icons/actions.js');
5
6
 
6
7
  /* ══════════════════════════════════════════════════════════════════════════════
7
8
  Constants
@@ -235,7 +236,7 @@ function NiceFaviconGenerator({ icon, fill = '#1e1e1e', manifestConfig, onGenera
235
236
  return (jsxRuntime.jsxs("div", { className: `nice-favicon-generator ${className}`, style: styles.container, children: [jsxRuntime.jsxs("div", { style: styles.section, children: [jsxRuntime.jsx("h3", { style: styles.sectionTitle, children: "Manifest Configuration" }), jsxRuntime.jsxs("div", { style: styles.formGrid, children: [jsxRuntime.jsxs("div", { style: styles.formGroup, children: [jsxRuntime.jsx("label", { style: styles.label, children: "App Name" }), jsxRuntime.jsx("input", { type: "text", value: config.name, onChange: (e) => setConfig((c) => ({ ...c, name: e.target.value })), style: styles.input })] }), jsxRuntime.jsxs("div", { style: styles.formGroup, children: [jsxRuntime.jsx("label", { style: styles.label, children: "Short Name" }), jsxRuntime.jsx("input", { type: "text", value: config.shortName, onChange: (e) => setConfig((c) => ({ ...c, shortName: e.target.value })), style: styles.input })] }), jsxRuntime.jsxs("div", { style: styles.formGroup, children: [jsxRuntime.jsx("label", { style: styles.label, children: "Theme Color" }), jsxRuntime.jsx("input", { type: "color", value: config.themeColor, onChange: (e) => setConfig((c) => ({ ...c, themeColor: e.target.value })), style: styles.colorInput })] }), jsxRuntime.jsxs("div", { style: styles.formGroup, children: [jsxRuntime.jsx("label", { style: styles.label, children: "Background Color" }), jsxRuntime.jsx("input", { type: "color", value: config.backgroundColor, onChange: (e) => setConfig((c) => ({ ...c, backgroundColor: e.target.value })), style: styles.colorInput })] }), jsxRuntime.jsxs("div", { style: styles.formGroup, children: [jsxRuntime.jsx("label", { style: styles.label, children: "Display Mode" }), jsxRuntime.jsxs("select", { value: config.display, onChange: (e) => setConfig((c) => ({ ...c, display: e.target.value })), style: styles.input, children: [jsxRuntime.jsx("option", { value: "standalone", children: "Standalone" }), jsxRuntime.jsx("option", { value: "fullscreen", children: "Fullscreen" }), jsxRuntime.jsx("option", { value: "minimal-ui", children: "Minimal UI" }), jsxRuntime.jsx("option", { value: "browser", children: "Browser" })] })] }), jsxRuntime.jsxs("div", { style: styles.formGroup, children: [jsxRuntime.jsx("label", { style: styles.label, children: "Start URL" }), jsxRuntime.jsx("input", { type: "text", value: config.startUrl, onChange: (e) => setConfig((c) => ({ ...c, startUrl: e.target.value })), style: styles.input })] })] })] }), jsxRuntime.jsxs("div", { style: styles.actions, children: [jsxRuntime.jsx("button", { onClick: handleGenerate, disabled: isGenerating, style: {
236
237
  ...styles.button,
237
238
  ...(isGenerating ? styles.buttonDisabled : styles.buttonPrimary),
238
- }, children: isGenerating ? 'Generating...' : 'Generate Favicons' }), assets.length > 0 && (jsxRuntime.jsx("button", { onClick: downloadAll, style: { ...styles.button, ...styles.buttonSecondary }, children: "Download All" }))] }), assets.length > 0 && (jsxRuntime.jsxs("div", { style: styles.section, children: [jsxRuntime.jsxs("div", { style: styles.tabs, children: [jsxRuntime.jsx("button", { style: { ...styles.tab, ...(activeTab === 'preview' ? styles.tabActive : {}) }, onClick: () => setActiveTab('preview'), children: "Preview" }), jsxRuntime.jsx("button", { style: { ...styles.tab, ...(activeTab === 'manifest' ? styles.tabActive : {}) }, onClick: () => setActiveTab('manifest'), children: "manifest.json" }), jsxRuntime.jsx("button", { style: { ...styles.tab, ...(activeTab === 'html' ? styles.tabActive : {}) }, onClick: () => setActiveTab('html'), children: "HTML Tags" })] }), activeTab === 'preview' && (jsxRuntime.jsx("div", { style: styles.assetGrid, children: assets.map((asset) => (jsxRuntime.jsxs("div", { style: styles.assetCard, children: [jsxRuntime.jsx("div", { style: styles.assetPreview, children: jsxRuntime.jsx("img", { src: asset.dataUrl, alt: asset.filename, style: { maxWidth: '64px', maxHeight: '64px' } }) }), jsxRuntime.jsxs("div", { style: styles.assetInfo, children: [jsxRuntime.jsx("span", { style: styles.assetName, children: asset.filename }), jsxRuntime.jsxs("span", { style: styles.assetSize, children: [asset.size, "x", asset.size] }), jsxRuntime.jsx("span", { style: styles.assetPurpose, children: asset.purpose })] }), jsxRuntime.jsx("button", { onClick: () => downloadSingle(asset), style: styles.downloadBtn, children: "\u2193" })] }, asset.filename))) })), activeTab === 'manifest' && jsxRuntime.jsx("pre", { style: styles.codeBlock, children: getManifestJson() }), activeTab === 'html' && jsxRuntime.jsx("pre", { style: styles.codeBlock, children: getHtmlTags() })] })), jsxRuntime.jsxs("div", { style: styles.reference, children: [jsxRuntime.jsx("h4", { style: styles.referenceTitle, children: "Favicon Sizes Reference" }), jsxRuntime.jsxs("table", { style: styles.table, children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [jsxRuntime.jsx("th", { style: styles.th, children: "File" }), jsxRuntime.jsx("th", { style: styles.th, children: "Size" }), jsxRuntime.jsx("th", { style: styles.th, children: "Purpose" })] }) }), jsxRuntime.jsx("tbody", { children: FAVICON_SIZES.map((f) => (jsxRuntime.jsxs("tr", { children: [jsxRuntime.jsxs("td", { style: styles.td, children: [f.name, ".", f.format] }), jsxRuntime.jsxs("td", { style: styles.td, children: [f.size, "x", f.size] }), jsxRuntime.jsx("td", { style: styles.td, children: f.purpose })] }, f.name))) })] })] })] }));
239
+ }, children: isGenerating ? 'Generating...' : 'Generate Favicons' }), assets.length > 0 && (jsxRuntime.jsx("button", { onClick: downloadAll, style: { ...styles.button, ...styles.buttonSecondary }, children: "Download All" }))] }), assets.length > 0 && (jsxRuntime.jsxs("div", { style: styles.section, children: [jsxRuntime.jsxs("div", { style: styles.tabs, children: [jsxRuntime.jsx("button", { style: { ...styles.tab, ...(activeTab === 'preview' ? styles.tabActive : {}) }, onClick: () => setActiveTab('preview'), children: "Preview" }), jsxRuntime.jsx("button", { style: { ...styles.tab, ...(activeTab === 'manifest' ? styles.tabActive : {}) }, onClick: () => setActiveTab('manifest'), children: "manifest.json" }), jsxRuntime.jsx("button", { style: { ...styles.tab, ...(activeTab === 'html' ? styles.tabActive : {}) }, onClick: () => setActiveTab('html'), children: "HTML Tags" })] }), activeTab === 'preview' && (jsxRuntime.jsx("div", { style: styles.assetGrid, children: assets.map((asset) => (jsxRuntime.jsxs("div", { style: styles.assetCard, children: [jsxRuntime.jsx("div", { style: styles.assetPreview, children: jsxRuntime.jsx("img", { src: asset.dataUrl, alt: asset.filename, style: { maxWidth: '64px', maxHeight: '64px' } }) }), jsxRuntime.jsxs("div", { style: styles.assetInfo, children: [jsxRuntime.jsx("span", { style: styles.assetName, children: asset.filename }), jsxRuntime.jsxs("span", { style: styles.assetSize, children: [asset.size, "x", asset.size] }), jsxRuntime.jsx("span", { style: styles.assetPurpose, children: asset.purpose })] }), jsxRuntime.jsx("button", { onClick: () => downloadSingle(asset), style: styles.downloadBtn, "aria-label": `Download ${asset.filename}`, children: jsxRuntime.jsx(actions.NtdDownload, { size: 14, variant: "outline" }) })] }, asset.filename))) })), activeTab === 'manifest' && jsxRuntime.jsx("pre", { style: styles.codeBlock, children: getManifestJson() }), activeTab === 'html' && jsxRuntime.jsx("pre", { style: styles.codeBlock, children: getHtmlTags() })] })), jsxRuntime.jsxs("div", { style: styles.reference, children: [jsxRuntime.jsx("h4", { style: styles.referenceTitle, children: "Favicon Sizes Reference" }), jsxRuntime.jsxs("table", { style: styles.table, children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [jsxRuntime.jsx("th", { style: styles.th, children: "File" }), jsxRuntime.jsx("th", { style: styles.th, children: "Size" }), jsxRuntime.jsx("th", { style: styles.th, children: "Purpose" })] }) }), jsxRuntime.jsx("tbody", { children: FAVICON_SIZES.map((f) => (jsxRuntime.jsxs("tr", { children: [jsxRuntime.jsxs("td", { style: styles.td, children: [f.name, ".", f.format] }), jsxRuntime.jsxs("td", { style: styles.td, children: [f.size, "x", f.size] }), jsxRuntime.jsx("td", { style: styles.td, children: f.purpose })] }, f.name))) })] })] })] }));
239
240
  }
240
241
  /* ══════════════════════════════════════════════════════════════════════════════
241
242
  Styles
@@ -2,18 +2,19 @@
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var React = require('react');
5
+ var actions = require('./icons/actions.js');
6
+ var files = require('./icons/files.js');
7
+ var media = require('./icons/media.js');
8
+ var navigation = require('./icons/navigation.js');
9
+ var ui = require('./icons/ui.js');
5
10
 
6
11
  const MAX_HISTORY_ITEMS = 20;
7
- /* ─── Chevron SVG ─── */
8
- const Chevron = () => (jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("polyline", { points: "6 9 12 15 18 9" }) }));
9
- /* ─── Search SVG ─── */
10
- const SearchIcon = () => (jsxRuntime.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "8" }), jsxRuntime.jsx("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" })] }));
11
- /* ─── Star SVG (favorites) ─── */
12
- const StarIcon = ({ filled }) => (jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: filled ? 'currentColor' : 'none', stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" }) }));
13
- /* ─── Clock SVG (history) ─── */
14
- const ClockIcon = () => (jsxRuntime.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [jsxRuntime.jsx("circle", { cx: "12", cy: "12", r: "10" }), jsxRuntime.jsx("polyline", { points: "12 6 12 12 16 14" })] }));
15
- /* ─── Check SVG (multi-select) ─── */
16
- const CheckIcon = () => (jsxRuntime.jsx("svg", { width: "10", height: "10", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" }) }));
12
+ /* ─── Small icons: the package's own (until 1.2.0 these were pasted SVGs) ─── */
13
+ const Chevron = () => jsxRuntime.jsx(navigation.NtdChevronDown, { size: 12, variant: "outline" });
14
+ const SearchIcon = () => jsxRuntime.jsx(actions.NtdSearch, { size: 14, variant: "outline" });
15
+ const StarIcon = ({ filled }) => (jsxRuntime.jsx(ui.NtdStar, { size: 12, variant: filled ? 'solid' : 'outline' }));
16
+ const ClockIcon = () => jsxRuntime.jsx(ui.NtdClock, { size: 12, variant: "outline" });
17
+ const CheckIcon = () => jsxRuntime.jsx(actions.NtdCheck, { size: 10, variant: "outline" });
17
18
  /* ─── localStorage helpers ─── */
18
19
  function loadFromStorage(key, fallback) {
19
20
  if (typeof window === 'undefined') {
@@ -70,7 +71,7 @@ function saveToStorage(key, value) {
70
71
  * }
71
72
  * ```
72
73
  */
73
- const NiceIconPicker = React.forwardRef(function NiceIconPicker({ icons, value = null, values = [], onChange, onChangeMulti, multiSelect = false, maxSelections, placeholder = 'Select icon…', variant = 'solid', gridIconSize = 'md', triggerIconSize = 'sm', categories: categoriesProp, className, disabled = false, clearable = true, virtualized = false, virtualizedItemCount = 100, showHistory = false, showFavorites = false, storageKeyPrefix = 'ntd-icon-picker', enableDragAndDrop = false, onDragStart, onDragEnd, }, ref) {
74
+ const NiceIconPicker = /* @__PURE__ */ React.forwardRef(function NiceIconPicker({ icons, value = null, values = [], onChange, onChangeMulti, multiSelect = false, maxSelections, placeholder = 'Select icon…', variant = 'solid', gridIconSize = 'md', triggerIconSize = 'sm', categories: categoriesProp, className, disabled = false, clearable = true, virtualized = false, virtualizedItemCount = 100, showHistory = false, showFavorites = false, storageKeyPrefix = 'ntd-icon-picker', enableDragAndDrop = false, onDragStart, onDragEnd, }, ref) {
74
75
  var _a;
75
76
  const [isOpen, setIsOpen] = React.useState(false);
76
77
  const [search, setSearch] = React.useState('');
@@ -85,13 +86,7 @@ const NiceIconPicker = React.forwardRef(function NiceIconPicker({ icons, value =
85
86
  const [history, setHistory] = React.useState(() => loadFromStorage(historyKey, []));
86
87
  // Multi-select state (internal when uncontrolled)
87
88
  const [internalValues, setInternalValues] = React.useState([]);
88
- const selectedValues = multiSelect
89
- ? values.length > 0
90
- ? values
91
- : internalValues
92
- : value
93
- ? [value]
94
- : [];
89
+ const selectedValues = React.useMemo(() => (multiSelect ? (values.length > 0 ? values : internalValues) : value ? [value] : []), [multiSelect, values, internalValues, value]);
95
90
  const rootRef = React.useRef(null);
96
91
  const searchInputRef = React.useRef(null);
97
92
  /* ─── Favorites helpers ─── */
@@ -397,14 +392,14 @@ const NiceIconPicker = React.forwardRef(function NiceIconPicker({ icons, value =
397
392
  }
398
393
  return selectedEntry ? readableName(selectedEntry.name) : placeholder;
399
394
  }, [multiSelect, selectedEntries, selectedEntry, placeholder]);
400
- return (jsxRuntime.jsxs("div", { ref: rootRef, className: `ntd-picker${isOpen ? ' open' : ''}${disabled ? ' disabled' : ''}${multiSelect ? ' multi' : ''}${className ? ` ${className}` : ''}`, children: [jsxRuntime.jsxs("button", { type: "button", className: "ntd-picker-trigger", onClick: handleToggle, disabled: disabled, "aria-haspopup": "listbox", "aria-expanded": isOpen, children: [jsxRuntime.jsx("span", { className: "ntd-picker-trigger-icon", children: selectedEntry ? (jsxRuntime.jsx(selectedEntry.Component, { size: triggerIconSize, variant: variant })) : multiSelect && selectedEntries.length > 1 ? (jsxRuntime.jsx("span", { className: "ntd-picker-multi-badge", children: selectedEntries.length })) : (jsxRuntime.jsxs("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", children: [jsxRuntime.jsx("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }), jsxRuntime.jsx("rect", { x: "14", y: "3", width: "7", height: "7", rx: "1" }), jsxRuntime.jsx("rect", { x: "3", y: "14", width: "7", height: "7", rx: "1" }), jsxRuntime.jsx("rect", { x: "14", y: "14", width: "7", height: "7", rx: "1" })] })) }), jsxRuntime.jsx("span", { className: `ntd-picker-trigger-label${!selectedEntry && selectedEntries.length === 0 ? ' ntd-picker-trigger-placeholder' : ''}`, children: triggerLabel }), jsxRuntime.jsx("span", { className: "ntd-picker-trigger-chevron", children: jsxRuntime.jsx(Chevron, {}) })] }), isOpen && (jsxRuntime.jsxs("div", { className: "ntd-picker-dropdown", role: "listbox", children: [jsxRuntime.jsxs("div", { className: "ntd-picker-search", children: [jsxRuntime.jsx("span", { className: "ntd-picker-search-icon", children: jsxRuntime.jsx(SearchIcon, {}) }), jsxRuntime.jsx("input", { ref: searchInputRef, type: "text", placeholder: "Search icons\u2026", value: search, onChange: (e) => setSearch(e.target.value), "aria-label": "Search icons" })] }), (allCategories.length > 1 || showFavorites || showHistory) && (jsxRuntime.jsxs("div", { className: "ntd-picker-tabs", role: "tablist", children: [jsxRuntime.jsx("button", { type: "button", className: `ntd-picker-tab${activeCategory === null ? ' active' : ''}`, onClick: () => setActiveCategory(null), role: "tab", "aria-selected": activeCategory === null, children: "All" }), showFavorites && (jsxRuntime.jsxs("button", { type: "button", className: `ntd-picker-tab ntd-picker-tab-special${activeCategory === '__favorites__' ? ' active' : ''}`, onClick: () => setActiveCategory('__favorites__'), role: "tab", "aria-selected": activeCategory === '__favorites__', title: "Favorites", children: [jsxRuntime.jsx(StarIcon, { filled: true }), " Favorites", favorites.length > 0 && (jsxRuntime.jsx("span", { className: "ntd-picker-tab-count", children: favorites.length }))] })), showHistory && history.length > 0 && (jsxRuntime.jsxs("button", { type: "button", className: `ntd-picker-tab ntd-picker-tab-special${activeCategory === '__history__' ? ' active' : ''}`, onClick: () => setActiveCategory('__history__'), role: "tab", "aria-selected": activeCategory === '__history__', title: "Recently used", children: [jsxRuntime.jsx(ClockIcon, {}), " Recent"] })), allCategories.map((cat) => (jsxRuntime.jsx("button", { type: "button", className: `ntd-picker-tab${activeCategory === cat ? ' active' : ''}`, onClick: () => setActiveCategory(cat), role: "tab", "aria-selected": activeCategory === cat, children: cat }, cat)))] })), jsxRuntime.jsx("div", { className: "ntd-picker-grid-wrap", ref: gridWrapRef, children: filtered.length === 0 ? (jsxRuntime.jsxs("div", { className: "ntd-picker-empty", children: [jsxRuntime.jsx("div", { className: "ntd-picker-empty-icon", children: "\u2205" }), activeCategory === '__favorites__'
395
+ return (jsxRuntime.jsxs("div", { ref: rootRef, className: `ntd-picker${isOpen ? ' ntd-picker--open' : ''}${disabled ? ' ntd-picker--disabled' : ''}${multiSelect ? ' ntd-picker--multi' : ''}${className ? ` ${className}` : ''}`, children: [jsxRuntime.jsxs("button", { type: "button", className: "ntd-picker-trigger", onClick: handleToggle, disabled: disabled, "aria-haspopup": "listbox", "aria-expanded": isOpen, children: [jsxRuntime.jsx("span", { className: "ntd-picker-trigger-icon", children: selectedEntry ? (jsxRuntime.jsx(selectedEntry.Component, { size: triggerIconSize, variant: variant })) : multiSelect && selectedEntries.length > 1 ? (jsxRuntime.jsx("span", { className: "ntd-picker-multi-badge", children: selectedEntries.length })) : (jsxRuntime.jsx(files.NtdGrid, { size: 16, variant: "outline" })) }), jsxRuntime.jsx("span", { className: `ntd-picker-trigger-label${!selectedEntry && selectedEntries.length === 0 ? ' ntd-picker-trigger-placeholder' : ''}`, children: triggerLabel }), jsxRuntime.jsx("span", { className: "ntd-picker-trigger-chevron", children: jsxRuntime.jsx(Chevron, {}) })] }), isOpen && (jsxRuntime.jsxs("div", { className: "ntd-picker-dropdown", role: "listbox", children: [jsxRuntime.jsxs("div", { className: "ntd-picker-search", children: [jsxRuntime.jsx("span", { className: "ntd-picker-search-icon", children: jsxRuntime.jsx(SearchIcon, {}) }), jsxRuntime.jsx("input", { ref: searchInputRef, type: "text", placeholder: "Search icons\u2026", value: search, onChange: (e) => setSearch(e.target.value), "aria-label": "Search icons" })] }), (allCategories.length > 1 || showFavorites || showHistory) && (jsxRuntime.jsxs("div", { className: "ntd-picker-tabs", role: "tablist", children: [jsxRuntime.jsx("button", { type: "button", className: `ntd-picker-tab${activeCategory === null ? ' ntd-picker-tab--active' : ''}`, onClick: () => setActiveCategory(null), role: "tab", "aria-selected": activeCategory === null, children: "All" }), showFavorites && (jsxRuntime.jsxs("button", { type: "button", className: `ntd-picker-tab ntd-picker-tab-special${activeCategory === '__favorites__' ? ' ntd-picker-tab--active' : ''}`, onClick: () => setActiveCategory('__favorites__'), role: "tab", "aria-selected": activeCategory === '__favorites__', title: "Favorites", children: [jsxRuntime.jsx(StarIcon, { filled: true }), " Favorites", favorites.length > 0 && (jsxRuntime.jsx("span", { className: "ntd-picker-tab-count", children: favorites.length }))] })), showHistory && history.length > 0 && (jsxRuntime.jsxs("button", { type: "button", className: `ntd-picker-tab ntd-picker-tab-special${activeCategory === '__history__' ? ' ntd-picker-tab--active' : ''}`, onClick: () => setActiveCategory('__history__'), role: "tab", "aria-selected": activeCategory === '__history__', title: "Recently used", children: [jsxRuntime.jsx(ClockIcon, {}), " Recent"] })), allCategories.map((cat) => (jsxRuntime.jsx("button", { type: "button", className: `ntd-picker-tab${activeCategory === cat ? ' ntd-picker-tab--active' : ''}`, onClick: () => setActiveCategory(cat), role: "tab", "aria-selected": activeCategory === cat, children: cat }, cat)))] })), jsxRuntime.jsx("div", { className: "ntd-picker-grid-wrap", ref: gridWrapRef, children: filtered.length === 0 ? (jsxRuntime.jsxs("div", { className: "ntd-picker-empty", children: [jsxRuntime.jsx("div", { className: "ntd-picker-empty-icon", children: jsxRuntime.jsx(media.NtdInbox, { size: 28, variant: "outline" }) }), activeCategory === '__favorites__'
401
396
  ? 'No favorites yet. Click the star icon to add.'
402
397
  : activeCategory === '__history__'
403
398
  ? 'No recent icons.'
404
399
  : 'No icons found'] })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [virtualized && visibleRange.start > 0 && (jsxRuntime.jsx("div", { style: { height: Math.floor(visibleRange.start / 6) * 48 } })), Array.from(grouped.entries()).map(([category, entries]) => (jsxRuntime.jsxs("div", { children: [!activeCategory && !(activeCategory === null || activeCategory === void 0 ? void 0 : activeCategory.startsWith('__')) && (jsxRuntime.jsx("div", { className: "ntd-picker-category-label", children: category })), jsxRuntime.jsx("div", { className: "ntd-picker-grid", children: entries.map((entry) => {
405
400
  const isSelected = selectedValues.includes(entry.name);
406
401
  const isFavorite = favorites.includes(entry.name);
407
- return (jsxRuntime.jsxs("button", { type: "button", className: `ntd-picker-cell${isSelected ? ' selected' : ''}${multiSelect ? ' multi-select' : ''}${enableDragAndDrop ? ' draggable' : ''}`, onClick: () => handleSelect(entry), "data-name": readableName(entry.name), role: "option", "aria-selected": isSelected, title: readableName(entry.name), draggable: enableDragAndDrop, onDragStart: enableDragAndDrop ? (e) => handleDragStart(entry, e) : undefined, onDragEnd: enableDragAndDrop ? (e) => handleDragEnd(entry, e) : undefined, children: [jsxRuntime.jsx(entry.Component, { size: gridIconSize, variant: variant }), multiSelect && isSelected && (jsxRuntime.jsx("span", { className: "ntd-picker-cell-check", children: jsxRuntime.jsx(CheckIcon, {}) })), showFavorites && (jsxRuntime.jsx("button", { type: "button", className: `ntd-picker-cell-fav${isFavorite ? ' active' : ''}`, onClick: (e) => handleFavoriteClick(e, entry.name), title: isFavorite ? 'Remove from favorites' : 'Add to favorites', children: jsxRuntime.jsx(StarIcon, { filled: isFavorite }) }))] }, entry.name));
402
+ return (jsxRuntime.jsxs("button", { type: "button", className: `ntd-picker-cell${isSelected ? ' ntd-picker-cell--selected' : ''}${multiSelect ? ' ntd-picker-cell--multi-select' : ''}${enableDragAndDrop ? ' ntd-picker-cell--draggable' : ''}`, onClick: () => handleSelect(entry), "data-name": readableName(entry.name), role: "option", "aria-selected": isSelected, title: readableName(entry.name), draggable: enableDragAndDrop, onDragStart: enableDragAndDrop ? (e) => handleDragStart(entry, e) : undefined, onDragEnd: enableDragAndDrop ? (e) => handleDragEnd(entry, e) : undefined, children: [jsxRuntime.jsx(entry.Component, { size: gridIconSize, variant: variant }), multiSelect && isSelected && (jsxRuntime.jsx("span", { className: "ntd-picker-cell-check", children: jsxRuntime.jsx(CheckIcon, {}) })), showFavorites && (jsxRuntime.jsx("button", { type: "button", className: `ntd-picker-cell-fav${isFavorite ? ' ntd-picker-cell-fav--active' : ''}`, onClick: (e) => handleFavoriteClick(e, entry.name), title: isFavorite ? 'Remove from favorites' : 'Add to favorites', children: jsxRuntime.jsx(StarIcon, { filled: isFavorite }) }))] }, entry.name));
408
403
  }) })] }, category))), virtualized && visibleRange.end < filtered.length && (jsxRuntime.jsx("div", { style: { height: Math.ceil((filtered.length - visibleRange.end) / 6) * 48 } }))] })) }), jsxRuntime.jsxs("div", { className: "ntd-picker-footer", children: [jsxRuntime.jsxs("span", { className: "ntd-picker-count", children: [filtered.length, " icon", filtered.length !== 1 ? 's' : '', multiSelect && selectedValues.length > 0 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [" \u2022 ", selectedValues.length, " selected"] })), maxSelections && multiSelect && jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [" (max ", maxSelections, ")"] })] }), clearable && selectedValues.length > 0 && (jsxRuntime.jsxs("button", { type: "button", className: "ntd-picker-clear", onClick: handleClear, children: ["Clear", multiSelect ? ' all' : ' selection'] })), multiSelect && (jsxRuntime.jsx("button", { type: "button", className: "ntd-picker-done", onClick: () => setIsOpen(false), children: "Done" }))] })] }))] }));
409
404
  });
410
405
 
@@ -2,35 +2,7 @@
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var React = require('react');
5
- require('./icons/navigation.js');
6
5
  var actions = require('./icons/actions.js');
7
- require('./icons/ui.js');
8
- require('./icons/sustainability.js');
9
- require('./icons/accessibility.js');
10
- require('./icons/legal.js');
11
- require('./icons/media.js');
12
- require('./icons/files.js');
13
- require('./icons/fun.js');
14
- require('./icons/weather.js');
15
- require('./icons/shapes.js');
16
- require('./icons/business.js');
17
- require('./icons/social.js');
18
- require('./icons/devtech.js');
19
- require('./icons/ecommerce.js');
20
- require('./icons/fintech.js');
21
- require('./icons/saas.js');
22
- require('./icons/smarthome.js');
23
- require('./icons/health.js');
24
- require('./icons/brand.js');
25
- require('./icons/gaming.js');
26
- require('./icons/ai.js');
27
- require('./icons/education.js');
28
- require('./icons/science.js');
29
- require('./icons/realestate.js');
30
- require('./icons/food.js');
31
- require('./icons/travel.js');
32
- require('./icons/sports.js');
33
- require('./icons/omniverk.js');
34
6
 
35
7
  /* ══════════════════════════════════════════════════════════════════════════════
36
8
  Constants
@@ -368,7 +340,12 @@ function NiceIconSetCreator({ icons, initialSelection, defaultConfig, onSelectio
368
340
  URL.revokeObjectURL(url);
369
341
  });
370
342
  }, [creator]);
371
- return (jsxRuntime.jsxs("div", { className: `nice-icon-set-creator ${className}`, style: styles.container, children: [jsxRuntime.jsxs("div", { style: styles.header, children: [jsxRuntime.jsx("h2", { style: styles.title, children: "Icon Set Creator" }), jsxRuntime.jsxs("div", { style: styles.stats, children: [creator.selectedCount, " / ", creator.items.length, " icons selected"] })] }), jsxRuntime.jsxs("div", { style: styles.content, children: [jsxRuntime.jsxs("div", { style: styles.configPanel, children: [jsxRuntime.jsx("h3", { style: styles.sectionTitle, children: "Configuration" }), jsxRuntime.jsxs("div", { style: styles.field, children: [jsxRuntime.jsx("label", { style: styles.fieldLabel, children: "Set Name" }), jsxRuntime.jsx("input", { type: "text", value: creator.config.name, onChange: (e) => creator.updateConfig({ name: e.target.value }), style: styles.input, placeholder: "MyIcons" })] }), jsxRuntime.jsxs("div", { style: styles.field, children: [jsxRuntime.jsx("label", { style: styles.fieldLabel, children: "Package Name" }), jsxRuntime.jsx("input", { type: "text", value: creator.config.packageName, onChange: (e) => creator.updateConfig({ packageName: e.target.value }), style: styles.input, placeholder: "@myproject/icons" })] }), jsxRuntime.jsxs("div", { style: styles.field, children: [jsxRuntime.jsx("label", { style: styles.fieldLabel, children: "Description" }), jsxRuntime.jsx("input", { type: "text", value: creator.config.description, onChange: (e) => creator.updateConfig({ description: e.target.value }), style: styles.input })] }), jsxRuntime.jsxs("div", { style: styles.fieldRow, children: [jsxRuntime.jsxs("div", { style: styles.field, children: [jsxRuntime.jsx("label", { style: styles.fieldLabel, children: "Version" }), jsxRuntime.jsx("input", { type: "text", value: creator.config.version, onChange: (e) => creator.updateConfig({ version: e.target.value }), style: styles.input })] }), jsxRuntime.jsxs("div", { style: styles.field, children: [jsxRuntime.jsx("label", { style: styles.fieldLabel, children: "License" }), jsxRuntime.jsx("input", { type: "text", value: creator.config.license, onChange: (e) => creator.updateConfig({ license: e.target.value }), style: styles.input })] })] }), jsxRuntime.jsxs("div", { style: styles.field, children: [jsxRuntime.jsx("label", { style: styles.fieldLabel, children: "Export Format" }), jsxRuntime.jsxs("select", { value: creator.config.format, onChange: (e) => creator.updateConfig({ format: e.target.value }), style: styles.select, children: [jsxRuntime.jsx("option", { value: "esm", children: "ES Modules" }), jsxRuntime.jsx("option", { value: "cjs", children: "CommonJS" }), jsxRuntime.jsx("option", { value: "both", children: "Both" })] })] }), jsxRuntime.jsxs("div", { style: styles.checkboxGroup, children: [jsxRuntime.jsxs("label", { style: styles.checkbox, children: [jsxRuntime.jsx("input", { type: "checkbox", checked: creator.config.generateTypes, onChange: (e) => creator.updateConfig({ generateTypes: e.target.checked }) }), "Generate TypeScript types"] }), jsxRuntime.jsxs("label", { style: styles.checkbox, children: [jsxRuntime.jsx("input", { type: "checkbox", checked: creator.config.treeShaking, onChange: (e) => creator.updateConfig({ treeShaking: e.target.checked }) }), "Tree-shaking friendly"] }), jsxRuntime.jsxs("label", { style: styles.checkbox, children: [jsxRuntime.jsx("input", { type: "checkbox", checked: creator.config.includeMetadata, onChange: (e) => creator.updateConfig({ includeMetadata: e.target.checked }) }), "Include metadata"] })] }), jsxRuntime.jsxs("div", { style: styles.exportActions, children: [jsxRuntime.jsx("button", { onClick: handleExport, style: styles.primaryButton, children: "Preview Export" }), jsxRuntime.jsx("button", { onClick: handleDownloadZip, style: styles.secondaryButton, children: "Download Files" })] })] }), jsxRuntime.jsxs("div", { style: styles.selectionPanel, children: [jsxRuntime.jsxs("div", { style: styles.selectionHeader, children: [jsxRuntime.jsx("input", { type: "text", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: "Search icons...", style: styles.searchInput }), jsxRuntime.jsxs("select", { value: categoryFilter, onChange: (e) => setCategoryFilter(e.target.value), style: styles.categorySelect, children: [jsxRuntime.jsx("option", { value: "all", children: "All Categories" }), categories.map((cat) => (jsxRuntime.jsx("option", { value: cat, children: cat }, cat)))] })] }), jsxRuntime.jsxs("div", { style: styles.selectionActions, children: [jsxRuntime.jsx("button", { onClick: creator.selectAll, style: styles.smallButton, children: "Select All" }), jsxRuntime.jsx("button", { onClick: creator.deselectAll, style: styles.smallButton, children: "Deselect All" })] }), jsxRuntime.jsx("div", { style: styles.iconGrid, children: filteredItems.map((item) => (jsxRuntime.jsxs("div", { onClick: () => creator.toggleIcon(item.originalName), style: {
343
+ return (jsxRuntime.jsxs("div", { className: `nice-icon-set-creator ${className}`, style: styles.container, children: [jsxRuntime.jsxs("div", { style: styles.header, children: [jsxRuntime.jsx("h2", { style: styles.title, children: "Icon Set Creator" }), jsxRuntime.jsxs("div", { style: styles.stats, children: [creator.selectedCount, " / ", creator.items.length, " icons selected"] })] }), jsxRuntime.jsxs("div", { style: styles.content, children: [jsxRuntime.jsxs("div", { style: styles.configPanel, children: [jsxRuntime.jsx("h3", { style: styles.sectionTitle, children: "Configuration" }), jsxRuntime.jsxs("div", { style: styles.field, children: [jsxRuntime.jsx("label", { style: styles.fieldLabel, children: "Set Name" }), jsxRuntime.jsx("input", { type: "text", value: creator.config.name, onChange: (e) => creator.updateConfig({ name: e.target.value }), style: styles.input, placeholder: "MyIcons" })] }), jsxRuntime.jsxs("div", { style: styles.field, children: [jsxRuntime.jsx("label", { style: styles.fieldLabel, children: "Package Name" }), jsxRuntime.jsx("input", { type: "text", value: creator.config.packageName, onChange: (e) => creator.updateConfig({ packageName: e.target.value }), style: styles.input, placeholder: "@myproject/icons" })] }), jsxRuntime.jsxs("div", { style: styles.field, children: [jsxRuntime.jsx("label", { style: styles.fieldLabel, children: "Description" }), jsxRuntime.jsx("input", { type: "text", value: creator.config.description, onChange: (e) => creator.updateConfig({ description: e.target.value }), style: styles.input })] }), jsxRuntime.jsxs("div", { style: styles.fieldRow, children: [jsxRuntime.jsxs("div", { style: styles.field, children: [jsxRuntime.jsx("label", { style: styles.fieldLabel, children: "Version" }), jsxRuntime.jsx("input", { type: "text", value: creator.config.version, onChange: (e) => creator.updateConfig({ version: e.target.value }), style: styles.input })] }), jsxRuntime.jsxs("div", { style: styles.field, children: [jsxRuntime.jsx("label", { style: styles.fieldLabel, children: "License" }), jsxRuntime.jsx("input", { type: "text", value: creator.config.license, onChange: (e) => creator.updateConfig({ license: e.target.value }), style: styles.input })] })] }), jsxRuntime.jsxs("div", { style: styles.field, children: [jsxRuntime.jsx("label", { style: styles.fieldLabel, children: "Export Format" }), jsxRuntime.jsxs("select", { value: creator.config.format, onChange: (e) => creator.updateConfig({ format: e.target.value }), style: styles.select, children: [jsxRuntime.jsx("option", { value: "esm", children: "ES Modules" }), jsxRuntime.jsx("option", { value: "cjs", children: "CommonJS" }), jsxRuntime.jsx("option", { value: "both", children: "Both" })] })] }), jsxRuntime.jsxs("div", { style: styles.checkboxGroup, children: [jsxRuntime.jsxs("label", { style: styles.checkbox, children: [jsxRuntime.jsx("input", { type: "checkbox", checked: creator.config.generateTypes, onChange: (e) => creator.updateConfig({ generateTypes: e.target.checked }) }), "Generate TypeScript types"] }), jsxRuntime.jsxs("label", { style: styles.checkbox, children: [jsxRuntime.jsx("input", { type: "checkbox", checked: creator.config.treeShaking, onChange: (e) => creator.updateConfig({ treeShaking: e.target.checked }) }), "Tree-shaking friendly"] }), jsxRuntime.jsxs("label", { style: styles.checkbox, children: [jsxRuntime.jsx("input", { type: "checkbox", checked: creator.config.includeMetadata, onChange: (e) => creator.updateConfig({ includeMetadata: e.target.checked }) }), "Include metadata"] })] }), jsxRuntime.jsxs("div", { style: styles.exportActions, children: [jsxRuntime.jsx("button", { onClick: handleExport, style: styles.primaryButton, children: "Preview Export" }), jsxRuntime.jsx("button", { onClick: handleDownloadZip, style: styles.secondaryButton, children: "Download Files" })] })] }), jsxRuntime.jsxs("div", { style: styles.selectionPanel, children: [jsxRuntime.jsxs("div", { style: styles.selectionHeader, children: [jsxRuntime.jsx("input", { type: "text", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), placeholder: "Search icons...", style: styles.searchInput }), jsxRuntime.jsxs("select", { value: categoryFilter, onChange: (e) => setCategoryFilter(e.target.value), style: styles.categorySelect, children: [jsxRuntime.jsx("option", { value: "all", children: "All Categories" }), categories.map((cat) => (jsxRuntime.jsx("option", { value: cat, children: cat }, cat)))] })] }), jsxRuntime.jsxs("div", { style: styles.selectionActions, children: [jsxRuntime.jsx("button", { onClick: creator.selectAll, style: styles.smallButton, children: "Select All" }), jsxRuntime.jsx("button", { onClick: creator.deselectAll, style: styles.smallButton, children: "Deselect All" })] }), jsxRuntime.jsx("div", { style: styles.iconGrid, children: filteredItems.map((item) => (jsxRuntime.jsxs("div", { role: "checkbox", "aria-checked": item.included, "aria-label": item.customName, tabIndex: 0, onClick: () => creator.toggleIcon(item.originalName), onKeyDown: (e) => {
344
+ if (e.key === 'Enter' || e.key === ' ') {
345
+ e.preventDefault();
346
+ creator.toggleIcon(item.originalName);
347
+ }
348
+ }, style: {
372
349
  ...styles.iconItem,
373
350
  borderColor: item.included ? '#3b82f6' : '#e5e7eb',
374
351
  backgroundColor: item.included ? '#eff6ff' : '#fff',
@@ -187,7 +187,8 @@ function injectStyles() {
187
187
  * />
188
188
  * ```
189
189
  */
190
- const NtdBadge = React.forwardRef(({ icon: Icon, count = 0, maxCount = 99, showZero = false, position = 'top-right', variant = 'standard', badgeColor = '#ef4444', textColor = '#ffffff', animated = true, pulse = false, iconProps = {}, className, style, 'aria-label': ariaLabel, }, ref) => {
190
+ const NtdBadge = /* @__PURE__ */ Object.assign(
191
+ /* @__PURE__ */ React.forwardRef(({ icon: Icon, count = 0, maxCount = 99, showZero = false, position = 'top-right', variant = 'standard', badgeColor = '#ef4444', textColor = '#ffffff', animated = true, pulse = false, iconProps = {}, className, style, 'aria-label': ariaLabel, }, ref) => {
191
192
  var _a, _b;
192
193
  const [isEntering, setIsEntering] = React.useState(false);
193
194
  const [countChanging, setCountChanging] = React.useState(false);
@@ -237,8 +238,7 @@ const NtdBadge = React.forwardRef(({ icon: Icon, count = 0, maxCount = 99, showZ
237
238
  backgroundColor: badgeColor,
238
239
  color: textColor,
239
240
  }, "aria-hidden": "true", children: variant !== 'dot' && displayCount }))] }));
240
- });
241
- NtdBadge.displayName = 'NtdBadge';
241
+ }), { displayName: 'NtdBadge' });
242
242
  /* ────────────────────────────────────────────────────────────────────────────
243
243
  NtdStatusDot COMPONENT
244
244
  ───────────────────────────────────────────────────────────────────────────── */
@@ -257,7 +257,8 @@ NtdBadge.displayName = 'NtdBadge';
257
257
  * <NtdStatusDot icon={NtdUser} status="away" position="bottom-right" />
258
258
  * ```
259
259
  */
260
- const NtdStatusDot = React.forwardRef(({ icon: Icon, status, statusColor, position = 'bottom-right', dotSize = 'md', animated = true, pulse = false, iconProps = {}, className, style, }, ref) => {
260
+ const NtdStatusDot = /* @__PURE__ */ Object.assign(
261
+ /* @__PURE__ */ React.forwardRef(({ icon: Icon, status, statusColor, position = 'bottom-right', dotSize = 'md', animated = true, pulse = false, iconProps = {}, className, style, }, ref) => {
261
262
  var _a, _b;
262
263
  React.useEffect(() => {
263
264
  injectStyles();
@@ -285,8 +286,7 @@ const NtdStatusDot = React.forwardRef(({ icon: Icon, status, statusColor, positi
285
286
  backgroundColor: resolvedColor,
286
287
  color: resolvedColor,
287
288
  }, "aria-hidden": "true" })] }));
288
- });
289
- NtdStatusDot.displayName = 'NtdStatusDot';
289
+ }), { displayName: 'NtdStatusDot' });
290
290
  /* ────────────────────────────────────────────────────────────────────────────
291
291
  NtdIconOverlay COMPONENT
292
292
  ───────────────────────────────────────────────────────────────────────────── */
@@ -311,7 +311,8 @@ NtdStatusDot.displayName = 'NtdStatusDot';
311
311
  * />
312
312
  * ```
313
313
  */
314
- const NtdIconOverlay = React.forwardRef(({ icon: Icon, overlay, position = 'bottom-right', overlayScale = 0.5, overlayBg, circularBg = false, iconProps = {}, className, style, }, ref) => {
314
+ const NtdIconOverlay = /* @__PURE__ */ Object.assign(
315
+ /* @__PURE__ */ React.forwardRef(({ icon: Icon, overlay, position = 'bottom-right', overlayScale = 0.5, overlayBg, circularBg = false, iconProps = {}, className, style, }, ref) => {
315
316
  var _a, _b;
316
317
  React.useEffect(() => {
317
318
  injectStyles();
@@ -333,8 +334,7 @@ const NtdIconOverlay = React.forwardRef(({ icon: Icon, overlay, position = 'bott
333
334
  height: overlaySize,
334
335
  backgroundColor: overlayBg,
335
336
  }, children: overlay })] }));
336
- });
337
- NtdIconOverlay.displayName = 'NtdIconOverlay';
337
+ }), { displayName: 'NtdIconOverlay' });
338
338
  /**
339
339
  * Stack two icons for composite imagery.
340
340
  *
@@ -356,7 +356,8 @@ NtdIconOverlay.displayName = 'NtdIconOverlay';
356
356
  * />
357
357
  * ```
358
358
  */
359
- const NtdIconStack = React.forwardRef(({ base: BaseIcon, overlay: OverlayIcon, baseProps = {}, overlayProps = {}, position = 'bottom-right', overlayScale = 0.6, size, className, style, }, ref) => {
359
+ const NtdIconStack = /* @__PURE__ */ Object.assign(
360
+ /* @__PURE__ */ React.forwardRef(({ base: BaseIcon, overlay: OverlayIcon, baseProps = {}, overlayProps = {}, position = 'bottom-right', overlayScale = 0.6, size, className, style, }, ref) => {
360
361
  var _a, _b, _c;
361
362
  const resolvedSize = size
362
363
  ? typeof size === 'number'
@@ -373,8 +374,7 @@ const NtdIconStack = React.forwardRef(({ base: BaseIcon, overlay: OverlayIcon, b
373
374
  }, children: [jsxRuntime.jsx(BaseIcon, { ...baseProps, size: resolvedSize }), jsxRuntime.jsx("div", { className: "ntd-icon-overlay", style: {
374
375
  ...POSITION_STYLES[position],
375
376
  }, children: jsxRuntime.jsx(OverlayIcon, { ...overlayProps, size: overlaySize }) })] }));
376
- });
377
- NtdIconStack.displayName = 'NtdIconStack';
377
+ }), { displayName: 'NtdIconStack' });
378
378
 
379
379
  exports.NtdBadge = NtdBadge;
380
380
  exports.NtdIconOverlay = NtdIconOverlay;
@@ -2,11 +2,11 @@
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var React = require('react');
5
- var types = require('./types.js');
6
5
  var actions = require('./icons/actions.js');
7
6
  var media = require('./icons/media.js');
8
7
  var navigation = require('./icons/navigation.js');
9
8
  var ui = require('./icons/ui.js');
9
+ var types = require('./types.js');
10
10
 
11
11
  /* ────────────────────────────────────────────────────────────────────────────
12
12
  EASING FUNCTIONS
@@ -147,7 +147,8 @@ const morphStyles = `
147
147
  * />
148
148
  * ```
149
149
  */
150
- const NtdIconMorph = React.forwardRef(({ from: FromIcon, to: ToIcon, morphed: controlledMorphed, trigger = 'none', duration = 300, easing = 'ease-in-out', size = 'md', variant = 'solid', primaryColor = 'currentColor', secondaryColor, onMorphStart, onMorphEnd, className, style, 'aria-label': ariaLabel, }, ref) => {
150
+ const NtdIconMorph = /* @__PURE__ */ Object.assign(
151
+ /* @__PURE__ */ React.forwardRef(({ from: FromIcon, to: ToIcon, morphed: controlledMorphed, trigger = 'none', duration = 300, easing = 'ease-in-out', size = 'md', variant = 'solid', primaryColor = 'currentColor', secondaryColor, onMorphStart, onMorphEnd, className, style, 'aria-label': ariaLabel, }, ref) => {
151
152
  var _a, _b;
152
153
  // Internal state for self-managed triggers
153
154
  const [internalMorphed, setInternalMorphed] = React.useState(false);
@@ -239,9 +240,13 @@ const NtdIconMorph = React.forwardRef(({ from: FromIcon, to: ToIcon, morphed: co
239
240
  height: resolvedSize,
240
241
  cursor: trigger !== 'none' ? 'pointer' : undefined,
241
242
  ...style,
242
- }, onClick: handleClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onFocus: handleFocus, onBlur: handleBlur, tabIndex: trigger === 'focus' ? 0 : undefined, role: trigger !== 'none' ? 'button' : undefined, "aria-label": ariaLabel, "aria-pressed": trigger !== 'none' ? morphed : undefined, children: [jsxRuntime.jsx("div", { className: `ntd-morph-icon ${morphed ? 'ntd-morph-icon--inactive' : 'ntd-morph-icon--active'}`, style: transitionStyle, "aria-hidden": morphed, children: jsxRuntime.jsx(FromIcon, { ...iconProps }) }), jsxRuntime.jsx("div", { className: `ntd-morph-icon ${morphed ? 'ntd-morph-icon--active' : 'ntd-morph-icon--inactive'}`, style: transitionStyle, "aria-hidden": !morphed, children: jsxRuntime.jsx(ToIcon, { ...iconProps }) })] }));
243
- });
244
- NtdIconMorph.displayName = 'NtdIconMorph';
243
+ }, onClick: handleClick, onKeyDown: (e) => {
244
+ if (trigger === 'click' && (e.key === 'Enter' || e.key === ' ')) {
245
+ e.preventDefault();
246
+ handleClick();
247
+ }
248
+ }, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onFocus: handleFocus, onBlur: handleBlur, tabIndex: trigger === 'focus' || trigger === 'click' ? 0 : undefined, role: trigger !== 'none' ? 'button' : undefined, "aria-label": ariaLabel, "aria-pressed": trigger !== 'none' ? morphed : undefined, children: [jsxRuntime.jsx("div", { className: `ntd-morph-icon ${morphed ? 'ntd-morph-icon--inactive' : 'ntd-morph-icon--active'}`, style: transitionStyle, "aria-hidden": morphed, children: jsxRuntime.jsx(FromIcon, { ...iconProps }) }), jsxRuntime.jsx("div", { className: `ntd-morph-icon ${morphed ? 'ntd-morph-icon--active' : 'ntd-morph-icon--inactive'}`, style: transitionStyle, "aria-hidden": !morphed, children: jsxRuntime.jsx(ToIcon, { ...iconProps }) })] }));
249
+ }), { displayName: 'NtdIconMorph' });
245
250
  /**
246
251
  * Path-based morphing using CSS transitions on SVG path data.
247
252
  * Requires browser support for CSS `d` property transitions (modern browsers).
@@ -256,7 +261,8 @@ NtdIconMorph.displayName = 'NtdIconMorph';
256
261
  * />
257
262
  * ```
258
263
  */
259
- const NtdPathMorph = React.forwardRef(({ pair, morphed: controlledMorphed, trigger = 'none', duration = 300, easing = 'ease-in-out', size = 'md', color = 'currentColor', strokeWidth = 2, filled = false, onMorphStart, onMorphEnd, className, style, 'aria-label': ariaLabel, }, ref) => {
264
+ const NtdPathMorph = /* @__PURE__ */ Object.assign(
265
+ /* @__PURE__ */ React.forwardRef(({ pair, morphed: controlledMorphed, trigger = 'none', duration = 300, easing = 'ease-in-out', size = 'md', color = 'currentColor', strokeWidth = 2, filled = false, onMorphStart, onMorphEnd, className, style, 'aria-label': ariaLabel, }, ref) => {
260
266
  var _a, _b;
261
267
  const [internalMorphed, setInternalMorphed] = React.useState(false);
262
268
  const morphed = controlledMorphed !== null && controlledMorphed !== void 0 ? controlledMorphed : internalMorphed;
@@ -312,8 +318,12 @@ const NtdPathMorph = React.forwardRef(({ pair, morphed: controlledMorphed, trigg
312
318
  }, onClick: handleClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, role: trigger !== 'none' ? 'button' : 'img', "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : `${pair} icon`, "aria-pressed": trigger !== 'none' ? morphed : undefined, children: jsxRuntime.jsx("path", { d: currentPath, fill: filled ? color : 'none', stroke: filled ? 'none' : color, strokeWidth: filled ? 0 : strokeWidth, strokeLinecap: "round", strokeLinejoin: "round", style: {
313
319
  transition: `d ${duration}ms ${resolvedEasing}, fill ${duration}ms ${resolvedEasing}, stroke ${duration}ms ${resolvedEasing}`,
314
320
  } }) }));
315
- });
316
- NtdPathMorph.displayName = 'NtdPathMorph';
321
+ }), { displayName: 'NtdPathMorph' });
322
+ /* ────────────────────────────────────────────────────────────────────────────
323
+ PREDEFINED MORPH PAIR COMPONENT
324
+ Convenience wrapper for common morphing patterns
325
+ ───────────────────────────────────────────────────────────────────────────── */
326
+ // Import icons lazily for predefined pairs
317
327
  const ICON_PAIRS = {
318
328
  'menu-close': { from: navigation.NtdMenu, to: navigation.NtdClose },
319
329
  'play-pause': { from: media.NtdPlay, to: media.NtdPause },
@@ -337,15 +347,15 @@ const ICON_PAIRS = {
337
347
  * <NtdMorphPair pair="sun-moon" trigger="click" />
338
348
  * ```
339
349
  */
340
- const NtdMorphPair = React.forwardRef(({ pair, ...props }, ref) => {
350
+ const NtdMorphPair = /* @__PURE__ */ Object.assign(
351
+ /* @__PURE__ */ React.forwardRef(({ pair, ...props }, ref) => {
341
352
  const iconPair = ICON_PAIRS[pair];
342
353
  if (!iconPair) {
343
354
  console.warn(`NtdMorphPair: Unknown pair "${pair}"`);
344
355
  return null;
345
356
  }
346
357
  return jsxRuntime.jsx(NtdIconMorph, { ref: ref, from: iconPair.from, to: iconPair.to, ...props });
347
- });
348
- NtdMorphPair.displayName = 'NtdMorphPair';
358
+ }), { displayName: 'NtdMorphPair' });
349
359
  /**
350
360
  * Hook for managing morph state with animation awareness.
351
361
  *
@@ -43,7 +43,8 @@ function interpolateSegments(from, to, t) {
43
43
  /* ────────────────────────────────────────────────────────────────────────────
44
44
  COMPONENT
45
45
  ───────────────────────────────────────────────────────────────────────────── */
46
- const NtdStateMorph = React.forwardRef(({ states, currentState, fills, strokes, strokeWidth = 2, duration = 300, easing: _easing = 'ease-in-out', size = 'md', viewBox = '0 0 24 24', className, style, 'aria-label': ariaLabel, onTransitionEnd, }, ref) => {
46
+ const NtdStateMorph = /* @__PURE__ */ Object.assign(
47
+ /* @__PURE__ */ React.forwardRef(({ states, currentState, fills, strokes, strokeWidth = 2, duration = 300, easing: _easing = 'ease-in-out', size = 'md', viewBox = '0 0 24 24', className, style, 'aria-label': ariaLabel, onTransitionEnd, }, ref) => {
47
48
  var _a;
48
49
  const svgRef = React.useRef(null);
49
50
  const animRef = React.useRef(0);
@@ -111,8 +112,7 @@ const NtdStateMorph = React.forwardRef(({ states, currentState, fills, strokes,
111
112
  getSvgElement: () => svgRef.current,
112
113
  }));
113
114
  return (jsxRuntime.jsx("svg", { ref: svgRef, xmlns: "http://www.w3.org/2000/svg", viewBox: viewBox, width: resolvedSize, height: resolvedSize, fill: "none", className: className, style: style, "aria-label": ariaLabel, role: ariaLabel ? 'img' : undefined, children: jsxRuntime.jsx("path", { d: currentPath, fill: currentFill, stroke: currentStroke, strokeWidth: strokeWidth, strokeLinecap: "round", strokeLinejoin: "round" }) }));
114
- });
115
- NtdStateMorph.displayName = 'NtdStateMorph';
115
+ }), { displayName: 'NtdStateMorph' });
116
116
  /* ────────────────────────────────────────────────────────────────────────────
117
117
  COLOR INTERPOLATION
118
118
  ───────────────────────────────────────────────────────────────────────────── */
@@ -239,7 +239,7 @@ function useAnimationSequence(config) {
239
239
  * </AnimationController>
240
240
  * ```
241
241
  */
242
- const AnimationController = React.forwardRef(function AnimationController(props, ref) {
242
+ const AnimationController = /* @__PURE__ */ React.forwardRef(function AnimationController(props, ref) {
243
243
  const { children, animation, autoPlay = false, playState: externalPlayState, onStart, onEnd, onStepChange, onPause, onResume, className, style, } = props;
244
244
  // Determine if sequence or single animation
245
245
  const isSequence = isSequenceConfig(animation);
@@ -424,7 +424,7 @@ const AnimationController = React.forwardRef(function AnimationController(props,
424
424
  * </InteractiveIcon>
425
425
  * ```
426
426
  */
427
- const InteractiveIcon = React.forwardRef(function InteractiveIcon(props, ref) {
427
+ const InteractiveIcon = /* @__PURE__ */ React.forwardRef(function InteractiveIcon(props, ref) {
428
428
  const { children, config, disabled = false, onInteractionStart, onInteractionEnd, className, style, } = props;
429
429
  const [isActive, setIsActive] = React.useState(false);
430
430
  const [isLeaving, setIsLeaving] = React.useState(false);
@@ -538,7 +538,14 @@ const InteractiveIcon = React.forwardRef(function InteractiveIcon(props, ref) {
538
538
  display: 'inline-flex',
539
539
  cursor: disabled ? 'default' : config.trigger === 'click' ? 'pointer' : undefined,
540
540
  ...style,
541
- }, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onClick: handleClick, onFocus: handleFocus, onBlur: handleBlur, tabIndex: config.trigger === 'focus' ? 0 : undefined, role: config.trigger === 'click' ? 'button' : undefined, children: animatedChild }));
541
+ }, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, onClick: handleClick, onKeyDown: handleClick
542
+ ? (e) => {
543
+ if (e.key === 'Enter' || e.key === ' ') {
544
+ e.preventDefault();
545
+ handleClick();
546
+ }
547
+ }
548
+ : undefined, onFocus: handleFocus, onBlur: handleBlur, tabIndex: config.trigger === 'focus' || config.trigger === 'click' ? 0 : undefined, role: config.trigger === 'click' ? 'button' : undefined, children: animatedChild }));
542
549
  });
543
550
  /* ────────────────────────────────────────────────────────────────────────────
544
551
  6. UTILITY FUNCTIONS
@@ -7,14 +7,17 @@ var smilAnimations = require('./smilAnimations.js');
7
7
  var types = require('./types.js');
8
8
 
9
9
  /* ── Dark mode detection hook ───────────────────────── */
10
+ // No `matchMedia` (jsdom without a polyfill, some embedded webviews): light, and nothing to
11
+ // subscribe to — an icon must not throw where a page renders.
12
+ const hasMatchMedia = () => typeof window !== 'undefined' && typeof window.matchMedia === 'function';
10
13
  function getColorScheme() {
11
- if (typeof window === 'undefined') {
14
+ if (!hasMatchMedia()) {
12
15
  return 'light';
13
16
  }
14
17
  return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
15
18
  }
16
19
  function subscribeColorScheme(callback) {
17
- if (typeof window === 'undefined') {
20
+ if (!hasMatchMedia()) {
18
21
  return () => { };
19
22
  }
20
23
  const mq = window.matchMedia('(prefers-color-scheme: dark)');