@antadesign/anta 0.3.19 → 0.3.21

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 (90) hide show
  1. package/README.md +1 -1
  2. package/dist/anta_helpers.d.ts +11 -2
  3. package/dist/anta_helpers.js +9 -0
  4. package/dist/components/Banner.d.ts +3 -3
  5. package/dist/components/Button.d.ts +1 -1
  6. package/dist/components/Calendar.d.ts +11 -12
  7. package/dist/components/Card.d.ts +1 -1
  8. package/dist/components/Card.js +1 -1
  9. package/dist/components/Checkbox.d.ts +8 -9
  10. package/dist/components/Dialog.d.ts +1 -1
  11. package/dist/components/Expander.d.ts +5 -6
  12. package/dist/components/Input.d.ts +2 -2
  13. package/dist/components/Input.js +1 -1
  14. package/dist/components/InputAutocomplete.d.ts +8 -8
  15. package/dist/components/InputAutocomplete.js +24 -18
  16. package/dist/components/InputTime.d.ts +3 -3
  17. package/dist/components/InputTime.js +1 -1
  18. package/dist/components/Menu.d.ts +2 -2
  19. package/dist/components/MenuItem.d.ts +1 -1
  20. package/dist/components/MenuItem.js +1 -1
  21. package/dist/components/Progress.d.ts +1 -1
  22. package/dist/components/RadioGroup.d.ts +14 -15
  23. package/dist/components/RadioGroup.js +5 -2
  24. package/dist/components/Select.d.ts +33 -40
  25. package/dist/components/Select.js +6 -2
  26. package/dist/components/SelectFaceted.d.ts +27 -33
  27. package/dist/components/SelectFaceted.js +5 -1
  28. package/dist/components/Slider.d.ts +5 -5
  29. package/dist/components/Switch.d.ts +4 -4
  30. package/dist/components/TabPanel.d.ts +1 -2
  31. package/dist/components/TabPanel.js +0 -1
  32. package/dist/components/Tabs.d.ts +9 -9
  33. package/dist/components/Tabs.js +5 -2
  34. package/dist/components/Text.d.ts +5 -3
  35. package/dist/components/Text.js +7 -3
  36. package/dist/components/Title.d.ts +1 -1
  37. package/dist/components/Toaster.d.ts +1 -1
  38. package/dist/components/Tooltip.d.ts +1 -1
  39. package/dist/elements/a-card.css +1 -1
  40. package/dist/elements/a-dialog.css +1 -1
  41. package/dist/elements/a-expander.css +1 -1
  42. package/dist/elements/a-expander.d.ts +1 -0
  43. package/dist/elements/a-expander.js +12 -2
  44. package/dist/elements/a-menu.d.ts +1 -8
  45. package/dist/elements/a-menu.js +1 -40
  46. package/dist/elements/a-progress.css +1 -1
  47. package/dist/elements/a-text.d.ts +4 -0
  48. package/dist/elements/a-text.js +10 -3
  49. package/dist/elements/a-tooltip.css +1 -1
  50. package/dist/elements/a-tooltip.d.ts +8 -1
  51. package/dist/elements/a-tooltip.js +88 -15
  52. package/dist/elements/index.d.ts +1 -1
  53. package/dist/general_types.d.ts +33 -22
  54. package/dist/index.d.ts +3 -3
  55. package/dist/theme-anta.css +1 -1
  56. package/docs/accessibility.md +4 -4
  57. package/docs/changelog.md +40 -13
  58. package/docs/comparison.md +1 -1
  59. package/docs/components/banner.md +17 -17
  60. package/docs/components/button.md +6 -6
  61. package/docs/components/card.md +5 -6
  62. package/docs/components/checkbox.md +17 -18
  63. package/docs/components/dialog.md +2 -2
  64. package/docs/components/expander.md +27 -30
  65. package/docs/components/icon.md +1 -1
  66. package/docs/components/input-autocomplete.md +15 -16
  67. package/docs/components/input-date.md +54 -59
  68. package/docs/components/input-time.md +7 -7
  69. package/docs/components/input.md +14 -14
  70. package/docs/components/menu.md +72 -8
  71. package/docs/components/progress.md +2 -2
  72. package/docs/components/radio.md +28 -25
  73. package/docs/components/select-faceted.md +95 -100
  74. package/docs/components/select.md +113 -115
  75. package/docs/components/slider.md +15 -10
  76. package/docs/components/switch.md +13 -13
  77. package/docs/components/tabs.md +23 -23
  78. package/docs/components/tag.md +5 -5
  79. package/docs/components/text.md +31 -7
  80. package/docs/components/title.md +1 -1
  81. package/docs/components/toaster.md +4 -4
  82. package/docs/components/tooltip.md +2 -2
  83. package/docs/credits.md +0 -4
  84. package/docs/index.md +1 -1
  85. package/docs/install-config.md +12 -7
  86. package/docs/normalization.md +6 -9
  87. package/docs/overview.md +1 -1
  88. package/docs/packages/stickers.md +1 -1
  89. package/docs/theming.md +15 -0
  90. package/package.json +3 -8
@@ -471,7 +471,7 @@ without taking ownership of `onClick`.
471
471
 
472
472
  ### Props
473
473
 
474
- Use this when you are not using the React or Preact wrapper and a native HTML control does not fit: construct the equivalent Anta web component from the elements below.
474
+ Use the web component directly when you are not using React or Preact and a native control does not fit.
475
475
 
476
476
  Set `role="button"` and `tabindex="0"` when authoring `<a-button>` directly.
477
477
 
@@ -506,7 +506,7 @@ wrapper sets them for you). A native `<button>` also carries its own default
506
506
  <button data-anta tone="critical" priority="tertiary">Delete</button>
507
507
  ```
508
508
 
509
- Reach for the props first: **`tone`** sets the colour (any CSS colour for a custom
509
+ Reach for the props first: **`tone`** sets the color (any CSS color for a custom
510
510
  tone — it derives the whole tone × priority × state curve in oklch), **`priority`**
511
511
  the emphasis, **`size`** the dimensions. The focus ring is the global
512
512
  [`--focus-ring`](../colors.md#focus-ring).
@@ -520,7 +520,7 @@ CSS (an un-layered rule beats `@layer anta` without `!important`). Set
520
520
  `background-color` / `color` **per state**, plus full type control (size,
521
521
  line-height, letter-spacing, `font-feature-settings`), padding, radius, even a
522
522
  frosted `backdrop-filter` — no need to touch a single token. **`light-dark()`** works
523
- too (Anta sets `color-scheme` from its theme toggle), so colours adapt to dark mode
523
+ too (Anta sets `color-scheme` from its theme toggle), so colors adapt to dark mode
524
524
  with no `.dark` selector. The classes below are just for the demos:
525
525
 
526
526
  ```css
@@ -537,14 +537,14 @@ a-button.checkout {
537
537
  }
538
538
  a-button.checkout:hover { background: linear-gradient(140deg, light-dark(#3a3a42, #fff), light-dark(#161618, #cacace)); }
539
539
  a-button.checkout:active { background: linear-gradient(140deg, light-dark(#000, #ececf0), light-dark(#1a1a1c, #fff)); }
540
- a-button.checkout a-button-label { /* customised label */
540
+ a-button.checkout a-button-label { /* customized label */
541
541
  text-transform: uppercase;
542
542
  letter-spacing: 0.14em;
543
543
  font-weight: 600;
544
544
  }
545
545
 
546
546
  /* Second — liquid glass: frost + translucent tint + a diagonal specular sheen,
547
- a top/bottom bevel, and a soft lift. Sits on a colourful backdrop so it reads. */
547
+ a top/bottom bevel, and a soft lift. Sits on a colorful backdrop so it reads. */
548
548
  a-button.glass {
549
549
  color: #fff;
550
550
  background-color: rgba(255, 255, 255, 0.12);
@@ -600,4 +600,4 @@ beyond the button so it can rotate behind the label without exposing an edge.
600
600
 
601
601
  Don't reach for the resolved `--button-fg` / `--button-bg`: they're recomputed per
602
602
  state, so setting one only catches a single state — restyle per state as above, or
603
- use `tone` for a full custom-colour curve.
603
+ use `tone` for a full custom-color curve.
@@ -116,10 +116,9 @@ round (`999px`, clamped to the box). Omit it for the default (`--card-radius`, 8
116
116
 
117
117
  ## Header controls
118
118
 
119
- There's no dedicated actions slot. For a control at the top-right of the header — a
120
- "more" button, a tag — pass a laid-out node as the `header` and put the title and
121
- the control in it yourself (a flex row). You own the layout, so the title and
122
- control sit exactly where you place them.
119
+ There is no dedicated actions slot. To place a control in the top-right of the
120
+ header, pass a layout node as `header`. For example, use a flex row containing
121
+ the title and a "more" button. That layout determines where both items appear.
123
122
 
124
123
  ```tsx
125
124
  <Card
@@ -179,7 +178,7 @@ out of it — its text is non-selectable and the whole surface navigates.
179
178
  href="/docs/ci"
180
179
  header={<><Icon shape="book-open" /> CI integration guide</>}
181
180
  >
182
- Wire Antithesis into your pipeline in a few minutes.
181
+ Connect your CI pipeline in a few minutes.
183
182
  </Card>
184
183
  ```
185
184
 
@@ -254,7 +253,7 @@ it also blocks navigation until the load resolves.
254
253
  color keeps its hue while lightness/chroma are pinned. `'neutral'` (the
255
254
  default) is the same as omitting it. |
256
255
 
257
- Use this when you are not using the React or Preact wrapper and a native HTML control does not fit: construct the equivalent Anta web component from the elements below.
256
+ Use the web component directly when you are not using React or Preact and a native control does not fit.
258
257
 
259
258
  Slots hold media, header, and footer content. Unslotted content is the card body.
260
259
 
@@ -6,7 +6,7 @@ The `Checkbox` wrapper renders an `<a-checkbox>` element that manages its own st
6
6
 
7
7
  ## Tone
8
8
 
9
- `tone` colours the **mark** — the checked-box fill and, for a tinted tone, the
9
+ `tone` colors the **mark** — the checked-box fill and, for a tinted tone, the
10
10
  unselected box border (a light shade of the fill that darkens on hover and active,
11
11
  like the neutral border; `neutral` keeps a grey border). The label and hint stay
12
12
  neutral. Six named tones (`neutral` default), or pass any CSS color for a custom tone.
@@ -29,7 +29,7 @@ read as a validation error. Same value set as `tone`.
29
29
  <Checkbox defaultChecked toneSelected="critical">Checked mark tinted</Checkbox>
30
30
  ```
31
31
 
32
- ## Colouring the text
32
+ ## Coloring the text
33
33
 
34
34
  There's no text-tone prop. To tint the **label**, set `color` on the checkbox with a
35
35
  theme-aware `--text-N-{tone}` token (the label inherits it); for the **hint**, add a
@@ -38,7 +38,7 @@ to tint the whole control.
38
38
 
39
39
  ```css
40
40
  /* Mark via the prop, text via a plain color rule — the label inherits the host
41
- colour, the hint is targeted directly. The class is just for the demo — swap
41
+ color, the hint is targeted directly. The class is just for the demo — swap
42
42
  your own selector. */
43
43
  a-checkbox.toned-text { color: var(--text-1-critical); }
44
44
  a-checkbox.toned-text a-checkbox-hint { color: var(--text-3-critical); }
@@ -56,7 +56,7 @@ Three sizes scale the box **and** the label + hint type together: `small`
56
56
  <Checkbox defaultChecked size="large">Large</Checkbox>
57
57
  ```
58
58
 
59
- ## Label & hint
59
+ ## Label and hint
60
60
 
61
61
  Pass the label as `children` or the `label` prop. Add a `hint` for a secondary line beneath. For a label-less checkbox (e.g. a table "select all"), pass `aria-label`.
62
62
 
@@ -177,7 +177,7 @@ Space toggles the checkbox. Follows the [WAI-ARIA checkbox pattern](https://www.
177
177
  uncontrolled checkbox. `'indeterminate'` shows the minus glyph and takes
178
178
  visual precedence; clicking it requests `true`. |
179
179
  | `defaultChecked?` | CheckboxValue | false | Initial checked state for an uncontrolled checkbox. Read once; later
180
- changes ignored (the element then owns the state). |
180
+ changes are ignored and the element updates its state after interaction. |
181
181
  | `disabled?` | boolean | — | Disable the checkbox (no interaction, dropped from the tab order). |
182
182
  | `hint?` | ReactNode | — | Secondary text rendered under the label — explanatory copy, like
183
183
  Input's hint. Not part of the accessible name. |
@@ -196,25 +196,24 @@ Space toggles the checkbox. Follows the [WAI-ARIA checkbox pattern](https://www.
196
196
  `detail` carries `{ next, prev }`. In controlled mode the element never
197
197
  self-applies — answer by updating `checked`, reject by doing nothing. |
198
198
  | `onValueChange?` | (event, attrs) => void | — | Like `onChange`, but with a `{ checked, indeterminate, name, value }` snapshot
199
- as the 2nd argument — the ergonomic "just give me the new value" callback
200
- (mirrors `Input`'s `onValueChange`). |
199
+ as the second argument, matching `Input`'s `onValueChange`. |
201
200
  | `round?` | boolean \| number \| string | — | Round the checkbox mark to a circle (`border-radius: 999px` on the box). Pass
202
201
  a `number` (px) or a CSS length string for a rounded-square mark instead. |
203
202
  | `size?` | 'small' \| 'medium' \| 'large' | 'medium' | Size variant. small=14px, medium=16px, large=18px box. |
204
- | `tone?` | 'brand' \| 'neutral' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Colour of the **mark** in every state — the checked-box fill *and* the
203
+ | `tone?` | 'brand' \| 'neutral' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Color of the **mark** in every state — the checked-box fill *and* the
205
204
  unselected box border. A named tone or any literal CSS color (`'#ff1493'`,
206
205
  `'rebeccapurple'`) for a one-off custom tone. Named tones track light/dark mode
207
- automatically; a custom colour keeps its hue + chroma and pins lightness to the
206
+ automatically; a custom color keeps its hue + chroma and pins lightness to the
208
207
  fill curve. Use `toneSelected` instead to tone only the checked mark and leave
209
- the empty box neutral. The label + hint stay neutral — recolour them in plain
208
+ the empty box neutral. The label + hint stay neutral — recolor them in plain
210
209
  CSS via the theme-aware `--text-N-{tone}` tokens. |
211
- | `toneSelected?` | 'brand' \| 'neutral' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Like `tone`, but coloured onto the **checked mark only** — the empty box stays
210
+ | `toneSelected?` | 'brand' \| 'neutral' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Like `tone`, but colored onto the **checked mark only** — the empty box stays
212
211
  neutral grey until it's checked. Prefer this over `tone` when a resting tinted
213
212
  border would read as a validation state. Same value set as `tone`; if both are
214
213
  set, `tone` governs the off-state border and `toneSelected` the checked fill. |
215
214
  | `value?` | string | "on" | Value submitted with the form when checked — like a native checkbox. |
216
215
 
217
- Use this when you are not using the React or Preact wrapper and a native HTML control does not fit: construct the equivalent Anta web component from the elements below.
216
+ Use the web component directly when you are not using React or Preact and a native control does not fit.
218
217
 
219
218
  The focusable host carries the state. Label and hint are light-DOM children.
220
219
 
@@ -242,8 +241,8 @@ treatments.
242
241
  </div>
243
242
  ```
244
243
 
245
- Reach for the props first: **`tone`** colours the mark in every state,
246
- **`toneSelected`** only the checked mark (any CSS colour for a custom tone — it
244
+ Reach for the props first: **`tone`** colors the mark in every state,
245
+ **`toneSelected`** only the checked mark (any CSS color for a custom tone — it
247
246
  derives the full rest/hover/active curve in oklch), **`size`** the dimensions + type.
248
247
  To tint the label + hint, add a `color` rule (on the host for the label, on
249
248
  `a-checkbox-hint` for the hint) with the `--text-N-{tone}` tokens — there's no
@@ -251,7 +250,7 @@ text-tone prop. The focus ring is the global
251
250
  [`--focus-ring`](../colors.md#focus-ring).
252
251
 
253
252
  ```tsx
254
- <Checkbox tone="#e0457b" defaultChecked>Custom colour</Checkbox>
253
+ <Checkbox tone="#e0457b" defaultChecked>Custom color</Checkbox>
255
254
  ```
256
255
 
257
256
  For anything else, `<a-checkbox>` is light-DOM — the **box is `::before`**, the
@@ -262,7 +261,7 @@ without `!important`). The classes below are just for the demos:
262
261
 
263
262
  ```css
264
263
  /* Outlined — an unfilled box: the checked box keeps its background and paints the
265
- border + checkmark in the tone colour (light-dark() tunes both themes at once). */
264
+ border + checkmark in the tone color (light-dark() tunes both themes at once). */
266
265
  a-checkbox.outlined:state(checked)::before {
267
266
  background: var(--checkbox-bg);
268
267
  border-color: light-dark(#5f4bc3, #7460d7);
@@ -272,7 +271,7 @@ a-checkbox.outlined:state(checked)::after {
272
271
  }
273
272
 
274
273
  /* Customized — bold label, bigger circular box, bigger checkmark.
275
- Colours use light-dark() so they're tuned for both themes at once. */
274
+ Colors use light-dark() so they're tuned for both themes at once. */
276
275
  a-checkbox.customized { font-weight: 700; }
277
276
  a-checkbox.customized::before,
278
277
  a-checkbox.customized::after { inline-size: 24px; block-size: 24px; margin-block-start: -2px; }
@@ -284,7 +283,7 @@ a-checkbox.customized:state(checked)::before {
284
283
  }
285
284
 
286
285
  /* Beautified — a full white heart mark swapped in via --checkbox-mask-check
287
- (centred by the default mask-position), sized down a touch, on a pink fill */
286
+ (centered by the default mask-position), sized down a touch, on a pink fill */
288
287
  a-checkbox.beautified {
289
288
  --checkbox-mask-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3c1.74 0 3.41.81 4.5 2.09C13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54z'/%3E%3C/svg%3E");
290
289
  }
@@ -210,7 +210,7 @@ returns to whatever opened the dialog, from the native `<dialog>`.
210
210
  | `children?` | ReactNode | — | The dialog body. Scrolls when it overflows the available height. |
211
211
  | `closable?` | boolean | true | Whether the top-right ✕ button is present. It's one way to close the dialog,
212
212
  alongside Esc, the backdrop, a `data-dialog-close` / footer action, and your
213
- own code; `false` just removes the ✕, it doesn't make the dialog un-closable. |
213
+ own code; `false` removes the ✕ without making the dialog unclosable. |
214
214
  | `defaultOpen?` | boolean | — | Initial open state for the uncontrolled case (read once on mount). |
215
215
  | `footer?` | ReactNode | — | Footer content, usually the action buttons. Rendered in the bottom zone as
216
216
  a right-aligned row (wraps under pressure). Omit for none. |
@@ -245,7 +245,7 @@ returns to whatever opened the dialog, from the native `<dialog>`.
245
245
  corners at `--dialog-radius`. Omit for the position default: `center` is
246
246
  rounded, drawers and `fullscreen` are square. |
247
247
 
248
- Use this when you are not using the React or Preact wrapper and a native HTML control does not fit: construct the equivalent Anta web component from the elements below.
248
+ Use the web component directly when you are not using React or Preact and a native control does not fit.
249
249
 
250
250
  Slots hold the header, footer, and close control. Add `tabindex="0"` to every
251
251
  raw `<a-button>`.
@@ -94,7 +94,7 @@ it's a no-op there. Use it where the expander sits in a content column
94
94
  with room to its left (a prose measure); in a full-width / edge-to-edge
95
95
  container the chevron would overhang the edge.
96
96
 
97
- ## Title & level
97
+ ## Title and level
98
98
 
99
99
  `title` takes a string or any node. For a string, `level` (1–6) applies
100
100
  the matching heading **type scale** — the same scale as `<Title>` —
@@ -114,14 +114,14 @@ horizontally.
114
114
 
115
115
  When you need real heading **semantics** — so the title lands in a
116
116
  page's table of contents (and assistive tech announces it as a heading) —
117
- pass a `<Title>` (or your own `<h2>`–`<h6>`) as the `title` instead of a
118
- string. The node owns its own type scale, so set the level on it, not on
119
- `<Expander>`; a slotted heading keeps its block-rhythm margins, so zero
120
- them in the header:
117
+ pass a `<Title>` (or an application `<h2>`–`<h6>`) as the `title` instead of a
118
+ string. The heading's `level` sets its type scale, so set it on the heading,
119
+ not on `<Expander>`. A slotted heading keeps its block margins, so reset them
120
+ in the header:
121
121
 
122
122
  ```tsx
123
- {/* A node title owns its own scale + heading semantics: set the level on
124
- the <Title>, not on <Expander>. (The preview uses element composition
123
+ {/* A Title supplies its type scale and heading semantics. Set the level on
124
+ the Title, not on Expander. (The preview uses element composition
125
125
  because these docs render statically; the title-prop form is identical.) */}
126
126
  <Expander title={<Title level={2}>Title level 2 example</Title>}>…</Expander>
127
127
  <Expander title={<Title level={4}>Title level 4 example</Title>}>…</Expander>
@@ -214,12 +214,11 @@ state stays as-is — disabling an open expander keeps it open. Header
214
214
 
215
215
  ## Open state
216
216
 
217
- Leave it uncontrolled and pass `defaultOpen` for the initial state — the
218
- element owns open/close from there. To drive it yourself, pass `open`
219
- and handle `onStateChange` (controlled): the expander then only follows
220
- the prop, and clicking the summary just *requests* a change — apply
221
- `detail.next` to your state to accept, or ignore it to reject. If you pass
222
- `open`, you own it.
217
+ For uncontrolled use, pass `defaultOpen` for the initial state. The element
218
+ then updates its open state after interaction. For controlled use, pass `open`
219
+ and handle `onStateChange`. The expander follows the `open` prop and reports a
220
+ requested change. Update application state with `detail.next` to accept it, or
221
+ leave the state unchanged to reject it.
223
222
 
224
223
  `onStateChange` is event-first: `(event, { next, prev })`, where `next`/`prev`
225
224
  are booleans (the requested / previous open state). `statechange` fires
@@ -243,16 +242,15 @@ const [open, setOpen] = useState(false)
243
242
 
244
243
  ## Controlled vs Uncontrolled
245
244
 
246
- Open state follows Anta's shared **state contract**. Leave it *uncontrolled* and
247
- the expander owns open/close; pass the controlled prop and *you* own it. The two
248
- layers speak different idioms — the `<Expander>` wrapper takes booleans, the
249
- `<a-expander>` element takes a `state` string enum — and the wrapper maps between
250
- them:
245
+ Open state follows Anta's shared **state contract**. In uncontrolled use, the
246
+ element updates open state. In controlled use, the application supplies it. The
247
+ `<Expander>` wrapper uses booleans; the `<a-expander>` element uses a `state`
248
+ string. The wrapper maps between them:
251
249
 
252
250
  | | `<Expander>` (JSX) | `<a-expander>` (element) |
253
251
  |---|---|---|
254
- | **Uncontrolled** — element owns it | `defaultOpen` | `default-state="open" \| "closed"` |
255
- | **Controlled** — you own it | `open` + `onStateChange` | `state="open" \| "closed"` + `statechange` |
252
+ | **Uncontrolled** | `defaultOpen` | `default-state="open" \| "closed"` |
253
+ | **Controlled** | `open` + `onStateChange` | `state="open" \| "closed"` + `statechange` |
256
254
  | **Change event** | `onStateChange(event, { next, prev })` — `next` / `prev` are **booleans** | `statechange`, a `CustomEvent<{ next, prev }>` — `'open'` / `'closed'` |
257
255
 
258
256
  `statechange` is **cancelable** and fires *before* the element applies the
@@ -330,10 +328,9 @@ function Accordion() {
330
328
  toggle (e.g. confirm before closing). `detail.next` is the requested
331
329
  open state, `detail.prev` the current one (booleans). In controlled
332
330
  mode, apply `detail.next` to `open` to accept, or do nothing to reject. |
333
- | `open?` | boolean | — | Controlled open state. When provided, the consumer owns open/close:
334
- the expander only follows this prop, and clicking the summary just
335
- requests a change via `onStateChange` (so a toggle can be rejected by
336
- not updating). Leave undefined for uncontrolled. |
331
+ | `open?` | boolean | — | Controlled open state. When provided, the consumer owns open/close. Selecting
332
+ the summary requests a change through `onStateChange`; omit `open` for
333
+ uncontrolled use. |
337
334
  | `outdent?` | boolean | — | Outdent the chevron into the left gutter so the title and body sit
338
335
  flush with surrounding content (the docs-header layout). Only takes
339
336
  effect with `priority="tertiary"` — on the filled priorities the
@@ -352,7 +349,7 @@ function Accordion() {
352
349
  its hue while lightness/chroma are pinned. `'neutral'` (the default) is
353
350
  the same as omitting it. |
354
351
 
355
- Use this when you are not using the React or Preact wrapper and a native HTML control does not fit: construct the equivalent Anta web component from the elements below.
352
+ Use the web component directly when you are not using React or Preact and a native control does not fit.
356
353
 
357
354
  Slots hold the title and actions. The details element contains the collapsible body.
358
355
 
@@ -369,7 +366,7 @@ Slots hold the title and actions. The details element contains the collapsible b
369
366
  ### Native HTML details
370
367
 
371
368
  For a simple disclosure, add `data-anta` to native `<details>`. It keeps the
372
- browser's opening, keyboard, and accessibility behaviour while taking on the
369
+ browser's opening, keyboard, and accessibility behavior while taking on the
373
370
  neutral tertiary Expander treatment. Add `priority="secondary"` or `"primary"`
374
371
  for a filled surface. `round`, `tone`, tertiary `outdent`, and `level="1"`–`"6"`
375
372
  use the matching Expander visual treatments. `level` changes visual type only;
@@ -382,9 +379,9 @@ use a heading inside the summary when you need heading semantics.
382
379
  </details>
383
380
  ```
384
381
 
385
- Reach for the props first: **`tone`** sets the colour (any CSS colour for a custom
382
+ Reach for the props first: **`tone`** sets the color (any CSS color for a custom
386
383
  tone — it derives the surface in oklch), **`priority`** the fill, **`level`** the
387
- heading. Two knobs are worth keeping: **`--expander-tone-source`** (the colour a
384
+ heading. Two knobs are worth keeping: **`--expander-tone-source`** (the color a
388
385
  custom `tone` derives from — set it to drive the palette from your own variable) and
389
386
  **`--expander-gutter`** (the shared left inset that re-insets header + body + chevron
390
387
  in lockstep; `outdent` sets it to `0`).
@@ -435,12 +432,12 @@ a-expander.hover-tint::part(summary):active { background: var(--bg-2); }
435
432
  ```
436
433
 
437
434
  **Highlight the title on hover.** The title inherits its `color` from `::part(summary)`,
438
- so recolour the part on hover and the title (and the `currentColor` chevron) follow — a
435
+ so recolor the part on hover and the title (and the `currentColor` chevron) follow — a
439
436
  custom title node that sets its own `color` opts out. Here we also drop the tertiary
440
437
  hover underline on the light-DOM `a-expander-summary`:
441
438
 
442
439
  ```css
443
- a-expander.title-highlight::part(summary):hover { color: #e5484d; } /* title colour on hover */
440
+ a-expander.title-highlight::part(summary):hover { color: #e5484d; } /* title color on hover */
444
441
  a-expander.title-highlight a-expander-summary { text-decoration: none; } /* drop the hover underline */
445
442
  ```
446
443
 
@@ -31,7 +31,7 @@ accessible loading status.
31
31
  noise alongside neighbouring text. |
32
32
  | `size?` | number | 16 | Width and height in pixels. |
33
33
 
34
- Use this when you are not using the React or Preact wrapper and a native HTML control does not fit: construct the equivalent Anta web component from the elements below.
34
+ Use the web component directly when you are not using React or Preact and a native control does not fit.
35
35
 
36
36
  Set the accessible name on the raw element. Use `--icon-size` for a portable custom
37
37
  size.
@@ -1,14 +1,14 @@
1
1
  # InputAutocomplete
2
2
 
3
- `InputAutocomplete` — a text field whose value is a free string, with a suggestion list that assists
4
- without constraining. Type anything: a value that isn't in the list stays as you
5
- typed it, and picking a suggestion fills the field. For a value that must be one of
6
- the options, use [Select](./select.md) with `filter`.
3
+ `InputAutocomplete` is a text field with a suggestion list. Its value remains a
4
+ free-form string: text that is not in the list stays in the field, and selecting
5
+ a suggestion fills the field. Use [Select](./select.md) with `filter` when the
6
+ value must be one of the options.
7
7
 
8
- It's a **composed component**, an [Input](./input.md) stitched to a [Menu](./menu.md) of
9
- suggestions. The field text arrives through **`onValueChange`**; `onSelect` fires
10
- only when a suggestion is chosen. Controlled via `value`, uncontrolled via
11
- `defaultValue`.
8
+ InputAutocomplete uses an [Input](./input.md) for the field and a [Menu](./menu.md)
9
+ for suggestions. **`onValueChange`** reports field text. `onSelect` runs only
10
+ after someone chooses a suggestion. Use `value` to control it, or `defaultValue`
11
+ for uncontrolled use.
12
12
 
13
13
  ## Free text is the point
14
14
 
@@ -29,7 +29,7 @@ closes the list; clicking the field to place the caret keeps it open.
29
29
 
30
30
  - **`true`** (default): built-in case-insensitive substring match on each option's
31
31
  `value` / `label` / `hint`.
32
- - **a function** `(option, query) => boolean`: your own matcher, called per option.
32
+ - **a function** `(option, query) => boolean`: a custom matcher, called for each option.
33
33
  - **`false`**: show `suggestions` as-is, doing no local filtering. Use this when you
34
34
  fetch or filter results yourself (async / remote) and feed the current set through
35
35
  `suggestions`.
@@ -44,12 +44,12 @@ Suggestions are bare strings or `SelectOption`s, the same option shape
44
44
  | `suggestions` | string \| SelectOption[] | — | The suggestions: bare strings or `SelectOption`s (`value` / `label` / `hint` /
45
45
  `icon` / `tone` / `disabled`). A flat list; picking one fills the field. |
46
46
  | `clearable?` | boolean | — | Show a clear button while the field has text. |
47
- | `defaultValue?` | string | — | Initial value for the uncontrolled case (the wrapper then owns it). |
47
+ | `defaultValue?` | string | — | Initial value for uncontrolled use. |
48
48
  | `disabled?` | boolean | — | Disable the field. |
49
49
  | `filter?` | boolean \| (option, query) => boolean | true | How suggestions match the text. `true` uses the built-in case-insensitive
50
50
  substring match on `value` / `label` / `hint`; a function `(option, query) =>
51
- boolean` does custom matching; `false` shows `suggestions` verbatim so you
52
- can filter them yourself (async / remote). |
51
+ boolean` uses a custom matcher; `false` shows `suggestions` unchanged for
52
+ application-provided async or remote filtering. |
53
53
  | `hint?` | ReactNode | — | Hint under the field. |
54
54
  | `label?` | ReactNode | — | Field label. |
55
55
  | `leading?` | ReactNode | — | Leading adornment inside the field. |
@@ -61,7 +61,7 @@ Suggestions are bare strings or `SelectOption`s, the same option shape
61
61
  | `size?` | 'small' \| 'medium' \| 'large' | medium | Field size. |
62
62
  | `status?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' | — | Validation status. |
63
63
  | `statusIcon?` | (string & {}) \| false \| IconShape | — | Status icon override, or `false` to drop it. |
64
- | `tone?` | string | — | Custom accent colour — a named tone or any CSS colour. |
64
+ | `tone?` | string | — | Custom accent color — a named tone or any CSS color. |
65
65
  | `trailing?` | ReactNode | — | Trailing adornment inside the field. |
66
66
  | `value?` | string | — | Controlled value: the field's text, a **free** string not constrained to a
67
67
  suggestion. Leave undefined for uncontrolled. |
@@ -76,9 +76,8 @@ For browser-native suggestions, pair a native input with a `<datalist>`. It
76
76
  keeps free-form entry and lets the browser filter and fill matching options,
77
77
  while `data-anta` supplies the field appearance.
78
78
 
79
- The suggestions popup is owned by the browser, so use `InputAutocomplete` when
80
- you need custom option content, popup styling, or consistent interaction across
81
- browsers.
79
+ The browser renders the suggestions popup. Use `InputAutocomplete` for custom
80
+ option content, popup styling, or consistent behavior across browsers.
82
81
 
83
82
  ```html
84
83
  <input data-anta type="text" list="people" placeholder="Search people">
@@ -94,17 +94,19 @@ field converts it (18 → 6 PM).
94
94
  The sections below document `Calendar`, the month grid `InputDate` opens. Reach for
95
95
  it directly when you want the grid inline, without a field.
96
96
 
97
- `Calendar` is **composed from Anta components in light DOM**, with nothing hidden in
98
- a shadow root. The days and prev/next chevrons are `<Button>`s (a selected day is a
99
- `tertiary` Button in its selected state, toned `brand`), inside a form-associated `<a-calendar>`
100
- grid. Date math runs on the [Temporal API](https://tc39.es/proposal-temporal/docs/),
101
- bundled via `temporal-polyfill`. For a raw grid, import `buildMonth` from
102
- `@antadesign/anta`: it returns localized weekday headers and every day record you
103
- need to render — ISO value, accessible label, and selected, disabled, today, and
104
- outside-month state. It does not coordinate navigation, roving focus, selection, or
105
- re-renders for you. The value is an ISO `YYYY-MM-DD` string, never a `Date`. It works
106
- controlled (`value` + `onStateChange`) or uncontrolled (`defaultValue`), and
107
- participates in forms under `name`.
97
+ `Calendar` uses Anta components in light DOM; it has no hidden shadow-root UI.
98
+ The day cells and previous/next chevrons are `<Button>`s inside a
99
+ form-associated `<a-calendar>` grid. Date calculations use the
100
+ [Temporal API](https://tc39.es/proposal-temporal/docs/) through
101
+ `temporal-polyfill`.
102
+
103
+ For a raw grid, import `buildMonth` from `@antadesign/anta`. It returns
104
+ localized weekday headers and day records with ISO values, accessible labels,
105
+ and selected, disabled, today, and outside-month state. It does not manage
106
+ navigation, roving focus, selection, or rendering. The value is an ISO
107
+ `YYYY-MM-DD` string, never a `Date`. Use `value` with `onStateChange` to
108
+ control it, or `defaultValue` for uncontrolled use. It participates in forms
109
+ under `name`.
108
110
 
109
111
  **Not SSR-safe.** `Calendar` (and `InputDate`, which embeds it) reads the current
110
112
  date (`Temporal.Now`) and locale (`navigator.language`) at render, so a server
@@ -241,60 +243,53 @@ stop, and an `aria-live` region announces the month when it changes.
241
243
 
242
244
  ## Customization
243
245
 
244
- The family stacks in layers: `InputDate` composes `Input` + `Menu` + `Calendar`,
245
- and `Calendar` itself splits into the `<a-calendar>` element (the day grid) and a
246
- JSX wrapper (the navigation chrome). Knowing which layer owns what tells you where to
247
- reach when you extend it, and lets a non-React consumer rebuild the chrome from stock
248
- elements.
249
-
250
- ### Components composition
251
-
252
- `InputDate` has no `a-inputdate` element; the wrapper is the coordinator, the role
253
- `Select` plays over `Input` + `Menu`. It renders an editable `<Input>` trigger and a
254
- `<Menu>` holding a `<Calendar>` (with `time`, the hour/minute row and AM/PM `Tabs`
255
- sit under the grid), and owns the draft text, the lenient parse on commit, and the
256
- ISO value. The menu anchors to the field and opens on click (via the `Menu`'s own
257
- anchor-click trigger, like `Select`) — a mouse open leaves focus in the field so you
258
- can keep typing, while ↓ opens it and moves focus into the grid. That
259
- focus move is declarative: `InputDate` bumps `Calendar`'s `focusSignal`, which
260
- renders a `data-focus` attribute the `<a-calendar>` element reads to focus the active
261
- day — the wrapper never touches the DOM. Nesting a stateful component in a menu has
262
- one wrinkle: the `Calendar` (and `Tabs`) dispatch their own
263
- `statechange`, so the `Menu` acts only on its own `open` / `closed`, and a bubbled
264
- pick isn't mistaken for a dismiss.
265
-
266
- The `<a-calendar>` element owns the grid and nothing else. It wires the day
267
- `<button>`s you render into it (click and keyboard: arrows, Home/End,
268
- PageUp/PageDown), holds the submitted value via `ElementInternals`,
269
- and dispatches the events: `statechange` / `change` on a pick, and `navigate` when a
270
- key pages past the rendered month. It's framework-agnostic and works on its own, with
271
- no notion of a "current month" and no sight of `min` / `max`.
272
-
273
- Everything above the grid is the JSX wrapper, rendered as **siblings outside**
274
- `<a-calendar>` from ordinary components: the prev/next arrows are `<Button>`s, and the
275
- month/year picker is a `<Button>` opening a `<Menu>` of year `MenuItem`s, each a
276
- submenu of months. The wrapper holds the displayed-month cursor in state, derives the
277
- day cells and the arrows' `disabled` state from `min` / `max`, and turns a click on an
278
- arrow, a pick in the menu, or a `navigate` event into a new cursor, then re-renders
279
- the grid. So range enforcement (disabled days, capped arrows, a disabled picker for a
280
- single-month range) lives entirely in the wrapper; the element only refuses to
281
- activate a day you've rendered `disabled`.
282
-
283
- That seam is why the element has no `min` / `max` and the switcher is a sibling: the
284
- grid stays a small, portable authority, and the chrome (Anta `Button`s and a `Menu`)
285
- is composition you can replace or rebuild. **Without React**, render the grid from the
286
- exported engine (`buildMonth`) and drive it with the same glue the wrapper packages:
246
+ `InputDate` uses Input, Menu, and Calendar. Calendar uses an `<a-calendar>`
247
+ element for the day grid and a JSX wrapper for navigation. The sections below
248
+ describe which layer provides each behavior and how to recreate the interface
249
+ without React.
250
+
251
+ ### Build it from elements
252
+
253
+ `InputDate` has no `a-inputdate` element. Its wrapper renders an editable
254
+ `<Input>` and a `<Menu>` containing a `<Calendar>`. When `time` is set, the
255
+ hour/minute fields and AM/PM `Tabs` appear below the grid. The wrapper manages
256
+ draft text, parsing on commit, and the ISO value.
257
+
258
+ Clicking the field opens the menu while keeping focus in the field. Pressing
259
+ ↓ opens the menu and moves focus to the grid. The wrapper passes a
260
+ `focusSignal` to Calendar, which renders `data-focus`; `<a-calendar>` then
261
+ focuses the active day. Calendar and Tabs emit their own `statechange` events,
262
+ but Menu responds only to changes in its own open state.
263
+
264
+ The `<a-calendar>` element provides grid behavior. It connects the supplied day
265
+ `<button>`s to click and keyboard navigation, including arrows, Home,
266
+ End, PageUp, and PageDown. It stores the form
267
+ value through `ElementInternals` and emits `statechange` / `change` on selection
268
+ and `navigate` when keyboard navigation leaves the displayed month. It is
269
+ framework-agnostic and does not track a current month, `min`, or `max`.
270
+
271
+ The JSX wrapper renders the controls above the grid as siblings of
272
+ `<a-calendar>`. The previous/next arrows are `<Button>`s. The month/year picker
273
+ is a `<Button>` that opens a `<Menu>` of year `MenuItem`s, each with a month
274
+ submenu. The wrapper stores the displayed-month cursor in state and derives day
275
+ cells and the arrows' `disabled` states from `min` and `max`. A click on an
276
+ arrow, a menu selection, or a `navigate` event updates the cursor and re-renders
277
+ the grid. The wrapper enforces the range. The element only ignores a day that
278
+ was rendered with `disabled`.
279
+
280
+ The element has no `min` or `max` because the wrapper provides the surrounding
281
+ controls. Without React, render the grid with `buildMonth` and add the
282
+ navigation behavior shown below:
287
283
 
288
284
  ```html
289
- <!-- `.calendar` is your own wrapper; the switcher is plain Buttons + a Menu. -->
285
+ <!-- `.calendar` scopes this example. Use an application selector instead. -->
290
286
  <div class="calendar" style="display: inline-flex; flex-direction: column; gap: 6px">
291
287
  <div style="display: flex; align-items: center">
292
288
  <a-button priority="tertiary" data-prev aria-label="Previous month"><a-icon shape="chevron-left"></a-icon></a-button>
293
289
  <a-button priority="tertiary" data-heading style="flex: 1; justify-content: center" aria-haspopup="menu"></a-button>
294
290
  <a-button priority="tertiary" data-next aria-label="Next month"><a-icon shape="chevron-right"></a-icon></a-button>
295
291
  </div>
296
- <!-- The element wires whatever day cells you render; it owns selection,
297
- keyboard, the form value, and the events. -->
292
+ <!-- The element provides selection, keyboard behavior, form value, and events. -->
298
293
  <a-calendar role="group" name="date"></a-calendar>
299
294
  </div>
300
295
  <script type="module">
@@ -367,7 +362,7 @@ field treatments.
367
362
  ```
368
363
 
369
364
  The calendar is **light DOM**, so everything is plain CSS, with no shadow parts or
370
- hidden internals. The days and chevrons are real `<a-button>`s, so their colours,
365
+ hidden internals. The days and chevrons are real `<a-button>`s, so their colors,
371
366
  hover, focus ring, and selected look come from the Button styles and theme
372
367
  themselves; they sit inside the `<a-calendar>` grid, and the switcher header sits in
373
368
  the `.anta-calendar` shell. An un-layered consumer rule beats `@layer anta` without
@@ -384,7 +379,7 @@ the `.anta-calendar` shell. An un-layered consumer rule beats `@layer anta` with
384
379
  Each day is a `<a-button data-part="day-cell" data-date="YYYY-MM-DD">`, so a
385
380
  specific date is addressable by its `data-date`: tint it, or hang an event marker
386
381
  off a `::after` (give the cell `position: relative` first). Below, three days carry a
387
- brand dot and one is flagged in the critical colour.
382
+ brand dot and one is flagged in the critical color.
388
383
 
389
384
  ```css
390
385
  /* Day cells are `<a-button data-part="day-cell" data-date="YYYY-MM-DD">`. Give them a