@nice2dev/ui-presentations 1.2.2 → 1.3.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 CHANGED
@@ -1,5 +1,385 @@
1
1
  # @nice2dev/ui-presentations — Changelog
2
2
 
3
+ ## 1.3.1
4
+
5
+ No changes in this release.
6
+
7
+ ## 1.3.0
8
+
9
+ ### Patch Changes
10
+
11
+ - ada5a2d: Keyboard, gamepad and remote input for every Nice control (TODO_1.3.0, ADR-005).
12
+
13
+ - `@nice2dev/ui-core` gets the input layer, also as its own entry `@nice2dev/ui-core/input`:
14
+ one engine per page that turns keys, pad buttons and remote keys into intents (`navigate`,
15
+ `activate`, `back`, `secondary`, `tertiary`, `menu`, `view`, `sectionPrev` / `sectionNext`,
16
+ `pagePrev` / `pageNext`, `first` / `last`, `scroll`, `toggleHints`). No animation frame without a
17
+ pad; changes only, no re-render per frame; repeat with acceleration, stick hysteresis, several
18
+ pads, Xbox / PlayStation / Nintendo / Steam / generic families (Nintendo confirms with the right
19
+ button). Pads also emulate the matching key on the focused element, so controls with a keyboard
20
+ pattern work with a pad as they are.
21
+ - Focus without registration: spatial moves between tabbable elements, focus scopes
22
+ (`useFocusScope`, `<NiceFocusScope>`) with memory, wrapping, traps and escalation at an edge,
23
+ regions for F6 / Select, focus recovery when the focused element disappears. Value controls are
24
+ engaged first on a pad (`useEngage`): the d-pad passes them by until A.
25
+ - `useRovingFocus` (APG keys, 1-D and 2-D, typeahead, RTL), `useOverlayFocus` (initial focus,
26
+ trap, Escape / B, overlay stack, return to the opener), `useIntent`, `useInputMethod`,
27
+ `useGamepadFamily`, `useInputPreferences`, `NiceInputProvider` (preferences persisted in
28
+ `NiceUserPreferences` as `global.input`; `useUserPreferencesOptional` added).
29
+ - `@nice2dev/testing`: `mockGamepad()` with a controlled frame clock, `pressKey()`,
30
+ `pressIntent()`, `describeInputContract()` / `runInputContract()`, `stubLayout()` /
31
+ `stubGridLayout()` for jsdom.
32
+ - Focus visibility: in pad and remote modes the ring shows on plain `:focus` (the browsers'
33
+ `:focus-visible` heuristics miss focus moved by a pad); an engaged control wears
34
+ `--nice-focus-ring-engaged`; `scroll-padding` on the root from `--nice-scroll-padding-top` /
35
+ `-bottom`. `NiceDisplayValue` drew no ring: its outline used the box-shadow token as a colour.
36
+ - The old APIs are layers over the engine and `@deprecated` (removal only in a breaking release):
37
+ `useGamepad` reads the engine's frames — no animation loop of its own and no render per frame;
38
+ `NiceSpatialNavProvider` takes intents instead of a `window` keydown listener, so it no longer
39
+ steals the arrow keys of text fields; `useRovingTabIndex` runs on `useRovingFocus` (2-D in
40
+ `grid`); `createNavigationActions` fires once per stick push instead of every frame.
41
+ - Button prompts (B1–B4, B6, B7): 41 glyphs of pad buttons (Xbox, PlayStation, Nintendo, generic
42
+ positions), bumpers, triggers, d-pad, sticks, remote keys and the macOS key symbols — outline
43
+ built-ins of `NiceIcon` and filled, coloured `Ntd*` icons of `@nice2dev/icons` under the same
44
+ names (`pad-xbox-a` → `NtdPadXboxA`); `NiceKeyCap` (words translated, arrows and ⌘ ⌥ ⇧ as
45
+ glyphs); `NiceButtonPrompt` (the button or key of an intent for the device in use, the pad
46
+ family and the user's bindings); `NiceInputHintBar` + `useInputHints` (the actions of the focus
47
+ path); `useNiceAction` (application actions with a key, a pad intent, a scope, `when`,
48
+ `aria-keyshortcuts`, conflict warnings) and `useNiceActions` / `triggerNiceAction` for command
49
+ palettes. `NiceKeyboardHint` is reachable with Tab, draws an icon instead of "?", keycaps, and
50
+ the pad button of shortcuts that carry an `intent` (`COMMON_SHORTCUTS` do); `NiceSkipLink`
51
+ translates its default text. 64 dictionary keys in six languages.
52
+ - `NiceDeviceManager`, the karaoke pad player, the note particles (ui-audio) and the model viewer
53
+ (ui-3d) read pads through the engine (`getInputEngine().gamepadSnapshot`,
54
+ `useConnectedGamepads`). `@nice2dev/ui` re-exports the app-facing part of the input layer.
55
+ - `NiceInputSettings` (new): the input preferences and the rebinding of every intent to keys or a
56
+ pad button, captured from the next press. `NiceCommandPalette` opens on the `menu` intent
57
+ (Ctrl+K, Start, the remote's menu key), keeps focus inside, moves with the d-pad, runs with A
58
+ and lists the `useNiceAction` actions (`includeActions`, default on).
59
+ - Shells are focus scopes (D1, D2): `NiceNavShell`, `NiceAppShell` and the shells of
60
+ `NiceShells` move with the arrows and the d-pad, have F6 / Select regions, switch sections with
61
+ LB / RB and show the hint bar in pad mode (`hintBar`: `bottom` by default, `top`, `none`).
62
+ `NiceNavShell` gets an APG tab strip with a tab menu and moving tabs without dragging
63
+ (Ctrl+Shift+← →), moves focus into the new page after navigating (`focusContentOnNavigate`),
64
+ remembers focus per route and announces the page; `contentArrows: 'native'` gives the arrows
65
+ back to the page.
66
+ - Tabs (C6): every tab list moves with ← → Home End and the d-pad (`useRovingFocus`, also new
67
+ `activateOnMove`). `NiceTabs` links each tab to its panel (`aria-controls` /
68
+ `aria-labelledby`), sets `aria-orientation`, switches with LB / RB in its scope and shows those
69
+ prompts with `showHints`. `NiceCarousel` moves between its dots; ← → on the carousel go on to
70
+ the page at an end without wrapping. The sheet buttons of `NiceSpreadsheet` and the tabs of
71
+ `NiceMobileTabs` are now `role="tab"` with `aria-selected` (they were buttons with
72
+ `aria-pressed` — tests that look them up as buttons must look up tabs); stepping onto "More"
73
+ does not open its sheet.
74
+ - Overlays (C12): every modal, drawer, sheet, popover, lightbox, picker popup and confirmation
75
+ runs on `useOverlayFocus`. Escape / B close only the top overlay — they listened on the
76
+ document before, so one Escape closed every open overlay at once — and focus returns to the
77
+ element that opened it. `useFocusTrap` runs on `useOverlayFocus` (it took its element list
78
+ once, so elements added later broke the trap); a modal no longer pulls focus back from a popup
79
+ opened above it (a select's list portalled after it). An overlay that can be closed shows
80
+ "B Close" in the hint bar (`closeHint`); `useInputHints` takes several publishers per element
81
+ (`fallback` hints give way). Consent dialogs (`NiceCookieConsent`, `NiceGDPRConsent`) keep focus
82
+ until answered. `NiceLightbox`, the mobile `NiceImageGallery`, both print previews and
83
+ `NiceTutorial` take LB / RB (and LT / RT for zoom) on a pad; their keys listen on the overlay
84
+ instead of the window. The context menus (`NiceOverlayContextMenu`, `NiceTouchMenuPopover`)
85
+ open from the menu key, Shift+F10 and X, move with the arrows and letters, and a submenu
86
+ closes on ← / Escape alone. `NiceWindowManager` / `NiceWindow`: windows are F6 / View regions,
87
+ raised when focus enters them, and the taskbar moves with the arrows. `NiceCommandBar` gets
88
+ `aria-activedescendant` and unique ids. The raw glyphs used as icons in `NiceTutorial`, the
89
+ print preview of `@nice2dev/ui-printing` and `NiceGlobalSearch` are `NiceIcon` / `NiceKeyCap`.
90
+ - Menus (C7): `useMenuButton` (new) — ↓ / ↑ on the trigger open the menu on its first / last
91
+ item, the arrows, Home End and letters move, Enter / Space activate items that are not buttons,
92
+ Escape / B, focus leaving and a press outside close it, and a pad's d-pad moves past the trigger
93
+ (A opens). It runs `NiceDropDownButton`, `NiceSpeedDialAction`, `NiceUserMenu`, the extra-action
94
+ menus of `NiceTopNav`, `NiceHamburgerMenu`, the desktop Start menu and the "Open" menu of
95
+ `NiceThemeBuilder`. `NiceUserMenu` and the `NiceTopNav` action menus closed 200 / 180 ms after
96
+ their button lost focus, so focus could never move into them. `NiceTopMenu` is an APG menubar;
97
+ `NiceNavMenu` moves focus into an opened panel (it never did), adds Home / End, moves in two
98
+ dimensions in a mega panel and opens / closes its flyouts from the keyboard; panels opened by
99
+ hovering leave focus where it is. The closed panel of `NiceHamburgerMenu` is inert (Tab reached
100
+ its hidden items). The quick settings of `NiceDeviceTile` are a `dialog`, not a `menu`.
101
+ - Select lists (C3): with the default `searchable`, `NiceSelect` moved focus into a search
102
+ field that had no keys — the list could not be used from the keyboard at all. The field and the
103
+ trigger now share the keys (↑ ↓ PageUp PageDown, Home / End on the trigger, Enter, Escape), the
104
+ list opens on the selected option, names the highlighted one (`aria-activedescendant`), keeps
105
+ it in view and gives focus back to the trigger after a pick; a pad moves and picks in the field.
106
+ The same for `NiceLookup`, `NiceCountryPicker`, `NiceLanguagePicker` and `NiceThemePicker`
107
+ (after a pick from their search field focus was lost to the page), `NiceAutocomplete`,
108
+ `NiceMention` and `NiceSearchInput`. A select open inside a modal now closes alone on Escape.
109
+ `useOverlayFocus` takes `initialFocus: 'none'` and returns focus to the element focused before
110
+ an `autoFocus` child took it.
111
+ - Lists (C8): every list of items is an APG listbox with one tab stop — the arrows, Home End,
112
+ PageUp PageDown and letters move, Enter / Space (A on a pad) pick: `NiceList` (one listbox with
113
+ groups too), both columns of `NicePickList`, `NiceRevisionHistory`, `NiceTaskInbox` and both
114
+ panels of `NiceReconciliationView` (Space picks a row, Enter opens its details as a double
115
+ click does; its rows were `role="row"`, each a tab stop, and `focusStatements()` /
116
+ `focusEntries()` focused nothing). The fields with a list of suggestions drive it from the field
117
+ (`aria-activedescendant`) and with a pad: `NiceTagBox` (a list opened by focus alone has no
118
+ highlight, so Enter still submits a form), `NiceTagInput` (a combobox only with `suggestions`),
119
+ `NiceAccountPicker`, `NiceContactPicker`, `NiceCommandBar` and `NiceGlobalSearch` (Enter and the
120
+ pad took the result from before the filter). The dropdowns of `NiceModeSelector` and
121
+ `NiceDisplayStylePicker` are select-only comboboxes that open on the current item. These fields
122
+ and triggers are `role="combobox"` now — tests that look them up as textboxes or buttons must
123
+ look up comboboxes. Each column of `NiceCascadeSelect` is a listbox: → / Enter go into an
124
+ option's children, ← back; it opens on the selected path and Escape returns focus to the
125
+ trigger. The panel of `NiceIconPicker` is a dialog on the overlay stack (it listened for Escape
126
+ on the document) with a two-dimensional icon grid. The time columns of the `NiceDateTimePicker`
127
+ popup are spinbuttons (Home / End, PageUp / PageDown); the wheel beside them is for the pointer.
128
+ The palette of `NiceWorkflowDesigner` inserts an element on Enter / Space.
129
+ - Trees (C9): `useTreeFocus` (new, also exported from `@nice2dev/ui`) — the APG tree view on
130
+ nested or flat (`aria-level`) trees: one tab stop, ↑ ↓ Home End and letters move, → opens an
131
+ item or enters it, ← closes it or goes to its parent, `*` opens the siblings; Enter / Space and
132
+ a pad's A click the item's row and a pad's X / Shift+F10 open its context menu, so the
133
+ components keep their click handlers. `NiceTreeView` (the items had only the pointer; F2 edits
134
+ and focus comes back after the edit; its context menu is a real menu with focus in it and
135
+ Escape back to the item), `NiceTreeSelect` (↓ / ↑ / Enter on the field open the tree with
136
+ focus in it, ↓ from the search box goes to the tree, a pick returns focus to the field),
137
+ the page tree of `NiceWiki`, the resource tree of `NiceAccessManager` and the mobile tree of
138
+ `NiceTopNav` (each node was two tab stops — its toggle and its link — and the mobile tree had
139
+ `role="tree"` with no items in it).
140
+ - Data grids (C10): `useGridFocus` (new, also exported from `@nice2dev/ui`) — the APG data grid:
141
+ one tab stop, the arrows move by row and column, Home / End along a row, Ctrl+Home / Ctrl+End
142
+ to the corners, PageUp / PageDown by rows; Enter / Space / a pad's A click the cell, and a cell
143
+ holding one control (a header's "toggle all", a row checkbox, a link) is reached on that
144
+ control. `NicePermissionMatrix` (the grants had only the pointer), `NiceModuleGrid` (its cells
145
+ are `gridcell`s now and `role="grid"` sits on the table, no longer on the whole control with
146
+ its toolbar and pagination — tests that look the grid up still find it, by its label too; a
147
+ cell's Enter selects its row, a header's sorts; the mobile cards are a listbox of options, not
148
+ rows), `NiceWarehouseView` (ui-erp; every bin was a tab stop, and a focused bin shows its
149
+ details as a hovered one does). `NiceSpreadsheet` adds Home / End, Ctrl+Home / Ctrl+End and
150
+ PageUp / PageDown.
151
+ - One of several (C4): `NiceSegmentedControl` is a radio group — one tab stop, the arrows (a
152
+ pad's d-pad) move and select; its options were toggle buttons with `aria-pressed`, one tab stop
153
+ each (tests that look them up as pressed buttons must look up checked radios). So are the
154
+ true / false, NPS and star scales of the assessment widgets (`NiceSurvey`, `NiceQuiz`,
155
+ `NicePollLive`). `NiceRadioGroup` and the payment method selector were native radio groups
156
+ already.
157
+ - Sliders (C5): `NiceRangeSlider`'s thumbs had no keys at all — the arrows step, PageUp /
158
+ PageDown take a tenth of the range, Home / End go as far as the thumb may, and they are named
159
+ "Minimum" / "Maximum" with the formatted value as `aria-valuetext`. `NiceKnob`, `NiceTempDial`
160
+ and `NiceRating` add PageUp / PageDown and Home / End; `NiceTempDial` consumes its keys (the
161
+ arrows also scrolled the page, and an engaged pad's d-pad moved focus away instead of stepping).
162
+ - Toolbars (C13): the toolbars of `NiceDocumentEditor`, `NiceImageEditor`, `NicePDFViewer`, the
163
+ file manager, the component playground's canvas and `NiceDock` are one tab stop with the arrows
164
+ along the bar and Home / End between their buttons (their fields and selects keep their own
165
+ keys); they are named, a side dock is a vertical toolbar and a focused dock item magnifies as a
166
+ hovered one does. The file manager's panels name the item under their cursor
167
+ (`aria-activedescendant`) — its rows were no options, so ↑ ↓ moved a cursor no screen reader
168
+ could follow.
169
+ - Dates (C11): `NiceCalendar` is an APG date grid — its days had no keys at all though the hint
170
+ listed them: focus sits on a day (one tab stop), ← → a day, ↑ ↓ a week, Home / End the week,
171
+ PageUp / PageDown a month, Shift+PageUp / PageDown a year, crossing into the next month as
172
+ needed; Enter / Space pick; a pad's LB / RB change the month and LT / RT the year; the month
173
+ and year pickers move in two dimensions and a pick keeps focus in the calendar. The
174
+ `NiceDateTimePicker` field opens its picker with Alt+↓, the context-menu key, Shift+F10 or a
175
+ pad's X (its button is no tab stop), focus on the day; the clock's hour and minute are
176
+ spinbuttons. The single-field `NiceDateRangeBox` opens with Enter / Space / ↓, its popup is on
177
+ the overlay stack (it closed on any Escape on the page) and a picked range returns focus to
178
+ the field. In the engine a read-only text field is not engaged: a pad's A acts as its Enter.
179
+ - Number fields (C2): WAI-ARIA spinbutton keys — ↑ ↓ a step, PageUp / PageDown ten, Home / End
180
+ the minimum / maximum (without a bound they stay the caret's). `NiceNumericInput` had no keys
181
+ at all; `NiceNumberInput` adds the big step and the bounds, a stepped value replaces the typed
182
+ text (it stayed on screen) and a read-only field no longer steps. With `showSteppers`
183
+ `NiceMoneyInput`'s amount is a `spinbutton` with the same keys — its stepper buttons are out of
184
+ the tab order, so the steps were pointer-only (the buttons show `NiceIcon`s instead of "−" /
185
+ "+"); without steppers it stays a text field. On a pad B on an engaged number field cancels:
186
+ the engine puts a native `<input type="number">`'s value from before back, and the new
187
+ `useEngage` option `restoreOnCancel` does it for a custom control (put the value back in
188
+ `onRelease(true)`). LT / RT on an engaged native field (minimum / maximum) went past React's
189
+ value tracker unseen — a controlled input never heard of it. The hint bar names what the
190
+ buttons do on an engaged control — "Adjust", "A Done, B Cancel" on number fields, "Start
191
+ Confirm, B Done" on a text field, "A Select, B Close" with a list open — and follows engaging
192
+ and opening a list (it only changed when focus moved).
193
+ - Composites (C14, part 1): `NiceAccordion` headers move with ↑ ↓ Home / End (each stays a Tab
194
+ stop; `type="button"` — in a form a header submitted it; `aria-controls` only while the panel
195
+ exists). `NiceCollapse`'s panel is named by its trigger; a header-toggled
196
+ `NiceCollapsibleCard` no longer takes Enter / Space from the controls in it. `NiceFAQ`'s
197
+ folded answers are `inert` (their buttons stayed in the Tab order while hidden) and a
198
+ foldable group has a button. `NiceStepper` steps are buttons with `allowStepClick` (pointer
199
+ only before) and the active one is `aria-current="step"`. `NiceWizard` and
200
+ `NiceSetupWizard` step back and on with LB / RB (Ctrl+PageUp / Ctrl+PageDown) — validated as
201
+ the buttons are, with hints; the wizard's progress is a `progressbar`, its step content a
202
+ named `group` (a `tabpanel` without tabs) and its validation error an `alert`; the setup
203
+ wizard's vertical layout moves through the steps with ↑ ↓. `NiceCarousel` waits while the
204
+ pointer is over it or focus is in it, has a button that stops / starts the rotation
205
+ (WCAG 2.2.2 — it never stopped), takes slides out of view out of the Tab order (`inert`),
206
+ announces a slide the user changed and changes slides on LB / RB. `NiceGallery`'s
207
+ thumbnails are one Tab stop (← → Home End move and show), `aria-pressed` on the shown one;
208
+ its autoplay waits the same way; LB / RB change the image. `NicePagination` buttons are
209
+ `type="button"` (in a form, Enter in a field "clicked" First / Previous), pages are named
210
+ ("Page 3"), the ellipsis is hidden, the jump field is labelled, the page change is announced
211
+ and LT / RT (PageUp / PageDown) turn the page, the prev / next buttons showing the triggers
212
+ next to them (B5). In a paged `NiceDataGrid` a pad's LT / RT turn the page from anywhere in
213
+ the grid — the keyboard's PageUp / PageDown stay the cell's. A breadcrumb with only `onClick`
214
+ is a button (an `<a>` without `href` had no Tab stop), separators are hidden. A clickable
215
+ `NiceTag` takes Enter / Space and, when removable, Delete / Backspace; `aria-pressed` with
216
+ `selected`; its remove button names the tag ("Remove: React").
217
+ - Composites (C14, part 2): `NiceColorPicker`'s saturation / brightness box is a slider — it
218
+ took only the pointer (← → saturation, ↑ ↓ brightness, Shift by ten, PageUp / PageDown,
219
+ Home / End); its presets are one Tab stop moved in two dimensions (as its shortcut hint
220
+ already promised), `aria-pressed` on the current one; every channel field is named and a
221
+ disabled picker is no Tab stop. `NiceGradientPicker`'s stops are sliders (← → move,
222
+ Delete removes; focus selects as a click does), its toggle groups show `aria-pressed`, every
223
+ field is named. `NiceColorPalette`'s hue wheel is a slider of the base hue (pointer only
224
+ before); its tints and shades took focus but no keys — one Tab stop now, Enter / Space
225
+ apply; focus into a colour row selects it. `NiceUpload`: an icon-only drop zone is named,
226
+ progress is a `progressbar`, a file's actions name the file and status changes are
227
+ announced. `NiceTutorial` is named by its step and described by its text, says the title of
228
+ a new step (focus stays on the Next button) and goes to the first / last step with Home /
229
+ End. In `useRovingFocus` the pressed button of a toggle group is the initial stop.
230
+ - TV / 10-foot mode (D4): `data-nice-tv` on any element applies the 10-foot variant of the
231
+ theme below it — type of 24–28 px on a 1080p picture, targets of 48–64 px, spacing × 1.5, a
232
+ stronger focus ring (`styles/tv.css`, part of the `@nice2dev/ui` stylesheet); the input engine
233
+ sets it on `<html>` in a TV browser (webOS, Tizen, Android TV …; `engine.isTv`), and
234
+ `NiceKioskShell` / `NiceNavShell` take `tv`, which also keeps a 5 % safe area for overscan.
235
+ Remote keys were already the engine's (A1).
236
+ - `NiceMdiWorkspace` (D1): the tab menu (right click, X on a pad, Shift+F10) is a menu that
237
+ takes focus, moves with ↑ ↓ and closes on Escape / B with focus back on its tab — it was a
238
+ plain box the keyboard never reached; it moves a tab left or right (the way without
239
+ dragging); Delete closes the focused tab; the unsaved-changes question is a modal dialog with
240
+ focus on Cancel; LB / RB (Ctrl+PageUp / Ctrl+PageDown) switch tabs from anywhere in the
241
+ workspace.
242
+ - Hover has a focus counterpart (C15): `NiceRate` previews the focused star; an auto-hidden
243
+ `NiceDockMenu` shows while focus is in it (a Tab reached its buttons while they stayed
244
+ hidden) and its icon or letter items are named by their text; a hover `NicePopover` opens on
245
+ focus of its trigger too and Escape there hides it first; `NiceTimeline` events took only the
246
+ pointer — they are one Tab stop moved by the arrows, Enter / Space open one and focus shows
247
+ its details; `NiceScheduler` events are Tab stops with Enter / Space and their details on
248
+ focus; the comment button of `NiceGitDiffViewer` shows on focus as on hover.
249
+ - Typing with a pad (H1, H2): `NiceOnScreenKeyboard` (new, `@nice2dev/ui`) — the d-pad moves
250
+ over the keys and A types; X deletes, Y types a space, LT / RT move the cursor, LB / RB change
251
+ the layout (letters with the accents of the interface language, symbols, more languages),
252
+ Start confirms and B closes; the buttons show next to their keys in pad mode; a physical
253
+ keyboard and touch type too; `modal={false}` makes it a standing keyboard of a page.
254
+ `NiceOnScreenKeyboardHost` (new) opens it for the text field a pad or remote engages (A on the
255
+ field) — every key goes into the field as typing would (a controlled field hears it in
256
+ `onChange`), Start submits as Enter (a form submits), B leaves the text as it is; number
257
+ fields get digits, a text area new lines; the `onScreenKeyboard` preference turns it off or
258
+ also opens it on touch (kiosks). The application shells render the host. Its layouts are the
259
+ keyboard core now in `@nice2dev/ui-core` (`NICE_KEYBOARD_LAYOUTS`, `buildKeyboardRows`,
260
+ `insertAtCaret` …), which `NiceTouchKeyboard` (ui-mobile) uses too — its exported type names
261
+ are unchanged. New built-in glyphs `key-backspace`, `key-space`, `key-caps` (and
262
+ `NtdKeyBackspace`, `NtdKeySpace`, `NtdKeyCaps` in `@nice2dev/icons`); `setFieldText` writes a
263
+ field's text past React's value tracker.
264
+ - Toasts (D3): `NiceToastContainer` is a region named "Notifications", so F6 or a pad's View
265
+ reaches the toasts while they never take focus; Escape / B dismisses the toast with focus,
266
+ which goes on to the next toast or back where it came from (it was lost with the toast). The
267
+ countdown waits while the pointer is over a toast or focus is in it (WCAG 2.2.1). A toast can
268
+ carry an `action` (`{ label, onClick }`, also in `useNiceToast`'s options, `NiceToastOptions`)
269
+ — it runs and dismisses the toast.
270
+ - `NiceScientificChart` (ui-science): the export buttons had no handler — CSV and JSON of the
271
+ visible data and SVG / PNG of the plot download now, and the new `onExport` takes every format
272
+ over (PDF is offered only with it); the tooltip sits beside the hovered point instead of the
273
+ plot's corner. The VLAN panel of `@nice2dev/ui-buildings` labels its connections with a key of
274
+ their own (in Polish it read "połączeń", the counted form).
275
+ - `NiceCodeEditor`: an inline `lsp={{ … }}` object re-created the Monaco editor on every render,
276
+ dropping its undo history and cursor — it is re-created only when the LSP config's content
277
+ changes. The audio editor's project hooks (`useProjectCRUD`, `useAutoSave`) word their status
278
+ messages and questions through the translator (some were Polish without diacritics).
279
+ - Prompts next to controls (B5): `NiceControlHint`, and `hint` / `showHint` on `NiceButton` — the
280
+ button or keys of its action, shown while hints are visible; keys also become
281
+ `aria-keyshortcuts`. `NiceButton` also passes `role`, `aria-selected`, `aria-pressed`,
282
+ `aria-expanded`, `aria-controls`, `aria-haspopup`, `tabIndex` and `onKeyDown`.
283
+ - Found by the showcase crawler (I4, `scripts/audit-input-crawl.mjs`): **no `NiceButton` showed a
284
+ focus ring** — the display styles write `box-shadow` inline (`none` for the default `flat`) and
285
+ that beat the `:focus-visible` rule; the ring is `!important` now, also for the `underlined` and
286
+ `neumorphic` fields. `NiceCodeEditor`, `NiceCodeDiffEditor`, `NiceSimpleCodeEditor` and
287
+ `NiceMarkdownEditor` were keyboard traps (Tab indents and Shift+Tab outdents, nothing left the
288
+ field): Escape, then Tab moves focus on (WCAG 2.1.2), said in the field's description, and a
289
+ read-only editor lets Tab through (it indented its text); `createTabEscape()` (new, ui-core
290
+ and ui) gives a control of your own the same. These editors, `NiceHtmlEditor`,
291
+ `NiceTerminalUI` and the search of `NicePickList` drew no focus at all — their frame shows the
292
+ ring now. The diagram buttons of `NiceGamepad` were pointer-only, so arming a button for an
293
+ assignment took a mouse: with a handler or an action tree they are buttons (one Tab stop, the
294
+ arrows move by geometry, Enter / Space / A press, `aria-pressed` while armed); an SVG element
295
+ has no `click()`, so a pad's A dispatches a click to one (`clickElement`, new). A sortable
296
+ `NiceDataGrid` header sorted only on a click: it is a Tab stop and sorts on
297
+ Enter / Space / A. `NicePasswordInput`'s show / hide button is a Tab stop (showing the password
298
+ took a pointer). The `NiceDateTimePicker` field says how its picker opens (`aria-haspopup`,
299
+ `aria-keyshortcuts="Alt+ArrowDown"`).
300
+ - More from the crawler (I4). `NiceDataGrid` took keys from anything inside it: with a focused
301
+ cell Tab never left the grid (a trap, also from a header) and the search field's arrows did
302
+ not move its caret — the cell cursor follows only the grid's own focus, and Tab at the edge of
303
+ a row leaves. `NiceSpreadsheet`'s formula bar kept Tab without an edit. `NiceModelEditor`
304
+ (ui-3d) listened on the whole page: Tab cycled its mode anywhere (focus moved nowhere on a page
305
+ with the editor), Space pressed no button and Ctrl+Z took the undo of every text field — its
306
+ shortcuts work inside the editor only, Tab and Space on its controls are theirs, Escape then
307
+ Tab leaves the viewport. `NiceDocumentEditor` indents a block on Tab and lets the keyboard out
308
+ as the code editors do (Escape, then Tab; its shortcut list says so). `NicePlaylistDualPane` (ui-audio)
309
+ switches panes on Tab, and Escape then Tab moves on. `NiceSeatingChart` / `NiceSeatPicker`
310
+ (events) take focus to the cursor seat — it stayed on the chart, out of a screen reader's
311
+ reach. Rings where there were none: the cursor row of `NiceKaraokeSongBrowser` (it looked the
312
+ same focused as not), `NiceFileManager`'s panels, `NiceTagInput`, the name field of
313
+ `NiceWorkflowDesigner`, `NiceDocumentEditor`, the chat and search fields of ui-communication
314
+ (`outline: none` inline), the search of `NiceGlobalSearch` and `NiceAccessLog`
315
+ (ui-enterprise), the fields of `NiceTaskManager` and `NiceTorrentUI` (templates) and of the
316
+ automation and scene editors (ui-buildings), the viewport of `NiceModelViewer` (ui-3d).
317
+ - `useOverlayFocus` gave focus back to the opener whenever an overlay closed with focus on the
318
+ page body — also for the moment of a Tab, when the opener's blur closed a popup it showed on
319
+ focus: a `NiceDataGrid` header with column stats took focus back on every Tab, a trap. Focus
320
+ goes back now only when it was in the overlay. The keyboard shortcuts of `GenericPlayer`
321
+ (ui-audio) and `NicePresentationPlayer` (ui-presentations) listened on the whole page — the
322
+ arrows of every list and a pad's d-pad (they move focus with them) did nothing on a page with a
323
+ player, Space pressed no button, and with a presentation Backspace deleted nothing and Enter
324
+ submitted nothing in any field; they work in the player or with focus on the page body, and
325
+ Space / Enter on the player's own buttons press them. A pad has no Tab: on a control of a
326
+ player its d-pad moves focus (as seek, volume or the next slide it kept focus in the player for
327
+ good); on the player itself or the page body a remote's arrows still turn the slides.
328
+ - Lint (I2): the whole jsx-a11y recommended set is on, with the input program's own rules against
329
+ page-wide key listeners and inline `outline: 'none'`. Found on the way: the reply box of
330
+ `NiceHelpdesk` and the search of `NiceCommandBar` took the outline away and showed nothing
331
+ instead — they show focus now.
332
+ - `NicePopover` (the one anchored to a `targetRef`) had no keyboard at all — it closed only on a
333
+ click outside it. It is a `dialog` named by its `title`, takes focus when it opens, closes on
334
+ Escape / B and gives focus back to its target (tests that count the page's dialogs see it now).
335
+ A pick in a `NiceSelect` inside it closed it and was lost (the select's list is portalled out
336
+ of the popover): such a click keeps it open.
337
+ - Rows, cards, tiles and list entries that answered a pointer only (C1) are buttons for the
338
+ keyboard and the pad: `role="button"`, a Tab stop, Enter / Space / A press them — a selection
339
+ toggle says `aria-pressed`, a folder or summary row `aria-expanded`, a check box drawn with a
340
+ `div` is a `checkbox` with its item's name. `clickOnActivationKey` (new, ui-core and ui) is the
341
+ `onKeyDown` for such an element: Enter and Space click it, once per press and with the
342
+ modifiers, so Ctrl+Enter selects as Ctrl+click does; keys of a control inside it stay that
343
+ control's. Dialog backdrops and click stoppers are `role="presentation"` (Escape / B close the
344
+ dialogs). Done so far in events (attraction picker and voting, round list), game-engine (the
345
+ Godot, Unity and Unreal project browsers, the asset store, the editor's hierarchy), licensing
346
+ (portal, transfer, the license table), templates (health, life dashboard, personal finance,
347
+ task manager, torrent UI) and `OmniWerkLogo`, whose `role="button"` took no key; ui-3d (model
348
+ editor outliner with expand / show-hide buttons, Add menu, context menu, timeline, particle
349
+ editor), ui-ai (dataset, experiment, model and labeling cards), ui-api (endpoints, schemas,
350
+ history), ui-audio (sample browser, bar-fill swatches, DMX cues and tracks, the "activate
351
+ audio" overlay, playlist grid / overview / sidebar / search / tags / track list),
352
+ ui-bi (ETL palette and nodes), ui-buildings (automations, zone card, scenes, network paths,
353
+ object library), ui-diagrams, ui-enterprise (access log, contract sections), ui-erp (capacity
354
+ planner — its time cells are named buttons, the only way to add an allocation — and inventory
355
+ cards), ui-forms, and in ui-core `NiceIcon` and `NiceTouchTarget` with an `onClick` and the
356
+ profiler's header — `NiceTouchTarget` also draws a focus ring now; ui-graphics (font glyphs, 2D game asset lists and state nodes, photo
357
+ overlays and colour swatches, pixel layers with show / lock buttons, palette and frames,
358
+ texture and UI designer layers, vector gradients and layers), ui-iot cards, ui-math templates,
359
+ ui-monitoring (saved queries, expandable log rows), ui-presentations (slide thumbnails and the
360
+ overview), ui-printing (template cards, schema fields, layers), ui-science (citations,
361
+ notebooks) and ui-video (live sources, timeline tracks and clips). A clickable `NiceIcon` is a
362
+ button now. `ImportPreviewDialog` (ui-buildings) carried `role="dialog"` on its backdrop — it
363
+ is on the dialog box now. The wheel of `NiceMobilePicker` still has no keys (it gets a
364
+ spinbutton column with E). Tests that count the buttons of these components find more.
365
+ - C1 in `@nice2dev/ui`: the rows, cards and items of the devops, data-branching, media, no-code,
366
+ tools, backup and chart components are buttons (selection toggles `aria-pressed`, folding rows
367
+ `aria-expanded`); a `NiceKanbanBoard` card that opens on a click and a `NiceTileView` tile with
368
+ `onTileClick` are buttons; `NiceTreeList` rows fold from the keyboard (the toggle is a named
369
+ button with `aria-expanded`); `NiceDataGrid`'s virtual group rows and detail toggles take
370
+ Enter / Space. A built-in `NiceIcon` with `onClick` is a button — it was `aria-hidden` and took
371
+ no key. `NiceSelect`, `NiceCountryPicker`, `NiceLanguagePicker` and `NiceThemePicker` clear with
372
+ Delete / Backspace on the trigger (`aria-keyshortcuts="Delete"`): the × in the trigger was
373
+ pointer-only (in `NiceSelect` a `role="button"` inside the trigger button) and is
374
+ `role="presentation"` now. `NiceModal`, `NiceConfirmDialog`, `NiceCommandPalette` and
375
+ `NiceGlobalSearch` stop clicks at the backdrop instead of the dialog — a click on the backdrop
376
+ itself closes, and no click inside or on it reaches a component around the overlay.
377
+ `NiceHtmlEditor`'s template list is a menu with keys, its emoji are buttons; `NiceGitManager`
378
+ opens a file's diff from its path, a button (a click elsewhere on the row did it before);
379
+ `NiceResourceAllocation`'s days are named buttons with `onSlotClick`. Options of comboboxes and
380
+ items of menus, trees and grids keep their click with a line disable naming the keys that
381
+ drive them. The empty cells of `NiceScheduler`'s grids get their keys with E.
382
+
3
383
  ## 1.2.2
4
384
 
5
385
  ### Patch Changes
@@ -0,0 +1 @@
1
+ export {};