@nice2dev/icons 1.1.10 → 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.
- package/CHANGELOG.md +173 -0
- package/dist/cjs/NiceDesktopIconExporter.js +2 -6
- package/dist/cjs/NiceFaviconGenerator.js +2 -1
- package/dist/cjs/NiceIconPicker.js +15 -20
- package/dist/cjs/NiceIconSetCreator.js +6 -29
- package/dist/cjs/NtdIconBadge.js +12 -12
- package/dist/cjs/NtdIconMorph.js +21 -11
- package/dist/cjs/NtdStateMorph.js +3 -3
- package/dist/cjs/animationControls.js +10 -3
- package/dist/cjs/createIcon.js +6 -10
- package/dist/cjs/headless-ui.js +3 -3
- package/dist/cjs/iconStyles.js +36 -34
- package/dist/cjs/icons/accessibility.js +13 -26
- package/dist/cjs/icons/actions.js +37 -50
- package/dist/cjs/icons/ai.js +15 -30
- package/dist/cjs/icons/brand.js +7 -18
- package/dist/cjs/icons/business.js +18 -106
- package/dist/cjs/icons/devtech.js +31 -142
- package/dist/cjs/icons/ecommerce.js +16 -32
- package/dist/cjs/icons/education.js +17 -34
- package/dist/cjs/icons/files.js +31 -62
- package/dist/cjs/icons/fintech.js +14 -28
- package/dist/cjs/icons/food.js +16 -32
- package/dist/cjs/icons/fun.js +13 -26
- package/dist/cjs/icons/gaming.js +15 -30
- package/dist/cjs/icons/health.js +13 -36
- package/dist/cjs/icons/index.js +4 -0
- package/dist/cjs/icons/legal.js +13 -26
- package/dist/cjs/icons/media.js +46 -46
- package/dist/cjs/icons/navigation.js +14 -28
- package/dist/cjs/icons/omniverk.js +10 -10
- package/dist/cjs/icons/realestate.js +17 -34
- package/dist/cjs/icons/saas.js +13 -26
- package/dist/cjs/icons/science.js +17 -34
- package/dist/cjs/icons/shapes.js +22 -44
- package/dist/cjs/icons/smarthome.js +13 -26
- package/dist/cjs/icons/social.js +8 -116
- package/dist/cjs/icons/sports.js +14 -28
- package/dist/cjs/icons/sustainability.js +15 -30
- package/dist/cjs/icons/travel.js +15 -30
- package/dist/cjs/icons/ui.js +39 -56
- package/dist/cjs/icons/weather.js +20 -40
- package/dist/cjs/index.js +4 -4
- package/dist/cjs/lottieIntegration.js +3 -3
- package/dist/cjs/nicetodev-icons.css +1 -1
- package/dist/cjs/particleEffects.js +11 -4
- package/dist/cjs/resolver.js +4 -0
- package/dist/cjs/rsc.js +1 -1
- package/dist/cjs/variantProps.js +2 -7
- package/dist/esm/NiceDesktopIconExporter.js +2 -6
- package/dist/esm/NiceFaviconGenerator.js +2 -1
- package/dist/esm/NiceIconPicker.js +16 -21
- package/dist/esm/NiceIconSetCreator.js +6 -29
- package/dist/esm/NtdIconBadge.js +12 -12
- package/dist/esm/NtdIconMorph.js +21 -11
- package/dist/esm/NtdStateMorph.js +3 -3
- package/dist/esm/animationControls.js +11 -4
- package/dist/esm/createIcon.js +7 -11
- package/dist/esm/headless-ui.js +3 -3
- package/dist/esm/iconStyles.js +36 -34
- package/dist/esm/icons/accessibility.js +13 -26
- package/dist/esm/icons/actions.js +37 -51
- package/dist/esm/icons/ai.js +15 -30
- package/dist/esm/icons/brand.js +7 -18
- package/dist/esm/icons/business.js +18 -106
- package/dist/esm/icons/devtech.js +31 -142
- package/dist/esm/icons/ecommerce.js +16 -32
- package/dist/esm/icons/education.js +17 -34
- package/dist/esm/icons/files.js +31 -62
- package/dist/esm/icons/fintech.js +14 -28
- package/dist/esm/icons/food.js +16 -32
- package/dist/esm/icons/fun.js +13 -26
- package/dist/esm/icons/gaming.js +15 -30
- package/dist/esm/icons/health.js +13 -36
- package/dist/esm/icons/index.js +3 -3
- package/dist/esm/icons/legal.js +13 -26
- package/dist/esm/icons/media.js +45 -47
- package/dist/esm/icons/navigation.js +14 -28
- package/dist/esm/icons/omniverk.js +10 -10
- package/dist/esm/icons/realestate.js +17 -34
- package/dist/esm/icons/saas.js +13 -26
- package/dist/esm/icons/science.js +17 -34
- package/dist/esm/icons/shapes.js +22 -44
- package/dist/esm/icons/smarthome.js +13 -26
- package/dist/esm/icons/social.js +8 -116
- package/dist/esm/icons/sports.js +14 -28
- package/dist/esm/icons/sustainability.js +15 -30
- package/dist/esm/icons/travel.js +15 -30
- package/dist/esm/icons/ui.js +39 -57
- package/dist/esm/icons/weather.js +20 -40
- package/dist/esm/index.js +4 -5
- package/dist/esm/lottieIntegration.js +3 -3
- package/dist/esm/nicetodev-icons.css +1 -1
- package/dist/esm/particleEffects.js +11 -4
- package/dist/esm/resolver.js +4 -0
- package/dist/esm/rsc.js +1 -1
- package/dist/esm/smilAnimations.js +1 -1
- package/dist/esm/variantProps.js +3 -7
- package/dist/types/NiceDesktopIconExporter.d.ts +1 -0
- package/dist/types/NtdIconBadge.d.ts +12 -4
- package/dist/types/NtdIconMorph.d.ts +10 -4
- package/dist/types/NtdStateMorph.d.ts +3 -1
- package/dist/types/createIcon.d.ts +1 -9
- package/dist/types/headless-ui.d.ts +6 -2
- package/dist/types/iconStyles.d.ts +33 -11
- package/dist/types/icons/actions.d.ts +1 -0
- package/dist/types/icons/index.d.ts +3 -3
- package/dist/types/icons/media.d.ts +3 -0
- package/dist/types/icons/ui.d.ts +2 -0
- package/dist/types/index.d.ts +2 -12
- package/dist/types/lottieIntegration.d.ts +3 -1
- package/dist/types/particleEffects.d.ts +3 -1
- package/dist/types/rsc.d.ts +1 -3
- package/dist/types/tailwind-plugin.d.ts +1 -1
- package/dist/types/types.d.ts +1 -2
- package/dist/types/variantProps.d.ts +3 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,178 @@
|
|
|
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
|
+
|
|
106
|
+
## 1.2.0
|
|
107
|
+
|
|
108
|
+
### Minor Changes
|
|
109
|
+
|
|
110
|
+
- 3a4939d: 1.2.0 — the API cleanup announced for this version, dictionaries per language by default, and
|
|
111
|
+
three new controls. **Breaking:** every removal has a replacement, listed name by name in
|
|
112
|
+
`documentation/omniverk/OMNIVERK_UPGRADE_1.2.0.md`.
|
|
113
|
+
|
|
114
|
+
**Removed (breaking).** All 118 `@deprecated` names: the aliases without the `Nice` prefix in
|
|
115
|
+
`ui-audio`, `ui-graphics` and `ui-3d`; `NiceBarcodeGenerator` (→ `NiceBarcode`), `NiceFloorPlanCanvas`
|
|
116
|
+
(→ `NiceSpatialEditor` in `@nice2dev/ui-buildings`), the v2 props and types of `NiceTopNav`,
|
|
117
|
+
`NiceProgress.showLabel`, `NiceCountryPicker.showDialCode` / `showFlag`, `type` on
|
|
118
|
+
`NiceDateTimePicker` / `NiceDateRangeBox` (→ `dateFormatPreset`); `ZoneOccupancy` in
|
|
119
|
+
`ui-buildings` and `events`, the `SmartHome*` types; the icon variant `flat` (→ `cutout`) and
|
|
120
|
+
`NiceIconEditor` (→ `NiceVectorEditor`); `NiceSizeLegacy`; the `snapGrid` module of `ui-diagrams` (→
|
|
121
|
+
`@nice2dev/spatial-core`); the opt-in stylesheet `@nice2dev/ui/css/legacy-bg-text-aliases.css`, which
|
|
122
|
+
formed an alias cycle with `style.css`. Props that were accepted and never read — 19 on
|
|
123
|
+
`NiceModuleGrid`, and more on `NiceAutocomplete`, `NiceTaskInbox`, `NiceConsentBanner`, the
|
|
124
|
+
building and communication controls, four `ui-audio` panels and `NiceStreamDashboard` — are gone
|
|
125
|
+
from the types. `NiceResourceAllocation` in `ui-erp` is `NiceCapacityPlanner` (the one in `ui`
|
|
126
|
+
keeps its name); `NiceGenericPlayerStageVisualizer` (→ `NiceStageVisualizer`) and
|
|
127
|
+
`NiceCubeBrowserProps` are removed. The `@nice2dev/ui/overlays` entry calls its modal, drawer,
|
|
128
|
+
bottom sheet and context menu `NiceOverlayModal`, `NiceOverlayDrawer`, `NiceOverlayBottomSheet` and
|
|
129
|
+
`NiceOverlayContextMenu`: the old names belonged to different components of `@nice2dev/ui`.
|
|
130
|
+
|
|
131
|
+
**Dictionaries per language.** `NiceI18nProvider` loads only the language in use, with `import()`
|
|
132
|
+
(it was `NiceI18nLazyProvider` in 1.1.10, which stays as the same component); the controls show their
|
|
133
|
+
built-in English until it arrives — `await loadNiceDictionary(lang)` before the first render to start
|
|
134
|
+
in the language. Nothing on the main entry of `@nice2dev/i18n` imports a dictionary any more:
|
|
135
|
+
`NICE_I18N_DICTIONARIES`, `createTranslator`, `NICE_I18N_VARIANTS` / `resolvePlVariant` and the
|
|
136
|
+
translation tooling moved to the new entry `@nice2dev/i18n/all`, and `@nice2dev/ui-core` no longer
|
|
137
|
+
re-exports the dictionary map. `@nice2dev/ui` with what it bundles: 1283 kB → 952 kB gzip loaded up
|
|
138
|
+
front. The `ui-audio` controls read the app's `NiceI18nProvider` now; their own provider overrides it.
|
|
139
|
+
|
|
140
|
+
**New controls.** `NiceRecurrenceEditor`, `NiceStopwatch`, `NiceCountdownTimer` (`@nice2dev/ui`) and
|
|
141
|
+
`NicePasswordGenerator` (`@nice2dev/auth`), plus `recurrenceDates()` and `generatePassword()`.
|
|
142
|
+
`NiceScheduler` honours a weekly rule's `byDay`, which it ignored.
|
|
143
|
+
|
|
144
|
+
**Visible changes.** The palette meets WCAG AA for text on every fill: darker fills in the light
|
|
145
|
+
theme, dark text on the fills of the dark theme (new `--nice-text-on-success` / `-error` / `-info` /
|
|
146
|
+
`-accent` / `-warning`; `NiceThemeText` takes `onSuccess`, `onError`, `onInfo`, `onWarning`). Mobile
|
|
147
|
+
and platform panels follow the app theme instead of `prefers-color-scheme`. Swipes in
|
|
148
|
+
`NiceSwipeActions`, `NiceTouchTable` and `NiceMobileCalendar` work with a mouse and a pen. The
|
|
149
|
+
`ui-forms` editors have the intended spacing (it was four times too large). `NiceMAM`,
|
|
150
|
+
`NiceTranscoder`, `NiceVideoAnnotator` and `NiceStreamDashboard` use `nice-`-prefixed BEM classes.
|
|
151
|
+
|
|
152
|
+
**Fixes.** Controls that invented results ask the host instead: `NiceIntegrationHub`,
|
|
153
|
+
`NiceMLStudio` (`onExperimentRun` may return metrics), `NiceRemoteManagement`
|
|
154
|
+
(`onCaptureScreenshot`), `NicePoseDetector` (`detector`), `NiceBatchScannerProvider`,
|
|
155
|
+
`NiceCacheStrategies`; `NiceLowCodeStudio` accepts dropped components. Controls that did nothing
|
|
156
|
+
work or say why they are off: `NiceStreamDashboard` adds sources, sends chat and runs the chosen
|
|
157
|
+
transition (new `onAddPlatform`, `onSendChatMessage`, `onTransition`, `onScreenshot`,
|
|
158
|
+
`onOpenAudioMixer`, `onOpenSettings`; `receiveChatMessage` feeds incoming chat), `NiceMLStudio`
|
|
159
|
+
downloads through `onModelDownload`, `NiceETLBuilder` saves through `onSave` (its Save button had
|
|
160
|
+
no handler), `NiceTranscoder` makes jobs of picked and dropped files, `NiceAutomationEditor` offers
|
|
161
|
+
the trigger types its model has. Texts of about fifty components go
|
|
162
|
+
through `t()` in six languages, among them the AI data grid, chart and form builders, the ML
|
|
163
|
+
studio, the report designer, the song picker, `NiceProtocolConfig`, `NiceETLBuilder` and
|
|
164
|
+
`NiceInlineHelp` — every key the controls pass to `t()` now has a dictionary entry, so none of
|
|
165
|
+
them stays English under another language; `NiceDataGridAI` sorts on a query in any language, not
|
|
166
|
+
only in English. `NiceWindow`, `NiceConsole`, `NiceFileManager` and `NiceGitManager` no longer
|
|
167
|
+
crash when `accessMode` switches to or from `'hidden'`. Ids come from `createId()` (`@nice2dev/ui-core`), so nothing throws
|
|
168
|
+
outside a secure context as `crypto.randomUUID()` did on plain http. `ui-3d` runs on three r183
|
|
169
|
+
without its deprecation warnings. `NiceRemoteManagement` calls the handlers of the latest render.
|
|
170
|
+
The AI hint popover and the `ui-platform` panels follow the app theme, not the system's or a
|
|
171
|
+
`.dark` class on the host. `NiceCommandPalette` has styles and its search filters;
|
|
172
|
+
`NiceTimeoutFeedback` starts its clock; `NiceOfflineBanner` takes `online`; Monaco's workers in
|
|
173
|
+
`NiceCodeEditor` load; the `ui-audio` panels that used Bootstrap classes use Nice controls; colours
|
|
174
|
+
that reached a canvas as `var(…)` (karaoke lanes and notes) are resolved first.
|
|
175
|
+
|
|
3
176
|
## 1.1.10
|
|
4
177
|
|
|
5
178
|
No changes in this release.
|
|
@@ -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
|
|
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: "
|
|
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
|
-
/* ───
|
|
8
|
-
const Chevron = () =>
|
|
9
|
-
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
const
|
|
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.
|
|
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),
|
|
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',
|
package/dist/cjs/NtdIconBadge.js
CHANGED
|
@@ -187,7 +187,8 @@ function injectStyles() {
|
|
|
187
187
|
* />
|
|
188
188
|
* ```
|
|
189
189
|
*/
|
|
190
|
-
const NtdBadge =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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;
|
package/dist/cjs/NtdIconMorph.js
CHANGED
|
@@ -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 =
|
|
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,
|
|
243
|
-
|
|
244
|
-
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
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
|
*
|