@nice2dev/icons 1.2.1 → 1.3.0

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 (94) hide show
  1. package/CHANGELOG.md +538 -0
  2. package/README.md +146 -134
  3. package/dist/cjs/NiceDesktopIconExporter.js +7 -3
  4. package/dist/cjs/NiceFaviconGenerator.js +6 -2
  5. package/dist/cjs/NiceIconPicker.js +36 -28
  6. package/dist/cjs/NiceIconPreview.js +3 -1
  7. package/dist/cjs/NiceIconSetCreator.js +7 -2
  8. package/dist/cjs/NtdIconBadge.js +18 -3
  9. package/dist/cjs/NtdIconMorph.js +3 -1
  10. package/dist/cjs/createIcon.js +10 -2
  11. package/dist/cjs/design-tokens.js +2 -0
  12. package/dist/cjs/iconMetadata.js +4 -0
  13. package/dist/cjs/iconParts.js +49 -0
  14. package/dist/cjs/icons/accessibility.js +12 -4
  15. package/dist/cjs/icons/actions.js +89 -25
  16. package/dist/cjs/icons/business.js +58 -28
  17. package/dist/cjs/icons/ecommerce.js +0 -20
  18. package/dist/cjs/icons/education.js +22 -9
  19. package/dist/cjs/icons/files.js +70 -56
  20. package/dist/cjs/icons/fun.js +39 -25
  21. package/dist/cjs/icons/gaming.js +29 -4
  22. package/dist/cjs/icons/health.js +11 -4
  23. package/dist/cjs/icons/index.js +63 -5
  24. package/dist/cjs/icons/input.js +120 -0
  25. package/dist/cjs/icons/legal.js +4 -9
  26. package/dist/cjs/icons/media.js +26 -11
  27. package/dist/cjs/icons/navigation.js +4 -2
  28. package/dist/cjs/icons/omniverk.js +19 -6
  29. package/dist/cjs/icons/realestate.js +10 -4
  30. package/dist/cjs/icons/saas.js +15 -4
  31. package/dist/cjs/icons/science.js +6 -3
  32. package/dist/cjs/icons/shapes.js +133 -31
  33. package/dist/cjs/icons/sports.js +6 -2
  34. package/dist/cjs/icons/ui.js +62 -20
  35. package/dist/cjs/icons/weather.js +18 -8
  36. package/dist/cjs/index.js +63 -5
  37. package/dist/cjs/nicetodev-icons.css +1 -1
  38. package/dist/cjs/resolver.js +55 -1
  39. package/dist/cjs/rsc.js +1 -1
  40. package/dist/cjs/utilities.js +4 -2
  41. package/dist/esm/NiceDesktopIconExporter.js +7 -3
  42. package/dist/esm/NiceFaviconGenerator.js +6 -2
  43. package/dist/esm/NiceIconPicker.js +37 -29
  44. package/dist/esm/NiceIconPreview.js +3 -1
  45. package/dist/esm/NiceIconSetCreator.js +7 -2
  46. package/dist/esm/NtdIconBadge.js +18 -3
  47. package/dist/esm/NtdIconMorph.js +3 -1
  48. package/dist/esm/createIcon.js +10 -2
  49. package/dist/esm/design-tokens.js +2 -0
  50. package/dist/esm/iconMetadata.js +4 -0
  51. package/dist/esm/iconParts.js +46 -0
  52. package/dist/esm/icons/accessibility.js +12 -4
  53. package/dist/esm/icons/actions.js +87 -26
  54. package/dist/esm/icons/business.js +58 -29
  55. package/dist/esm/icons/ecommerce.js +1 -19
  56. package/dist/esm/icons/education.js +22 -10
  57. package/dist/esm/icons/files.js +70 -56
  58. package/dist/esm/icons/fun.js +37 -25
  59. package/dist/esm/icons/gaming.js +29 -5
  60. package/dist/esm/icons/health.js +11 -4
  61. package/dist/esm/icons/index.js +10 -9
  62. package/dist/esm/icons/input.js +75 -0
  63. package/dist/esm/icons/legal.js +4 -9
  64. package/dist/esm/icons/media.js +26 -11
  65. package/dist/esm/icons/navigation.js +4 -2
  66. package/dist/esm/icons/omniverk.js +19 -6
  67. package/dist/esm/icons/realestate.js +10 -4
  68. package/dist/esm/icons/saas.js +15 -4
  69. package/dist/esm/icons/science.js +6 -3
  70. package/dist/esm/icons/shapes.js +128 -32
  71. package/dist/esm/icons/sports.js +6 -2
  72. package/dist/esm/icons/ui.js +62 -21
  73. package/dist/esm/icons/weather.js +18 -8
  74. package/dist/esm/index.js +10 -9
  75. package/dist/esm/nicetodev-icons.css +1 -1
  76. package/dist/esm/resolver.js +55 -1
  77. package/dist/esm/rsc.js +1 -1
  78. package/dist/esm/utilities.js +4 -2
  79. package/dist/types/design-tokens.d.ts +2 -0
  80. package/dist/types/iconParts.d.ts +19 -0
  81. package/dist/types/icons/actions.d.ts +3 -0
  82. package/dist/types/icons/business.d.ts +2 -0
  83. package/dist/types/icons/ecommerce.d.ts +0 -2
  84. package/dist/types/icons/education.d.ts +1 -0
  85. package/dist/types/icons/files.d.ts +2 -1
  86. package/dist/types/icons/fun.d.ts +6 -1
  87. package/dist/types/icons/gaming.d.ts +2 -0
  88. package/dist/types/icons/index.d.ts +10 -9
  89. package/dist/types/icons/input.d.ts +53 -0
  90. package/dist/types/icons/omniverk.d.ts +0 -2
  91. package/dist/types/icons/shapes.d.ts +6 -0
  92. package/dist/types/icons/ui.d.ts +1 -0
  93. package/dist/types/types.d.ts +6 -0
  94. package/package.json +3 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,543 @@
1
1
  # @nice2dev/icons — Changelog
2
2
 
3
+ ## 1.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 80c2c63: Icon browser feedback, round 29: 28 icons redrawn or fixed.
8
+
9
+ - New icons: `NtdEditDetail` (a pencil on a square frame, like `fa-pen-to-square`), `NtdSmile` and
10
+ `NtdGamepadOldschool`.
11
+ - Renames; the old names stay as `@deprecated` aliases of the same component:
12
+ - `NtdSmiley` → `NtdSmile`.
13
+ - `NtdGamepadController` → `NtdGamepad`. The modern pad (Xbox layout, grips that taper, sticks
14
+ and buttons in the accent colour on `solid`) now renders under `NtdGamepad`. The flat 16-bit
15
+ pad that had this name is now `NtdGamepadOldschool`. Code that imports `NtdGamepad` gets the
16
+ new look; import `NtdGamepadOldschool` to keep the old one.
17
+ - `NtdBilling` is an invoice with a card on it. The card itself is `NtdCreditCard`, which now looks
18
+ like a real card: the stripe higher, a long left-aligned number bar and a CVV box, with the
19
+ details in the accent colour.
20
+ - `cutout`: details drawn in the accent colour stay visible inside the cut, as they do on
21
+ `wireframe`. The mask drew them in black, so they were cut away with the shape.
22
+ - Accent lines that cut a shape are clipped to it and end flush with its edge in every variant.
23
+ Before, they stuck out with round ends. This applies to `NtdEdit`, `NtdCalendar`, `NtdMail`,
24
+ `NtdBriefcase`, `NtdBasketball`, `NtdDatabase`, `NtdCart` and `NtdCreditCard`. A renderer gets
25
+ the prefix for its clip-path ids in the new optional `IconRenderProps.uid`.
26
+ - Redrawn:
27
+ - `NtdDatabase`: three discs.
28
+ - `NtdCart`, `NtdHamburger`.
29
+ - `NtdBook`: pages and the back cover.
30
+ - `NtdSmile` and `NtdSad`: one shared face; an emotion is only its mouth.
31
+ - `NtdBarcode`: eleven narrower bars.
32
+ - `NtdMountain`: the snow cap is in full `secondaryColor`, and `outline` has snow too.
33
+ - Fixed:
34
+ - The tail of the corner arrows meets the arrowhead.
35
+ - `NtdChat`'s tail sits further right.
36
+ - `NtdLab`'s liquid is near the bottom of the flask.
37
+ - `NtdCalendar`'s rings are twice as wide.
38
+ - `NtdBriefcase`'s band is higher.
39
+ - New authored variants: `sharp` for `NtdBookmark` and `NtdFile` (square corners), and `rounded`
40
+ for `NtdCross`. `NtdFile`'s folded corner is in `secondaryColor`.
41
+ - `duotone` uses fills only, with no outline, in:
42
+ - `NtdPhone`: the handle in secondary.
43
+ - `NtdSquare`: left and right halves.
44
+ - `NtdLightning`: two triangles.
45
+ - The faces and the pads.
46
+
47
+ - e4cd134: Icon browser feedback, round 30: 55 icons.
48
+
49
+ - New icons:
50
+ - `NtdAdmin`: NtdUser in a tie.
51
+ - `NtdBookBookmark`: NtdBook with its ribbon. `NtdBook` itself now has a plain cover.
52
+ - Duplicates become `@deprecated` aliases of the icon they duplicated:
53
+ - `NtdZap` → `NtdLightning`
54
+ - `NtdShoppingCart` → `NtdCart`
55
+ - `NtdInvoiceDoc` → `NtdInvoice`
56
+
57
+ The repo's own code uses the new names: ui-enterprise, ui-mobile and the resolver's `zap`.
58
+
59
+ - Stroke glyphs drawn filled now use twice `strokeWidth` and follow it: `solid`, `vivid` and the
60
+ variants built from `solid`. This covers `NtdCheck`, `NtdPlus`, `NtdMinus`, `NtdClose` (which
61
+ ignored `strokeWidth`), `NtdDownload`, `NtdUpload`, `NtdMove`, the four `NtdCorner*` arrows,
62
+ the frame of `NtdEditDetail` and the prompt of `NtdTerminal`.
63
+ - In `sharp`, the arrows' tails stop short of the arrowhead, so their square caps no longer stick
64
+ out of the point: `NtdMove`, `NtdCorner*`, `NtdDownload`, `NtdUpload`.
65
+ - Corners are sharp in every variant but `rounded`:
66
+ - The outlines of `NtdHexagon`, `NtdTriangle`, `NtdCross` and `NtdHome` join with miters.
67
+ - Their `rounded` variant has real rounded corners. Before, it rendered the sharp shape.
68
+ - Paper icons share one page. `NtdFile`, `NtdFileText`, `NtdInvoice` and `NtdContract` use
69
+ NtdFile's page with its larger fold, secondary when filled, and their writing in the accent
70
+ colour:
71
+ - The invoice has rows of item and amount, with the total at the bottom right.
72
+ - The contract has two lines of text and two signature lines.
73
+ - Redrawn:
74
+ - `NtdSettings`: flat-topped teeth. The old round-toothed gear is now its `rounded` variant.
75
+ - `NtdSave`: a floppy disk with a wide shutter and window and a large label. Nothing sticks out
76
+ of the body.
77
+ - `NtdKey`: the bow at the top right with its hole on the key's axis, the teeth at the bottom
78
+ left.
79
+ - `NtdWheelchair`: the rider faces right and leans back, in a full wheel.
80
+ - `NtdLightning`: the step in the middle slants, and the duotone's two halves meet along it.
81
+ - `NtdMusic`: the note heads meet the stems without a step.
82
+ - `NtdDatabase`: three discs in the filled variants. The cap's edge used to read as a fourth.
83
+ - `NtdFire`: centred, with a taller left flame.
84
+ - `NtdMountain`: the snow edge has three uneven notches.
85
+ - `NtdFlag`: the pole is the cloth's left edge, and it is shorter.
86
+ - `NtdHome`: lower walls.
87
+ - Colours and details:
88
+ - `NtdEye`, solid: the eye is primary and the iris is in the accent colour.
89
+ - `NtdGlobe`, solid: filled, with its grid in the accent colour.
90
+ - `NtdGarage`: the door is drawn in the accent colour. Duotone is fills only.
91
+ - `NtdTax`: the percent sign is in the accent colour (it was white) and its dots are rings.
92
+ `NtdPercent`'s dots are rings too.
93
+ - `NtdCalendar`: narrower rings. Duotone is fills only: the header primary, the sheet secondary,
94
+ the dividing line in the accent colour.
95
+ - `NtdLink`, duotone: one ring primary, the other secondary.
96
+ - `NtdAtom`, solid: thinner orbits around a smaller nucleus.
97
+ - `NtdBriefcase`: the band sits lower and has a clasp.
98
+ - `NtdGamepad`: shorter, higher bumper seams, plain sticks, View/Menu closer together.
99
+ - `NtdHamburger`: a plain top bun and a thinner band of sauce.
100
+ - `NtdLab`: the liquid is inset evenly, so the glass is as thick at the walls as at the bottom.
101
+ - `NtdReceipt`: rows with amounts on the right and a total.
102
+ - Smaller fixes:
103
+ - `NtdBank`: taller roof.
104
+ - `NtdClock`: longer hands.
105
+ - `NtdCreditCard`: wider stripe, number lower.
106
+ - `NtdFolder`: wider tab.
107
+ - `NtdSmile`: lower smile.
108
+ - `NtdBook`: the pages reach the right edge.
109
+ - `NtdPadHome` uses NtdHome's house, and the `NtdPadDpad*` arrows are smaller. The matching
110
+ `pad-*` glyphs of ui-core's `NiceIcon` change with them.
111
+ - `variant="3d"` now renders icons whose shape has no height or width, such as `NtdMinus`. The
112
+ filter region was a share of a zero-height bounding box, so they rendered nothing.
113
+
114
+ - ada5a2d: Keyboard, gamepad and remote input for every Nice control (TODO_1.3.0, ADR-005).
115
+
116
+ - `@nice2dev/ui-core` gets the input layer, also as its own entry `@nice2dev/ui-core/input`:
117
+ one engine per page that turns keys, pad buttons and remote keys into intents (`navigate`,
118
+ `activate`, `back`, `secondary`, `tertiary`, `menu`, `view`, `sectionPrev` / `sectionNext`,
119
+ `pagePrev` / `pageNext`, `first` / `last`, `scroll`, `toggleHints`). No animation frame without a
120
+ pad; changes only, no re-render per frame; repeat with acceleration, stick hysteresis, several
121
+ pads, Xbox / PlayStation / Nintendo / Steam / generic families (Nintendo confirms with the right
122
+ button). Pads also emulate the matching key on the focused element, so controls with a keyboard
123
+ pattern work with a pad as they are.
124
+ - Focus without registration: spatial moves between tabbable elements, focus scopes
125
+ (`useFocusScope`, `<NiceFocusScope>`) with memory, wrapping, traps and escalation at an edge,
126
+ regions for F6 / Select, focus recovery when the focused element disappears. Value controls are
127
+ engaged first on a pad (`useEngage`): the d-pad passes them by until A.
128
+ - `useRovingFocus` (APG keys, 1-D and 2-D, typeahead, RTL), `useOverlayFocus` (initial focus,
129
+ trap, Escape / B, overlay stack, return to the opener), `useIntent`, `useInputMethod`,
130
+ `useGamepadFamily`, `useInputPreferences`, `NiceInputProvider` (preferences persisted in
131
+ `NiceUserPreferences` as `global.input`; `useUserPreferencesOptional` added).
132
+ - `@nice2dev/testing`: `mockGamepad()` with a controlled frame clock, `pressKey()`,
133
+ `pressIntent()`, `describeInputContract()` / `runInputContract()`, `stubLayout()` /
134
+ `stubGridLayout()` for jsdom.
135
+ - Focus visibility: in pad and remote modes the ring shows on plain `:focus` (the browsers'
136
+ `:focus-visible` heuristics miss focus moved by a pad); an engaged control wears
137
+ `--nice-focus-ring-engaged`; `scroll-padding` on the root from `--nice-scroll-padding-top` /
138
+ `-bottom`. `NiceDisplayValue` drew no ring: its outline used the box-shadow token as a colour.
139
+ - The old APIs are layers over the engine and `@deprecated` (removal only in a breaking release):
140
+ `useGamepad` reads the engine's frames — no animation loop of its own and no render per frame;
141
+ `NiceSpatialNavProvider` takes intents instead of a `window` keydown listener, so it no longer
142
+ steals the arrow keys of text fields; `useRovingTabIndex` runs on `useRovingFocus` (2-D in
143
+ `grid`); `createNavigationActions` fires once per stick push instead of every frame.
144
+ - Button prompts (B1–B4, B6, B7): 41 glyphs of pad buttons (Xbox, PlayStation, Nintendo, generic
145
+ positions), bumpers, triggers, d-pad, sticks, remote keys and the macOS key symbols — outline
146
+ built-ins of `NiceIcon` and filled, coloured `Ntd*` icons of `@nice2dev/icons` under the same
147
+ names (`pad-xbox-a` → `NtdPadXboxA`); `NiceKeyCap` (words translated, arrows and ⌘ ⌥ ⇧ as
148
+ glyphs); `NiceButtonPrompt` (the button or key of an intent for the device in use, the pad
149
+ family and the user's bindings); `NiceInputHintBar` + `useInputHints` (the actions of the focus
150
+ path); `useNiceAction` (application actions with a key, a pad intent, a scope, `when`,
151
+ `aria-keyshortcuts`, conflict warnings) and `useNiceActions` / `triggerNiceAction` for command
152
+ palettes. `NiceKeyboardHint` is reachable with Tab, draws an icon instead of "?", keycaps, and
153
+ the pad button of shortcuts that carry an `intent` (`COMMON_SHORTCUTS` do); `NiceSkipLink`
154
+ translates its default text. 64 dictionary keys in six languages.
155
+ - `NiceDeviceManager`, the karaoke pad player, the note particles (ui-audio) and the model viewer
156
+ (ui-3d) read pads through the engine (`getInputEngine().gamepadSnapshot`,
157
+ `useConnectedGamepads`). `@nice2dev/ui` re-exports the app-facing part of the input layer.
158
+ - `NiceInputSettings` (new): the input preferences and the rebinding of every intent to keys or a
159
+ pad button, captured from the next press. `NiceCommandPalette` opens on the `menu` intent
160
+ (Ctrl+K, Start, the remote's menu key), keeps focus inside, moves with the d-pad, runs with A
161
+ and lists the `useNiceAction` actions (`includeActions`, default on).
162
+ - Shells are focus scopes (D1, D2): `NiceNavShell`, `NiceAppShell` and the shells of
163
+ `NiceShells` move with the arrows and the d-pad, have F6 / Select regions, switch sections with
164
+ LB / RB and show the hint bar in pad mode (`hintBar`: `bottom` by default, `top`, `none`).
165
+ `NiceNavShell` gets an APG tab strip with a tab menu and moving tabs without dragging
166
+ (Ctrl+Shift+← →), moves focus into the new page after navigating (`focusContentOnNavigate`),
167
+ remembers focus per route and announces the page; `contentArrows: 'native'` gives the arrows
168
+ back to the page.
169
+ - Tabs (C6): every tab list moves with ← → Home End and the d-pad (`useRovingFocus`, also new
170
+ `activateOnMove`). `NiceTabs` links each tab to its panel (`aria-controls` /
171
+ `aria-labelledby`), sets `aria-orientation`, switches with LB / RB in its scope and shows those
172
+ prompts with `showHints`. `NiceCarousel` moves between its dots; ← → on the carousel go on to
173
+ the page at an end without wrapping. The sheet buttons of `NiceSpreadsheet` and the tabs of
174
+ `NiceMobileTabs` are now `role="tab"` with `aria-selected` (they were buttons with
175
+ `aria-pressed` — tests that look them up as buttons must look up tabs); stepping onto "More"
176
+ does not open its sheet.
177
+ - Overlays (C12): every modal, drawer, sheet, popover, lightbox, picker popup and confirmation
178
+ runs on `useOverlayFocus`. Escape / B close only the top overlay — they listened on the
179
+ document before, so one Escape closed every open overlay at once — and focus returns to the
180
+ element that opened it. `useFocusTrap` runs on `useOverlayFocus` (it took its element list
181
+ once, so elements added later broke the trap); a modal no longer pulls focus back from a popup
182
+ opened above it (a select's list portalled after it). An overlay that can be closed shows
183
+ "B Close" in the hint bar (`closeHint`); `useInputHints` takes several publishers per element
184
+ (`fallback` hints give way). Consent dialogs (`NiceCookieConsent`, `NiceGDPRConsent`) keep focus
185
+ until answered. `NiceLightbox`, the mobile `NiceImageGallery`, both print previews and
186
+ `NiceTutorial` take LB / RB (and LT / RT for zoom) on a pad; their keys listen on the overlay
187
+ instead of the window. The context menus (`NiceOverlayContextMenu`, `NiceTouchMenuPopover`)
188
+ open from the menu key, Shift+F10 and X, move with the arrows and letters, and a submenu
189
+ closes on ← / Escape alone. `NiceWindowManager` / `NiceWindow`: windows are F6 / View regions,
190
+ raised when focus enters them, and the taskbar moves with the arrows. `NiceCommandBar` gets
191
+ `aria-activedescendant` and unique ids. The raw glyphs used as icons in `NiceTutorial`, the
192
+ print preview of `@nice2dev/ui-printing` and `NiceGlobalSearch` are `NiceIcon` / `NiceKeyCap`.
193
+ - Menus (C7): `useMenuButton` (new) — ↓ / ↑ on the trigger open the menu on its first / last
194
+ item, the arrows, Home End and letters move, Enter / Space activate items that are not buttons,
195
+ Escape / B, focus leaving and a press outside close it, and a pad's d-pad moves past the trigger
196
+ (A opens). It runs `NiceDropDownButton`, `NiceSpeedDialAction`, `NiceUserMenu`, the extra-action
197
+ menus of `NiceTopNav`, `NiceHamburgerMenu`, the desktop Start menu and the "Open" menu of
198
+ `NiceThemeBuilder`. `NiceUserMenu` and the `NiceTopNav` action menus closed 200 / 180 ms after
199
+ their button lost focus, so focus could never move into them. `NiceTopMenu` is an APG menubar;
200
+ `NiceNavMenu` moves focus into an opened panel (it never did), adds Home / End, moves in two
201
+ dimensions in a mega panel and opens / closes its flyouts from the keyboard; panels opened by
202
+ hovering leave focus where it is. The closed panel of `NiceHamburgerMenu` is inert (Tab reached
203
+ its hidden items). The quick settings of `NiceDeviceTile` are a `dialog`, not a `menu`.
204
+ - Select lists (C3): with the default `searchable`, `NiceSelect` moved focus into a search
205
+ field that had no keys — the list could not be used from the keyboard at all. The field and the
206
+ trigger now share the keys (↑ ↓ PageUp PageDown, Home / End on the trigger, Enter, Escape), the
207
+ list opens on the selected option, names the highlighted one (`aria-activedescendant`), keeps
208
+ it in view and gives focus back to the trigger after a pick; a pad moves and picks in the field.
209
+ The same for `NiceLookup`, `NiceCountryPicker`, `NiceLanguagePicker` and `NiceThemePicker`
210
+ (after a pick from their search field focus was lost to the page), `NiceAutocomplete`,
211
+ `NiceMention` and `NiceSearchInput`. A select open inside a modal now closes alone on Escape.
212
+ `useOverlayFocus` takes `initialFocus: 'none'` and returns focus to the element focused before
213
+ an `autoFocus` child took it.
214
+ - Lists (C8): every list of items is an APG listbox with one tab stop — the arrows, Home End,
215
+ PageUp PageDown and letters move, Enter / Space (A on a pad) pick: `NiceList` (one listbox with
216
+ groups too), both columns of `NicePickList`, `NiceRevisionHistory`, `NiceTaskInbox` and both
217
+ panels of `NiceReconciliationView` (Space picks a row, Enter opens its details as a double
218
+ click does; its rows were `role="row"`, each a tab stop, and `focusStatements()` /
219
+ `focusEntries()` focused nothing). The fields with a list of suggestions drive it from the field
220
+ (`aria-activedescendant`) and with a pad: `NiceTagBox` (a list opened by focus alone has no
221
+ highlight, so Enter still submits a form), `NiceTagInput` (a combobox only with `suggestions`),
222
+ `NiceAccountPicker`, `NiceContactPicker`, `NiceCommandBar` and `NiceGlobalSearch` (Enter and the
223
+ pad took the result from before the filter). The dropdowns of `NiceModeSelector` and
224
+ `NiceDisplayStylePicker` are select-only comboboxes that open on the current item. These fields
225
+ and triggers are `role="combobox"` now — tests that look them up as textboxes or buttons must
226
+ look up comboboxes. Each column of `NiceCascadeSelect` is a listbox: → / Enter go into an
227
+ option's children, ← back; it opens on the selected path and Escape returns focus to the
228
+ trigger. The panel of `NiceIconPicker` is a dialog on the overlay stack (it listened for Escape
229
+ on the document) with a two-dimensional icon grid. The time columns of the `NiceDateTimePicker`
230
+ popup are spinbuttons (Home / End, PageUp / PageDown); the wheel beside them is for the pointer.
231
+ The palette of `NiceWorkflowDesigner` inserts an element on Enter / Space.
232
+ - Trees (C9): `useTreeFocus` (new, also exported from `@nice2dev/ui`) — the APG tree view on
233
+ nested or flat (`aria-level`) trees: one tab stop, ↑ ↓ Home End and letters move, → opens an
234
+ item or enters it, ← closes it or goes to its parent, `*` opens the siblings; Enter / Space and
235
+ a pad's A click the item's row and a pad's X / Shift+F10 open its context menu, so the
236
+ components keep their click handlers. `NiceTreeView` (the items had only the pointer; F2 edits
237
+ and focus comes back after the edit; its context menu is a real menu with focus in it and
238
+ Escape back to the item), `NiceTreeSelect` (↓ / ↑ / Enter on the field open the tree with
239
+ focus in it, ↓ from the search box goes to the tree, a pick returns focus to the field),
240
+ the page tree of `NiceWiki`, the resource tree of `NiceAccessManager` and the mobile tree of
241
+ `NiceTopNav` (each node was two tab stops — its toggle and its link — and the mobile tree had
242
+ `role="tree"` with no items in it).
243
+ - Data grids (C10): `useGridFocus` (new, also exported from `@nice2dev/ui`) — the APG data grid:
244
+ one tab stop, the arrows move by row and column, Home / End along a row, Ctrl+Home / Ctrl+End
245
+ to the corners, PageUp / PageDown by rows; Enter / Space / a pad's A click the cell, and a cell
246
+ holding one control (a header's "toggle all", a row checkbox, a link) is reached on that
247
+ control. `NicePermissionMatrix` (the grants had only the pointer), `NiceModuleGrid` (its cells
248
+ are `gridcell`s now and `role="grid"` sits on the table, no longer on the whole control with
249
+ its toolbar and pagination — tests that look the grid up still find it, by its label too; a
250
+ cell's Enter selects its row, a header's sorts; the mobile cards are a listbox of options, not
251
+ rows), `NiceWarehouseView` (ui-erp; every bin was a tab stop, and a focused bin shows its
252
+ details as a hovered one does). `NiceSpreadsheet` adds Home / End, Ctrl+Home / Ctrl+End and
253
+ PageUp / PageDown.
254
+ - One of several (C4): `NiceSegmentedControl` is a radio group — one tab stop, the arrows (a
255
+ pad's d-pad) move and select; its options were toggle buttons with `aria-pressed`, one tab stop
256
+ each (tests that look them up as pressed buttons must look up checked radios). So are the
257
+ true / false, NPS and star scales of the assessment widgets (`NiceSurvey`, `NiceQuiz`,
258
+ `NicePollLive`). `NiceRadioGroup` and the payment method selector were native radio groups
259
+ already.
260
+ - Sliders (C5): `NiceRangeSlider`'s thumbs had no keys at all — the arrows step, PageUp /
261
+ PageDown take a tenth of the range, Home / End go as far as the thumb may, and they are named
262
+ "Minimum" / "Maximum" with the formatted value as `aria-valuetext`. `NiceKnob`, `NiceTempDial`
263
+ and `NiceRating` add PageUp / PageDown and Home / End; `NiceTempDial` consumes its keys (the
264
+ arrows also scrolled the page, and an engaged pad's d-pad moved focus away instead of stepping).
265
+ - Toolbars (C13): the toolbars of `NiceDocumentEditor`, `NiceImageEditor`, `NicePDFViewer`, the
266
+ file manager, the component playground's canvas and `NiceDock` are one tab stop with the arrows
267
+ along the bar and Home / End between their buttons (their fields and selects keep their own
268
+ keys); they are named, a side dock is a vertical toolbar and a focused dock item magnifies as a
269
+ hovered one does. The file manager's panels name the item under their cursor
270
+ (`aria-activedescendant`) — its rows were no options, so ↑ ↓ moved a cursor no screen reader
271
+ could follow.
272
+ - Dates (C11): `NiceCalendar` is an APG date grid — its days had no keys at all though the hint
273
+ listed them: focus sits on a day (one tab stop), ← → a day, ↑ ↓ a week, Home / End the week,
274
+ PageUp / PageDown a month, Shift+PageUp / PageDown a year, crossing into the next month as
275
+ needed; Enter / Space pick; a pad's LB / RB change the month and LT / RT the year; the month
276
+ and year pickers move in two dimensions and a pick keeps focus in the calendar. The
277
+ `NiceDateTimePicker` field opens its picker with Alt+↓, the context-menu key, Shift+F10 or a
278
+ pad's X (its button is no tab stop), focus on the day; the clock's hour and minute are
279
+ spinbuttons. The single-field `NiceDateRangeBox` opens with Enter / Space / ↓, its popup is on
280
+ the overlay stack (it closed on any Escape on the page) and a picked range returns focus to
281
+ the field. In the engine a read-only text field is not engaged: a pad's A acts as its Enter.
282
+ - Number fields (C2): WAI-ARIA spinbutton keys — ↑ ↓ a step, PageUp / PageDown ten, Home / End
283
+ the minimum / maximum (without a bound they stay the caret's). `NiceNumericInput` had no keys
284
+ at all; `NiceNumberInput` adds the big step and the bounds, a stepped value replaces the typed
285
+ text (it stayed on screen) and a read-only field no longer steps. With `showSteppers`
286
+ `NiceMoneyInput`'s amount is a `spinbutton` with the same keys — its stepper buttons are out of
287
+ the tab order, so the steps were pointer-only (the buttons show `NiceIcon`s instead of "−" /
288
+ "+"); without steppers it stays a text field. On a pad B on an engaged number field cancels:
289
+ the engine puts a native `<input type="number">`'s value from before back, and the new
290
+ `useEngage` option `restoreOnCancel` does it for a custom control (put the value back in
291
+ `onRelease(true)`). LT / RT on an engaged native field (minimum / maximum) went past React's
292
+ value tracker unseen — a controlled input never heard of it. The hint bar names what the
293
+ buttons do on an engaged control — "Adjust", "A Done, B Cancel" on number fields, "Start
294
+ Confirm, B Done" on a text field, "A Select, B Close" with a list open — and follows engaging
295
+ and opening a list (it only changed when focus moved).
296
+ - Composites (C14, part 1): `NiceAccordion` headers move with ↑ ↓ Home / End (each stays a Tab
297
+ stop; `type="button"` — in a form a header submitted it; `aria-controls` only while the panel
298
+ exists). `NiceCollapse`'s panel is named by its trigger; a header-toggled
299
+ `NiceCollapsibleCard` no longer takes Enter / Space from the controls in it. `NiceFAQ`'s
300
+ folded answers are `inert` (their buttons stayed in the Tab order while hidden) and a
301
+ foldable group has a button. `NiceStepper` steps are buttons with `allowStepClick` (pointer
302
+ only before) and the active one is `aria-current="step"`. `NiceWizard` and
303
+ `NiceSetupWizard` step back and on with LB / RB (Ctrl+PageUp / Ctrl+PageDown) — validated as
304
+ the buttons are, with hints; the wizard's progress is a `progressbar`, its step content a
305
+ named `group` (a `tabpanel` without tabs) and its validation error an `alert`; the setup
306
+ wizard's vertical layout moves through the steps with ↑ ↓. `NiceCarousel` waits while the
307
+ pointer is over it or focus is in it, has a button that stops / starts the rotation
308
+ (WCAG 2.2.2 — it never stopped), takes slides out of view out of the Tab order (`inert`),
309
+ announces a slide the user changed and changes slides on LB / RB. `NiceGallery`'s
310
+ thumbnails are one Tab stop (← → Home End move and show), `aria-pressed` on the shown one;
311
+ its autoplay waits the same way; LB / RB change the image. `NicePagination` buttons are
312
+ `type="button"` (in a form, Enter in a field "clicked" First / Previous), pages are named
313
+ ("Page 3"), the ellipsis is hidden, the jump field is labelled, the page change is announced
314
+ and LT / RT (PageUp / PageDown) turn the page, the prev / next buttons showing the triggers
315
+ next to them (B5). In a paged `NiceDataGrid` a pad's LT / RT turn the page from anywhere in
316
+ the grid — the keyboard's PageUp / PageDown stay the cell's. A breadcrumb with only `onClick`
317
+ is a button (an `<a>` without `href` had no Tab stop), separators are hidden. A clickable
318
+ `NiceTag` takes Enter / Space and, when removable, Delete / Backspace; `aria-pressed` with
319
+ `selected`; its remove button names the tag ("Remove: React").
320
+ - Composites (C14, part 2): `NiceColorPicker`'s saturation / brightness box is a slider — it
321
+ took only the pointer (← → saturation, ↑ ↓ brightness, Shift by ten, PageUp / PageDown,
322
+ Home / End); its presets are one Tab stop moved in two dimensions (as its shortcut hint
323
+ already promised), `aria-pressed` on the current one; every channel field is named and a
324
+ disabled picker is no Tab stop. `NiceGradientPicker`'s stops are sliders (← → move,
325
+ Delete removes; focus selects as a click does), its toggle groups show `aria-pressed`, every
326
+ field is named. `NiceColorPalette`'s hue wheel is a slider of the base hue (pointer only
327
+ before); its tints and shades took focus but no keys — one Tab stop now, Enter / Space
328
+ apply; focus into a colour row selects it. `NiceUpload`: an icon-only drop zone is named,
329
+ progress is a `progressbar`, a file's actions name the file and status changes are
330
+ announced. `NiceTutorial` is named by its step and described by its text, says the title of
331
+ a new step (focus stays on the Next button) and goes to the first / last step with Home /
332
+ End. In `useRovingFocus` the pressed button of a toggle group is the initial stop.
333
+ - TV / 10-foot mode (D4): `data-nice-tv` on any element applies the 10-foot variant of the
334
+ theme below it — type of 24–28 px on a 1080p picture, targets of 48–64 px, spacing × 1.5, a
335
+ stronger focus ring (`styles/tv.css`, part of the `@nice2dev/ui` stylesheet); the input engine
336
+ sets it on `<html>` in a TV browser (webOS, Tizen, Android TV …; `engine.isTv`), and
337
+ `NiceKioskShell` / `NiceNavShell` take `tv`, which also keeps a 5 % safe area for overscan.
338
+ Remote keys were already the engine's (A1).
339
+ - `NiceMdiWorkspace` (D1): the tab menu (right click, X on a pad, Shift+F10) is a menu that
340
+ takes focus, moves with ↑ ↓ and closes on Escape / B with focus back on its tab — it was a
341
+ plain box the keyboard never reached; it moves a tab left or right (the way without
342
+ dragging); Delete closes the focused tab; the unsaved-changes question is a modal dialog with
343
+ focus on Cancel; LB / RB (Ctrl+PageUp / Ctrl+PageDown) switch tabs from anywhere in the
344
+ workspace.
345
+ - Hover has a focus counterpart (C15): `NiceRate` previews the focused star; an auto-hidden
346
+ `NiceDockMenu` shows while focus is in it (a Tab reached its buttons while they stayed
347
+ hidden) and its icon or letter items are named by their text; a hover `NicePopover` opens on
348
+ focus of its trigger too and Escape there hides it first; `NiceTimeline` events took only the
349
+ pointer — they are one Tab stop moved by the arrows, Enter / Space open one and focus shows
350
+ its details; `NiceScheduler` events are Tab stops with Enter / Space and their details on
351
+ focus; the comment button of `NiceGitDiffViewer` shows on focus as on hover.
352
+ - Typing with a pad (H1, H2): `NiceOnScreenKeyboard` (new, `@nice2dev/ui`) — the d-pad moves
353
+ over the keys and A types; X deletes, Y types a space, LT / RT move the cursor, LB / RB change
354
+ the layout (letters with the accents of the interface language, symbols, more languages),
355
+ Start confirms and B closes; the buttons show next to their keys in pad mode; a physical
356
+ keyboard and touch type too; `modal={false}` makes it a standing keyboard of a page.
357
+ `NiceOnScreenKeyboardHost` (new) opens it for the text field a pad or remote engages (A on the
358
+ field) — every key goes into the field as typing would (a controlled field hears it in
359
+ `onChange`), Start submits as Enter (a form submits), B leaves the text as it is; number
360
+ fields get digits, a text area new lines; the `onScreenKeyboard` preference turns it off or
361
+ also opens it on touch (kiosks). The application shells render the host. Its layouts are the
362
+ keyboard core now in `@nice2dev/ui-core` (`NICE_KEYBOARD_LAYOUTS`, `buildKeyboardRows`,
363
+ `insertAtCaret` …), which `NiceTouchKeyboard` (ui-mobile) uses too — its exported type names
364
+ are unchanged. New built-in glyphs `key-backspace`, `key-space`, `key-caps` (and
365
+ `NtdKeyBackspace`, `NtdKeySpace`, `NtdKeyCaps` in `@nice2dev/icons`); `setFieldText` writes a
366
+ field's text past React's value tracker.
367
+ - Toasts (D3): `NiceToastContainer` is a region named "Notifications", so F6 or a pad's View
368
+ reaches the toasts while they never take focus; Escape / B dismisses the toast with focus,
369
+ which goes on to the next toast or back where it came from (it was lost with the toast). The
370
+ countdown waits while the pointer is over a toast or focus is in it (WCAG 2.2.1). A toast can
371
+ carry an `action` (`{ label, onClick }`, also in `useNiceToast`'s options, `NiceToastOptions`)
372
+ — it runs and dismisses the toast.
373
+ - `NiceScientificChart` (ui-science): the export buttons had no handler — CSV and JSON of the
374
+ visible data and SVG / PNG of the plot download now, and the new `onExport` takes every format
375
+ over (PDF is offered only with it); the tooltip sits beside the hovered point instead of the
376
+ plot's corner. The VLAN panel of `@nice2dev/ui-buildings` labels its connections with a key of
377
+ their own (in Polish it read "połączeń", the counted form).
378
+ - `NiceCodeEditor`: an inline `lsp={{ … }}` object re-created the Monaco editor on every render,
379
+ dropping its undo history and cursor — it is re-created only when the LSP config's content
380
+ changes. The audio editor's project hooks (`useProjectCRUD`, `useAutoSave`) word their status
381
+ messages and questions through the translator (some were Polish without diacritics).
382
+ - Prompts next to controls (B5): `NiceControlHint`, and `hint` / `showHint` on `NiceButton` — the
383
+ button or keys of its action, shown while hints are visible; keys also become
384
+ `aria-keyshortcuts`. `NiceButton` also passes `role`, `aria-selected`, `aria-pressed`,
385
+ `aria-expanded`, `aria-controls`, `aria-haspopup`, `tabIndex` and `onKeyDown`.
386
+ - Found by the showcase crawler (I4, `scripts/audit-input-crawl.mjs`): **no `NiceButton` showed a
387
+ focus ring** — the display styles write `box-shadow` inline (`none` for the default `flat`) and
388
+ that beat the `:focus-visible` rule; the ring is `!important` now, also for the `underlined` and
389
+ `neumorphic` fields. `NiceCodeEditor`, `NiceCodeDiffEditor`, `NiceSimpleCodeEditor` and
390
+ `NiceMarkdownEditor` were keyboard traps (Tab indents and Shift+Tab outdents, nothing left the
391
+ field): Escape, then Tab moves focus on (WCAG 2.1.2), said in the field's description, and a
392
+ read-only editor lets Tab through (it indented its text); `createTabEscape()` (new, ui-core
393
+ and ui) gives a control of your own the same. These editors, `NiceHtmlEditor`,
394
+ `NiceTerminalUI` and the search of `NicePickList` drew no focus at all — their frame shows the
395
+ ring now. The diagram buttons of `NiceGamepad` were pointer-only, so arming a button for an
396
+ assignment took a mouse: with a handler or an action tree they are buttons (one Tab stop, the
397
+ arrows move by geometry, Enter / Space / A press, `aria-pressed` while armed); an SVG element
398
+ has no `click()`, so a pad's A dispatches a click to one (`clickElement`, new). A sortable
399
+ `NiceDataGrid` header sorted only on a click: it is a Tab stop and sorts on
400
+ Enter / Space / A. `NicePasswordInput`'s show / hide button is a Tab stop (showing the password
401
+ took a pointer). The `NiceDateTimePicker` field says how its picker opens (`aria-haspopup`,
402
+ `aria-keyshortcuts="Alt+ArrowDown"`).
403
+ - More from the crawler (I4). `NiceDataGrid` took keys from anything inside it: with a focused
404
+ cell Tab never left the grid (a trap, also from a header) and the search field's arrows did
405
+ not move its caret — the cell cursor follows only the grid's own focus, and Tab at the edge of
406
+ a row leaves. `NiceSpreadsheet`'s formula bar kept Tab without an edit. `NiceModelEditor`
407
+ (ui-3d) listened on the whole page: Tab cycled its mode anywhere (focus moved nowhere on a page
408
+ with the editor), Space pressed no button and Ctrl+Z took the undo of every text field — its
409
+ shortcuts work inside the editor only, Tab and Space on its controls are theirs, Escape then
410
+ Tab leaves the viewport. `NiceDocumentEditor` indents a block on Tab and lets the keyboard out
411
+ as the code editors do (Escape, then Tab; its shortcut list says so). `NicePlaylistDualPane` (ui-audio)
412
+ switches panes on Tab, and Escape then Tab moves on. `NiceSeatingChart` / `NiceSeatPicker`
413
+ (events) take focus to the cursor seat — it stayed on the chart, out of a screen reader's
414
+ reach. Rings where there were none: the cursor row of `NiceKaraokeSongBrowser` (it looked the
415
+ same focused as not), `NiceFileManager`'s panels, `NiceTagInput`, the name field of
416
+ `NiceWorkflowDesigner`, `NiceDocumentEditor`, the chat and search fields of ui-communication
417
+ (`outline: none` inline), the search of `NiceGlobalSearch` and `NiceAccessLog`
418
+ (ui-enterprise), the fields of `NiceTaskManager` and `NiceTorrentUI` (templates) and of the
419
+ automation and scene editors (ui-buildings), the viewport of `NiceModelViewer` (ui-3d).
420
+ - `useOverlayFocus` gave focus back to the opener whenever an overlay closed with focus on the
421
+ page body — also for the moment of a Tab, when the opener's blur closed a popup it showed on
422
+ focus: a `NiceDataGrid` header with column stats took focus back on every Tab, a trap. Focus
423
+ goes back now only when it was in the overlay. The keyboard shortcuts of `GenericPlayer`
424
+ (ui-audio) and `NicePresentationPlayer` (ui-presentations) listened on the whole page — the
425
+ arrows of every list and a pad's d-pad (they move focus with them) did nothing on a page with a
426
+ player, Space pressed no button, and with a presentation Backspace deleted nothing and Enter
427
+ submitted nothing in any field; they work in the player or with focus on the page body, and
428
+ Space / Enter on the player's own buttons press them. A pad has no Tab: on a control of a
429
+ player its d-pad moves focus (as seek, volume or the next slide it kept focus in the player for
430
+ good); on the player itself or the page body a remote's arrows still turn the slides.
431
+ - Lint (I2): the whole jsx-a11y recommended set is on, with the input program's own rules against
432
+ page-wide key listeners and inline `outline: 'none'`. Found on the way: the reply box of
433
+ `NiceHelpdesk` and the search of `NiceCommandBar` took the outline away and showed nothing
434
+ instead — they show focus now.
435
+ - `NicePopover` (the one anchored to a `targetRef`) had no keyboard at all — it closed only on a
436
+ click outside it. It is a `dialog` named by its `title`, takes focus when it opens, closes on
437
+ Escape / B and gives focus back to its target (tests that count the page's dialogs see it now).
438
+ A pick in a `NiceSelect` inside it closed it and was lost (the select's list is portalled out
439
+ of the popover): such a click keeps it open.
440
+ - Rows, cards, tiles and list entries that answered a pointer only (C1) are buttons for the
441
+ keyboard and the pad: `role="button"`, a Tab stop, Enter / Space / A press them — a selection
442
+ toggle says `aria-pressed`, a folder or summary row `aria-expanded`, a check box drawn with a
443
+ `div` is a `checkbox` with its item's name. `clickOnActivationKey` (new, ui-core and ui) is the
444
+ `onKeyDown` for such an element: Enter and Space click it, once per press and with the
445
+ modifiers, so Ctrl+Enter selects as Ctrl+click does; keys of a control inside it stay that
446
+ control's. Dialog backdrops and click stoppers are `role="presentation"` (Escape / B close the
447
+ dialogs). Done so far in events (attraction picker and voting, round list), game-engine (the
448
+ Godot, Unity and Unreal project browsers, the asset store, the editor's hierarchy), licensing
449
+ (portal, transfer, the license table), templates (health, life dashboard, personal finance,
450
+ task manager, torrent UI) and `OmniWerkLogo`, whose `role="button"` took no key; ui-3d (model
451
+ editor outliner with expand / show-hide buttons, Add menu, context menu, timeline, particle
452
+ editor), ui-ai (dataset, experiment, model and labeling cards), ui-api (endpoints, schemas,
453
+ history), ui-audio (sample browser, bar-fill swatches, DMX cues and tracks, the "activate
454
+ audio" overlay, playlist grid / overview / sidebar / search / tags / track list),
455
+ ui-bi (ETL palette and nodes), ui-buildings (automations, zone card, scenes, network paths,
456
+ object library), ui-diagrams, ui-enterprise (access log, contract sections), ui-erp (capacity
457
+ planner — its time cells are named buttons, the only way to add an allocation — and inventory
458
+ cards), ui-forms, and in ui-core `NiceIcon` and `NiceTouchTarget` with an `onClick` and the
459
+ profiler's header — `NiceTouchTarget` also draws a focus ring now; ui-graphics (font glyphs, 2D game asset lists and state nodes, photo
460
+ overlays and colour swatches, pixel layers with show / lock buttons, palette and frames,
461
+ texture and UI designer layers, vector gradients and layers), ui-iot cards, ui-math templates,
462
+ ui-monitoring (saved queries, expandable log rows), ui-presentations (slide thumbnails and the
463
+ overview), ui-printing (template cards, schema fields, layers), ui-science (citations,
464
+ notebooks) and ui-video (live sources, timeline tracks and clips). A clickable `NiceIcon` is a
465
+ button now. `ImportPreviewDialog` (ui-buildings) carried `role="dialog"` on its backdrop — it
466
+ is on the dialog box now. The wheel of `NiceMobilePicker` still has no keys (it gets a
467
+ spinbutton column with E). Tests that count the buttons of these components find more.
468
+ - C1 in `@nice2dev/ui`: the rows, cards and items of the devops, data-branching, media, no-code,
469
+ tools, backup and chart components are buttons (selection toggles `aria-pressed`, folding rows
470
+ `aria-expanded`); a `NiceKanbanBoard` card that opens on a click and a `NiceTileView` tile with
471
+ `onTileClick` are buttons; `NiceTreeList` rows fold from the keyboard (the toggle is a named
472
+ button with `aria-expanded`); `NiceDataGrid`'s virtual group rows and detail toggles take
473
+ Enter / Space. A built-in `NiceIcon` with `onClick` is a button — it was `aria-hidden` and took
474
+ no key. `NiceSelect`, `NiceCountryPicker`, `NiceLanguagePicker` and `NiceThemePicker` clear with
475
+ Delete / Backspace on the trigger (`aria-keyshortcuts="Delete"`): the × in the trigger was
476
+ pointer-only (in `NiceSelect` a `role="button"` inside the trigger button) and is
477
+ `role="presentation"` now. `NiceModal`, `NiceConfirmDialog`, `NiceCommandPalette` and
478
+ `NiceGlobalSearch` stop clicks at the backdrop instead of the dialog — a click on the backdrop
479
+ itself closes, and no click inside or on it reaches a component around the overlay.
480
+ `NiceHtmlEditor`'s template list is a menu with keys, its emoji are buttons; `NiceGitManager`
481
+ opens a file's diff from its path, a button (a click elsewhere on the row did it before);
482
+ `NiceResourceAllocation`'s days are named buttons with `onSlotClick`. Options of comboboxes and
483
+ items of menus, trees and grids keep their click with a line disable naming the keys that
484
+ drive them. The empty cells of `NiceScheduler`'s grids get their keys with E.
485
+
486
+ ### Patch Changes
487
+
488
+ - 325df23: Icon browser feedback, round 31:
489
+
490
+ - `NtdDatabase`: the gaps between the discs are bands of even height, cut square at the sides. A
491
+ stroked arc clipped to the body used to thin to a wedge there. The silhouette is now one path,
492
+ so no seam shows along the cap.
493
+ - `NtdMountain`: the snow is in the accent colour, and in secondary in duotone and vivid.
494
+ - `NtdLab`: bubbles only in vivid, as accent dots in a secondary liquid. In the other filled
495
+ variants the liquid is in the accent colour.
496
+ - `NtdAtom`: the nucleus is in the accent colour in every variant that fills it.
497
+ - `NtdSave`: a shorter shutter and a taller label.
498
+ - `NtdInvoice`: the writing sits a little lower, with wider gaps between items and amounts.
499
+ - `NtdReceipt`: the amounts sit further right.
500
+ - `NtdBank`: a taller roof.
501
+
502
+ ## 1.2.2
503
+
504
+ ### Patch Changes
505
+
506
+ - 06eb0d2: 1.2.2 — library texts through the translator, a translator in the packages that had none, and the
507
+ end of the hook-dependency warnings. Nothing removed or renamed. Upgrade notes:
508
+ `documentation/omniverk/OMNIVERK_UPGRADE_1.2.2.md`.
509
+
510
+ **Translations.** 2,825 new keys in the global dictionary (en, pl, de, fr, es, uk), 80 in the local
511
+ dictionaries of ui-math, ui-diagrams and ui-presentations: column headers, option labels, texts in
512
+ conditions and templates, messages given to setters, labels returned by helpers, Polish texts that
513
+ were the English default. Relative dates through `Intl.RelativeTimeFormat`, plural forms through
514
+ `…One` / `…Many` keys. ui-science, ui-platform, ui-mobile, auth, licensing, templates, social and
515
+ the icon tools translate through `useNiceTranslation` (new peer `@nice2dev/ui-core ^1.2.0`);
516
+ ui-security reads the global translator when its own provider is absent.
517
+
518
+ **Additions.** `labelKey` on ui-mobile `TabItem` and `SwipeAction` (the presets set it);
519
+ `registerWebAuthn` / `authenticateWebAuthn` take the WebAuthn options `NiceWebAuthnButton` used to
520
+ drop (defaults unchanged); `NiceKeyboardHint` shows `descriptionKey`. Eight icons in
521
+ `@nice2dev/icons` — `NtdPoint`, `NtdSegment`, `NtdPerpendicular`, `NtdParallel`, `NtdMidpoint`,
522
+ `NtdAngleBisector`, `NtdGroup`, `NtdUngroup` — and the same names as `NiceIcon` built-ins.
523
+
524
+ **Behaviour changes, agreed.** ui-math, ui-diagrams and ui-presentations follow the app's global
525
+ `NiceI18nProvider` language when their own provider is absent (they stayed English);
526
+ `NicePresentationEditor` without `lang` takes the surrounding language. Icons drawn as glyphs are
527
+ Nice icons: the `NiceGeometry` tools, Align / Group / Ungroup / Layout of the diagram toolbar, the
528
+ presentation grid toggle, zoom and "Add Track" of `NiceDMXTimeline`. icons-gaming and
529
+ icons-filetypes name an icon by its `title` and are decorative without one, like `createIcon`
530
+ (screen readers read "GiHeart" or "DOCX file icon"); new optional `title` on the gaming icon props.
531
+
532
+ **Hook dependencies (161 → 0).** Fixed along the way: `NiceLowPowerMode` re-rendered forever from
533
+ mount and overflowed the stack on wake; `GenericPlayer` / `NiceGenericPlayerStage` restarted the
534
+ track on a volume change; `NiceDMXTimeline` called `onPlay` on every frame and missed cues added
535
+ during playback; `NiceConflictResolution` `autoResolve` never resolved; `NiceMAM` selected by the
536
+ previous filter; `NiceRulesEngine` "Run All" kept only the last result; `NiceCodeEditor` saved with
537
+ the first render's `onSave`; a consumer's cursor handler switched off `NiceCodeEditorAI`
538
+ completion; `useRadioStream` lost a volume set before the first play; `NiceGameEditor` shortcuts,
539
+ `useVoiceControl` continuous sessions, `NiceDeviceTrust` with a host storing the score.
540
+
3
541
  ## 1.2.1
4
542
 
5
543
  ### Patch Changes