@nice2dev/icons 1.2.1 → 1.2.2

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 (38) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/cjs/NiceDesktopIconExporter.js +7 -3
  3. package/dist/cjs/NiceFaviconGenerator.js +6 -2
  4. package/dist/cjs/NiceIconPicker.js +20 -10
  5. package/dist/cjs/NiceIconPreview.js +3 -1
  6. package/dist/cjs/NiceIconSetCreator.js +7 -2
  7. package/dist/cjs/NtdIconBadge.js +18 -3
  8. package/dist/cjs/NtdIconMorph.js +3 -1
  9. package/dist/cjs/design-tokens.js +2 -0
  10. package/dist/cjs/iconMetadata.js +4 -0
  11. package/dist/cjs/icons/actions.js +22 -0
  12. package/dist/cjs/icons/index.js +8 -0
  13. package/dist/cjs/icons/shapes.js +67 -0
  14. package/dist/cjs/index.js +8 -0
  15. package/dist/cjs/nicetodev-icons.css +1 -1
  16. package/dist/cjs/resolver.js +9 -0
  17. package/dist/cjs/utilities.js +4 -2
  18. package/dist/esm/NiceDesktopIconExporter.js +7 -3
  19. package/dist/esm/NiceFaviconGenerator.js +6 -2
  20. package/dist/esm/NiceIconPicker.js +20 -10
  21. package/dist/esm/NiceIconPreview.js +3 -1
  22. package/dist/esm/NiceIconSetCreator.js +7 -2
  23. package/dist/esm/NtdIconBadge.js +18 -3
  24. package/dist/esm/NtdIconMorph.js +3 -1
  25. package/dist/esm/design-tokens.js +2 -0
  26. package/dist/esm/iconMetadata.js +4 -0
  27. package/dist/esm/icons/actions.js +21 -1
  28. package/dist/esm/icons/index.js +2 -2
  29. package/dist/esm/icons/shapes.js +62 -1
  30. package/dist/esm/index.js +2 -2
  31. package/dist/esm/nicetodev-icons.css +1 -1
  32. package/dist/esm/resolver.js +9 -0
  33. package/dist/esm/utilities.js +4 -2
  34. package/dist/types/design-tokens.d.ts +2 -0
  35. package/dist/types/icons/actions.d.ts +2 -0
  36. package/dist/types/icons/index.d.ts +2 -2
  37. package/dist/types/icons/shapes.d.ts +6 -0
  38. package/package.json +3 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # @nice2dev/icons — Changelog
2
2
 
3
+ ## 1.2.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 06eb0d2: 1.2.2 — library texts through the translator, a translator in the packages that had none, and the
8
+ end of the hook-dependency warnings. Nothing removed or renamed. Upgrade notes:
9
+ `documentation/omniverk/OMNIVERK_UPGRADE_1.2.2.md`.
10
+
11
+ **Translations.** 2,825 new keys in the global dictionary (en, pl, de, fr, es, uk), 80 in the local
12
+ dictionaries of ui-math, ui-diagrams and ui-presentations: column headers, option labels, texts in
13
+ conditions and templates, messages given to setters, labels returned by helpers, Polish texts that
14
+ were the English default. Relative dates through `Intl.RelativeTimeFormat`, plural forms through
15
+ `…One` / `…Many` keys. ui-science, ui-platform, ui-mobile, auth, licensing, templates, social and
16
+ the icon tools translate through `useNiceTranslation` (new peer `@nice2dev/ui-core ^1.2.0`);
17
+ ui-security reads the global translator when its own provider is absent.
18
+
19
+ **Additions.** `labelKey` on ui-mobile `TabItem` and `SwipeAction` (the presets set it);
20
+ `registerWebAuthn` / `authenticateWebAuthn` take the WebAuthn options `NiceWebAuthnButton` used to
21
+ drop (defaults unchanged); `NiceKeyboardHint` shows `descriptionKey`. Eight icons in
22
+ `@nice2dev/icons` — `NtdPoint`, `NtdSegment`, `NtdPerpendicular`, `NtdParallel`, `NtdMidpoint`,
23
+ `NtdAngleBisector`, `NtdGroup`, `NtdUngroup` — and the same names as `NiceIcon` built-ins.
24
+
25
+ **Behaviour changes, agreed.** ui-math, ui-diagrams and ui-presentations follow the app's global
26
+ `NiceI18nProvider` language when their own provider is absent (they stayed English);
27
+ `NicePresentationEditor` without `lang` takes the surrounding language. Icons drawn as glyphs are
28
+ Nice icons: the `NiceGeometry` tools, Align / Group / Ungroup / Layout of the diagram toolbar, the
29
+ presentation grid toggle, zoom and "Add Track" of `NiceDMXTimeline`. icons-gaming and
30
+ icons-filetypes name an icon by its `title` and are decorative without one, like `createIcon`
31
+ (screen readers read "GiHeart" or "DOCX file icon"); new optional `title` on the gaming icon props.
32
+
33
+ **Hook dependencies (161 → 0).** Fixed along the way: `NiceLowPowerMode` re-rendered forever from
34
+ mount and overflowed the stack on wake; `GenericPlayer` / `NiceGenericPlayerStage` restarted the
35
+ track on a volume change; `NiceDMXTimeline` called `onPlay` on every frame and missed cues added
36
+ during playback; `NiceConflictResolution` `autoResolve` never resolved; `NiceMAM` selected by the
37
+ previous filter; `NiceRulesEngine` "Run All" kept only the last result; `NiceCodeEditor` saved with
38
+ the first render's `onSave`; a consumer's cursor handler switched off `NiceCodeEditorAI`
39
+ completion; `useRadioStream` lost a volume set before the first play; `NiceGameEditor` shortcuts,
40
+ `useVoiceControl` continuous sessions, `NiceDeviceTrust` with a host storing the score.
41
+
3
42
  ## 1.2.1
4
43
 
5
44
  ### Patch Changes
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
+ var uiCore = require('@nice2dev/ui-core');
4
5
  var React = require('react');
5
6
 
6
7
  /* ══════════════════════════════════════════════════════════════════════════════
@@ -626,24 +627,27 @@ Note: iconutil is only available on macOS.
626
627
  * ```
627
628
  */
628
629
  const NiceDesktopIconExporter = ({ icon, initialConfig, onExport, className = '', }) => {
630
+ const { t } = uiCore.useNiceTranslation();
629
631
  const { config, setConfig, icons, isExporting, progress, exportAll, downloadAll, downloadSingle, } = useDesktopIconExporter(icon, initialConfig);
630
632
  const handleExport = async () => {
631
633
  await exportAll();
632
634
  onExport === null || onExport === void 0 ? void 0 : onExport(icons);
633
635
  };
634
636
  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", { className: "nice-desktop-icon-exporter__preview-box", style: {
637
+ 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: t('desktopIconExporter.preview', '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
638
  width: Math.min(size, 128),
637
639
  height: Math.min(size, 128),
638
640
  backgroundColor: config.backgroundColor || '#f0f0f0',
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) => {
641
+ }, 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: t('desktopIconExporter.configuration', 'Configuration') }), jsxRuntime.jsxs("label", { children: [t('desktopIconExporter.iconName', 'Icon Name:'), jsxRuntime.jsx("input", { type: "text", value: config.name, onChange: (e) => setConfig((c) => ({ ...c, name: e.target.value })) })] }), jsxRuntime.jsxs("label", { children: [t('desktopIconExporter.fillColor', 'Fill Color:'), jsxRuntime.jsx("input", { type: "color", value: config.fillColor, onChange: (e) => setConfig((c) => ({ ...c, fillColor: e.target.value })) })] }), jsxRuntime.jsxs("label", { children: [t('desktopIconExporter.background', '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: t('desktopIconExporter.transparent', 'Transparent') })] }), jsxRuntime.jsxs("label", { children: [t('desktopIconExporter.padding', 'Padding: {padding}%').replace('{padding}', String(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 })) }), t('desktopIconExporter.windowsIco', 'Windows (.ico)')] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.includeMacOS, onChange: (e) => setConfig((c) => ({ ...c, includeMacOS: e.target.checked })) }), t('desktopIconExporter.macosIconset', 'macOS (.iconset)')] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.includeLinux, onChange: (e) => setConfig((c) => ({ ...c, includeLinux: e.target.checked })) }), t('desktopIconExporter.linuxHicolor', 'Linux (hicolor)')] }), jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.includeRetina, onChange: (e) => setConfig((c) => ({ ...c, includeRetina: e.target.checked })) }), t('desktopIconExporter.hidpiRetina2x3x', 'HiDPI/Retina (@2x, @3x)')] })] }), jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__sizes", children: [jsxRuntime.jsx("h4", { children: t('desktopIconExporter.sizes', 'Sizes:') }), DESKTOP_ICON_SIZES.map(({ size, label }) => (jsxRuntime.jsxs("label", { children: [jsxRuntime.jsx("input", { type: "checkbox", checked: config.sizes.includes(size), onChange: (e) => {
640
642
  setConfig((c) => ({
641
643
  ...c,
642
644
  sizes: e.target.checked
643
645
  ? [...c.sizes, size].sort((a, b) => a - b)
644
646
  : c.sizes.filter((s) => s !== size),
645
647
  }));
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))) })] }))] }));
648
+ } }), label] }, size)))] })] }), jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__actions", children: [jsxRuntime.jsx("button", { onClick: handleExport, disabled: isExporting, children: isExporting
649
+ ? t('desktopIconExporter.exporting', 'Exporting... {progress}%').replace('{progress}', String(Math.round(progress)))
650
+ : t('desktopIconExporter.generateIcons', 'Generate Icons') }), jsxRuntime.jsx("button", { onClick: downloadAll, disabled: isExporting || icons.length === 0, children: t('desktopIconExporter.downloadAllZip', 'Download All (ZIP)') })] }), icons.length > 0 && (jsxRuntime.jsxs("div", { className: "nice-desktop-icon-exporter__results", children: [jsxRuntime.jsx("h3", { children: t('desktopIconExporter.generatedIcons', 'Generated Icons ({icons})').replace('{icons}', String(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: t('desktopIconExporter.download', 'Download') })] }, exportedIcon.filename))) })] }))] }));
647
651
  };
648
652
 
649
653
  exports.DESKTOP_ICON_SIZES = DESKTOP_ICON_SIZES;
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
+ var uiCore = require('@nice2dev/ui-core');
4
5
  var React = require('react');
5
6
  var actions = require('./icons/actions.js');
6
7
 
@@ -225,6 +226,7 @@ function useFaviconGenerator(icon, fill = '#1e1e1e', initialConfig) {
225
226
  * Favicon generator component for creating all favicon variants.
226
227
  */
227
228
  function NiceFaviconGenerator({ icon, fill = '#1e1e1e', manifestConfig, onGenerate, className = '', }) {
229
+ const { t } = uiCore.useNiceTranslation();
228
230
  const { config, setConfig, assets, isGenerating, generate, downloadAll, downloadSingle, getManifestJson, getHtmlTags, } = useFaviconGenerator(icon, fill, manifestConfig);
229
231
  const [activeTab, setActiveTab] = React.useState('preview');
230
232
  const handleGenerate = async () => {
@@ -233,10 +235,12 @@ function NiceFaviconGenerator({ icon, fill = '#1e1e1e', manifestConfig, onGenera
233
235
  onGenerate(assets, getManifestJson());
234
236
  }
235
237
  };
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: {
238
+ 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: t('faviconGenerator.manifestConfiguration', 'Manifest Configuration') }), jsxRuntime.jsxs("div", { style: styles.formGrid, children: [jsxRuntime.jsxs("div", { style: styles.formGroup, children: [jsxRuntime.jsx("label", { style: styles.label, children: t('faviconGenerator.appName', '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: t('faviconGenerator.shortName', '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: t('faviconGenerator.themeColor', '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: t('faviconGenerator.backgroundColor', '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: t('faviconGenerator.displayMode', '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: t('faviconGenerator.standalone', 'Standalone') }), jsxRuntime.jsx("option", { value: "fullscreen", children: t('faviconGenerator.fullscreen', 'Fullscreen') }), jsxRuntime.jsx("option", { value: "minimal-ui", children: t('faviconGenerator.minimalUi', 'Minimal UI') }), jsxRuntime.jsx("option", { value: "browser", children: t('faviconGenerator.browser', 'Browser') })] })] }), jsxRuntime.jsxs("div", { style: styles.formGroup, children: [jsxRuntime.jsx("label", { style: styles.label, children: t('faviconGenerator.startUrl', '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: {
237
239
  ...styles.button,
238
240
  ...(isGenerating ? styles.buttonDisabled : styles.buttonPrimary),
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))) })] })] })] }));
241
+ }, children: isGenerating
242
+ ? t('faviconGenerator.generating', 'Generating...')
243
+ : t('faviconGenerator.generateFavicons', 'Generate Favicons') }), assets.length > 0 && (jsxRuntime.jsx("button", { onClick: downloadAll, style: { ...styles.button, ...styles.buttonSecondary }, children: t('faviconGenerator.downloadAll', '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: t('faviconGenerator.preview', '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: t('faviconGenerator.htmlTags', '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": t('faviconGenerator.download', 'Download {filename}').replace('{filename}', String(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: t('faviconGenerator.faviconSizesReference', '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: t('faviconGenerator.file', 'File') }), jsxRuntime.jsx("th", { style: styles.th, children: t('faviconGenerator.size', 'Size') }), jsxRuntime.jsx("th", { style: styles.th, children: t('faviconGenerator.purpose', '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))) })] })] })] }));
240
244
  }
241
245
  /* ══════════════════════════════════════════════════════════════════════════════
242
246
  Styles
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
+ var uiCore = require('@nice2dev/ui-core');
4
5
  var React = require('react');
5
6
  var actions = require('./icons/actions.js');
6
7
  var files = require('./icons/files.js');
@@ -71,8 +72,9 @@ function saveToStorage(key, value) {
71
72
  * }
72
73
  * ```
73
74
  */
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) {
75
+ const NiceIconPicker = /* @__PURE__ */ React.forwardRef(function NiceIconPicker({ icons, value = null, values = [], onChange, onChangeMulti, multiSelect = false, maxSelections, placeholder, 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) {
75
76
  var _a;
77
+ const { t } = uiCore.useNiceTranslation();
76
78
  const [isOpen, setIsOpen] = React.useState(false);
77
79
  const [search, setSearch] = React.useState('');
78
80
  const [activeCategory, setActiveCategory] = React.useState(null);
@@ -388,19 +390,27 @@ const NiceIconPicker = /* @__PURE__ */ React.forwardRef(function NiceIconPicker(
388
390
  if (selectedEntries.length === 1) {
389
391
  return readableName(selectedEntries[0].name);
390
392
  }
391
- return `${selectedEntries.length} icons selected`;
393
+ return t('iconPicker.iconsSelected', '{count} icons selected').replace('{count}', String(selectedEntries.length));
392
394
  }
393
- return selectedEntry ? readableName(selectedEntry.name) : placeholder;
394
- }, [multiSelect, selectedEntries, selectedEntry, placeholder]);
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__'
396
- ? 'No favorites yet. Click the star icon to add.'
395
+ return selectedEntry
396
+ ? readableName(selectedEntry.name)
397
+ : (placeholder !== null && placeholder !== void 0 ? placeholder : t('iconPicker.selectIcon', 'Select icon…'));
398
+ }, [multiSelect, selectedEntries, selectedEntry, placeholder, t]);
399
+ 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: t('iconPicker.searchIcons', 'Search icons…'), value: search, onChange: (e) => setSearch(e.target.value), "aria-label": t('iconPicker.searchIcons2', '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: t('iconPicker.all', '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: t('iconPicker.favorites', 'Favorites'), children: [jsxRuntime.jsx(StarIcon, { filled: true }), " ", t('iconPicker.favorites', '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: t('iconPicker.recentlyUsed', 'Recently used'), children: [jsxRuntime.jsx(ClockIcon, {}), " ", t('iconPicker.recent', '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__'
400
+ ? t('iconPicker.noFavoritesYetClickThe', 'No favorites yet. Click the star icon to add.')
397
401
  : activeCategory === '__history__'
398
- ? 'No recent icons.'
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) => {
402
+ ? t('iconPicker.noRecentIcons', 'No recent icons.')
403
+ : t('iconPicker.noIconsFound', '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) => {
400
404
  const isSelected = selectedValues.includes(entry.name);
401
405
  const isFavorite = favorites.includes(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));
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" }))] })] }))] }));
406
+ 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
407
+ ? t('iconPicker.removeFromFavorites', 'Remove from favorites')
408
+ : t('iconPicker.addToFavorites', 'Add to favorites'), children: jsxRuntime.jsx(StarIcon, { filled: isFavorite }) }))] }, entry.name));
409
+ }) })] }, 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 === 1
410
+ ? t('iconPicker.iconCountOne', '{count} icon')
411
+ : t('iconPicker.iconCountMany', '{count} icons')).replace('{count}', String(filtered.length)), multiSelect && selectedValues.length > 0 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [' ', t('iconPicker.selected', '• {selectedValues} selected').replace('{selectedValues}', String(selectedValues.length))] })), maxSelections && multiSelect && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [' ', t('iconPicker.max', '(max {maxSelections})').replace('{maxSelections}', String(maxSelections))] }))] }), clearable && selectedValues.length > 0 && (jsxRuntime.jsx("button", { type: "button", className: "ntd-picker-clear", onClick: handleClear, children: multiSelect
412
+ ? t('iconPicker.clearAll', 'Clear all')
413
+ : t('iconPicker.clearSelection', 'Clear selection') })), multiSelect && (jsxRuntime.jsx("button", { type: "button", className: "ntd-picker-done", onClick: () => setIsOpen(false), children: t('iconPicker.done', 'Done') }))] })] }))] }));
404
414
  });
405
415
 
406
416
  exports.NiceIconPicker = NiceIconPicker;
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
+ var uiCore = require('@nice2dev/ui-core');
4
5
  var React = require('react');
5
6
 
6
7
  /* ══════════════════════════════════════════════════════════════════════════════
@@ -66,6 +67,7 @@ const animationCSS = `
66
67
  * Icon preview component with multiple modes and sizes.
67
68
  */
68
69
  function NiceIconPreview({ icon: Icon, iconName = 'Icon', mode = 'both', layout = 'grid', sizes = DEFAULT_SIZES, showAnimation = true, animations = DEFAULT_ANIMATIONS, fill, className = '', }) {
70
+ const { t } = uiCore.useNiceTranslation();
69
71
  const [selectedAnimation, setSelectedAnimation] = React.useState(null);
70
72
  // Inject animation styles
71
73
  const styleSheet = React.useMemo(() => jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: animationCSS } }), []);
@@ -77,7 +79,7 @@ function NiceIconPreview({ icon: Icon, iconName = 'Icon', mode = 'both', layout
77
79
  background: BACKGROUND_COLORS[bgMode],
78
80
  }, children: jsxRuntime.jsx(Icon, { size: size, fill: iconFill, className: selectedAnimation || undefined }) }));
79
81
  };
80
- return (jsxRuntime.jsxs("div", { className: `nice-icon-preview ${className}`, style: styles.container, children: [styleSheet, jsxRuntime.jsxs("div", { style: styles.header, children: [jsxRuntime.jsx("h3", { style: styles.title, children: iconName }), showAnimation && (jsxRuntime.jsxs("div", { style: styles.animationControls, children: [jsxRuntime.jsx("span", { style: styles.animationLabel, children: "Animation:" }), jsxRuntime.jsxs("select", { value: selectedAnimation || '', onChange: (e) => setSelectedAnimation(e.target.value || null), style: styles.select, children: [jsxRuntime.jsx("option", { value: "", children: "None" }), animations.map((a) => (jsxRuntime.jsx("option", { value: a.className, children: a.name }, a.className)))] })] }))] }), layout === 'grid' && (jsxRuntime.jsxs("div", { style: styles.gridContainer, children: [(mode === 'light' || mode === 'both') && (jsxRuntime.jsxs("div", { style: styles.section, children: [jsxRuntime.jsx("h4", { style: styles.sectionTitle, children: "Light Mode" }), jsxRuntime.jsx("div", { style: styles.sizeGrid, children: sizes.map((s) => (jsxRuntime.jsxs("div", { style: styles.sizeItem, children: [renderIcon(s.size, 'light', fill), jsxRuntime.jsx("span", { style: styles.sizeLabel, children: s.label })] }, s.size))) })] })), (mode === 'dark' || mode === 'both') && (jsxRuntime.jsxs("div", { style: styles.section, children: [jsxRuntime.jsx("h4", { style: styles.sectionTitle, children: "Dark Mode" }), jsxRuntime.jsx("div", { style: styles.sizeGrid, children: sizes.map((s) => (jsxRuntime.jsxs("div", { style: styles.sizeItem, children: [renderIcon(s.size, 'dark', fill), jsxRuntime.jsx("span", { style: styles.sizeLabel, children: s.label })] }, s.size))) })] })), mode === 'gradient' && (jsxRuntime.jsxs("div", { style: styles.section, children: [jsxRuntime.jsx("h4", { style: styles.sectionTitle, children: "Gradient Background" }), jsxRuntime.jsx("div", { style: styles.sizeGrid, children: sizes.map((s) => (jsxRuntime.jsxs("div", { style: styles.sizeItem, children: [renderIcon(s.size, 'gradient', '#ffffff'), jsxRuntime.jsx("span", { style: styles.sizeLabel, children: s.label })] }, s.size))) })] }))] })), layout === 'list' && (jsxRuntime.jsx("div", { style: styles.listContainer, children: sizes.map((s) => (jsxRuntime.jsxs("div", { style: styles.listRow, children: [jsxRuntime.jsx("span", { style: styles.listLabel, children: s.label }), renderIcon(s.size, 'light', fill), renderIcon(s.size, 'dark', fill)] }, s.size))) })), layout === 'comparison' && (jsxRuntime.jsxs("div", { style: styles.comparisonContainer, children: [jsxRuntime.jsxs("div", { style: styles.comparisonSide, children: [jsxRuntime.jsx("h4", { style: styles.sectionTitle, children: "Light" }), jsxRuntime.jsx("div", { style: { ...styles.comparisonBox, background: BACKGROUND_COLORS.light }, children: jsxRuntime.jsx(Icon, { size: 96, fill: fill || '#1e1e1e', className: selectedAnimation || undefined }) })] }), jsxRuntime.jsxs("div", { style: styles.comparisonSide, children: [jsxRuntime.jsx("h4", { style: styles.sectionTitle, children: "Dark" }), jsxRuntime.jsx("div", { style: { ...styles.comparisonBox, background: BACKGROUND_COLORS.dark }, children: jsxRuntime.jsx(Icon, { size: 96, fill: fill || '#ffffff', className: selectedAnimation || undefined }) })] })] }))] }));
82
+ return (jsxRuntime.jsxs("div", { className: `nice-icon-preview ${className}`, style: styles.container, children: [styleSheet, jsxRuntime.jsxs("div", { style: styles.header, children: [jsxRuntime.jsx("h3", { style: styles.title, children: iconName }), showAnimation && (jsxRuntime.jsxs("div", { style: styles.animationControls, children: [jsxRuntime.jsx("span", { style: styles.animationLabel, children: t('iconPreview.animation', 'Animation:') }), jsxRuntime.jsxs("select", { value: selectedAnimation || '', onChange: (e) => setSelectedAnimation(e.target.value || null), style: styles.select, children: [jsxRuntime.jsx("option", { value: "", children: t('iconPreview.none', 'None') }), animations.map((a) => (jsxRuntime.jsx("option", { value: a.className, children: a.name }, a.className)))] })] }))] }), layout === 'grid' && (jsxRuntime.jsxs("div", { style: styles.gridContainer, children: [(mode === 'light' || mode === 'both') && (jsxRuntime.jsxs("div", { style: styles.section, children: [jsxRuntime.jsx("h4", { style: styles.sectionTitle, children: t('iconPreview.lightMode', 'Light Mode') }), jsxRuntime.jsx("div", { style: styles.sizeGrid, children: sizes.map((s) => (jsxRuntime.jsxs("div", { style: styles.sizeItem, children: [renderIcon(s.size, 'light', fill), jsxRuntime.jsx("span", { style: styles.sizeLabel, children: s.label })] }, s.size))) })] })), (mode === 'dark' || mode === 'both') && (jsxRuntime.jsxs("div", { style: styles.section, children: [jsxRuntime.jsx("h4", { style: styles.sectionTitle, children: t('iconPreview.darkMode', 'Dark Mode') }), jsxRuntime.jsx("div", { style: styles.sizeGrid, children: sizes.map((s) => (jsxRuntime.jsxs("div", { style: styles.sizeItem, children: [renderIcon(s.size, 'dark', fill), jsxRuntime.jsx("span", { style: styles.sizeLabel, children: s.label })] }, s.size))) })] })), mode === 'gradient' && (jsxRuntime.jsxs("div", { style: styles.section, children: [jsxRuntime.jsx("h4", { style: styles.sectionTitle, children: t('iconPreview.gradientBackground', 'Gradient Background') }), jsxRuntime.jsx("div", { style: styles.sizeGrid, children: sizes.map((s) => (jsxRuntime.jsxs("div", { style: styles.sizeItem, children: [renderIcon(s.size, 'gradient', '#ffffff'), jsxRuntime.jsx("span", { style: styles.sizeLabel, children: s.label })] }, s.size))) })] }))] })), layout === 'list' && (jsxRuntime.jsx("div", { style: styles.listContainer, children: sizes.map((s) => (jsxRuntime.jsxs("div", { style: styles.listRow, children: [jsxRuntime.jsx("span", { style: styles.listLabel, children: s.label }), renderIcon(s.size, 'light', fill), renderIcon(s.size, 'dark', fill)] }, s.size))) })), layout === 'comparison' && (jsxRuntime.jsxs("div", { style: styles.comparisonContainer, children: [jsxRuntime.jsxs("div", { style: styles.comparisonSide, children: [jsxRuntime.jsx("h4", { style: styles.sectionTitle, children: t('iconPreview.light', 'Light') }), jsxRuntime.jsx("div", { style: { ...styles.comparisonBox, background: BACKGROUND_COLORS.light }, children: jsxRuntime.jsx(Icon, { size: 96, fill: fill || '#1e1e1e', className: selectedAnimation || undefined }) })] }), jsxRuntime.jsxs("div", { style: styles.comparisonSide, children: [jsxRuntime.jsx("h4", { style: styles.sectionTitle, children: t('iconPreview.dark', 'Dark') }), jsxRuntime.jsx("div", { style: { ...styles.comparisonBox, background: BACKGROUND_COLORS.dark }, children: jsxRuntime.jsx(Icon, { size: 96, fill: fill || '#ffffff', className: selectedAnimation || undefined }) })] })] }))] }));
81
83
  }
82
84
  /* ══════════════════════════════════════════════════════════════════════════════
83
85
  Styles
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
+ var uiCore = require('@nice2dev/ui-core');
4
5
  var React = require('react');
5
6
  var actions = require('./icons/actions.js');
6
7
 
@@ -10,6 +11,7 @@ var actions = require('./icons/actions.js');
10
11
  const DEFAULT_CONFIG = {
11
12
  name: 'MyIcons',
12
13
  packageName: '@myproject/icons',
14
+ // audit-allow: i18n — the generated package.json's default description, not UI copy
13
15
  description: 'Custom icon set',
14
16
  version: '1.0.0',
15
17
  author: '',
@@ -287,6 +289,7 @@ function useIconSetCreator(options) {
287
289
  * Icon Set Creator component for building custom icon packages.
288
290
  */
289
291
  function NiceIconSetCreator({ icons, initialSelection, defaultConfig, onSelectionChange: _onSelectionChange, onExport, className = '', }) {
292
+ const { t } = uiCore.useNiceTranslation();
290
293
  const creator = useIconSetCreator({ icons, initialSelection, defaultConfig });
291
294
  const [searchQuery, setSearchQuery] = React.useState('');
292
295
  const [categoryFilter, setCategoryFilter] = React.useState('all');
@@ -340,7 +343,9 @@ function NiceIconSetCreator({ icons, initialSelection, defaultConfig, onSelectio
340
343
  URL.revokeObjectURL(url);
341
344
  });
342
345
  }, [creator]);
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) => {
346
+ 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: t('iconSetCreator.iconSetCreator', 'Icon Set Creator') }), jsxRuntime.jsx("div", { style: styles.stats, children: t('iconSetCreator.iconsSelected', '{selectedCount} / {items} icons selected')
347
+ .replace('{selectedCount}', String(creator.selectedCount))
348
+ .replace('{items}', String(creator.items.length)) })] }), jsxRuntime.jsxs("div", { style: styles.content, children: [jsxRuntime.jsxs("div", { style: styles.configPanel, children: [jsxRuntime.jsx("h3", { style: styles.sectionTitle, children: t('iconSetCreator.configuration', 'Configuration') }), jsxRuntime.jsxs("div", { style: styles.field, children: [jsxRuntime.jsx("label", { style: styles.fieldLabel, children: t('iconSetCreator.setName', '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: t('iconSetCreator.packageName', '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: t('iconSetCreator.description', '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: t('iconSetCreator.version', '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: t('iconSetCreator.license', '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: t('iconSetCreator.exportFormat', '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: t('iconSetCreator.esModules', 'ES Modules') }), jsxRuntime.jsx("option", { value: "cjs", children: "CommonJS" }), jsxRuntime.jsx("option", { value: "both", children: t('iconSetCreator.both', '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 }) }), t('iconSetCreator.generateTypescriptTypes', '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 }) }), t('iconSetCreator.treeShakingFriendly', '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 }) }), t('iconSetCreator.includeMetadata', 'Include metadata')] })] }), jsxRuntime.jsxs("div", { style: styles.exportActions, children: [jsxRuntime.jsx("button", { onClick: handleExport, style: styles.primaryButton, children: t('iconSetCreator.previewExport', 'Preview Export') }), jsxRuntime.jsx("button", { onClick: handleDownloadZip, style: styles.secondaryButton, children: t('iconSetCreator.downloadFiles', '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: t('iconSetCreator.searchIcons', '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: t('iconSetCreator.allCategories', '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: t('iconSetCreator.selectAll', 'Select All') }), jsxRuntime.jsx("button", { onClick: creator.deselectAll, style: styles.smallButton, children: t('iconSetCreator.deselectAll', '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
349
  if (e.key === 'Enter' || e.key === ' ') {
345
350
  e.preventDefault();
346
351
  creator.toggleIcon(item.originalName);
@@ -349,7 +354,7 @@ function NiceIconSetCreator({ icons, initialSelection, defaultConfig, onSelectio
349
354
  ...styles.iconItem,
350
355
  borderColor: item.included ? '#3b82f6' : '#e5e7eb',
351
356
  backgroundColor: item.included ? '#eff6ff' : '#fff',
352
- }, children: [jsxRuntime.jsx(item.icon, { size: 32 }), jsxRuntime.jsx("span", { style: styles.iconName, children: item.customName }), item.included && (jsxRuntime.jsx("span", { style: styles.checkmark, children: jsxRuntime.jsx(actions.NtdCheck, { size: 14 }) }))] }, item.originalName))) })] }), previewOutput && (jsxRuntime.jsxs("div", { style: styles.previewPanel, children: [jsxRuntime.jsx("h3", { style: styles.sectionTitle, children: "Export Preview" }), previewOutput.map((file) => (jsxRuntime.jsxs("div", { style: styles.filePreview, children: [jsxRuntime.jsx("div", { style: styles.fileName, children: file.filename }), jsxRuntime.jsxs("pre", { style: styles.codePreview, children: [file.content.slice(0, 1000), file.content.length > 1000 && '...'] })] }, file.filename)))] }))] })] }));
357
+ }, children: [jsxRuntime.jsx(item.icon, { size: 32 }), jsxRuntime.jsx("span", { style: styles.iconName, children: item.customName }), item.included && (jsxRuntime.jsx("span", { style: styles.checkmark, children: jsxRuntime.jsx(actions.NtdCheck, { size: 14 }) }))] }, item.originalName))) })] }), previewOutput && (jsxRuntime.jsxs("div", { style: styles.previewPanel, children: [jsxRuntime.jsx("h3", { style: styles.sectionTitle, children: t('iconSetCreator.exportPreview', 'Export Preview') }), previewOutput.map((file) => (jsxRuntime.jsxs("div", { style: styles.filePreview, children: [jsxRuntime.jsx("div", { style: styles.fileName, children: file.filename }), jsxRuntime.jsxs("pre", { style: styles.codePreview, children: [file.content.slice(0, 1000), file.content.length > 1000 && '...'] })] }, file.filename)))] }))] })] }));
353
358
  }
354
359
  /* ══════════════════════════════════════════════════════════════════════════════
355
360
  Styles
@@ -1,9 +1,19 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
+ var uiCore = require('@nice2dev/ui-core');
4
5
  var React = require('react');
5
6
  var types = require('./types.js');
6
7
 
8
+ /** The status in words for the accessible name — English defaults of `ntdIconBadge.statusValue.*`. */
9
+ const STATUS_WORDS = {
10
+ online: 'online',
11
+ offline: 'offline',
12
+ busy: 'busy',
13
+ away: 'away',
14
+ dnd: 'do not disturb',
15
+ invisible: 'invisible',
16
+ };
7
17
  /* ────────────────────────────────────────────────────────────────────────────
8
18
  CONSTANTS
9
19
  ───────────────────────────────────────────────────────────────────────────── */
@@ -190,6 +200,7 @@ function injectStyles() {
190
200
  const NtdBadge = /* @__PURE__ */ Object.assign(
191
201
  /* @__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) => {
192
202
  var _a, _b;
203
+ const { t } = uiCore.useNiceTranslation();
193
204
  const [isEntering, setIsEntering] = React.useState(false);
194
205
  const [countChanging, setCountChanging] = React.useState(false);
195
206
  const prevCountRef = React.useRef(count);
@@ -213,6 +224,7 @@ const NtdBadge = /* @__PURE__ */ Object.assign(
213
224
  const timer = setTimeout(() => setIsEntering(false), 300);
214
225
  return () => clearTimeout(timer);
215
226
  }
227
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- the enter animation plays once, when the badge mounts
216
228
  }, []);
217
229
  const shouldShowBadge = count > 0 || showZero;
218
230
  const displayCount = count > maxCount ? `${maxCount}+` : count.toString();
@@ -233,7 +245,9 @@ const NtdBadge = /* @__PURE__ */ Object.assign(
233
245
  width: resolvedSize,
234
246
  height: resolvedSize,
235
247
  ...style,
236
- }, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : (shouldShowBadge ? `${count} notifications` : undefined), children: [jsxRuntime.jsx(Icon, { ...iconProps }), shouldShowBadge && (jsxRuntime.jsx("span", { className: badgeClasses, style: {
248
+ }, "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : (shouldShowBadge
249
+ ? t('ntdIconBadge.notifications', '{count} notifications').replace('{count}', String(count))
250
+ : undefined), children: [jsxRuntime.jsx(Icon, { ...iconProps }), shouldShowBadge && (jsxRuntime.jsx("span", { className: badgeClasses, style: {
237
251
  ...POSITION_STYLES[position],
238
252
  backgroundColor: badgeColor,
239
253
  color: textColor,
@@ -259,7 +273,8 @@ const NtdBadge = /* @__PURE__ */ Object.assign(
259
273
  */
260
274
  const NtdStatusDot = /* @__PURE__ */ Object.assign(
261
275
  /* @__PURE__ */ React.forwardRef(({ icon: Icon, status, statusColor, position = 'bottom-right', dotSize = 'md', animated = true, pulse = false, iconProps = {}, className, style, }, ref) => {
262
- var _a, _b;
276
+ var _a, _b, _c;
277
+ const { t } = uiCore.useNiceTranslation();
263
278
  React.useEffect(() => {
264
279
  injectStyles();
265
280
  }, []);
@@ -279,7 +294,7 @@ const NtdStatusDot = /* @__PURE__ */ Object.assign(
279
294
  width: resolvedIconSize,
280
295
  height: resolvedIconSize,
281
296
  ...style,
282
- }, role: "status", "aria-label": `Status: ${status}`, children: [jsxRuntime.jsx(Icon, { ...iconProps }), jsxRuntime.jsx("span", { className: dotClasses, style: {
297
+ }, role: "status", "aria-label": t('ntdIconBadge.status', 'Status: {status}').replace('{status}', t('ntdIconBadge.statusValue.' + status, (_c = STATUS_WORDS[status]) !== null && _c !== void 0 ? _c : status)), children: [jsxRuntime.jsx(Icon, { ...iconProps }), jsxRuntime.jsx("span", { className: dotClasses, style: {
283
298
  ...POSITION_STYLES[position],
284
299
  width: resolvedDotSize,
285
300
  height: resolvedDotSize,
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
+ var uiCore = require('@nice2dev/ui-core');
4
5
  var React = require('react');
5
6
  var actions = require('./icons/actions.js');
6
7
  var media = require('./icons/media.js');
@@ -264,6 +265,7 @@ const NtdIconMorph = /* @__PURE__ */ Object.assign(
264
265
  const NtdPathMorph = /* @__PURE__ */ Object.assign(
265
266
  /* @__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) => {
266
267
  var _a, _b;
268
+ const { t } = uiCore.useNiceTranslation();
267
269
  const [internalMorphed, setInternalMorphed] = React.useState(false);
268
270
  const morphed = controlledMorphed !== null && controlledMorphed !== void 0 ? controlledMorphed : internalMorphed;
269
271
  const [isAnimating, setIsAnimating] = React.useState(false);
@@ -315,7 +317,7 @@ const NtdPathMorph = /* @__PURE__ */ Object.assign(
315
317
  return (jsxRuntime.jsx("svg", { ref: ref, xmlns: "http://www.w3.org/2000/svg", viewBox: pathData.viewBox, width: resolvedSize, height: resolvedSize, className: `ntd-path-morph ${className !== null && className !== void 0 ? className : ''}`, style: {
316
318
  cursor: trigger !== 'none' ? 'pointer' : undefined,
317
319
  ...style,
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: {
320
+ }, onClick: handleClick, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, role: trigger !== 'none' ? 'button' : 'img', "aria-label": ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : t('ntdIconMorph.icon', '{pair} icon').replace('{pair}', String(pair)), "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: {
319
321
  transition: `d ${duration}ms ${resolvedEasing}, fill ${duration}ms ${resolvedEasing}, stroke ${duration}ms ${resolvedEasing}`,
320
322
  } }) }));
321
323
  }), { displayName: 'NtdPathMorph' });
@@ -29,6 +29,8 @@ Object.defineProperty(exports, '__esModule', { value: true });
29
29
  * @version 1.0.0
30
30
  * @since 2026-03
31
31
  * @license MIT
32
+ *
33
+ * audit-allow: i18n-file — token descriptions written into Style Dictionary output, not UI copy.
32
34
  */
33
35
  /* ────────────────────────────────────────────────────────────────────────────
34
36
  DEFAULT TOKEN VALUES
@@ -17,6 +17,8 @@
17
17
  /* ────────────────────────────────────────────────────────────────────────────
18
18
  CATEGORY METADATA
19
19
  ───────────────────────────────────────────────────────────────────────────── */
20
+ // audit-allow: i18n — English data for the host's icon browser and searchIcons(); no control of
21
+ // this package shows it.
20
22
  const CATEGORY_INFO = {
21
23
  actions: {
22
24
  label: 'Actions',
@@ -364,6 +366,7 @@ function getSearchSuggestions(partialQuery, limit = 5) {
364
366
  This will be populated when icons are imported
365
367
  ───────────────────────────────────────────────────────────────────────────── */
366
368
  // Example metadata definitions (actual ones will be in icon files)
369
+ // audit-allow: i18n — English search metadata: searchIcons() matches these words.
367
370
  const UI_ICON_METADATA = {
368
371
  NtdHome: {
369
372
  category: 'ui',
@@ -430,6 +433,7 @@ const UI_ICON_METADATA = {
430
433
  related: ['NtdBellOff', 'NtdAlarm'],
431
434
  },
432
435
  };
436
+ // audit-allow: i18n — English search metadata: searchIcons() matches these words.
433
437
  const ACTION_ICON_METADATA = {
434
438
  NtdPlay: {
435
439
  category: 'actions',
@@ -251,6 +251,26 @@ const NtdUnlock = /* @__PURE__ */ createIcon.createIcon({
251
251
  vivid: ({ primaryColor, secondaryColor }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2.5", fill: primaryColor }), jsxRuntime.jsx("rect", { x: "3", y: "11", width: "18", height: "11", rx: "2.5", fill: "white", opacity: "0.08" }), jsxRuntime.jsx("circle", { cx: "12", cy: "15.5", r: "1.5", fill: secondaryColor }), jsxRuntime.jsx("rect", { x: "11.25", y: "16.5", width: "1.5", height: "2", rx: "0.5", fill: "#3B82F6" }), jsxRuntime.jsx("path", { d: "M7 11V7a5 5 0 019.9-1", stroke: "white", strokeWidth: "1" })] })),
252
252
  },
253
253
  });
254
+ // Group / ungroup selected objects (1.2.2: the diagram toolbar drew them as ⊞ / ⊟).
255
+ // Group: two objects inside the corners of one selection frame; ungroup: the two apart.
256
+ const NtdGroup = /* @__PURE__ */ createIcon.createIcon({
257
+ displayName: 'NtdGroup',
258
+ paths: {
259
+ solid: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: "M3 7V3h4M17 3h4v4M21 17v4h-4M7 21H3v-4", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }), jsxRuntime.jsx("rect", { x: "7", y: "7", width: "5", height: "5", fill: primaryColor }), jsxRuntime.jsx("rect", { x: "12", y: "12", width: "5", height: "5", fill: primaryColor })] })),
260
+ outline: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsx("path", { d: "M3 7V3h4M17 3h4v4M21 17v4h-4M7 21H3v-4M7 7h5v5H7zM12 12h5v5h-5z", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round", strokeLinejoin: "round", fill: "none" })),
261
+ duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { x: "7", y: "7", width: "5", height: "5", fill: secondaryColor, opacity: secondaryOpacity }), jsxRuntime.jsx("rect", { x: "12", y: "12", width: "5", height: "5", fill: secondaryColor, opacity: secondaryOpacity }), jsxRuntime.jsx("path", { d: "M3 7V3h4M17 3h4v4M21 17v4h-4M7 21H3v-4M7 7h5v5H7zM12 12h5v5h-5z", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinecap: "round", strokeLinejoin: "round", fill: "none" })] })),
262
+ vivid: ({ primaryColor, secondaryColor: _secondaryColor }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("path", { d: "M3 7V3h4M17 3h4v4M21 17v4h-4M7 21H3v-4", stroke: primaryColor, strokeWidth: "2.2", strokeLinecap: "round", strokeLinejoin: "round", fill: "none" }), jsxRuntime.jsx("rect", { x: "7", y: "7", width: "5", height: "5", fill: primaryColor }), jsxRuntime.jsx("rect", { x: "12", y: "12", width: "5", height: "5", fill: primaryColor })] })),
263
+ },
264
+ });
265
+ const NtdUngroup = /* @__PURE__ */ createIcon.createIcon({
266
+ displayName: 'NtdUngroup',
267
+ paths: {
268
+ solid: ({ primaryColor, strokeWidth: _strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { x: "3", y: "3", width: "8", height: "8", rx: "1", fill: primaryColor }), jsxRuntime.jsx("rect", { x: "13", y: "13", width: "8", height: "8", rx: "1", fill: primaryColor })] })),
269
+ outline: ({ primaryColor, strokeWidth }) => (jsxRuntime.jsx("path", { d: "M3 3h8v8H3zM13 13h8v8h-8z", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinejoin: "round", fill: "none" })),
270
+ duotone: ({ primaryColor, secondaryColor, secondaryOpacity, strokeWidth }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { x: "3", y: "3", width: "8", height: "8", fill: secondaryColor, opacity: secondaryOpacity }), jsxRuntime.jsx("rect", { x: "13", y: "13", width: "8", height: "8", fill: secondaryColor, opacity: secondaryOpacity }), jsxRuntime.jsx("path", { d: "M3 3h8v8H3zM13 13h8v8h-8z", stroke: primaryColor, strokeWidth: strokeWidth, strokeLinejoin: "round", fill: "none" })] })),
271
+ vivid: ({ primaryColor, secondaryColor: _secondaryColor }) => (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("rect", { x: "3", y: "3", width: "8", height: "8", rx: "1", fill: primaryColor }), jsxRuntime.jsx("rect", { x: "13", y: "13", width: "8", height: "8", rx: "1", fill: primaryColor }), jsxRuntime.jsx("rect", { x: "3", y: "3", width: "8", height: "8", rx: "1", fill: "white", opacity: "0.1" }), jsxRuntime.jsx("rect", { x: "13", y: "13", width: "8", height: "8", rx: "1", fill: "white", opacity: "0.1" })] })),
272
+ },
273
+ });
254
274
 
255
275
  exports.NtdCheck = NtdCheck;
256
276
  exports.NtdClipboard = NtdClipboard;
@@ -258,6 +278,7 @@ exports.NtdCopy = NtdCopy;
258
278
  exports.NtdDownload = NtdDownload;
259
279
  exports.NtdEdit = NtdEdit;
260
280
  exports.NtdFilter = NtdFilter;
281
+ exports.NtdGroup = NtdGroup;
261
282
  exports.NtdLink = NtdLink;
262
283
  exports.NtdLock = NtdLock;
263
284
  exports.NtdLogIn = NtdLogIn;
@@ -274,6 +295,7 @@ exports.NtdShare = NtdShare;
274
295
  exports.NtdSort = NtdSort;
275
296
  exports.NtdTrash = NtdTrash;
276
297
  exports.NtdUndo = NtdUndo;
298
+ exports.NtdUngroup = NtdUngroup;
277
299
  exports.NtdUnlock = NtdUnlock;
278
300
  exports.NtdUpload = NtdUpload;
279
301
  exports.NtdZoomIn = NtdZoomIn;
@@ -52,6 +52,7 @@ exports.NtdCopy = actions.NtdCopy;
52
52
  exports.NtdDownload = actions.NtdDownload;
53
53
  exports.NtdEdit = actions.NtdEdit;
54
54
  exports.NtdFilter = actions.NtdFilter;
55
+ exports.NtdGroup = actions.NtdGroup;
55
56
  exports.NtdLink = actions.NtdLink;
56
57
  exports.NtdLock = actions.NtdLock;
57
58
  exports.NtdLogIn = actions.NtdLogIn;
@@ -68,6 +69,7 @@ exports.NtdShare = actions.NtdShare;
68
69
  exports.NtdSort = actions.NtdSort;
69
70
  exports.NtdTrash = actions.NtdTrash;
70
71
  exports.NtdUndo = actions.NtdUndo;
72
+ exports.NtdUngroup = actions.NtdUngroup;
71
73
  exports.NtdUnlock = actions.NtdUnlock;
72
74
  exports.NtdUpload = actions.NtdUpload;
73
75
  exports.NtdZoomIn = actions.NtdZoomIn;
@@ -234,6 +236,7 @@ exports.NtdTree = weather.NtdTree;
234
236
  exports.NtdUmbrella = weather.NtdUmbrella;
235
237
  exports.NtdWave = weather.NtdWave;
236
238
  exports.NtdWind = weather.NtdWind;
239
+ exports.NtdAngleBisector = shapes.NtdAngleBisector;
237
240
  exports.NtdArrowDownCircle = shapes.NtdArrowDownCircle;
238
241
  exports.NtdArrowLeftCircle = shapes.NtdArrowLeftCircle;
239
242
  exports.NtdArrowRightCircle = shapes.NtdArrowRightCircle;
@@ -247,11 +250,16 @@ exports.NtdCross = shapes.NtdCross;
247
250
  exports.NtdDiamond = shapes.NtdDiamond;
248
251
  exports.NtdHexagon = shapes.NtdHexagon;
249
252
  exports.NtdMaximize = shapes.NtdMaximize;
253
+ exports.NtdMidpoint = shapes.NtdMidpoint;
250
254
  exports.NtdMinimize = shapes.NtdMinimize;
251
255
  exports.NtdMove = shapes.NtdMove;
252
256
  exports.NtdOctagon = shapes.NtdOctagon;
257
+ exports.NtdParallel = shapes.NtdParallel;
253
258
  exports.NtdPentagon = shapes.NtdPentagon;
259
+ exports.NtdPerpendicular = shapes.NtdPerpendicular;
260
+ exports.NtdPoint = shapes.NtdPoint;
254
261
  exports.NtdRepeat = shapes.NtdRepeat;
262
+ exports.NtdSegment = shapes.NtdSegment;
255
263
  exports.NtdShuffle = shapes.NtdShuffle;
256
264
  exports.NtdSquare = shapes.NtdSquare;
257
265
  exports.NtdStar4 = shapes.NtdStar4;