@jonmilner/ui 0.1.2 → 0.2.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.
package/dist/Field/index.mjs
CHANGED
|
@@ -60,8 +60,9 @@ function p({ size: e = "sm", font: n, weight: i, leading: a, truncate: o, color:
|
|
|
60
60
|
function m({ children: n, match: a, size: u = "sm", font: d, weight: f, leading: p, truncate: m, color: h = "danger", className: g, style: _, ...v }) {
|
|
61
61
|
let [y, b] = t(v), x = l.toArray(n).some((e) => e !== "");
|
|
62
62
|
return /* @__PURE__ */ c(r, {
|
|
63
|
+
"aria-atomic": !0,
|
|
64
|
+
"aria-live": "assertive",
|
|
63
65
|
as: "div",
|
|
64
|
-
role: "alert",
|
|
65
66
|
size: u,
|
|
66
67
|
font: d,
|
|
67
68
|
weight: f,
|
package/dist/docs/Field.md
CHANGED
|
@@ -81,7 +81,7 @@ import { Field as BaseField } from "@base-ui/react/field";
|
|
|
81
81
|
|
|
82
82
|
- The label is the control's accessible name; clicking it focuses the control.
|
|
83
83
|
- The description and the error join the control's `aria-describedby`, so they are read with it. Base UI adds them after hydration; server HTML has the label link and `aria-invalid`.
|
|
84
|
-
- The error slot is
|
|
84
|
+
- The error slot is an assertive, atomic live region (`aria-live="assertive"`, `aria-atomic="true"`) that stays in the page, so a message is announced when it appears, also after a client-side submit. Several fields failing at once each announce. It has no `role="alert"`, so an empty slot is not an alert: a test finds a field's error by its text or the control's description, not `getByRole("alert")`.
|
|
85
85
|
- The error is never color alone: a decorative alert icon (`aria-hidden`, at the text's size) leads the message, so it reads as an error under forced colors too, and the message says what is wrong and how to fix it.
|
|
86
86
|
|
|
87
87
|
## Props
|
package/dist/docs/manifest.json
CHANGED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# 0.2.0
|
|
2
|
+
|
|
3
|
+
`Field.Error`'s slot, in every `Field`, `MultiSelect` and `SearchField`, is now an `aria-live="assertive"` `aria-atomic="true"` region with no `role="alert"`, so an empty slot is no longer an alert (decision 0097).
|
|
4
|
+
|
|
5
|
+
## Find
|
|
6
|
+
|
|
7
|
+
In the app's tests (`*.test.tsx`, `*.stories.tsx`, Playwright specs), queries for a field's error by the alert role:
|
|
8
|
+
|
|
9
|
+
- `getByRole("alert")`, `findByRole("alert")`, `queryByRole("alert")`, `getAllByRole("alert")`: regex `(get|find|query)(All)?ByRole\(\s*["']alert["']`
|
|
10
|
+
- CSS selectors in tests: the exact string `[role="alert"]` or `role="alert"`
|
|
11
|
+
- In the app's stylesheets (`*.css`, `*.css.ts`), the same `[role="alert"]` string: a rule that styled field errors by the role no longer matches
|
|
12
|
+
|
|
13
|
+
Skip matches that target a `Toast` or the app's own alerts; only field errors changed.
|
|
14
|
+
|
|
15
|
+
## Replace
|
|
16
|
+
|
|
17
|
+
Find the error by its text, or check the control's description:
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
// before
|
|
21
|
+
expect(screen.getByRole("alert")).toHaveTextContent("Enter an email address.");
|
|
22
|
+
// after
|
|
23
|
+
expect(screen.getByText("Enter an email address.")).toBeInTheDocument();
|
|
24
|
+
expect(screen.getByRole("textbox", { name: "Email" })).toHaveAccessibleDescription(
|
|
25
|
+
expect.stringContaining("Enter an email address."),
|
|
26
|
+
);
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
// before
|
|
31
|
+
field.querySelector('[role="alert"]');
|
|
32
|
+
// after
|
|
33
|
+
field.querySelector('[aria-live="assertive"]');
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```css
|
|
37
|
+
/* before */
|
|
38
|
+
.form [role="alert"] {
|
|
39
|
+
margin-block-start: 4px;
|
|
40
|
+
}
|
|
41
|
+
/* after */
|
|
42
|
+
.form [aria-live="assertive"] {
|
|
43
|
+
margin-block-start: 4px;
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
A test that asserted no alert was present, to work around the empty slot, no longer needs the workaround: `queryByRole("alert")` is now `null` while a field has no error.
|
|
48
|
+
|
|
49
|
+
## Verify
|
|
50
|
+
|
|
51
|
+
Run the app's test command (`pnpm test`); it passes with no query left that finds a field's error by `role="alert"`.
|