@jsenv/navi 0.29.470 → 0.29.472
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/dist/dev/jsenv_navi.js +595 -313
- package/dist/dev/jsenv_navi.js.map +22 -20
- package/dist/jsenv_navi.js +566 -311
- package/dist/jsenv_navi.js.map +22 -20
- package/docs/AI_INSTRUCTIONS.md +2 -2
- package/docs/popup_open.md +52 -0
- package/docs/testid.md +15 -2
- package/package.json +1 -1
package/docs/AI_INSTRUCTIONS.md
CHANGED
|
@@ -141,8 +141,8 @@ start when unsure which export solves a problem.
|
|
|
141
141
|
|
|
142
142
|
- `popup_open.md` — a popup owns its open state; `command` + `commandFor`,
|
|
143
143
|
`triggerNaviCommand` as the last resort; opening ON something; a press that
|
|
144
|
-
opens and acts is a `Picker`; Escape cancels; the close cross;
|
|
145
|
-
`signal`/`navState`/`open`; a popup that loads data; `mount`; a closed
|
|
144
|
+
opens and acts is a `Picker`; Escape cancels; the close cross; its name
|
|
145
|
+
(`Popup.Title`); `signal`/`navState`/`open`; a popup that loads data; `mount`; a closed
|
|
146
146
|
`Dialog` costs one element until asked (a row may hold the dialogs of its
|
|
147
147
|
own actions). Before passing `open`, calling `triggerNaviCommand`, or
|
|
148
148
|
writing a close button.
|
package/docs/popup_open.md
CHANGED
|
@@ -14,6 +14,7 @@ What opens a `Dialog` or a `Popover`, and who owns the fact that it is open.
|
|
|
14
14
|
- [Reacting to open and close](#reacting-to-open-and-close)
|
|
15
15
|
- [Escape cancels, the other gestures keep](#escape-cancels-the-other-gestures-keep)
|
|
16
16
|
- [The close cross](#the-close-cross)
|
|
17
|
+
- [Its name](#its-name)
|
|
17
18
|
- [When the app holds the open state](#when-the-app-holds-the-open-state)
|
|
18
19
|
- [A popup that loads data](#a-popup-that-loads-data)
|
|
19
20
|
- [What the popup holds while it is closed](#what-the-popup-holds-while-it-is-closed)
|
|
@@ -182,6 +183,11 @@ the element itself, so the popup element passed as the source resolves to that
|
|
|
182
183
|
popup — the short form above. To trigger from another element, give it a
|
|
183
184
|
`commandFor` pointing at the popup's `id`.
|
|
184
185
|
|
|
186
|
+
A picker's `<input>` carries `aria-expanded` too, for assistive tech, beside its
|
|
187
|
+
role (see [Its name](#its-name)). It repeats the state of the picker's root and
|
|
188
|
+
is not a target of its own: a command triggered from that input reaches the
|
|
189
|
+
picker, as one triggered from anything else in it does.
|
|
190
|
+
|
|
185
191
|
## The anchor
|
|
186
192
|
|
|
187
193
|
A popup opens on the place the open names, on the `anchor` prop when the open
|
|
@@ -285,6 +291,10 @@ far from every press that opens it, it has to be told what it is about and has
|
|
|
285
291
|
to answer somebody. The content can still be one component used in every picker:
|
|
286
292
|
"the prompt exists once" is a question about components, not about the DOM.
|
|
287
293
|
|
|
294
|
+
An `aria-labelledby` on a `Picker` names its trigger, not its popup: a shared
|
|
295
|
+
dialog that pointed at its title that way names itself with `<Popup.Title>`
|
|
296
|
+
once it is a picker's popup (see [Its name](#its-name)).
|
|
297
|
+
|
|
288
298
|
What each row costs depends on what reads the picker's value before anything
|
|
289
299
|
opens. A picker told no value — no `value`, `defaultValue` or `signal` — holds
|
|
290
300
|
what the control in its popup holds, so that popup is built, closed, as soon as
|
|
@@ -616,6 +626,48 @@ it and says why, and a `Picker` validates what its popup holds and runs its
|
|
|
616
626
|
action on the way out, an invalid value keeping it open. Hiding or disabling the
|
|
617
627
|
cross to hold a popup open only removes the one way out that is visible.
|
|
618
628
|
|
|
629
|
+
## Its name
|
|
630
|
+
|
|
631
|
+
A screen reader announces a popup by its name, and
|
|
632
|
+
`getByRole("dialog", { name })` finds it by it; unnamed, it is "dialog" and
|
|
633
|
+
nothing else. The first of these names it:
|
|
634
|
+
|
|
635
|
+
1. `aria-label` / `aria-labelledby` on the popup — `popupAriaLabel` /
|
|
636
|
+
`popupAriaLabelledBy` on a `Picker`, whose own `aria-label` names its
|
|
637
|
+
trigger;
|
|
638
|
+
2. its title, written as `<Popup.Title>` (`<Dialog.Title>`,
|
|
639
|
+
`<Popover.Title>`): a heading, `h2` unless `as` says otherwise, that names
|
|
640
|
+
the popup it sits in with no id to wire — and, written in a picker's
|
|
641
|
+
children, whichever mode the popup opens in;
|
|
642
|
+
3. for a `Picker`'s popup, the trigger's name: its `aria-labelledby` or
|
|
643
|
+
`aria-label`, the label a picker that picks nothing draws, or the `<Label>`
|
|
644
|
+
pointing at it. What was pressed is a fair name for what it opened.
|
|
645
|
+
|
|
646
|
+
```jsx
|
|
647
|
+
<Picker
|
|
648
|
+
id="report_book"
|
|
649
|
+
picksNothing
|
|
650
|
+
standalone
|
|
651
|
+
ui="Report this book"
|
|
652
|
+
popupAriaDescribedBy="report_target"
|
|
653
|
+
>
|
|
654
|
+
<Popup.Title>Report</Popup.Title>
|
|
655
|
+
<p id="report_target">“Title”, chapter 3</p>
|
|
656
|
+
<ReportForm />
|
|
657
|
+
</Picker>
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
A `Popover` has no role of its own, and a name on an element without one is
|
|
661
|
+
read by nobody: a named popover is a `dialog`, unless given another `role`. A
|
|
662
|
+
picker's popover always is, which is what its trigger announces
|
|
663
|
+
(`aria-haspopup="dialog"`, `aria-expanded`). A title inside a
|
|
664
|
+
`mode="callout"` picker names nothing: a callout is read as its message.
|
|
665
|
+
|
|
666
|
+
A `<label>` wrapping the picker does not name its popup: it holds the trigger
|
|
667
|
+
and the popup with it, so the popup would be named after its own content. A
|
|
668
|
+
hand-written `<label for>` names it once it has an `id`; navi's `<Label>` always
|
|
669
|
+
has one.
|
|
670
|
+
|
|
619
671
|
## When the app holds the open state
|
|
620
672
|
|
|
621
673
|
A popup whose being-open is a fact about the application rather than about the
|
package/docs/testid.md
CHANGED
|
@@ -90,13 +90,26 @@ found by nothing, while the host is what the user focuses and what
|
|
|
90
90
|
|
|
91
91
|
```html
|
|
92
92
|
<div class="navi_picker" navi-control="picker" aria-expanded="false">
|
|
93
|
-
<input
|
|
93
|
+
<input
|
|
94
|
+
navi-control-host="picker"
|
|
95
|
+
role="combobox"
|
|
96
|
+
aria-haspopup="dialog"
|
|
97
|
+
aria-expanded="false"
|
|
98
|
+
aria-label="Aide"
|
|
99
|
+
readonly
|
|
100
|
+
/>
|
|
94
101
|
</div>
|
|
95
102
|
```
|
|
96
103
|
|
|
97
104
|
Which role that host answers to is what the control really is, not what it is
|
|
98
105
|
drawn like: a button's host is a `<button>`, and a picker's host is an
|
|
99
|
-
`<input>`
|
|
106
|
+
`<input>` that answers to `combobox` — it shows a value the user does not type,
|
|
107
|
+
and opens what changes it. It says whether its popup is open (`aria-expanded`)
|
|
108
|
+
and what that popup is (`aria-haspopup="dialog"`): a `dialog` in every mode,
|
|
109
|
+
found with `getByRole("dialog", { name })` once open (see
|
|
110
|
+
[popup_open.md](./popup_open.md#its-name) for its name). A picker showing the
|
|
111
|
+
browser's own picker (a `type` with no children) is the `textbox` its
|
|
112
|
+
`<input>` is.
|
|
100
113
|
|
|
101
114
|
A picker that picks nothing is the exception, and answers to `button`: its
|
|
102
115
|
popup is a question (`type="confirm"`) or something to read
|