@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
@@ -1,14 +1,13 @@
1
1
  # Select
2
2
 
3
- A single- or multi-select dropdown: a read-only field showing the chosen value(s)
4
- over a menu of options. Click to open; it anchors to the field, dismisses on
5
- outside-click or `Esc`, and highlights the chosen row.
3
+ `Select` lets people choose one or more options from a dropdown. Its read-only
4
+ field shows the selected value. Click the field to open the menu. The menu
5
+ closes when a user clicks outside it or presses Esc.
6
6
 
7
- It's a **composed component**, an [Input](./input.md) trigger stitched to a
8
- [Menu](./menu.md). Options are a JSON array of strings or objects, like
9
- [RadioGroup](./radio.md) and [Tabs](./tabs.md); changes arrive
10
- through one **`onValueChange`**. Controlled via `value`, uncontrolled via
11
- `defaultValue`.
7
+ Select uses an [Input](./input.md) for its field and a [Menu](./menu.md) for its
8
+ dropdown. Pass `options` as an array of strings or objects. Use `value` with
9
+ **`onValueChange`** to control the selection, or use `defaultValue` for an
10
+ uncontrolled Select.
12
11
 
13
12
  ## Options
14
13
 
@@ -40,7 +39,7 @@ skipped by the keyboard.
40
39
  <Select indicator="radio" options={OPTIONS} value={one} onValueChange={setOne} /> // leading radio
41
40
  <Select options={OPTIONS} value={one} onValueChange={setOne} /> // tint only (default)
42
41
 
43
- // Tone the selected row: named tone or custom colour (the indicator adopts it)
42
+ // Tone the selected row: named tone or custom color (the indicator adopts it)
44
43
  <Select indicator="check" toneSelected="brand" options={OPTIONS} value={one} onValueChange={setOne} />
45
44
  <Select indicator="radio" toneSelected="#c026d3" options={OPTIONS} value={one} onValueChange={setOne} />
46
45
 
@@ -53,7 +52,7 @@ skipped by the keyboard.
53
52
  />
54
53
  ```
55
54
 
56
- `selection` sets **behaviour**, `indicator` sets the single-select **mark**.
55
+ `selection` sets **behavior**, `indicator` sets the single-select **mark**.
57
56
 
58
57
  `selection="single"` (the default) keeps `value` a single value and closes on pick.
59
58
  `indicator` then picks the row mark: **`"none"`** (default; a tint-only highlight),
@@ -69,10 +68,11 @@ selection shows the `placeholder`). A
69
68
  **Select all** top row shows by default; it toggles everything, and
70
69
  its box goes mixed when only some are on. Pass **`selectAll={false}`** to drop it.
71
70
 
72
- On a multi-select, **`Alt`+Click** a row (⌥+Click on macOS) to *isolate* it: clear
73
- the rest and select only that one. A cursor-following hint teaches the accelerator;
74
- override it per row with `SelectOption.tooltip` (or `''` to suppress). This rides on
75
- the Select all row, so `selectAll={false}` drops it too.
71
+ In a multi-select, **`Alt`+Click** a row to clear every other selection and
72
+ select that row. On macOS, use Option instead of Alt.
73
+ The standard tooltip describes this shortcut when the pointer is over a row.
74
+ Set `SelectOption.tooltip` to replace it, or to `''` to hide it. The shortcut
75
+ is available only when `selectAll` is enabled, so `selectAll={false}` removes it.
76
76
 
77
77
  Each checkable row is the control itself (`role="menuitemcheckbox"` /
78
78
  `menuitemradio`, `aria-checked`); the checkbox / radio / check is a passive indicator
@@ -105,14 +105,14 @@ option's **value, label, or hint**. It's **whitespace-flexible** (a typed space
105
105
  matches any run of whitespace) and **bolds the matched substring** in the results.
106
106
  Pass a **function** `(option, query) => boolean` for custom matching (no highlight).
107
107
 
108
- The menu becomes a **combobox**: opening focuses the search field, `↑`/`↓` move a
109
- cursor through the matches (focus stays in the field, so you keep typing), `Enter`
110
- picks the active one, and `Esc` closes. The field stays **pinned** while the matches
111
- scroll beneath it, and the menu re-anchors to the trigger as the list shrinks. No
112
- matches shows a "No matches" row, and the query resets when the menu closes. In
113
- `multiple` mode, `selectAll` acts on the currently-visible matches.
108
+ With `filter`, Select behaves as a **combobox**. Opening it focuses the search
109
+ field. ↑ and ↓ move through matching options while focus
110
+ stays in the field. Enter selects the active option, and Esc
111
+ closes the menu. The search field stays visible while the results scroll. A
112
+ "No matches" row appears when nothing matches, and the query resets when the
113
+ menu closes. In `multiple` mode, `selectAll` affects only the visible matches.
114
114
 
115
- ## Value & changes
115
+ ## Value and changes
116
116
 
117
117
  ```tsx
118
118
  const [field, setField] = useState('stream')
@@ -142,22 +142,22 @@ object), give `value` a **stable primitive key** (a date's ISO string, a record'
142
142
  and read the full value back off `attrs.option`.
143
143
 
144
144
  ```tsx
145
- // Rich value: id is the key, the full record rides on the option.
145
+ // Use the ID as the value and attach the full record to the option.
146
146
  <Select
147
147
  options={runs.map((r) => ({ value: r.id, label: r.name, run: r }))}
148
148
  onValueChange={(id, attrs) => { if (!('all' in attrs)) openRun(attrs.option.run) }}
149
149
  />
150
150
 
151
- // Date filter: the ISO string is the value — round-trips as text, rebuild on read.
151
+ // Use an ISO string as the value, then convert it back to a Date in the callback.
152
152
  <Select
153
153
  options={days.map((d) => ({ value: d.toISOString(), label: fmt(d) }))}
154
154
  onValueChange={(iso) => setDay(new Date(iso))}
155
155
  />
156
156
  ```
157
157
 
158
- Leave `value` off and pass `defaultValue` for an **uncontrolled** select (the
159
- wrapper owns the value). Pass `value` to **control** it: the field follows the prop,
160
- and a pick only requests a change that you apply in `onValueChange`.
158
+ For an **uncontrolled** Select, omit `value` and pass `defaultValue`. For a
159
+ **controlled** Select, pass `value` and update it in `onValueChange`. The field
160
+ then shows the value supplied by the application.
161
161
 
162
162
  **`onValueChange(value, attrs)`** is the single selection callback. The new value
163
163
  comes first (a single value, or an array in `multiple` mode), with a snapshot
@@ -219,7 +219,7 @@ annotated tree for rendering.
219
219
  Bare-string options normalize to `{ value, label }`; a value under more than one
220
220
  section marks the leaf everywhere it occurs (selection is value-keyed).
221
221
 
222
- ## Size & status
222
+ ## Size and status
223
223
 
224
224
  ```tsx
225
225
  <Select label="Small · info" size="small" status="info" hint="Lowercase & dashes only" options={OPTIONS} defaultValue="stream" />
@@ -244,7 +244,10 @@ the glyph and, for `critical`, validity. See the
244
244
 
245
245
  ## Customization
246
246
 
247
- Select is a composed wrapper with open seams. Rebuild it from the raw elements, or keep the wrapper and swap a row's **content** (`renderOption`) or its **selection mark** (`renderIndicator`) for your own nodes.
247
+ Select has no `<a-select>` element. The React and Preact wrapper coordinates an
248
+ Input and a Menu. You can use the wrapper, render custom option content with
249
+ `renderOption`, replace its selection mark with `renderIndicator`, or build the
250
+ same interaction from the raw elements.
248
251
 
249
252
  Pass `placement` to control where the options menu opens relative to its field. It
250
253
  uses the same values as `Menu` and still flips or clamps when space is limited.
@@ -254,17 +257,17 @@ uses the same values as `Menu` and still flips or clamps when space is limited.
254
257
  <Select placement="top-end" offset={8} options={OPTIONS} label="Field" />
255
258
  ```
256
259
 
257
- ### Components composition
260
+ ### Build it from elements
258
261
 
259
- `Select` has no `<a-select>` element; the wrapper *is* the coordinator. It renders
260
- `<Input readOnly>` + `<Menu>`, reflects the value into the field and each option's
261
- `selected`, and turns a pick into `onValueChange`. Positioning, dismissal, and
262
- in-menu keyboard come from `Menu`. The same result is reachable **without React**:
263
- the menu anchors to its previous sibling, so a field, a menu, and a little glue make
264
- a working select:
262
+ The wrapper renders a read-only `<Input>` and a `<Menu>`. It updates the field
263
+ and each option's `selected` state from the value, and reports a pick through
264
+ `onValueChange`. Menu handles positioning, dismissal, and keyboard navigation.
265
+
266
+ The following example shows the equivalent markup without React or Preact. Place
267
+ the Menu directly after the Input so it can use that Input as its trigger.
265
268
 
266
269
  ```html
267
- <!-- `.select` is your own wrapper class; everything below is scoped to it. -->
270
+ <!-- `.select` scopes this example's CSS. Use an application selector instead. -->
268
271
  <div class="select" style="width: 240px">
269
272
  <!-- Read-only field trigger; `dim-actions` dims the chevron at rest. The
270
273
  trailing slot supplies the inline inset (--input-trailing-inset); the
@@ -302,8 +305,7 @@ a working select:
302
305
  </script>
303
306
  ```
304
307
 
305
- That glue (tracking `selected`, flipping the chevron, updating the field) is what
306
- the React `Select` packages.
308
+ The React and Preact `Select` wrapper performs those updates for you.
307
309
 
308
310
  ### Custom option rendering
309
311
 
@@ -341,10 +343,10 @@ const LABEL = { in_progress: 'In progress', completed: 'Completed', incomplete:
341
343
  </div>
342
344
  ```
343
345
 
344
- **`renderOption(option, state)`** replaces a row's **content** (the
345
- `label`/`hint`/`icon` layout) with your own node. Select still supplies the row box,
346
- click, ARIA, and the selection indicator; you return what goes *inside*. It styles
347
- the menu **rows**. Set each option's `label` for the closed trigger text.
346
+ **`renderOption(option, state)`** replaces the built-in `label`, `hint`, and
347
+ `icon` layout for a row. Select still renders the row container, click behavior,
348
+ ARIA attributes, and selection indicator. Set each option's `label` for the
349
+ closed field text.
348
350
 
349
351
  Attach your own fields to each option (`SelectOption` carries an index signature) and
350
352
  read them back off `option`; those extra fields are typed `unknown`, so cast once at
@@ -352,10 +354,11 @@ the top. `state` gives you `value` / `selected` / `disabled` for the row. Give y
352
354
  root `flex: 1; min-width: 0` so it fills the row (an inner `margin-inline-start: auto`
353
355
  right-aligns a trailing element, like the status `Tag` here).
354
356
 
355
- It **composes** with everything else: `filter` still matches the option's
356
- `value` / `label` / `hint` (match-highlighting is skipped, since your content owns
357
- its display), and `indicator` / `selection` still draw the mark. Replace that mark
358
- too with `renderIndicator` (see [Custom indicators](#custom-indicators)).
357
+ `filter` still matches the option's `value`, `label`, and `hint`. Select does
358
+ not highlight matches in custom content because it cannot identify text within
359
+ the returned node. `indicator` and `selection` still provide the selection mark.
360
+ Use `renderIndicator` to replace that mark too; see
361
+ [Custom indicators](#custom-indicators).
359
362
 
360
363
  ### Limiting the width
361
364
 
@@ -478,7 +481,7 @@ const [value, setValue] = useState(['stream', 'message'])
478
481
  value={value}
479
482
  onValueChange={setValue}
480
483
  renderTrigger={({ open, selected }) => (
481
- // one focusable element the menu anchors to; it carries its own ARIA
484
+ // Return one focusable element. It supplies the required ARIA attributes.
482
485
  <Button icon="filter" label="Filter" priority="secondary"
483
486
  aria-haspopup="menu" aria-expanded={open ? 'true' : 'false'}>
484
487
  {selected.length > 0 && (
@@ -515,31 +518,31 @@ const [hidden, setHidden] = useState([])
515
518
  />
516
519
  ```
517
520
 
518
- **`renderTrigger(state)`** swaps the default field for your own trigger. Return
519
- **exactly one focusable element** (an Anta `Button` here) — the menu anchors to it (its
520
- own previous DOM sibling) and opens it on click, so a fragment or a wrapping `<div>`
521
- misanchors (the menu logs a console warning if the trigger has no focusable element).
522
- It leaves ARIA to you, so add `aria-haspopup="menu"` and `aria-expanded={state.open}`.
523
-
524
- `state` carries `open`, `value`, `selected`, `disabled`, and `icon`. `selected` is the
525
- resolved option list, so the multi-select count is `selected.length` (rendered here
526
- in a `Tag`, or `All` once every option is chosen). The field props (`label`, `size`,
527
- `status`, …) don't apply, since you own the element — except `icon`, which is handed
528
- through as `state.icon` so a custom trigger can place the same leading glyph (e.g. a
529
- `Button`'s `icon`).
530
-
531
- The second example pairs a custom trigger with `renderIndicator` for a **column
532
- visibility** control: an icon-only `Button` (`columns-3-cog`, tertiary), and options
533
- that are bare column names. Here selection means *hidden* — the mark reads `eye` while
534
- a column shows and flips to `eye-closed` once it's selected off. The trigger reads its count off the
535
- same `selected` list `renderTrigger` hands it, so the `Tag` stays empty until you turn a column off.
521
+ **`renderTrigger(state)`** replaces the default field. Return exactly one
522
+ focusable element, such as the Anta `Button` in this example. Select positions
523
+ the menu relative to that element and opens it when it is clicked. A fragment,
524
+ multiple sibling elements, or a non-focusable wrapper prevents Select from finding
525
+ the trigger. It logs a console warning when that happens. Add
526
+ `aria-haspopup="menu"` and `aria-expanded={state.open}` to the element.
527
+
528
+ `state` includes `open`, `value`, `selected`, `disabled`, and `icon`. `selected`
529
+ is the resolved option list, so `selected.length` is the multi-select count. The
530
+ default field props, including `label`, `size`, and `status`, do not apply to a
531
+ custom trigger. `state.icon` contains the Select `icon` prop so the replacement
532
+ trigger can display the same icon.
533
+
534
+ The second example uses a custom trigger and `renderIndicator` for a **column
535
+ visibility** control. The options are column names. In this example, a selected
536
+ option means that its column is hidden: the indicator changes from `eye` to
537
+ `eye-closed`. The Tag uses `selected.length`, so it appears only after a column
538
+ is hidden.
536
539
 
537
540
  ### Empty state
538
541
 
539
542
  ```tsx
540
543
  const [options, setOptions] = useState(['bug', 'feature', 'chore', 'docs'])
541
544
  const [value, setValue] = useState()
542
- const [loading, setLoading] = useState(false) // your own fetch state
545
+ const [loading, setLoading] = useState(false) // application fetch state
543
546
 
544
547
  <Select
545
548
  label="Tag"
@@ -565,21 +568,20 @@ const [loading, setLoading] = useState(false) // your own fetch state
565
568
  />
566
569
  ```
567
570
 
568
- **`renderEmpty({ query })`** fills the menu body when the option list is empty after
569
- the filter runs — a "no results" line, a loading indicator, or a create-from-query
570
- row. `query` is the current filter text: non-empty means the filter hid everything,
571
- empty means there were no options to begin with.
571
+ **`renderEmpty({ query })`** renders content when the option list is empty after
572
+ filtering. It can return a "No results" message, a loading indicator, or a row
573
+ that creates an option from `query`. A non-empty `query` means that filtering
574
+ removed every option; an empty `query` means that no options were supplied.
572
575
 
573
- There's **no built-in empty message** — omit `renderEmpty` and an empty list shows
574
- nothing. Loading isn't a Select prop either: you already own the fetch, so gate a
575
- `'Loading…'` branch on your own state (here a checkbox stands in for it).
576
+ Select has no built-in empty message. If `renderEmpty` is omitted, an empty list
577
+ has no content. Loading also belongs to application state, so return a
578
+ `'Loading…'` branch when that state is true.
576
579
 
577
- Whatever you return renders where the rows would. Wrap a message in a `MenuSeparator`
578
- — given text it renders a small muted caption and becomes an `aria-live="polite"`
579
- region, so the message is announced. Return a `MenuItem` — like the `Create "…"` row
580
- here, which arrow-keys and Enter reach like any option — to make it selectable.
580
+ The returned content replaces the option rows. A `MenuSeparator` with text is a
581
+ muted caption and an `aria-live="polite"` region. Return a `MenuItem`, such as
582
+ the `Create "…"` row, when the content must be selectable by keyboard.
581
583
 
582
- ### Groups & submenus
584
+ ### Groups and submenus
583
585
 
584
586
  ```tsx
585
587
  // The same tree drives both modes — selection is global, so `selection` is the
@@ -642,8 +644,7 @@ scannable list instead of hiding matches behind flyouts.
642
644
  (single → none, multiple → `[]`). Shown only while something is selected, so
643
645
  it never scrolls away in a long or filtered list. |
644
646
  | `clearLabel?` | string | Clear | Label for the `clearable` footer row. |
645
- | `defaultValue?` | V \| V[] | — | Initial value (an option's `value`) for the uncontrolled case — the
646
- wrapper then owns it. |
647
+ | `defaultValue?` | V \| V[] | — | Initial selected option value for uncontrolled use. |
647
648
  | `disabled?` | boolean | — | Disable the whole select. |
648
649
  | `filter?` | boolean \| (option, query) => boolean | — | Add a search field at the top of the menu that filters the options as you
649
650
  type. `true` uses the built-in matcher — a case-insensitive substring of the
@@ -658,10 +659,9 @@ scannable list instead of hiding matches behind flyouts.
658
659
  canonical Select look), or `'radio'` (a leading radio on every row).
659
660
  Multi-select always uses checkboxes. |
660
661
  | `label?` | string | — | Field label, above the trigger (Input's `label`). |
661
- | `leading?` | ReactNode | — | Arbitrary content for the default trigger's leading slot (piped straight to
662
- `Input`'s `leading`) — e.g. a key prefix before the value. Overrides the
663
- `icon`-derived glyph when both are set; include your own `<Icon>` if you want
664
- one alongside. Ignored with a custom `renderTrigger`. |
662
+ | `leading?` | ReactNode | — | Content for the default trigger's `leading` slot, such as a key prefix
663
+ before the value. It replaces the icon derived from `icon`. Include an
664
+ `<Icon>` in this content when both are needed. Ignored by `renderTrigger`. |
665
665
  | `offset?` | number | 4 | Gap in pixels between the trigger and the options menu. |
666
666
  | `onValueChange?` | (value, attrs) => void | — | Fires after the selection changes, with the new value and a
667
667
  `{ value, option }` snapshot. Select has no discrete element state, so
@@ -681,13 +681,12 @@ scannable list instead of hiding matches behind flyouts.
681
681
  `indicator` / `selection`); only the drawn mark changes, so pair it with an
682
682
  `indicator` (`'check'` / `'radio'`) or `selection="multiple"` for the
683
683
  semantics. Composes with `renderOption`. |
684
- | `renderOption?` | (option, state) => ReactNode | — | Render the **content** of each option row yourself, replacing the built-in
685
- `label`/`hint`/`icon` layout. Select still supplies the row box, click, ARIA,
686
- and the selection indicator — you return only what goes *inside*. Read extra
687
- fields off the option (see `SelectOption`'s index signature) plus an
688
- `OptionState` (`value`/`selected`/`disabled`). Filtering still works (it
689
- matches the option's `value`/`label`/`hint`), but match-highlighting is
690
- skipped — your content owns its own display. |
684
+ | `renderOption?` | (option, state) => ReactNode | — | Replaces the built-in `label`, `hint`, and `icon` layout for each option row.
685
+ Select still supplies the row container, click handling, ARIA attributes, and
686
+ selection indicator. Read extra option fields through `SelectOption`'s index
687
+ signature. `state` contains `value`, `selected`, and `disabled`. Filtering
688
+ still matches the option's `value`, `label`, and `hint`, but Select cannot
689
+ highlight matches within the returned content. |
691
690
  | `renderSummary?` | (selected) => string \| undefined | — | `multiple` only: build the trigger's selection summary text yourself,
692
691
  replacing the built-in "`All` / one label / `N selected`" logic. Receives
693
692
  the resolved selected options (`selected.length` is the count) and runs only
@@ -698,22 +697,20 @@ scannable list instead of hiding matches behind flyouts.
698
697
  back to the default for that case (e.g. customize only the count, keeping
699
698
  the single-label case built-in). For rich content (chips, multiple nodes)
700
699
  use `renderTrigger`, which replaces the whole field. |
701
- | `renderTrigger?` | (state) => ReactNode | — | Render your own trigger in place of the default field. Receives a
702
- `TriggerState` (`open` / `value` / `selected` / `disabled` / `icon`) to drive
703
- its look. **Return exactly one focusable element** (an Anta `Button`, say) —
704
- the menu anchors to it (its own previous DOM sibling) and opens it on click,
705
- so a fragment, multiple siblings, or a non-focusable wrapper will misanchor
706
- (the menu warns in the console if the trigger has no focusable element). Give
707
- the element `aria-haspopup="menu"` plus `aria-expanded={state.open}`. The custom
708
- trigger owns its own styling: the field props (`label`, `hint`, `size`, `status`,
709
- `placeholder`, `round`) and `className` / `style` apply to the *default* trigger
710
- only — put your own on the element you return. |
700
+ | `renderTrigger?` | (state) => ReactNode | — | Replaces the default field with a trigger returned from this function.
701
+ Receives `open`, `value`, `selected`, `disabled`, and `icon`. Return exactly
702
+ one focusable element, such as an Anta `Button`. The menu is positioned
703
+ relative to that element and opens when it is clicked. Do not return a
704
+ fragment, multiple siblings, or a non-focusable wrapper. Add
705
+ `aria-haspopup="menu"` and `aria-expanded={state.open}` to the element.
706
+ Field props (`label`, `hint`, `size`, `status`, `placeholder`, and `round`) and
707
+ `className` / `style` apply only to the default field. Add styling and
708
+ attributes to the returned element instead. |
711
709
  | `round?` | boolean \| number \| string | — | Round the field corners — `true` for fully round, or a number / CSS length. |
712
- | `selectAll?` | boolean | true | `multiple` only: a "Select all" row at the top that toggles every enabled
713
- option (the currently-visible ones when a `filter` query is active); its box
714
- shows the mixed state when only some are selected. On by default in
715
- `multiple` mode — set `false` to drop the row (and with it the Alt/⌥-click
716
- isolate accelerator it gates). |
710
+ | `selectAll?` | boolean | true | `multiple` only: shows a "Select all" row that toggles every enabled option,
711
+ or only the visible options when a filter query is active. Its checkbox is
712
+ mixed when some options are selected. It is on by default. Set it to `false`
713
+ to remove the row and the Alt/Option-click shortcut that selects only one row. |
717
714
  | `selectAllLabel?` | string | Select all | Label for the `selectAll` row. |
718
715
  | `selection?` | 'single' \| 'multiple' | single | Selection mode. `'single'` (the default) keeps `value` a single value and
719
716
  closes the menu on pick. Switch to `'multiple'` for checkboxes + an
@@ -727,10 +724,8 @@ scannable list instead of hiding matches behind flyouts.
727
724
  the chosen option. A named tone or a custom CSS color. Most visible with the
728
725
  tint-based marks (`indicator` `'none'` / `'check'`); with `'radio'` /
729
726
  `'checkbox'` it tones the label + indicator (those modes have no row tint). |
730
- | `value?` | V \| V[] | — | Controlled value — the `value` of the selected option. When provided, the
731
- consumer owns selection: the field follows this prop and a pick only
732
- *requests* a change via `onValueChange` (reject by not updating). Leave
733
- undefined for uncontrolled. |
727
+ | `value?` | V \| V[] | — | Controlled value: the selected option's `value`. Update it through
728
+ `onValueChange`. Leave it undefined for uncontrolled use. |
734
729
  | `verbose?` | boolean | — | `multiple` only: spell the picks out in the count summary — `3 selected:
735
730
  A, B, C` (labels comma-joined) in place of the bare `3 selected`. Applies
736
731
  to the multi-count case only: `All` stays `All`, a single pick stays its
@@ -774,13 +769,16 @@ the same thing):
774
769
 
775
770
  | Field | Type | Description |
776
771
  |---|---|---|
777
- | `value` | `OptionValue` | The option's identity: `string`, `number`, or `boolean` (`Select` infers the type from your `options`, compared with `===`). What `value` / `defaultValue` name and `onValueChange` reports. Required, unique across the tree. See [Value & changes](#value--changes) for non-string values and rich data. |
772
+ | `value` | `OptionValue` | The option's identity: `string`, `number`, or `boolean` (`Select` infers the type from your `options`, compared with `===`). What `value` / `defaultValue` name and `onValueChange` reports. Required, unique across the tree. See [Value and changes](#value-and-changes) for non-string values and rich data. |
778
773
  | `label` | `string` | Visible label. Defaults to `value`. |
779
774
  | `hint` | `string` | Secondary line under the label. |
780
775
  | `icon` | `IconShape` | Leading icon, after the selection indicator. |
781
776
  | `disabled` | `boolean` | Disable just this option. |
782
777
  | `tone` | `string` | The row's color across label, icon, hint, selected tint, and indicator. A named tone (`neutral` / `brand` / `info` / `success` / `warning` / `critical`) or any CSS color. |
783
778
  | `tooltip` | `React.ReactNode` | Row tooltip. In a `multiple` select with `selectAll`, a row with no `tooltip` shows the default "select only this" (Alt/⌥-click) hint; set it to override, or `''` to suppress. |
779
+ | `className` | `string` | CSS class on the rendered menu row. |
780
+ | `style` | `React.CSSProperties` | Inline styles on the rendered menu row. |
781
+ | `data-*` | `unknown` | Data attributes on the rendered menu row. `data-menu-*` is reserved for Select's selection and keyboard behavior. |
784
782
  | `[key: string]` | `unknown` | Your own data — attach anything and read it back in `renderOption`. |
785
783
 
786
784
  **`SelectGroup`** — a heading with items rendered inline beneath it.
@@ -829,7 +827,7 @@ inline `SelectGroup`, and a flyout `SelectSubmenu` (whose items are themselves
829
827
  />
830
828
  ```
831
829
 
832
- 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.
830
+ Use the web component directly when you are not using React or Preact and a native control does not fit.
833
831
 
834
832
  `Select` has no host element. Compose a read-only `<a-input>` trigger with an
835
833
  `<a-menu>` of options. The menu owns opening and dismissal; the short controller
@@ -875,7 +873,7 @@ model retain their regular native select. Use `Select` for filtering, multiple
875
873
  selection, nested menus, or custom option coordination.
876
874
 
877
875
  Use `data-anta-size="small"` or `"large"` for the field size. Native selects
878
- own their `size` attribute, and `round` gives the trigger matching rounded
876
+ continue to use their standard `size` attribute, and `round` gives the trigger matching rounded
879
877
  corners.
880
878
 
881
879
  ```html
@@ -900,7 +898,7 @@ Select is an [Input](./input.md) plus a [Menu](./menu.md), so it
900
898
  inherits both surfaces' hooks. Reach for props first, then plain CSS or `::part` for
901
899
  the rest. Don't override an element's internal `--*` output tokens.
902
900
 
903
- **Selection colour** routes through the props: a per-option `tone`, or `toneSelected`
901
+ **Selection color** routes through the props: a per-option `tone`, or `toneSelected`
904
902
  for the chosen row(s). Both take a named tone or any CSS color (a custom color keeps
905
903
  its hue, with lightness pinned to the brand text).
906
904
 
@@ -924,7 +922,7 @@ wrapper is inline-`display:contents`, so hit the icon itself).
924
922
  .ghost-select a-input:not(:hover):not(:focus-within)::part(field) {
925
923
  box-shadow: none;
926
924
  }
927
- /* Centre the chosen label in the field. */
925
+ /* Center the chosen label in the field. */
928
926
  .ghost-select a-input::part(input) { text-align: center; }
929
927
  /* The chevron's slot wrapper is inline display:contents; hide the icon itself. */
930
928
  .ghost-select a-input [slot="trailing"] a-icon { display: none; }
@@ -1,12 +1,17 @@
1
1
  # Slider
2
2
 
3
- **`Slider`** selects one numeric value from a range. Its label sits above the rail, and the value appears at the label row’s right edge by default. It works controlled with `value` and `onValueChange`, or uncontrolled with `defaultValue`.
3
+ **`Slider`** selects one numeric value from a range. Its label sits above the
4
+ rail, and the value appears at the right side of the label row by default. Use
5
+ `value` with `onValueChange` to control it, or `defaultValue` for uncontrolled use.
4
6
 
5
7
  ## Relative dragging
6
8
 
7
- Pressing the rail starts a grab from its current value. Moving right increases the value; moving left decreases it. The thumb does not jump to the press position. This is the default `trackClick="drag-only"` behaviour.
9
+ With the default `trackClick="drag-only"`, pressing the rail starts dragging
10
+ from the current value. Moving right increases the value, and moving left
11
+ decreases it. The thumb does not move to the point where the rail was pressed.
8
12
 
9
- Set `trackClick="jump"` for the conventional range-input interaction, where pressing the rail first moves the thumb to that position.
13
+ Set `trackClick="jump"` to move the thumb to the pressed position before
14
+ dragging, as a native range input does.
10
15
 
11
16
  Arrow keys change by `step`. Home and End set the minimum and maximum. PageUp and PageDown move by one tenth of the range.
12
17
 
@@ -27,7 +32,7 @@ Arrow keys change by `step`. Home and End set the minimum and maximum. PageUp an
27
32
 
28
33
  ## Size, tones, and radius
29
34
 
30
- `size` follows the input height scale: 24px, 28px, and 32px. `trackSize` sets the thickness of both rail segments without changing the control height; numbers use pixels and strings accept CSS lengths. `thumbSize` controls the thumb diameter, and `thumbFill` fills it with its resolved border colour. `tone` colours the filled rail. `thumbTone` separately colours the thumb stroke. The unfilled rail stays neutral. `round` shapes both the rail and thumb. Pass `true` for fully round corners or a number or CSS length for a shared custom radius.
35
+ `size` follows the input height scale: 24px, 28px, and 32px. `trackSize` sets the thickness of both rail segments without changing the control height; numbers use pixels and strings accept CSS lengths. `thumbSize` controls the thumb diameter, and `thumbFill` fills it with its resolved border color. `tone` colors the filled rail. `thumbTone` separately colors the thumb stroke. The unfilled rail stays neutral. `round` shapes both the rail and thumb. Pass `true` for fully round corners or a number or CSS length for a shared custom radius.
31
36
 
32
37
  ```tsx
33
38
  <Slider size="small" tone="info" label="Small" defaultValue={32} />
@@ -73,16 +78,16 @@ ticks to the rail. |
73
78
  for a shared custom radius. |
74
79
  | `size?` | 'small' \| 'medium' \| 'large' | 'medium' | Size variant. small=24px, medium=28px, large=32px tall. |
75
80
  | `step?` | number | 1 | Smallest keyboard and drag increment. |
76
- | `thumbFill?` | boolean | false | Fill the thumb with its resolved border colour. This follows `thumbTone`
81
+ | `thumbFill?` | boolean | false | Fill the thumb with its resolved border color. This follows `thumbTone`
77
82
  and interactive states. |
78
83
  | `thumbSize?` | number \| string | 18 | Diameter of the thumb. Numbers use pixels; strings are CSS lengths. Keep
79
84
  it at least as large as `trackSize`. |
80
- | `thumbTone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Colour of the thumb stroke. Pass a named tone or a literal CSS colour for a
85
+ | `thumbTone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Color of the thumb stroke. Pass a named tone or a literal CSS color for a
81
86
  one-off custom tone. Omit it to keep the thumb neutral. |
82
- | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Colour of the filled rail. Pass a named tone or a literal CSS colour for a
87
+ | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Color of the filled rail. Pass a named tone or a literal CSS color for a
83
88
  one-off custom tone. The unfilled rail stays neutral. |
84
- | `trackClick?` | 'drag-only' \| 'jump' | 'drag-only' | Track press behaviour. `drag-only` starts a relative grab from the current
85
- value; `jump` first moves to the press position. |
89
+ | `trackClick?` | 'drag-only' \| 'jump' | 'drag-only' | Controls what happens when the rail is pressed. `drag-only` starts dragging
90
+ from the current value. `jump` first moves to the pressed position. |
86
91
  | `trackSize?` | number \| string | 2 | Thickness of both rail segments. Numbers use pixels; strings are CSS
87
92
  lengths. Keep it no larger than the thumb diameter. |
88
93
  | `value?` | number | — | Controlled value. Update it from `onValueChange`. |
@@ -129,7 +134,7 @@ as `Slider`. In raw HTML, `round` needs a CSS length such as `"4px"`; JSX
129
134
 
130
135
  ## Styling
131
136
 
132
- `Slider` renders an `<a-slider>` with a circular thumb. `tone` and `thumbTone` accept named or custom CSS colours; custom values use the public `--slider-tone-source` and `--slider-thumb-tone-source` knobs. Use `round` to shape the rail and thumb together. Target its shadow parts to change their presentation without taking on the interaction code: `::part(thumb)` customises the thumb’s surface and stroke. The element exposes `header`, `label`, `value`, `control`, `track`, `fill`, `thumb`, `thumb-value`, `markers`, and `extras`.
137
+ `Slider` renders an `<a-slider>` with a circular thumb. `tone` and `thumbTone` accept named or custom CSS colors; custom values use the public `--slider-tone-source` and `--slider-thumb-tone-source` knobs. Use `round` to shape the rail and thumb together. Target its shadow parts to change their presentation without taking on the interaction code: `::part(thumb)` customizes the thumb’s surface and stroke. The element exposes `header`, `label`, `value`, `control`, `track`, `fill`, `thumb`, `thumb-value`, `markers`, and `extras`.
133
138
 
134
139
  ```css
135
140
  /* The class is only for the demo. Use your own selector. */
@@ -6,7 +6,7 @@ The `Switch` wrapper renders a form-associated `<a-switch>` element. It works un
6
6
 
7
7
  ## Tone
8
8
 
9
- `tone` colours the whole control: the checked track, plus the unchecked track border and thumb. Six named tones are available, or pass any CSS color for a custom tone. The label and hint stay neutral.
9
+ `tone` colors the whole control: the checked track, plus the unchecked track border and thumb. Six named tones are available, or pass any CSS color for a custom tone. The label and hint stay neutral.
10
10
 
11
11
  ```tsx
12
12
  <Switch defaultChecked tone="neutral" label="Neutral" />
@@ -17,16 +17,16 @@ The `Switch` wrapper renders a form-associated `<a-switch>` element. It works un
17
17
 
18
18
  ## Selected-only tone
19
19
 
20
- `toneSelected` colours the checked track only. The unchecked track and thumb stay neutral until the switch is on. Use it when a resting tinted control could imply a validation state. It accepts the same values as `tone`.
20
+ `toneSelected` colors the checked track only. The unchecked track and thumb stay neutral until the switch is on. Use it when a resting tinted control could imply a validation state. It accepts the same values as `tone`.
21
21
 
22
22
  ```tsx
23
23
  <Switch toneSelected="brand" label="Off stays neutral" />
24
24
  <Switch defaultChecked toneSelected="critical" label="Checked track tinted" />
25
25
  ```
26
26
 
27
- ## Colouring the text
27
+ ## Coloring the text
28
28
 
29
- There is no text-tone prop. To tint the label, set `color` on the switch with a theme-aware `--text-N-{tone}` token; to tint the hint, target `a-switch-hint`. Pair either with `tone` or `toneSelected` to colour the whole control.
29
+ There is no text-tone prop. To tint the label, set `color` on the switch with a theme-aware `--text-N-{tone}` token; to tint the hint, target `a-switch-hint`. Pair either with `tone` or `toneSelected` to color the whole control.
30
30
 
31
31
  ```css
32
32
  /* The class is only for the demo — use your own selector. */
@@ -54,7 +54,7 @@ Switches are fully rounded by default. Pass `round` with a number (pixels) or CS
54
54
  <Switch defaultChecked round={0} label="Square" />
55
55
  ```
56
56
 
57
- ## Label & hint
57
+ ## Label and hint
58
58
 
59
59
  Pass a plain label through `label`, or pass richer label content as children. Add `hint` for a secondary line beneath. `labelPosition="start"` places the label and hint before the control visually while source order remains stable. For a label-less switch, pass `aria-label`.
60
60
 
@@ -143,14 +143,14 @@ uncontrolled change; controlled consumers accept by updating `checked`. |
143
143
  | `round?` | boolean \| number \| string | — | Fully round the thumb and track. Pass a `number` (px) or CSS length string
144
144
  for a custom track radius; the thumb radius is 3px smaller. |
145
145
  | `size?` | 'small' \| 'medium' \| 'large' | 'medium' | Size variant. small=26×16px, medium=30×18px, large=34×20px. |
146
- | `tone?` | 'brand' \| 'neutral' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'brand' | Colour of the track and thumb. A tinted tone also colours the unchecked
147
- track border and thumb; use `toneSelected` to colour only the checked track. |
146
+ | `tone?` | 'brand' \| 'neutral' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'brand' | Color of the track and thumb. A tinted tone also colors the unchecked
147
+ track border and thumb; use `toneSelected` to color only the checked track. |
148
148
  | `toneSelected?` | 'brand' \| 'neutral' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'brand' | Like `tone`, but applies only while the switch is checked. The unchecked
149
- track and thumb stay neutral. If both are set, `tone` colours the unchecked
150
- state and `toneSelected` colours the checked track. |
149
+ track and thumb stay neutral. If both are set, `tone` colors the unchecked
150
+ state and `toneSelected` colors the checked track. |
151
151
  | `value?` | string | "on" | Value submitted while checked. |
152
152
 
153
- 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.
153
+ Use the web component directly when you are not using React or Preact and a native control does not fit.
154
154
 
155
155
  The focusable host carries the state. Label and hint are light-DOM children.
156
156
 
@@ -161,13 +161,13 @@ The focusable host carries the state. Label and hint are light-DOM children.
161
161
  </a-switch>
162
162
  ```
163
163
 
164
- Reach for the props first: **`tone`** colours the checked track plus the unchecked chrome, while **`toneSelected`** colours only the checked track. Both accept any CSS color; **`size`** scales the control, label, and hint. The focus ring is the global [`--focus-ring`](../colors.md#focus-ring).
164
+ Reach for the props first: **`tone`** colors the checked track plus the unchecked chrome, while **`toneSelected`** colors only the checked track. Both accept any CSS color; **`size`** scales the control, label, and hint. The focus ring is the global [`--focus-ring`](../colors.md#focus-ring).
165
165
 
166
166
  ```tsx
167
- <Switch tone="#e0457b" defaultChecked label="Custom colour" />
167
+ <Switch tone="#e0457b" defaultChecked label="Custom color" />
168
168
  ```
169
169
 
170
- `<a-switch>` is light DOM. The **track is `::before`**, the **thumb is `::after`**, and the label / hint are `a-switch-label` / `a-switch-hint` children. Target them with plain CSS. The classes below are only for the demos.
170
+ `<a-switch>` is light DOM. The **track is `::before`**, the **thumb is `::after`**, and the label / hint are `a-switch-label` / `a-switch-hint` children. Target them with plain CSS. The classes in these examples are demo hooks. Replace them with a selector you own.
171
171
 
172
172
  ```css
173
173
  a-switch.strong-label {