@antadesign/anta 0.3.25 → 0.3.27

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 (104) hide show
  1. package/README.md +26 -28
  2. package/dist/anta_helpers.d.ts +4 -0
  3. package/dist/anta_helpers.js +17 -3
  4. package/dist/box-types.d.ts +161 -0
  5. package/dist/box-types.js +0 -0
  6. package/dist/bundle.css +1 -1
  7. package/dist/bundle.js +25 -25
  8. package/dist/capture-types.d.ts +156 -0
  9. package/dist/capture-types.js +0 -0
  10. package/dist/components/Box.d.ts +52 -0
  11. package/dist/components/Box.js +55 -0
  12. package/dist/components/Capture.d.ts +39 -0
  13. package/dist/components/Capture.js +36 -0
  14. package/dist/components/capture-props.d.ts +30 -0
  15. package/dist/components/capture-props.js +44 -0
  16. package/dist/elements/a-avatar.css +1 -1
  17. package/dist/elements/a-banner.css +1 -1
  18. package/dist/elements/a-banner.js +4 -4
  19. package/dist/elements/a-box.css +1 -0
  20. package/dist/elements/a-box.d.ts +41 -0
  21. package/dist/elements/a-box.js +584 -0
  22. package/dist/elements/a-button.css +1 -1
  23. package/dist/elements/a-calendar.js +2 -2
  24. package/dist/elements/a-capture.css +1 -0
  25. package/dist/elements/a-capture.d.ts +10 -0
  26. package/dist/elements/a-capture.js +24 -0
  27. package/dist/elements/a-card.css +1 -1
  28. package/dist/elements/a-checkbox.css +1 -1
  29. package/dist/elements/a-checkbox.js +4 -4
  30. package/dist/elements/a-dialog.css +1 -1
  31. package/dist/elements/a-expander.css +1 -1
  32. package/dist/elements/a-expander.js +2 -2
  33. package/dist/elements/a-input-time.css +1 -1
  34. package/dist/elements/a-input-time.js +3 -3
  35. package/dist/elements/a-input.css +1 -1
  36. package/dist/elements/a-input.js +6 -6
  37. package/dist/elements/a-menu-item.css +1 -1
  38. package/dist/elements/a-menu-item.js +3 -3
  39. package/dist/elements/a-menu.css +1 -1
  40. package/dist/elements/a-menu.js +2 -2
  41. package/dist/elements/a-radio-group.js +3 -3
  42. package/dist/elements/a-radio.css +1 -1
  43. package/dist/elements/a-slider.css +1 -1
  44. package/dist/elements/a-slider.js +6 -6
  45. package/dist/elements/a-switch.css +1 -1
  46. package/dist/elements/a-switch.js +2 -2
  47. package/dist/elements/a-tabpanel.js +2 -2
  48. package/dist/elements/a-tabs.css +1 -1
  49. package/dist/elements/a-tabs.js +6 -6
  50. package/dist/elements/a-tag.css +1 -1
  51. package/dist/elements/a-text.css +1 -1
  52. package/dist/elements/a-title.css +1 -1
  53. package/dist/elements/a-toast.js +2 -2
  54. package/dist/elements/a-tooltip.css +1 -1
  55. package/dist/elements/a-tooltip.d.ts +4 -3
  56. package/dist/elements/a-tooltip.js +9 -5
  57. package/dist/elements/capture-input.d.ts +5 -0
  58. package/dist/elements/capture-input.js +609 -0
  59. package/dist/elements/index.d.ts +2 -0
  60. package/dist/elements/index.js +6 -0
  61. package/dist/general_types.d.ts +70 -0
  62. package/dist/index.d.ts +6 -0
  63. package/dist/index.js +4 -0
  64. package/dist/jsx-runtime.d.ts +3 -1
  65. package/docs/accessibility.md +24 -0
  66. package/docs/changelog.md +45 -3
  67. package/docs/colors.md +141 -0
  68. package/docs/comparison.md +463 -28
  69. package/docs/components/avatar.md +364 -0
  70. package/docs/components/banner.md +13 -27
  71. package/docs/components/box.md +354 -0
  72. package/docs/components/breadcrumbs.md +7 -6
  73. package/docs/components/button.md +48 -37
  74. package/docs/components/capture.md +345 -0
  75. package/docs/components/card.md +17 -38
  76. package/docs/components/checkbox.md +16 -39
  77. package/docs/components/dialog.md +14 -36
  78. package/docs/components/expander.md +15 -40
  79. package/docs/components/icon.md +111 -9
  80. package/docs/components/input-autocomplete.md +9 -11
  81. package/docs/components/input-date.md +33 -23
  82. package/docs/components/input-time.md +15 -23
  83. package/docs/components/input.md +27 -76
  84. package/docs/components/loader.md +7 -5
  85. package/docs/components/menu.md +73 -77
  86. package/docs/components/progress.md +10 -14
  87. package/docs/components/radio.md +17 -36
  88. package/docs/components/select-faceted.md +7 -25
  89. package/docs/components/select.md +24 -97
  90. package/docs/components/slider.md +16 -21
  91. package/docs/components/steps.md +38 -8
  92. package/docs/components/switch.md +11 -14
  93. package/docs/components/tabs.md +52 -40
  94. package/docs/components/tag.md +11 -22
  95. package/docs/components/text.md +10 -23
  96. package/docs/components/title.md +7 -8
  97. package/docs/components/toaster.md +6 -3
  98. package/docs/components/tooltip.md +13 -23
  99. package/docs/index.md +6 -3
  100. package/docs/install-config.md +24 -0
  101. package/docs/normalization.md +45 -0
  102. package/docs/packages/stickers.md +56 -0
  103. package/docs/theming.md +270 -0
  104. package/package.json +3 -1
@@ -13,6 +13,9 @@ decreases it. The thumb does not move to the point where the rail was pressed.
13
13
  Set `trackClick="jump"` to move the thumb to the pressed position before
14
14
  dragging, as a native range input does.
15
15
 
16
+ Releasing the pointer or losing pointer capture ends the drag. Moving back over
17
+ the slider without pressing leaves its value unchanged.
18
+
16
19
  Arrow keys change by `step`. Home and End set the minimum and maximum. PageUp and PageDown move by one tenth of the range.
17
20
 
18
21
  ```tsx
@@ -59,43 +62,35 @@ Arrow keys change by `step`. Home and End set the minimum and maximum. PageUp an
59
62
  />
60
63
  ```
61
64
 
62
- ### Props
65
+ ## Component props
63
66
 
64
67
  | Prop | Type | Default | Description |
65
68
  |------|------|---------|-------------|
66
69
  | `defaultValue?` | number | 0 | Initial uncontrolled value. |
67
70
  | `disabled?` | boolean | — | Disables pointer and keyboard interaction. |
68
- | `label?` | ReactNode | — | Visible field label, shown above the rail. A string supplies the slider's
69
- accessible name; give a rich label an explicit `aria-label`. |
70
- | `markers?` | SliderMarker[] | — | Compact text labels positioned below the rail. They do not add dots or
71
- ticks to the rail. |
71
+ | `label?` | ReactNode | — | Visible field label, shown above the rail. A string supplies the slider's accessible name; give a rich label an explicit `aria-label`. |
72
+ | `markers?` | SliderMarker[] | — | Compact text labels positioned below the rail. They do not add dots or ticks to the rail. |
72
73
  | `max?` | number | 100 | Highest permitted value. |
73
74
  | `min?` | number | 0 | Lowest permitted value. |
74
75
  | `name?` | string | — | Form field name. The current numeric value submits under this name. |
75
76
  | `onValueChange?` | (event, attrs) => void | — | Fires on every keyboard or pointer value change. |
76
77
  | `onValueCommit?` | (event, attrs) => void | — | Fires after a drag ends and after each keyboard value change. |
77
- | `round?` | boolean \| number \| string | — | Fully round the rail and thumb. Pass a number (px) or CSS length string
78
- for a shared custom radius. |
78
+ | `round?` | boolean \| number \| string | — | Fully round the rail and thumb. Pass a number (px) or CSS length string for a shared custom radius. |
79
79
  | `size?` | 'small' \| 'medium' \| 'large' | 'medium' | Size variant. small=24px, medium=28px, large=32px tall. |
80
80
  | `step?` | number | 1 | Smallest keyboard and drag increment. |
81
- | `thumbFill?` | boolean | false | Fill the thumb with its resolved border color. This follows `thumbTone`
82
- and interactive states. |
83
- | `thumbSize?` | number \| string | 16 | Diameter of the thumb. Numbers use pixels; strings are CSS lengths. Keep
84
- it at least as large as `trackSize`. |
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
86
- one-off custom tone. Omit it to keep the thumb neutral. |
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
88
- one-off custom tone. The unfilled rail stays neutral. |
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. |
91
- | `trackSize?` | number \| string | 2 | Thickness of both rail segments. Numbers use pixels; strings are CSS
92
- lengths. Keep it no larger than the thumb diameter. |
81
+ | `thumbFill?` | boolean | false | Fill the thumb with its resolved border color. This follows `thumbTone` and interactive states. |
82
+ | `thumbSize?` | number \| string | 16 | Diameter of the thumb. Numbers use pixels; strings are CSS lengths. Keep it at least as large as `trackSize`. |
83
+ | `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 one-off custom tone. Omit it to keep the thumb neutral. |
84
+ | `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 one-off custom tone. The unfilled rail stays neutral. |
85
+ | `trackClick?` | 'drag-only' \| 'jump' | 'drag-only' | Controls what happens when the rail is pressed. `drag-only` starts dragging from the current value. `jump` first moves to the pressed position. |
86
+ | `trackSize?` | number \| string | 2 | Thickness of both rail segments. Numbers use pixels; strings are CSS lengths. Keep it no larger than the thumb diameter. |
93
87
  | `value?` | number | — | Controlled value. Update it from `onValueChange`. |
94
- | `valueDisplay?` | 'end' \| 'inline' \| 'thumb' \| 'none' | 'end' | Where the live value appears. `end` puts it at the right edge of the label
95
- row. `inline` renders `Label: value`. `thumb` keeps it above the thumb. |
88
+ | `valueDisplay?` | 'end' \| 'inline' \| 'thumb' \| 'none' | 'end' | Where the live value appears. `end` puts it at the right edge of the label row. `inline` renders `Label: value`. `thumb` keeps it above the thumb. |
96
89
  | `valuePrefix?` | string | — | Text inserted before the live numeric value, such as `$`. |
97
90
  | `valueSuffix?` | string | — | Text inserted after the live numeric value, such as `%` or `°C`. |
98
91
 
92
+ ## Web Component
93
+
99
94
  Use `<a-slider>` when you are not using React or Preact. Add its `role` and accessible name yourself, then register it from `@antadesign/anta/elements`.
100
95
 
101
96
  ```html
@@ -225,6 +225,8 @@ the next step.
225
225
  </Steps>
226
226
  ```
227
227
 
228
+ ## Keyboard and accessibility
229
+
228
230
  Pass `label` to name the tablist. Arrow keys follow the orientation; `Home` and
229
231
  `End` move to the edges; `Enter` and `Space` activate a focused step. Disabled
230
232
  steps are skipped.
@@ -242,17 +244,43 @@ Events match [`Tabs`](./tabs.md#events).
242
244
  | `onChange(event)` | After selection | No | Native `change` event |
243
245
  | `onValueChange(event, { value })` | After selection | No | Selected value |
244
246
 
247
+ ## Steps props
248
+
245
249
  | Prop | Type | Default | Description |
246
250
  |------|------|---------|-------------|
247
251
  | `options` | StepOption[] | — | Ordered process phases. |
248
- | `priority?` | StepPriority | 'secondary' | Visual emphasis. Primary uses a solid selected marker and a stronger
249
- completed connector; secondary is the outlined default; tertiary is compact
250
- and borderless. |
251
- | `renderMarker?` | (option, state) => ReactNode | — | Builds a custom marker from a step and its current state. A returned node
252
- replaces `marker` and the built-in state marker; return `undefined` to use
253
- those fallbacks, or `null` for an empty ring. |
254
- | `tone?` | StepTone \| '' | 'neutral' | Tone applied to every step without its own `tone`. Error steps stay
255
- critical and disabled steps stay neutral. |
252
+ | `children?` | ReactNode | — | Optional `<TabPanel value="…">` panels, one per tab value. Each is a self-managing `<a-tabpanel>` that shows itself when its `value` is the active tab. Omit them to use `Tabs` as a bare selectable strip. To place panels in a different layout region, or to unmount an inactive panel, drive selection with a controlled `value` and render the content yourself (see the docs). |
253
+ | `defaultValue?` | string | — | Initial active value for the uncontrolled case. After first render `Tabs` owns selection itself. |
254
+ | `disabled?` | boolean | — | Disable the whole strip. |
255
+ | `fill?` | boolean | false | Makes horizontal tabs share the available inline space equally. |
256
+ | `label?` | string | — | Accessible name for the tablist (`aria-label`). |
257
+ | `onBlur?` | (event) => void | — | Focus left the strip entirely — wired to `focusout`. |
258
+ | `onChange?` | (event) => void | — | Fired *after* the active tab changes — a native `change` event. |
259
+ | `onFocus?` | (event) => void | — | Focus entered the strip (any tab) — wired to `focusin` (focus lands on a tab, not the tablist). |
260
+ | `onStateChange?` | (event, detail) => void | — | Fired whenever the active tab changes — event-first. `detail` is `{ next, prev }` (values; `null` = none). Cancelable: `event.preventDefault()` vetoes it (uncontrolled), or in controlled mode answer by updating `value`. |
261
+ | `onValueChange?` | (event, attrs) => void | — | Like `onChange`, but with a `{ value }` snapshot as the 2nd argument. |
262
+ | `orientation?` | 'horizontal' \| 'vertical' | 'horizontal' | Layout + arrow-key axis. Horizontal ellipsizes labels when tabs overflow (scroll is opt-in via CSS); vertical stacks them. |
263
+ | `priority?` | StepPriority | 'secondary' | Visual emphasis. Primary uses a solid selected marker and a stronger completed connector; secondary is the outlined default; tertiary is compact and borderless. |
264
+ | `renderMarker?` | (option, state) => ReactNode | — | Builds a custom marker from a step and its current state. A returned node replaces `marker` and the built-in state marker; return `undefined` to use those fallbacks, or `null` for an empty ring. |
265
+ | `size?` | 'small' \| 'medium' \| 'large' | 'medium' | Size — small 24px · medium 28px · large 32px tall, matching Button's scale (the tab's label leading runs a touch tighter, offset by 1px more block padding per side). |
266
+ | `tone?` | StepTone \| '' | 'neutral' | Tone applied to every step without its own `tone`. Error steps stay critical and disabled steps stay neutral. |
267
+ | `value?` | string | — | Controlled active value — the tab `value` to mark selected (and, when a `<TabPanel value="…">` shares it, the panel to reveal). When set, you own selection: the strip renders exactly what this says, and a user pick only *requests* a change via `onStateChange` — apply it by updating this prop. Leave undefined (and use `defaultValue`) for uncontrolled. |
268
+
269
+ ## Step option props
270
+
271
+ | Prop | Type | Default | Description |
272
+ |------|------|---------|-------------|
273
+ | `label` | ReactNode | — | Visible phase label. It ellipsizes in a constrained step; its full content is available in a tooltip only when clipped. |
274
+ | `state` | StepState | — | Application-owned process state. Selection and availability are separate; `error` keeps a critical icon and outline, and selection adds the fill. |
275
+ | `value` | string | — | Stable phase identity. Values must be unique within the sequence. |
276
+ | `className?` | string | — | CSS class on the option's rendered row. |
277
+ | `disabled?` | boolean | — | Disables this phase. A custom `marker` or `renderMarker` result is kept; otherwise it uses the incomplete marker. |
278
+ | `hint?` | ReactNode | — | Secondary text shown below the label. It ellipsizes in a constrained step; its full content is available in a tooltip only when clipped. |
279
+ | `marker?` | StepMarker | — | Replaces the marker derived from `state`. A number is shown directly; an Anta icon shape is rendered as an `<Icon>`. |
280
+ | `style?` | CSSProperties | — | Inline styles on the option's rendered row. |
281
+ | `tone?` | StepTone \| '' | inherits Steps `tone | Tone for this phase. It colors the label, hint, marker, and completed connector. Overrides the Steps `tone`; error steps stay critical and disabled steps stay neutral. |
282
+
283
+ ## Web Component
256
284
 
257
285
  For framework-free use, compose the same light DOM that `Steps` emits.
258
286
  `a-steps` and its `a-step-*` children are structural elements styled by the
@@ -288,6 +316,8 @@ import '@antadesign/anta/components/Steps.css'
288
316
  </div>
289
317
  ```
290
318
 
319
+ ## Styling
320
+
291
321
  Use `priority`, `size`, and `orientation` first. Set `tone` on each option. Each
292
322
  option also accepts `className`, `style`, and `data-*` attributes. Markers are
293
323
  light DOM; connectors are pseudo-elements.
@@ -123,33 +123,28 @@ The wrapper sets `role="switch"` and keeps `aria-checked` in sync with the curre
123
123
 
124
124
  Space toggles the switch. It follows the [WAI-ARIA switch pattern](https://www.w3.org/WAI/ARIA/apg/patterns/switch/).
125
125
 
126
- ### Props
126
+ ## Component props
127
127
 
128
128
  | Prop | Type | Default | Description |
129
129
  |------|------|---------|-------------|
130
130
  | `checked?` | boolean | — | Controlled checked value. In controlled mode, update this in `onStateChange`. |
131
131
  | `defaultChecked?` | boolean | false | Initial checked value for an uncontrolled switch. |
132
132
  | `disabled?` | boolean | — | Disables interaction and removes the switch from the tab order. |
133
- | `hint?` | ReactNode | — | Secondary text rendered under the label. It does not become part of the
134
- accessible name. |
133
+ | `hint?` | ReactNode | — | Secondary text rendered under the label. It does not become part of the accessible name. |
135
134
  | `label?` | string | — | Visible, stable label for the setting. Use `children` for richer label content. |
136
- | `labelPosition?` | 'start' \| 'end' | 'end' | Put the visible label before or after the control. Grid layout changes only
137
- the visual order, preserving DOM/source order for assistive technologies. |
135
+ | `labelPosition?` | 'start' \| 'end' | 'end' | Put the visible label before or after the control. Grid layout changes only the visual order, preserving DOM/source order for assistive technologies. |
138
136
  | `name?` | string | — | Form field name. A checked switch submits `value` under this name. |
139
137
  | `onChange?` | (event) => void | — | Native post-apply `change` event. |
140
- | `onStateChange?` | (event, detail) => void | — | Fired before a user toggle applies. Call `event.preventDefault()` to veto an
141
- uncontrolled change; controlled consumers accept by updating `checked`. |
138
+ | `onStateChange?` | (event, detail) => void | — | Fired before a user toggle applies. Call `event.preventDefault()` to veto an uncontrolled change; controlled consumers accept by updating `checked`. |
142
139
  | `onValueChange?` | (event, attrs) => void | — | Post-apply callback with the new form-relevant value snapshot. |
143
- | `round?` | boolean \| number \| string | — | Fully round the thumb and track. Pass a `number` (px) or CSS length string
144
- for a custom track radius; the thumb radius is 3px smaller. |
140
+ | `round?` | boolean \| number \| string | — | Fully round the thumb and track. Pass a `number` (px) or CSS length string for a custom track radius; the thumb radius is 3px smaller. |
145
141
  | `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' | 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
- | `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` colors the unchecked
150
- state and `toneSelected` colors the checked track. |
142
+ | `tone?` | 'brand' \| 'neutral' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'brand' | Color of the track and thumb. A tinted tone also colors the unchecked track border and thumb; use `toneSelected` to color only the checked track. |
143
+ | `toneSelected?` | 'brand' \| 'neutral' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'brand' | Like `tone`, but applies only while the switch is checked. The unchecked track and thumb stay neutral. If both are set, `tone` colors the unchecked state and `toneSelected` colors the checked track. |
151
144
  | `value?` | string | "on" | Value submitted while checked. |
152
145
 
146
+ ## Web Component
147
+
153
148
  Use the web component directly when you are not using React or Preact and a native control does not fit.
154
149
 
155
150
  The focusable host carries the state. Label and hint are light-DOM children.
@@ -161,6 +156,8 @@ The focusable host carries the state. Label and hint are light-DOM children.
161
156
  </a-switch>
162
157
  ```
163
158
 
159
+ ## Styling
160
+
164
161
  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
162
 
166
163
  ```tsx
@@ -166,6 +166,8 @@ its value is active. The panel names its tab as its accessible label
166
166
  Panels are **optional**. Without panels, `Tabs` renders the strip. Listen to
167
167
  `onStateChange` / `onValueChange` and render the content yourself.
168
168
 
169
+ ### JSX vs DOM
170
+
169
171
  The strip renders from the `options` array; each `<TabPanel>` renders a
170
172
  self-managing `<a-tabpanel>`. `Tabs` **never reads or toggles the panels**: there's
171
173
  no child introspection, so it renders the same in static SSR and works with any
@@ -196,6 +198,8 @@ and shows/hides **itself** via its own off-DOM `:state(active)`; nothing writes
196
198
  writes the light DOM, only your JSX does, which keeps a worker-thread reactive engine
197
199
  in sync.
198
200
 
201
+ ### Hiding an inactive panel
202
+
199
203
  A `<TabPanel>` stays mounted while inactive (its DOM, form values, and scroll
200
204
  survive tab switches); `hideMode` picks how it hides:
201
205
 
@@ -265,6 +269,8 @@ const [tab, setTab] = useState('overview')
265
269
  />
266
270
  ```
267
271
 
272
+ ## Keyboard & accessibility
273
+
268
274
  Every enabled tab is in the tab order; `Tab` / `Shift`+`Tab` step through them.
269
275
  The arrow keys also move between enabled tabs (wrapping at the ends), `Home` /
270
276
  `End` jump to the first / last, and `Space` / `Enter` activate the focused tab;
@@ -275,6 +281,8 @@ Pass `label` for the tablist's accessible name. Each `<TabPanel>` names its tab
275
281
  its accessible label (`aria-labelledby`), set off-DOM so nothing writes the panel's
276
282
  attributes.
277
283
 
284
+ ## Routing
285
+
278
286
  `Tabs` reports the picked value and leaves navigation to the app, so a strip can
279
287
  switch routes as readily as panels. Treat each `value` as a path: control `value`
280
288
  from the current location and navigate in `onStateChange` (the pick fires *on click*;
@@ -319,54 +327,56 @@ so those suit an uncontrolled strip reacting to its own pick. **`onFocus`** /
319
327
  <Tabs defaultValue="a" onValueChange={(_e, { value }) => route(value)}>…</Tabs>
320
328
  ```
321
329
 
330
+ ## Tabs props
331
+
322
332
  | Prop | Type | Default | Description |
323
333
  |------|------|---------|-------------|
324
- | `children?` | ReactNode | — | Optional `<TabPanel value="…">` panels, one per tab value. Each is a
325
- self-managing `<a-tabpanel>` that shows itself when its `value` is the active
326
- tab. Omit them to use `Tabs` as a bare selectable strip. To place panels in a
327
- different layout region, or to unmount an inactive panel, drive selection with
328
- a controlled `value` and render the content yourself (see the docs). |
329
- | `defaultValue?` | string | — | Initial active value for the uncontrolled case. After first render `Tabs`
330
- owns selection itself. |
334
+ | `children?` | ReactNode | — | Optional `<TabPanel value="…">` panels, one per tab value. Each is a self-managing `<a-tabpanel>` that shows itself when its `value` is the active tab. Omit them to use `Tabs` as a bare selectable strip. To place panels in a different layout region, or to unmount an inactive panel, drive selection with a controlled `value` and render the content yourself (see the docs). |
335
+ | `defaultValue?` | string | — | Initial active value for the uncontrolled case. After first render `Tabs` owns selection itself. |
331
336
  | `disabled?` | boolean | — | Disable the whole strip. |
332
337
  | `fill?` | boolean | false | Makes horizontal tabs share the available inline space equally. |
333
338
  | `label?` | string | — | Accessible name for the tablist (`aria-label`). |
334
- | `noslide?` | boolean | — | Disable the sliding indicator. By default the selected-tab indicator animates
335
- between tabs (a single rectangle, via CSS anchor positioning); `noslide` paints it
336
- per tab so it snaps with no movement. (Browsers without anchor positioning get that
337
- per-tab paint automatically — `noslide` is the explicit opt-out.) |
339
+ | `noslide?` | boolean | — | Disable the sliding indicator. By default the selected-tab indicator animates between tabs (a single rectangle, via CSS anchor positioning); `noslide` paints it per tab so it snaps with no movement. (Browsers without anchor positioning get that per-tab paint automatically — `noslide` is the explicit opt-out.) |
338
340
  | `onBlur?` | (event) => void | — | Focus left the strip entirely — wired to `focusout`. |
339
341
  | `onChange?` | (event) => void | — | Fired *after* the active tab changes — a native `change` event. |
340
- | `onFocus?` | (event) => void | — | Focus entered the strip (any tab) — wired to `focusin` (focus lands on a tab,
341
- not the tablist). |
342
- | `onStateChange?` | (event, detail) => void | — | Fired whenever the active tab changes — event-first. `detail` is
343
- `{ next, prev }` (values; `null` = none). Cancelable: `event.preventDefault()`
344
- vetoes it (uncontrolled), or in controlled mode answer by updating `value`. |
342
+ | `onFocus?` | (event) => void | — | Focus entered the strip (any tab) — wired to `focusin` (focus lands on a tab, not the tablist). |
343
+ | `onStateChange?` | (event, detail) => void | — | Fired whenever the active tab changes — event-first. `detail` is `{ next, prev }` (values; `null` = none). Cancelable: `event.preventDefault()` vetoes it (uncontrolled), or in controlled mode answer by updating `value`. |
345
344
  | `onValueChange?` | (event, attrs) => void | — | Like `onChange`, but with a `{ value }` snapshot as the 2nd argument. |
346
- | `options?` | TabOption[] | — | The tabs, as a data array (the strip's single source). Each entry is a
347
- `TabOption` (`value`, `label` or `children`, `icon`, `iconTrailing`, `tone`,
348
- `disabled`, `round`, `className`, `style`). `className` and `style` land on
349
- that option's individual `<a-tab>`, not on the strip. |
350
- | `orientation?` | 'horizontal' \| 'vertical' | 'horizontal' | Layout + arrow-key axis. Horizontal ellipsizes labels when tabs overflow (scroll
351
- is opt-in via CSS); vertical stacks them. |
352
- | `priority?` | 'primary' \| 'secondary' \| 'tertiary' | 'primary' | Visual priority. `primary` is the raised pill on a recessed track (the
353
- segmented-control look); `secondary` keeps that sizing but drops the track, marking
354
- the selected tab with a subtle active background fill; `tertiary` is a bottom-underline
355
- indicator under the selected tab (no track, no rest line). `tone` colors `secondary` +
356
- `tertiary`; `primary` stays neutral. |
357
- | `round?` | boolean \| number \| string | — | Fully-round the tabs and the sliding indicator (and the primary track
358
- well). Applies strip-wide; a single tab's `round` rounds just that tab. A
359
- `number` (px) or CSS length string sets a custom radius on the top-level
360
- track well only — the tab pills + indicator stay fully round. |
361
- | `size?` | 'small' \| 'medium' \| 'large' | 'medium' | Size — small 24px · medium 28px · large 32px tall, matching Button's scale (the tab's
362
- label leading runs a touch tighter, offset by 1px more block padding per side). |
363
- | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Tone applied to the selected indicator/label, or any literal CSS color for a
364
- one-off custom tone (derived in oklch). Named tones track light/dark. |
365
- | `value?` | string | — | Controlled active value — the tab `value` to mark selected (and, when a
366
- `<TabPanel value="…">` shares it, the panel to reveal). When set, you own
367
- selection: the strip renders exactly what this says, and a user pick only
368
- *requests* a change via `onStateChange` — apply it by updating this prop.
369
- Leave undefined (and use `defaultValue`) for uncontrolled. |
345
+ | `options?` | TabOption[] | — | The tabs, as a data array (the strip's single source). Each entry is a `TabOption` (`value`, `label` or `children`, `icon`, `iconTrailing`, `tone`, `disabled`, `round`, `className`, `style`). `className` and `style` land on that option's individual `<a-tab>`, not on the strip. |
346
+ | `orientation?` | 'horizontal' \| 'vertical' | 'horizontal' | Layout + arrow-key axis. Horizontal ellipsizes labels when tabs overflow (scroll is opt-in via CSS); vertical stacks them. |
347
+ | `priority?` | 'primary' \| 'secondary' \| 'tertiary' | 'primary' | Visual priority. `primary` is the raised pill on a recessed track (the segmented-control look); `secondary` keeps that sizing but drops the track, marking the selected tab with a subtle active background fill; `tertiary` is a bottom-underline indicator under the selected tab (no track, no rest line). `tone` colors `secondary` + `tertiary`; `primary` stays neutral. |
348
+ | `round?` | boolean \| number \| string | — | Fully-round the tabs and the sliding indicator (and the primary track well). Applies strip-wide; a single tab's `round` rounds just that tab. A `number` (px) or CSS length string sets a custom radius on the top-level track well only — the tab pills + indicator stay fully round. |
349
+ | `size?` | 'small' \| 'medium' \| 'large' | 'medium' | Size — small 24px · medium 28px · large 32px tall, matching Button's scale (the tab's label leading runs a touch tighter, offset by 1px more block padding per side). |
350
+ | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Tone applied to the selected indicator/label, or any literal CSS color for a one-off custom tone (derived in oklch). Named tones track light/dark. |
351
+ | `value?` | string | — | Controlled active value — the tab `value` to mark selected (and, when a `<TabPanel value="…">` shares it, the panel to reveal). When set, you own selection: the strip renders exactly what this says, and a user pick only *requests* a change via `onStateChange` — apply it by updating this prop. Leave undefined (and use `defaultValue`) for uncontrolled. |
352
+
353
+ ## Tab option props
354
+
355
+ | Prop | Type | Default | Description |
356
+ |------|------|---------|-------------|
357
+ | `value` | string | — | This tab's identity — pairs it with the `<TabPanel value="…">` of the same value, and the value reported by `onStateChange` / `onChange`. Unique per strip. |
358
+ | `children?` | ReactNode | — | Tab content when you need more than a string — used if `label` is omitted. |
359
+ | `className?` | string | — | CSS class on the option's rendered row. |
360
+ | `disabled?` | boolean | — | Disable just this tab — skipped by keyboard nav and dropped from the tab order (a disabled-but-selected tab stays reachable, per the ARIA pattern). |
361
+ | `icon?` | IconShape | — | Leading icon shape, rendered before the label. |
362
+ | `iconTrailing?` | IconShape | — | Trailing icon shape, rendered after the label. |
363
+ | `label?` | ReactNode | — | Visible label. The string shorthand for the tab's content; for richer content pass `children` instead (`label` wins when both are set). |
364
+ | `round?` | boolean | — | Fully-round just this tab's box. `<Tabs round>` rounds the whole strip (tabs + sliding indicator) instead. |
365
+ | `style?` | CSSProperties | — | Inline styles on the option's rendered row. |
366
+ | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | inherits the strip's `tone | Per-tab tone override, same vocabulary as `<Tabs tone>` — colors this one tab's label + icons (all priorities/modes, named or custom color) and, when it's the active tab, its indicator. For a **custom literal color** the sliding indicator can't adopt it (the shared moving element can't read a descendant's color), so a custom tone colors the label everywhere and the indicator only in `noslide`; the six **named** tones color both in every mode. Overrides the strip's `tone` for this tab. |
367
+ | `tooltip?` | ReactNode | — | Tooltip for this tab — a string or any node — shown **only when one of the tab's ellipsizing label parts is truncated** (tabs ellipsize when the strip overflows), so clipped content reveals its full text on hover while a tab that fits shows nothing. Rendered as a `truncatedOnly` `<Tooltip>` anchored to the tab. For an always-visible tooltip or other custom trigger content, use `children` with your own `<Tooltip>` instead. |
368
+
369
+ ## TabPanel props
370
+
371
+ | Prop | Type | Default | Description |
372
+ |------|------|---------|-------------|
373
+ | `value` | string | — | Pairs this panel with the tab (`options` entry) of the same `value`. |
374
+ | `children?` | ReactNode | — | Panel content — arbitrary React/Preact. |
375
+ | `className?` | string | — | CSS class on the rendered `<a-tabpanel>`. |
376
+ | `hideMode?` | 'display' \| 'visibility' | display | How this panel hides while inactive: `display` (default — removed from layout and the a11y tree) or `visibility` (keeps its layout box, to measure it or avoid reflow). Both stay mounted; to *not render* an inactive panel, render it conditionally off a controlled `value` (see the Tabs docs). |
377
+ | `style?` | CSSProperties | — | Inline style on the rendered `<a-tabpanel>`. |
378
+
379
+ ## Web Component
370
380
 
371
381
  Use the web component directly when you are not using React or Preact and a native control does not fit.
372
382
 
@@ -386,6 +396,8 @@ Add `fill` to make horizontal tabs share the available width equally.
386
396
  </div>
387
397
  ```
388
398
 
399
+ ## Styling
400
+
389
401
  Reach for the props first: **`tone`**, **`size`**, **`priority`**. The focus ring is
390
402
  the global `--focus-ring` (see [Colors](../colors.md#focus-ring)).
391
403
 
@@ -117,33 +117,20 @@ down 1px, since caps read larger than mixed case at the same size.
117
117
  <Tag allcaps label="Running" />
118
118
  ```
119
119
 
120
- ### Props
120
+ ## Component props
121
121
 
122
122
  | Prop | Type | Default | Description |
123
123
  |------|------|---------|-------------|
124
- | `allcaps?` | boolean | — | Render in all-caps instead of the default normal (mixed) case
125
- (uppercase tracks wider than the default body-text letter-spacing). |
124
+ | `allcaps?` | boolean | — | Render in all-caps instead of the default normal (mixed) case (uppercase tracks wider than the default body-text letter-spacing). |
126
125
  | `icon?` | IconShape | — | Leading icon shape. Sits flush before the label, scaled to the pill. |
127
126
  | `iconTrailing?` | IconShape | — | Trailing icon shape. Renders last, after the value. |
128
- | `label?` | string | — | A short "key" shown before the value. When paired with `value` it
129
- renders bold (weight 600), same color. On its own (no `value`) it's
130
- treated as the tag's primary text and keeps the default styling. |
131
- | `priority?` | 'primary' \| 'secondary' \| 'tertiary' | secondary | Emphasis level. `secondary` (the default) is the subtle alpha-tint
132
- fill; `primary` is a solid fill with white text; `tertiary` is a
133
- transparent outline. Omitting it (or passing `'secondary'`) renders
134
- the default and emits no DOM attribute. |
135
- | `size?` | 'small' \| 'medium' \| 'large' | medium | Size variant. `small` = 16px tall, `medium` = 20px, `large` = 24px
136
- (matching `Button`). Omit the attribute or pass `'medium'` for the
137
- default — both render identically and emit no DOM attribute. |
138
- | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | neutral | Semantic tone, or any literal CSS color (`'#ff1493'`, `'rebeccapurple'`)
139
- for a one-off custom tone. Each tone renders the secondary tag style:
140
- `--text-3-{tone}` text over an alpha tint of the tone's hue (fill + a
141
- slightly stronger hairline border). A custom color is tinted the same
142
- way, with the text deepened to a readable foreground. `'neutral'` (the
143
- default) is the gray tag — the same as omitting `tone`. |
144
- | `value?` | string | — | The tag's primary text — a status, count, version, duration, etc.
145
- Rendered in the default color and weight, with no divider from the
146
- label; the color + weight contrast does the separating. |
127
+ | `label?` | string | — | A short "key" shown before the value. When paired with `value` it renders bold (weight 600), same color. On its own (no `value`) it's treated as the tag's primary text and keeps the default styling. |
128
+ | `priority?` | 'primary' \| 'secondary' \| 'tertiary' | secondary | Emphasis level. `secondary` (the default) is the subtle alpha-tint fill; `primary` is a solid fill with white text; `tertiary` is a transparent outline. Omitting it (or passing `'secondary'`) renders the default and emits no DOM attribute. |
129
+ | `size?` | 'small' \| 'medium' \| 'large' | medium | Size variant. `small` = 16px tall, `medium` = 20px, `large` = 24px (matching `Button`). Omit the attribute or pass `'medium'` for the default — both render identically and emit no DOM attribute. |
130
+ | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | neutral | Semantic tone, or any literal CSS color (`'#ff1493'`, `'rebeccapurple'`) for a one-off custom tone. Each tone renders the secondary tag style: `--text-3-{tone}` text over an alpha tint of the tone's hue (fill + a slightly stronger hairline border). A custom color is tinted the same way, with the text deepened to a readable foreground. `'neutral'` (the default) is the gray tag — the same as omitting `tone`. |
131
+ | `value?` | string | — | The tag's primary text — a status, count, version, duration, etc. Rendered in the default color and weight, with no divider from the label; the color + weight contrast does the separating. |
132
+
133
+ ## Web Component
147
134
 
148
135
  Use the web component directly when you are not using React or Preact and a native control does not fit.
149
136
 
@@ -157,6 +144,8 @@ Use `a-tag-label` for the key and `a-tag-value` for its value.
157
144
  </a-tag>
158
145
  ```
159
146
 
147
+ ## Styling
148
+
160
149
  Reach for the props first: **`tone`** sets the color (any CSS color for a custom
161
150
  tone — it derives the fill / border / text in oklch), **`priority`** the fill style,
162
151
  **`size`** the dimensions.
@@ -97,34 +97,19 @@ more" and "Show less". `collapsible` takes effect only with `expandable`.
97
97
  <Text truncate={3} expandable collapsible>{longSentence}</Text>
98
98
  ```
99
99
 
100
- ### Props
100
+ ## Component props
101
101
 
102
102
  | Prop | Type | Default | Description |
103
103
  |------|------|---------|-------------|
104
- | `collapsible?` | boolean | — | Let the reader collapse back after expanding: the chevron becomes a
105
- "Show more" / "Show less" toggle that stays visible while expanded.
106
- Only takes effect together with `expandable`. |
107
- | `expandable?` | boolean | — | Show a fade hint and chevron over the truncated text and let the user
108
- expand it by clicking the chevron region or pressing Enter while the
109
- chevron has keyboard focus. Only takes effect together with `truncate`.
110
- On its own, expanding is **one-way** — the control is removed once
111
- expanded; add `collapsible` for a two-way toggle. |
104
+ | `collapsible?` | boolean | — | Let the reader collapse back after expanding: the chevron becomes a "Show more" / "Show less" toggle that stays visible while expanded. Only takes effect together with `expandable`. |
105
+ | `expandable?` | boolean | — | Show a fade hint and chevron over the truncated text and let the user expand it by clicking the chevron region or pressing Enter while the chevron has keyboard focus. Only takes effect together with `truncate`. On its own, expanding is **one-way** — the control is removed once expanded; add `collapsible` for a two-way toggle. |
112
106
  | `inline?` | boolean | — | Render as inline-block instead of the default block element. |
113
- | `priority?` | 'primary' \| 'secondary' \| 'tertiary' \| 'quaternary' | secondary | Visual priority. Maps to text-1..text-4 (`primary` = text-1, the
114
- strongest). The default is `secondary` (text-2) — body text reads a
115
- step softer than the strongest foreground; pass `primary` for emphasis. |
107
+ | `priority?` | 'primary' \| 'secondary' \| 'tertiary' \| 'quaternary' | secondary | Visual priority. Maps to text-1..text-4 (`primary` = text-1, the strongest). The default is `secondary` (text-2) — body text reads a step softer than the strongest foreground; pass `primary` for emphasis. |
116
108
  | `size?` | 'small' \| 'medium' \| 'large' | medium | Type scale. `small` = 13/16, `medium` = 15/20, `large` = 17/24. |
117
- | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | neutral | Color tint. `neutral` (the default) is the untinted `--text-{N}` scale; a
118
- named tone applies the matching `--text-{N}-{tone}` palette. Any literal CSS
119
- color (`'#ff1493'`, `'rebeccapurple'`) is a one-off custom tone — its hue is
120
- kept while lightness/chroma are pinned per priority in oklch. |
121
- | `truncate?` | boolean \| number | — | Truncate with a trailing ellipsis. `true` (or `1`) clamps to a
122
- single line; any integer ≥ 2 clamps to that many lines; `0` or a
123
- negative value means no truncation. A clipped, non-expandable JSX
124
- `Text` shows its text content in a tooltip by default. Nest a
125
- `<Tooltip>` to provide your own tooltip instead. Uses the
126
- `-webkit-line-clamp` technique, supported in all major browsers
127
- (Firefox 68+, Chrome, Safari, Edge). |
109
+ | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | neutral | Color tint. `neutral` (the default) is the untinted `--text-{N}` scale; a named tone applies the matching `--text-{N}-{tone}` palette. Any literal CSS color (`'#ff1493'`, `'rebeccapurple'`) is a one-off custom tone — its hue is kept while lightness/chroma are pinned per priority in oklch. |
110
+ | `truncate?` | boolean \| number | — | Truncate with a trailing ellipsis. `true` (or `1`) clamps to a single line; any integer ≥ 2 clamps to that many lines; `0` or a negative value means no truncation. A clipped, non-expandable JSX `Text` shows its text content in a tooltip by default. Nest a `<Tooltip>` to provide your own tooltip instead. Uses the `-webkit-line-clamp` technique, supported in all major browsers (Firefox 68+, Chrome, Safari, Edge). |
111
+
112
+ ## Web Component
128
113
 
129
114
  Use the web component directly when you are not using React or Preact and a native control does not fit.
130
115
 
@@ -136,6 +121,8 @@ Use `<a-text>` directly for a block that carries the text priority and tone.
136
121
  </a-text>
137
122
  ```
138
123
 
124
+ ## Styling
125
+
139
126
  Color comes from **`priority`** (the neutral text level) and **`tone`** (the tint);
140
127
  `size` and the type props set the rest. For a named tone, `Text` consumes the
141
128
  global **text role tokens** (`--text-1` … `--text-5`, the `-{tone}` tints,
@@ -93,18 +93,15 @@ The four priorities are shown across every named tone at `level={3}`. Omit
93
93
  document outline or SEO needs heading elements; the reset applies the same type
94
94
  scale.
95
95
 
96
- ### Props
96
+ ## Component props
97
97
 
98
98
  | Prop | Type | Default | Description |
99
99
  |------|------|---------|-------------|
100
- | `level?` | 1 \| 2 \| 3 \| 4 \| 5 \| 6 | 2 | Heading level, 1-6. Drives font-size, line-height, and vertical
101
- rhythm. Also surfaced to assistive tech via `aria-level`
102
- (h1 is typically reserved for the page title). |
100
+ | `level?` | 1 \| 2 \| 3 \| 4 \| 5 \| 6 | 2 | Heading level, 1-6. Drives font-size, line-height, and vertical rhythm. Also surfaced to assistive tech via `aria-level` (h1 is typically reserved for the page title). |
103
101
  | `priority?` | 'primary' \| 'secondary' \| 'tertiary' \| 'quaternary' | primary | Visual priority. Maps to text-1..text-4 (`primary` = text-1). |
104
- | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | neutral | Color tint. `neutral` (the default) is the untinted `--text-{N}` scale; a
105
- named tone applies the matching `--text-{N}-{tone}` palette. Any literal CSS
106
- color (`'#ff1493'`, `'rebeccapurple'`) is a one-off custom tone — its hue is
107
- kept while lightness/chroma are pinned per priority in oklch. |
102
+ | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | neutral | Color tint. `neutral` (the default) is the untinted `--text-{N}` scale; a named tone applies the matching `--text-{N}-{tone}` palette. Any literal CSS color (`'#ff1493'`, `'rebeccapurple'`) is a one-off custom tone — its hue is kept while lightness/chroma are pinned per priority in oklch. |
103
+
104
+ ## Web Component
108
105
 
109
106
  Use the web component directly when you are not using React or Preact and a native control does not fit.
110
107
 
@@ -116,6 +113,8 @@ Set the heading role and level when writing `<a-title>` directly.
116
113
  </a-title>
117
114
  ```
118
115
 
116
+ ## Styling
117
+
119
118
  `priority` selects a neutral text level. Named `tone`s use the matching global
120
119
  text tokens. A literal `tone` is stored in `--title-tone-source` and resolved
121
120
  into the four priority levels.
@@ -222,13 +222,14 @@ Toaster.manager.add(() => <Banner tone="critical" message="Connection lost" />,
222
222
  })
223
223
  ```
224
224
 
225
- ### Props
225
+ ## Component props
226
226
 
227
227
  | Prop | Type | Default | Description |
228
228
  |------|------|---------|-------------|
229
229
  | `label?` | string | 'Notifications' | Accessible label for the region landmark. |
230
- | `toaster?` | Toaster | — | The store this region renders. Omit to bind the default store driven by
231
- `Toaster.manager`; pass a `createToaster()` for an isolated region. |
230
+ | `toaster?` | Toaster | — | The store this region renders. Omit to bind the default store driven by `Toaster.manager`; pass a `createToaster()` for an isolated region. |
231
+
232
+ ## Web Component
232
233
 
233
234
  Use the web component directly when you are not using React or Preact and a native control does not fit.
234
235
 
@@ -266,6 +267,8 @@ remove the toast from the DOM.
266
267
  </script>
267
268
  ```
268
269
 
270
+ ## Styling
271
+
269
272
  The region and item are plain custom elements — style them with ordinary CSS
270
273
  (`@layer anta`, so an un-layered rule of yours wins without `!important`).
271
274
 
@@ -117,32 +117,20 @@ arrives later works normally; a bubble whose content is cleared while it's open
117
117
  closes itself. Content that's a single icon or image (an element, no text) still
118
118
  shows.
119
119
 
120
- ### Props
120
+ ## Component props
121
121
 
122
122
  | Prop | Type | Default | Description |
123
123
  |------|------|---------|-------------|
124
- | `children?` | ReactNode | — | Tooltip content. Renders anything — text, markup, an icon + text.
125
- Lives in the light DOM, so it's styleable with your own plain CSS. |
126
- | `delay?` | number | 300 | Show delay in milliseconds after hover / focus. Never use `0` — use
127
- ~`50` for a near-instant tooltip (0 has caused issues in practice). |
128
- | `follow?` | boolean | — | Follow the cursor instead of pinning under the anchor. The bubble is
129
- pinned (anchored beneath the target) by default; pass `follow` for the
130
- cursor-tracking behavior, which fades by distance as the cursor leaves. |
131
- | `interactive?` | boolean | — | Make the bubble hoverable and clickable — enables pointer events and
132
- keeps it open while the cursor is over it, so its content (links,
133
- buttons) can be interacted with. Always pinned (an interactive bubble
134
- can't follow the cursor, even with `follow`). |
135
- | `placement?` | 'top' \| 'bottom' | bottom | Which side of the anchor the bubble prefers. Auto-flips to the other
136
- side when there isn't room. |
137
- | `round?` | boolean \| number \| string | — | Round the bubble to a 20px radius (matching a round menu). Pass a `number`
138
- (px) or a CSS length string for a custom radius. |
139
- | `truncatedOnly?` | boolean | — | Only show when the target is actually truncated (its text overflows and is
140
- ellipsized); a label that fits gets no tooltip. The check is a UI-thread
141
- layout read, re-measured on each show. By default it measures every Anta
142
- ellipsizing label part inside the anchor, then the anchor itself —
143
- override with `truncatedSelector`. |
144
- | `truncatedSelector?` | string | — | CSS selector (resolved within the anchor) for the element or elements
145
- whose overflow decides whether a `truncatedOnly` tooltip shows. |
124
+ | `children?` | ReactNode | — | Tooltip content. Renders anything — text, markup, an icon + text. Lives in the light DOM, so it's styleable with your own plain CSS. |
125
+ | `delay?` | number | 300 | Show delay in milliseconds after hover / focus. Never use `0` — use ~`50` for a near-instant tooltip (0 has caused issues in practice). |
126
+ | `follow?` | boolean | — | Follow the cursor instead of pinning under the anchor. The bubble is pinned (anchored beneath the target) by default; pass `follow` for the cursor-tracking behavior, which fades by distance as the cursor leaves. |
127
+ | `interactive?` | boolean | — | Make the bubble hoverable and clickable — enables pointer events and keeps it open while the cursor is over it, so its content (links, buttons) can be interacted with. Always pinned (an interactive bubble can't follow the cursor, even with `follow`). |
128
+ | `placement?` | 'top' \| 'bottom' | bottom | Which side of the anchor the bubble prefers. Auto-flips to the other side when there isn't room. |
129
+ | `round?` | boolean \| number \| string | — | Round the bubble to a 20px radius (matching a round menu). Pass a `number` (px) or a CSS length string for a custom radius. |
130
+ | `truncatedOnly?` | boolean | — | Only show when the target is actually truncated (its text overflows and is ellipsized); a label that fits gets no tooltip. The check is a UI-thread layout read, re-measured on each show. By default it measures every Anta ellipsizing label part inside the anchor, then the anchor itself — override with `truncatedSelector`. |
131
+ | `truncatedSelector?` | string | — | CSS selector (resolved within the anchor) for the element or elements whose overflow decides whether a `truncatedOnly` tooltip shows. |
132
+
133
+ ## Web Component
146
134
 
147
135
  Use the web component directly when you are not using React or Preact and a native control does not fit.
148
136
 
@@ -155,6 +143,8 @@ Place `<a-tooltip>` inside the element it describes.
155
143
  </a-button>
156
144
  ```
157
145
 
146
+ ## Styling
147
+
158
148
  The bubble lives in shadow DOM and is exposed as a single **part** — style the box
159
149
  (background, frost, shadow, radius, padding, a border) with `::part(bubble)`. Its
160
150
  *content* is slotted light DOM with a **normalized text baseline** (Anta body