@antadesign/anta 0.3.33 → 0.3.35

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 (205) hide show
  1. package/LICENSE.md +14 -1
  2. package/README.md +9 -0
  3. package/dist/anta_helpers.d.ts +46 -30
  4. package/dist/anta_helpers.js +66 -25
  5. package/dist/bundle.css +1 -1
  6. package/dist/bundle.js +2 -1353
  7. package/dist/components/Banner.d.ts +25 -40
  8. package/dist/components/Banner.js +15 -17
  9. package/dist/components/Breadcrumbs.d.ts +0 -1
  10. package/dist/components/Breadcrumbs.js +0 -1
  11. package/dist/components/Button.d.ts +2 -3
  12. package/dist/components/Button.js +1 -0
  13. package/dist/components/ButtonCopy.js +3 -2
  14. package/dist/components/Calendar.js +13 -13
  15. package/dist/components/Card.d.ts +9 -17
  16. package/dist/components/Card.js +50 -46
  17. package/dist/components/Dialog.d.ts +1 -0
  18. package/dist/components/Dialog.js +16 -10
  19. package/dist/components/Expander.d.ts +6 -21
  20. package/dist/components/Expander.js +24 -23
  21. package/dist/components/Icon.d.ts +8 -14
  22. package/dist/components/Input.d.ts +77 -96
  23. package/dist/components/Input.js +23 -27
  24. package/dist/components/InputAutocomplete.d.ts +29 -10
  25. package/dist/components/InputAutocomplete.js +25 -8
  26. package/dist/components/InputDate.d.ts +0 -1
  27. package/dist/components/InputDate.js +2 -3
  28. package/dist/components/InputTime.d.ts +10 -4
  29. package/dist/components/InputTime.js +20 -16
  30. package/dist/components/Loader.d.ts +2 -2
  31. package/dist/components/Menu.d.ts +5 -4
  32. package/dist/components/Menu.js +13 -8
  33. package/dist/components/MenuItem.js +1 -14
  34. package/dist/components/MenuItemCopy.js +2 -2
  35. package/dist/components/Panel.d.ts +3 -1
  36. package/dist/components/Panel.js +17 -11
  37. package/dist/components/Progress.d.ts +21 -23
  38. package/dist/components/Progress.js +13 -9
  39. package/dist/components/RadioGroup.js +6 -8
  40. package/dist/components/{select-parts.css → Select.css} +1 -1
  41. package/dist/components/Select.d.ts +53 -36
  42. package/dist/components/Select.js +53 -98
  43. package/dist/components/SelectFaceted.d.ts +7 -4
  44. package/dist/components/SelectFaceted.js +21 -10
  45. package/dist/components/Slider.d.ts +28 -11
  46. package/dist/components/Slider.js +20 -20
  47. package/dist/components/Steps.css +1 -1
  48. package/dist/components/Steps.d.ts +0 -1
  49. package/dist/components/Steps.js +1 -12
  50. package/dist/components/Tabs.d.ts +17 -20
  51. package/dist/components/Tabs.js +7 -9
  52. package/dist/components/Text.d.ts +55 -36
  53. package/dist/components/Text.js +35 -22
  54. package/dist/components/Title.d.ts +19 -27
  55. package/dist/components/Title.js +2 -1
  56. package/dist/components/Toaster.js +9 -2
  57. package/dist/components/Tooltip.d.ts +10 -15
  58. package/dist/components/copy-props.d.ts +14 -3
  59. package/dist/components/copy-props.js +14 -3
  60. package/dist/components/select-tree.d.ts +24 -0
  61. package/dist/components/select-tree.js +35 -0
  62. package/dist/element-base.d.ts +10 -0
  63. package/dist/element-base.js +15 -0
  64. package/dist/elements/a-avatar.css +1 -1
  65. package/dist/elements/a-avatar.js +2 -28
  66. package/dist/elements/a-banner.css +1 -1
  67. package/dist/elements/a-banner.d.ts +4 -1
  68. package/dist/elements/a-banner.js +22 -112
  69. package/dist/elements/a-breadcrumbs.d.ts +1 -0
  70. package/dist/elements/a-breadcrumbs.js +1 -0
  71. package/dist/elements/a-button.css +1 -1
  72. package/dist/elements/a-button.d.ts +10 -7
  73. package/dist/elements/a-button.js +18 -1
  74. package/dist/elements/a-calendar.d.ts +14 -13
  75. package/dist/elements/a-calendar.js +29 -24
  76. package/dist/elements/a-card.css +1 -1
  77. package/dist/elements/a-card.d.ts +0 -9
  78. package/dist/elements/a-card.js +0 -184
  79. package/dist/elements/a-checkbox.css +1 -1
  80. package/dist/elements/a-copy.css +1 -1
  81. package/dist/elements/a-copy.d.ts +1 -5
  82. package/dist/elements/a-copy.js +129 -108
  83. package/dist/elements/a-dialog.css +1 -1
  84. package/dist/elements/a-dialog.d.ts +1 -1
  85. package/dist/elements/a-dialog.js +68 -194
  86. package/dist/elements/a-expander.css +1 -1
  87. package/dist/elements/a-expander.d.ts +4 -30
  88. package/dist/elements/a-expander.js +85 -344
  89. package/dist/elements/a-icon.d.ts +5 -23
  90. package/dist/elements/a-icon.js +1 -2
  91. package/dist/elements/a-input-date.d.ts +1 -0
  92. package/dist/elements/a-input-date.js +1 -0
  93. package/dist/elements/a-input-time.css +1 -1
  94. package/dist/elements/a-input-time.d.ts +2 -1
  95. package/dist/elements/a-input-time.js +101 -168
  96. package/dist/elements/a-input.css +1 -1
  97. package/dist/elements/a-input.d.ts +10 -8
  98. package/dist/elements/a-input.js +155 -230
  99. package/dist/elements/a-loader.d.ts +5 -8
  100. package/dist/elements/a-loader.js +1 -2
  101. package/dist/elements/a-menu-item.css +1 -1
  102. package/dist/elements/a-menu-item.d.ts +5 -3
  103. package/dist/elements/a-menu-item.js +5 -1
  104. package/dist/elements/a-menu.css +1 -1
  105. package/dist/elements/a-menu.d.ts +5 -7
  106. package/dist/elements/a-menu.js +383 -299
  107. package/dist/elements/a-panel.css +1 -1
  108. package/dist/elements/a-panel.js +19 -37
  109. package/dist/elements/a-progress.css +1 -1
  110. package/dist/elements/a-progress.d.ts +0 -22
  111. package/dist/elements/a-progress.js +0 -100
  112. package/dist/elements/a-radio-group.d.ts +1 -1
  113. package/dist/elements/a-radio-group.js +6 -4
  114. package/dist/elements/a-select-faceted.d.ts +1 -0
  115. package/dist/elements/a-select-faceted.js +1 -0
  116. package/dist/elements/a-select.d.ts +1 -0
  117. package/dist/elements/a-select.js +1 -0
  118. package/dist/elements/a-slider.css +1 -1
  119. package/dist/elements/a-slider.d.ts +11 -3
  120. package/dist/elements/a-slider.js +244 -242
  121. package/dist/elements/a-steps.d.ts +1 -0
  122. package/dist/elements/a-steps.js +1 -0
  123. package/dist/elements/a-switch.css +1 -1
  124. package/dist/elements/a-tab.css +1 -1
  125. package/dist/elements/a-tabpanel.d.ts +2 -2
  126. package/dist/elements/a-tabpanel.js +13 -3
  127. package/dist/elements/a-tabs.css +1 -1
  128. package/dist/elements/a-tabs.d.ts +1 -1
  129. package/dist/elements/a-tabs.js +6 -4
  130. package/dist/elements/a-tag.css +1 -1
  131. package/dist/elements/a-tag.d.ts +1 -0
  132. package/dist/elements/a-tag.js +1 -0
  133. package/dist/elements/a-text.css +1 -1
  134. package/dist/elements/a-text.d.ts +6 -43
  135. package/dist/elements/a-text.js +110 -193
  136. package/dist/elements/a-title.css +1 -1
  137. package/dist/elements/a-title.d.ts +1 -0
  138. package/dist/elements/a-title.js +1 -0
  139. package/dist/elements/a-toast.css +1 -1
  140. package/dist/elements/a-toast.d.ts +10 -45
  141. package/dist/elements/a-toast.js +80 -66
  142. package/dist/elements/a-toaster.css +1 -1
  143. package/dist/elements/a-toaster.js +9 -44
  144. package/dist/elements/a-tooltip.css +1 -1
  145. package/dist/elements/a-tooltip.d.ts +1 -1
  146. package/dist/elements/a-tooltip.js +142 -136
  147. package/dist/elements/copy-behavior.d.ts +1 -1
  148. package/dist/elements/copy-behavior.js +21 -21
  149. package/dist/elements/index.d.ts +9 -3
  150. package/dist/elements/index.js +6 -6
  151. package/dist/elements/input-focus-modality.d.ts +15 -0
  152. package/dist/elements/input-focus-modality.js +44 -0
  153. package/dist/elements/input-trailing-actions.d.ts +5 -0
  154. package/dist/elements/input-trailing-actions.js +38 -0
  155. package/dist/elements/shadow-aria.d.ts +2 -0
  156. package/dist/elements/shadow-aria.js +2 -1
  157. package/dist/elements/value-input.d.ts +3 -0
  158. package/dist/elements/value-input.js +12 -0
  159. package/dist/general_types.d.ts +103 -96
  160. package/dist/index.d.ts +1 -1
  161. package/dist/input-events.d.ts +4 -0
  162. package/dist/input-events.js +15 -0
  163. package/dist/jsx-runtime.d.ts +70 -23
  164. package/dist/jsx-runtime.js +26 -19
  165. package/dist/native-event-props.d.ts +2 -0
  166. package/dist/native-event-props.js +10 -0
  167. package/dist/reset.css +1 -1
  168. package/dist/theme-antithesis.css +10 -1
  169. package/dist/theme-antune.css +1 -1
  170. package/docs/accessibility.md +17 -3
  171. package/docs/changelog.md +384 -2
  172. package/docs/comparison.md +2 -2
  173. package/docs/components/avatar.md +5 -0
  174. package/docs/components/banner.md +117 -187
  175. package/docs/components/breadcrumbs.md +9 -6
  176. package/docs/components/button.md +22 -0
  177. package/docs/components/card.md +74 -28
  178. package/docs/components/checkbox.md +9 -10
  179. package/docs/components/dialog.md +83 -32
  180. package/docs/components/expander.md +198 -435
  181. package/docs/components/icon.md +11 -17
  182. package/docs/components/input-autocomplete.md +152 -52
  183. package/docs/components/input-date.md +175 -148
  184. package/docs/components/input-time.md +81 -38
  185. package/docs/components/input.md +343 -349
  186. package/docs/components/loader.md +2 -1
  187. package/docs/components/menu.md +35 -6
  188. package/docs/components/panel.md +18 -0
  189. package/docs/components/progress.md +83 -49
  190. package/docs/components/radio.md +39 -43
  191. package/docs/components/select-faceted.md +54 -7
  192. package/docs/components/select.md +390 -386
  193. package/docs/components/slider.md +136 -19
  194. package/docs/components/steps.md +6 -3
  195. package/docs/components/switch.md +8 -9
  196. package/docs/components/tabs.md +110 -104
  197. package/docs/components/text.md +110 -86
  198. package/docs/components/title.md +47 -33
  199. package/docs/components/toaster.md +242 -84
  200. package/docs/components/tooltip.md +204 -113
  201. package/docs/install-config.md +461 -96
  202. package/docs/packages/plot.md +228 -143
  203. package/docs/theming.md +29 -13
  204. package/package.json +43 -4
  205. package/theme-antithesis-license.md +66 -0
@@ -65,7 +65,8 @@ Use `<Loader>` when you need a value, speed, or accessible loading status.
65
65
 
66
66
  ## Web Component
67
67
 
68
- Use a raw `<a-loader>` when you are not using the JSX wrapper. Set its size,
68
+ Loader needs its stylesheet without JavaScript registration. Use a raw
69
+ `<a-loader>` outside the JSX wrapper. Set its size,
69
70
  speed, and determinate percentage with CSS custom properties. `value` selects
70
71
  the static ring; `--loader-value` is the percentage it shows.
71
72
 
@@ -7,6 +7,11 @@ on outside-click, `Escape`, or scroll. Rows are dedicated **`MenuItem`s** (not
7
7
  buttons), with optional leading icons, trailing keyboard hints, separators,
8
8
  grouped sections, and nested submenus.
9
9
 
10
+ The trigger can be replaced while Menu stays mounted, such as when a responsive
11
+ layout switches controls. Keep Menu immediately after the replacement element.
12
+ Menu reconnects its trigger listeners and popup relationships without resetting
13
+ its open state.
14
+
10
15
  Open state is uncontrolled by default — pass **`onStateChange`** (event-first:
11
16
  `(event, { next, prev })`, or listen for the raw **`statechange`** event) to
12
17
  observe it, or pass **`open`** to control it, applying `detail.next` to `open`
@@ -213,7 +218,7 @@ footer stays the menu's divider.
213
218
  <Button>Filter</Button>
214
219
  <Menu inset={8}>
215
220
  <a-menu-header slot="header" data-menu-open>
216
- <Input size="small" placeholder="Filter…" />
221
+ <Input size="small" placeholder="Filter…" aria-label="Filter items" />
217
222
  </a-menu-header>
218
223
  <MenuItem label="Design" />
219
224
  <MenuItem label="Engineering" />
@@ -488,7 +493,7 @@ or do nothing to reject. (Submenus are always uncontrolled, regardless of `open`
488
493
  | `open?` | boolean | — | Controlled open state. Omit for the default **uncontrolled** menu (it opens/closes itself via its triggers). Pass a boolean to **control** it: the menu's visibility follows `open`, and user dismiss (Esc, outside-click, select) fires `onStateChange` *without* self-closing — you update `open` in response. Submenus are always uncontrolled regardless of this. See STATEFUL-COMPONENTS.md. |
489
494
  | `placement?` | 'bottom-start' \| 'bottom-end' \| 'top-start' \| 'top-end' \| 'bottom' \| 'top' \| 'right-start' \| 'right-end' \| 'left-start' \| 'left-end' \| 'right' \| 'left' | bottom-start | Preferred placement relative to the trigger. `bottom` / `top` place the menu below / above; `right` / `left` place it beside (like a submenu flyout). The cross-axis suffix (`-start` / `-end`) aligns the near / far edges, and no suffix centers on the trigger. The menu flips to the opposite side when the preferred one lacks room, and clamps to the viewport. |
490
495
  | `role?` | string | menu | ARIA role of the menu surface. |
491
- | `round?` | boolean \| number \| string | — | Round the menu: the container softens to a 20px radius and its items go fully round. A `number` (px) or CSS length string tunes the container radius only — items stay full pills. |
496
+ | `round?` | boolean \| number \| string | — | Round the menu container to a 20px radius. A `number` (px) or CSS length string sets a custom container radius. Items use the container radius minus `inset`, clamped to zero. Nested submenus inherit the container radius unless they set their own `round` value. |
492
497
  | `stopPropagation?` | boolean \| string \| string[] | — | Contain events so they don't bubble out of the menu to ancestor handlers (e.g. a clickable row the menu sits in). Selecting an item is always contained; this extends it to whole event types. `true` contains `click`; pass an event name or list (`"click pointerdown"`) to contain those. |
493
498
 
494
499
  ## MenuItem props
@@ -521,12 +526,16 @@ or do nothing to reject. (Submenus are always uncontrolled, regardless of `open`
521
526
 
522
527
  ## Web Component
523
528
 
524
- Use the web component directly when you are not using React or Preact and a native control does not fit.
529
+ Use `<a-menu>` and `<a-menu-item>` directly outside JSX.
525
530
 
526
531
  Put a focusable trigger immediately before `<a-menu>` and omit `state` for an
527
532
  uncontrolled menu. Its light-DOM `<a-menu-item>` rows need their own `tabindex`
528
533
  values.
529
534
 
535
+ Follow [Install and configure](../install-config.md) to load styles and browser behavior.
536
+ For server-rendered applications, also follow
537
+ [Browser hydration](../install-config.md#browser-hydration).
538
+
530
539
  ```html
531
540
  <a-button role="button" tabindex="0" aria-haspopup="menu">
532
541
  <a-button-label>Actions</a-button-label>
@@ -539,9 +548,29 @@ values.
539
548
 
540
549
  ## Styling
541
550
 
542
- The popover surface lives in shadow DOM and is exposed as a **part** — style its
551
+ Menu item corners follow the container radius minus `inset`, clamped to zero.
552
+ The default 8px container radius and 4px inset give items a 4px radius.
553
+ The Antithesis theme uses a 2px container radius, so its items have square corners
554
+ with the default inset. Pass `round` for a 20px container radius and 16px item
555
+ radius, or pass a number or CSS length for a custom container radius.
556
+ Nested submenus inherit the container radius unless they set their own `round`
557
+ value. Each submenu subtracts its own `inset` to determine its item radius.
558
+ Use `round` and `inset` to keep these radii connected. A direct CSS override of
559
+ `::part(menu)` or a menu item's `border-radius` controls that surface independently.
560
+
561
+ The popover surface lives in shadow DOM. Style its
543
562
  chrome (background, frost, border, radius, shadow, padding, min-width) with
544
- `::part(menu)`. Menu items are light DOM, so style them (and their
563
+ `::part(menu)`. Use `::part(scroll)` for the scrolling body and `::part(header)` /
564
+ `::part(footer)` for the pinned slots. Keep `display` overrides scoped to
565
+ `::part(menu):popover-open` so closed menus remain hidden. Position and available
566
+ height follow the trigger and viewport; overrides of positioning, visibility,
567
+ transforms, or transitions can change those behaviors.
568
+
569
+ Put overrides in `components`, `utilities`, or unlayered CSS. If older part
570
+ overrides are in `base`, move them to a later layer so they take precedence over
571
+ Anta's defaults. See [Cascade layers](../install-config.md#cascade-layers).
572
+
573
+ Menu items are light DOM, so style them (and their
545
574
  `a-icon` / `kbd` / `a-menu-item-label` children) directly. Match **both** item
546
575
  shapes — the `a-menu-item` custom element and the `a[data-anta-menu-item]` link —
547
576
  with `:is(a-menu-item, a[data-anta-menu-item])`, or a link row skips your item
@@ -555,7 +584,7 @@ a-menu.fancy::part(menu) {
555
584
  border-radius: 22px;
556
585
  min-width: 240px;
557
586
  padding: 8px;
558
- background: light-dark(rgba(255,255,255,0.55), rgba(28,26,32,0.5));
587
+ background: light-dark(color-mix(in oklch, white 55%, transparent), color-mix(in oklch, rgb(28,26,32) 50%, transparent));
559
588
  backdrop-filter: blur(28px) saturate(180%);
560
589
  }
561
590
  /* Items are light DOM — style them directly. `:is()` catches both an
@@ -154,6 +154,24 @@ maximized scrolling surface. In normal mode, the content slot uses `display: con
154
154
  The maximized surface also uses `overflow: auto`; override
155
155
  `::part(content)` to change its overflow separately from the normal Panel.
156
156
 
157
+ The `::part(placeholder)` region reserves the normal content size while the
158
+ surface is maximized. Panel measures its width and height, but your `::part()`
159
+ rules can override those dimensions. Changing layout properties such as `width`,
160
+ `height`, `padding`, `border`, or `box-sizing` can change the reserved space and
161
+ move neighboring content. To preserve that space, customize `background` or
162
+ `outline` and leave layout properties unchanged.
163
+
164
+ Use `::part(content)::backdrop` to style the native popover backdrop. By default,
165
+ the backdrop is transparent and ignores pointer events.
166
+
167
+ Defaults live in external CSS and follow Anta's cascade layers. Put normal
168
+ part overrides in `components`, `utilities`, or unlayered CSS. A `base` layer
169
+ rule no longer overrides these defaults. See [Content Security Policy](../install-config.md#content-security-policy)
170
+ for stylesheet loading and inline-style constraints.
171
+
172
+ Inside another shadow root, load `@antadesign/anta/elements/a-panel.css` in
173
+ that root through a stylesheet link. Document styles cannot reach Panel there.
174
+
157
175
  Enter a note, then select **Maximize panel** and **Restore panel**. The input
158
176
  keeps its value. The `panel-demo` classes supply this example's appearance;
159
177
  replace them with your own selectors.
@@ -1,27 +1,27 @@
1
- // The demo source lives in a sibling `.ts` file rather than inline
2
- // here because Astro's MDX pipeline trims leading whitespace from
3
- // JSX-attribute template literals, which scrambles the indentation
4
- // Monaco needs for folding ranges. A regular module import preserves
5
- // the template literal's bytes verbatim.
1
+ // Keep the playground source in a module so MDX preserves its indentation.
6
2
 
7
3
  # Progress
8
4
 
9
- `Progress` shows task completion. Pass `value` for known progress. Omit it, or
10
- pass `false`, while work is underway without a known duration.
5
+ Use Progress for uploads, downloads, and other tasks that take time. Show a
6
+ percentage when you know the total, or a loading animation while completion is
7
+ unknown. Add a label and hint to explain what is happening.
11
8
 
12
- ## Value, label and hint
9
+ ## Value, label, and hint
13
10
 
14
11
  ```tsx
15
12
  <Progress value={60} />
16
- <Progress value={42} label="Uploading files…" hint="3 of 7" />
13
+ <Progress value={3} max={7} label="Uploading files…" hint="3 of 7" />
17
14
 
18
- // Omit value, or pass false, while the duration is unknown.
15
+ // Omit value while the total is unknown.
19
16
  <Progress label="Preparing upload…" hint="~ 3 minutes left" />
20
17
  ```
21
18
 
22
- `value` sets known completion relative to `max`, which defaults to `100`.
23
- `label` follows the percentage. `hint` is right-aligned. With no `value`, the
24
- label identifies indeterminate work and the loading animation takes the track.
19
+ Pass `value` to show completion. For a percentage, use the default `max` of
20
+ `100`. For a count, pass the total as `max`; the example shows 3 of 7 files.
21
+
22
+ Use `label` to name the task and `hint` for details such as completed items or an
23
+ estimated time. While the total is unknown, omit `value` or pass `false` to show
24
+ loading stripes without a percentage.
25
25
 
26
26
  ## Size
27
27
 
@@ -31,8 +31,8 @@ label identifies indeterminate work and the loading animation takes the track.
31
31
  <Progress size="large" tone="info" value={60} label="Large" hint="~ 3 minutes left" />
32
32
  ```
33
33
 
34
- `size` scales the track and the default label row together. `medium` is the
35
- default.
34
+ Use `small` for compact task lists and `large` for more prominent feedback.
35
+ The track, percentage, label, and hint scale together.
36
36
 
37
37
  ## Tone
38
38
 
@@ -45,8 +45,9 @@ default.
45
45
  <Progress value={60} tone="#e0457b" label="Custom" />
46
46
  ```
47
47
 
48
- `tone` colors the track, indicator, and label row. Use `neutral` for the
49
- default, a named semantic tone, or any CSS color.
48
+ Use `brand` for the primary task or a semantic tone to match its status. Keep
49
+ the task's meaning in its label or hint so readers can understand it without
50
+ color. Pass a CSS color for a custom tone.
50
51
 
51
52
  ## Border
52
53
 
@@ -78,9 +79,9 @@ default, a named semantic tone, or any CSS color.
78
79
  />
79
80
  ```
80
81
 
81
- The track starts borderless. Set a border width to reveal its tone-aware border
82
- color. A bottom edge works for an indicator at the top of an app. A top edge
83
- works for one at the bottom.
82
+ Add a border to separate progress from the surrounding content. A bottom
83
+ border suits a bar along the top of an app; a top border suits one along the
84
+ bottom. The border color follows the tone.
84
85
 
85
86
  ## Round
86
87
 
@@ -89,25 +90,40 @@ works for one at the bottom.
89
90
  <Progress value={60} round={4} label="4px radius" />
90
91
  ```
91
92
 
92
- `round` makes the track fully round. Pass a number or CSS length for a custom
93
- radius.
93
+ Use `round` for a pill-shaped track. Pass a number in pixels or a CSS length
94
+ to match the corners of nearby content.
95
+
96
+ ## Custom content
97
+
98
+ Use `children` when task details need more than a plain label and hint. Pass
99
+ `label` and `hint` to keep an accessible description of the task.
100
+
101
+ ```tsx
102
+ <Progress value={3} max={5} label="Sending report.csv" hint="3 of 5">
103
+ <Text>Sending <strong>report.csv</strong> · 3 of 5</Text>
104
+ </Progress>
105
+ ```
94
106
 
95
107
  ## Component props
96
108
 
97
109
  | Prop | Type | Default | Description |
98
110
  |------|------|---------|-------------|
99
- | `hint?` | string | — | Right-aligned hint text (e.g. "3 of 7"). Like `label`, it's not rendered when custom `children` are provided but still feeds the accessible name. |
100
- | `label?` | string | — | Text label displayed after the percentage, or on its own for indeterminate progress. When you provide custom `children` (which replace the default label row), `label` is no longer rendered — but it still supplies the progressbar's accessible name. |
101
- | `max?` | number | 100 | Upper bound of the range. |
102
- | `round?` | boolean \| number \| string | — | Fully-round track (`border-radius: 999px`); the fill is clipped to it. Pass a `number` (px) or a CSS length string for a custom radius. |
111
+ | `hint?` | string | — | Details shown at the end of the row, such as "3 of 7" or a time estimate. Included in the accessible name even when custom `children` replace the row. |
112
+ | `label?` | string | — | Task name shown after the percentage, or on its own during loading. Custom `children` replace the label row; this prop still supplies the progressbar's accessible name. |
113
+ | `max?` | number | 100 | Total amount to complete. Use a positive number to show a count, such as 3 of 7 files. When `value` is supplied, a non-positive or non-finite total shows an empty fill. |
114
+ | `round?` | boolean \| number \| string | — | Pill-shaped track. Pass a number in pixels or a CSS length for a custom corner radius. |
103
115
  | `size?` | 'small' \| 'medium' \| 'large' | medium | Size variant. Scales the track and the default label row together. |
104
- | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Color variant, or any literal CSS color for a one-off custom tone (the surface / indicator / text are derived from it in oklch). Named tones track light/dark automatically. |
105
- | `value?` | number \| false | — | Current progress value. Omit this prop, or pass `false`, to show indeterminate progress. Negative values are clamped to 0. |
116
+ | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Color for the track, fill, and label row. Pass a named tone or a CSS color. Named tones follow the current theme. |
117
+ | `value?` | number \| false | — | Completed amount relative to `max`. Omit this prop or pass `false` to show a loading animation without a percentage. Values are clamped to the range; non-finite values show zero completion. |
118
+
119
+ <a id="raw-html"></a>
106
120
 
107
121
  ## Web Component
108
122
 
123
+ <a id="web-component"></a>
124
+
109
125
  ```html
110
- <a-progress style="width: 100%" value="42" max="100" tone="info" role="progressbar"
126
+ <a-progress value="42" max="100" tone="info" role="progressbar"
111
127
  aria-valuenow="42" aria-valuemin="0" aria-valuemax="100" aria-label="Upload, 42%">
112
128
  <a-progress-label>
113
129
  <a-progress-number>42%</a-progress-number>
@@ -123,12 +139,25 @@ radius.
123
139
  </a-progress>
124
140
  ```
125
141
 
126
- Use this when you are not using the React or Preact wrapper and a native HTML
127
- control does not fit: construct the equivalent Anta web component from the
128
- elements below.
142
+ Use `<a-progress>` directly when you need its label layout in plain HTML.
143
+ `a-progress-number`, `a-progress-text`, and `a-progress-hint` form the default
144
+ row; you can also supply your own content.
145
+
146
+ Load `@antadesign/anta/elements/a-progress` or the full bundle. Add `role` and
147
+ ARIA values on the host, and keep them in sync with `value`, `max`, and visible
148
+ text. Omit `value` for loading stripes.
129
149
 
130
- Add the progressbar semantics and label structure when using the element
131
- directly.
150
+ The JSX wrapper supplies the markup, numeric CSS variables, and ARIA from props.
151
+ Raw `value` and `max` rendering requires numeric CSS `attr()`, which is not
152
+ available in every browser that meets Anta's minimum requirements. Numeric
153
+ `--progress-value` and `--progress-max` variables override the corresponding
154
+ attributes. JSX supplies and updates them automatically across supported browsers.
155
+
156
+ Server-rendered JSX values use inline style attributes. A CSP with
157
+ `style-src-attr 'none'` blocks these variables; attribute rendering then requires
158
+ numeric CSS `attr()` support. Native `<progress data-anta>` uses browser-owned
159
+ values without inline CSS variables across supported browsers. See
160
+ [Content Security Policy](../install-config.md#content-security-policy).
132
161
 
133
162
  ### Native HTML progress
134
163
 
@@ -146,33 +175,38 @@ directly.
146
175
  <progress data-anta round="50px" aria-label="Preparing upload" style="width: 100%"></progress>
147
176
  ```
148
177
 
149
- For a plain HTML progress indicator, add `data-anta` to `<progress>`. It keeps
150
- the browser's native semantics, including indeterminate progress when `value`
151
- is absent, while using Anta's track, fill, tone, and size treatments. Native
152
- progress does not render Anta's label or hint structure; give it an accessible
153
- name instead.
178
+ Use `<progress data-anta>` for a native progress bar with Anta's appearance.
179
+ The browser handles completion and accessibility from `value` and `max`. Omit
180
+ `value` for unknown completion, and give the control an accessible name.
181
+
182
+ Native progress supports tone, size, and rounding. It has no built-in label row.
183
+ The same Progress entry and full bundle style both forms.
154
184
 
155
185
  ## Styling
156
186
 
157
187
  ```css
158
- /* a fancy bar: rounded track (all sides), a multi-stop gradient fill with a glow,
159
- and a crisp hard right edge (the default soft right-edge fade is cleared). */
188
+ /* Rounded track and gradient fill with a glow. */
160
189
  a-progress.fancy {
161
190
  border-radius: 999px;
162
191
  background: light-dark(var(--bg-5), #26232c);
163
192
  }
164
- a-progress.fancy::part(indicator) {
165
- background: linear-gradient(90deg, #6a5acd, #d44ea3 55%, #ff8a5b);
166
- box-shadow: 0 0 12px rgba(212, 78, 163, 0.55); /* glow */
193
+ a-progress.fancy::before {
194
+ background: linear-gradient(
195
+ 90deg,
196
+ light-dark(#6a5acd, #8b7cf0),
197
+ light-dark(#d44ea3, #ec64bc) 55%,
198
+ light-dark(#ff8a5b, #ffa477)
199
+ );
200
+ box-shadow: 0 0 12px color-mix(in oklch, #d44ea3 55%, transparent);
167
201
  }
168
- a-progress.fancy::part(indicator)::after { background: none; } /* hard right edge */
169
202
 
170
- /* the percentage / label / hint are light-DOM children — recolor for the bar */
203
+ /* Keep the label readable against the custom fill. */
171
204
  a-progress.fancy a-progress-number,
172
205
  a-progress.fancy a-progress-text { color: #fff; }
173
206
  a-progress.fancy a-progress-hint { color: var(--text-2); }
174
207
  ```
175
208
 
176
- For one-offs, the **track** is the host (style `a-progress` directly) and the
177
- **indicator** (fill bar) is a shadow **part** — `::part(indicator)`. The `.fancy`
178
- class is just for the demo.
209
+ Use `tone`, `size`, and `round` for the component's appearance. For further
210
+ customization, style `a-progress` for the track and `a-progress::before` for the
211
+ fill or loading stripes. Target the label tags or your own children for text
212
+ styling. `.fancy` belongs to this example.
@@ -1,9 +1,8 @@
1
1
  # Radio
2
2
 
3
- A single-select control. `RadioGroup` is the whole component — you pass it an
4
- `options` array and it renders one radio per entry, owning selection, keyboard
5
- navigation, and the form value. There's no separate `Radio` component: options
6
- are data, not markup.
3
+ Use RadioGroup when someone needs to choose one option from a visible set,
4
+ such as a plan or contact method. Pass the choices through `options` and add
5
+ a group label to explain the decision.
7
6
 
8
7
  ## Options, label, and hint
9
8
 
@@ -20,12 +19,11 @@ are data, not markup.
20
19
  />
21
20
  ```
22
21
 
23
- Each entry needs a unique `value` (its identity and submitted value) and a
24
- `label`, plus an optional `hint` — secondary copy rendered under that option,
25
- styled like `Input`'s hint.
22
+ Give each option a unique `value` and a `label`. Add an option `hint` when a
23
+ choice needs explanation. The selected option's value is submitted with the form.
26
24
 
27
- The group's own `label` and `hint` form a header **above** the options: the
28
- `label` first, the `hint` (an instruction for the whole set) directly under it.
25
+ Use the group's `label` to name the whole set and its `hint` for instructions
26
+ that apply to every option.
29
27
 
30
28
  Each option can also set `className`, `style`, and `data-*`.
31
29
  `RadioGroup` forwards them to that option's `<a-radio>` so you can add
@@ -161,25 +159,15 @@ enabled one), the arrow keys (`↑`/`↓`/`←`/`→`) move the selection betwee
161
159
  options (wrapping at the ends), and `Space` / `Enter` select the focused option.
162
160
  Follows the [WAI-ARIA radio-group pattern](https://www.w3.org/WAI/ARIA/apg/patterns/radio/).
163
161
 
164
- Under the hood the split is deliberate. The `<a-radio-group>` web component
165
- **never mutates the DOM** — it coordinates entirely off-DOM: selection is set as a
166
- property on each `<a-radio>` (which reflects it into `:state(selected)` +
167
- `aria-checked` via its own `ElementInternals`), the form value goes through
168
- `ElementInternals`, and focus is tracked with `aria-activedescendant`. Each
169
- option's light-DOM label and hint also become its accessible name and description
170
- through direct element references, without generated IDs. The
171
- **roving `tabindex`** — which option Tab lands on — is the one piece rendered
172
- declaratively, by the `RadioGroup` wrapper, from the current value. That's why
173
- selection is owned by the element but the wrapper holds the value: it needs it to
174
- place the tab stop. (Hand-assembling raw `<a-radio-group>` / `<a-radio>` works
175
- too; make the group the tab stop with `tabindex="0"` and it falls back to
176
- `aria-activedescendant` for keyboard nav.)
162
+ Each option's label names it for screen readers, and its hint supplies a
163
+ description. Give the group a `label` or `aria-label` so the choice itself also
164
+ has an accessible name.
177
165
 
178
166
  ## Forms
179
167
 
180
- `<a-radio-group>` is a form-associated custom element. Give it a `name` and the
181
- selected option's `value` is submitted with the form like a native radio group;
182
- form reset restores the `defaultValue` selection.
168
+ Add `name` to submit the selected option's value with a form. An uncontrolled
169
+ group returns to `defaultValue` on form reset. For a controlled group, handle
170
+ the reset request in `onStateChange` and update `value` as needed.
183
171
 
184
172
  ```tsx
185
173
  <form>
@@ -193,7 +181,7 @@ form reset restores the `defaultValue` selection.
193
181
 
194
182
  ## Controlled vs. uncontrolled
195
183
 
196
- **Uncontrolled** — pass `defaultValue` and let the group own selection:
184
+ Pass `defaultValue` when the group can manage its own selection:
197
185
 
198
186
  ```tsx
199
187
  <RadioGroup name="plan" defaultValue="pro" options={[
@@ -203,9 +191,9 @@ form reset restores the `defaultValue` selection.
203
191
  ]} />
204
192
  ```
205
193
 
206
- **Controlled** — pass `value` + `onStateChange` and own it yourself. The group
207
- fires *before* applying, so you accept by updating `value` and reject by doing
208
- nothing (or `event.preventDefault()` to veto in uncontrolled mode):
194
+ Pass `value` with `onStateChange` when the application controls selection.
195
+ Update `value` to accept a requested choice, or leave it unchanged to reject it.
196
+ For an uncontrolled group, call `event.preventDefault()` to cancel a user pick:
209
197
 
210
198
  ```tsx
211
199
  const [plan, setPlan] = useState('pro')
@@ -213,7 +201,7 @@ const [plan, setPlan] = useState('pro')
213
201
  <RadioGroup
214
202
  name="plan"
215
203
  value={plan}
216
- onStateChange={(e, { next }) => setPlan(next)}
204
+ onStateChange={(_event, { next }) => { if (next !== null) setPlan(next) }}
217
205
  options={[
218
206
  { value: 'free', label: 'Free' },
219
207
  { value: 'pro', label: 'Pro' },
@@ -237,20 +225,20 @@ Three callbacks, in firing order:
237
225
  | `onChange(e)` | **after** selection applies | — | native `change` event |
238
226
  | `onValueChange(e, attrs)` | **after** selection applies | — | `{ value, name }` |
239
227
 
240
- Reach for **`onStateChange`** to intercept/veto or to filter on `reason` (reset vs
241
- restore vs user); for the everyday "react to the new value", use **`onValueChange`**.
242
- `onChange` is the plain native hook. **`onFocus` / `onBlur`** report focus entering
243
- and leaving the *group* (wired to `focusin` / `focusout`, since focus lands on an
244
- individual option).
245
-
246
- The group has `onStateChange` because its selection is a **discrete** state (one
247
- of a fixed set) the element self-applies — so a transition can be vetoed before it
248
- lands, and it carries `reason`. Value-based composites without a self-applying
249
- element — `Input`, and the composed `Select` — skip it and expose only
250
- `onValueChange`; the `onValueChange` shape is the same across all of them.
228
+ Use `onStateChange` to control or cancel a selection request. Its `reason`
229
+ distinguishes a user pick from form reset or restoration. Use `onValueChange`
230
+ to save or react to an applied selection. `onChange` exposes the native event.
231
+ `onFocus` and `onBlur` report focus entering and leaving the group.
251
232
 
252
233
  ```tsx
253
- <RadioGroup onValueChange={(_e, { value }) => save(value)} options={…} />
234
+ <RadioGroup
235
+ label="Contact method"
236
+ onValueChange={(_event, { value }) => save(value)}
237
+ options={[
238
+ { value: 'email', label: 'Email' },
239
+ { value: 'sms', label: 'SMS' },
240
+ ]}
241
+ />
254
242
  ```
255
243
 
256
244
  ## RadioGroup props
@@ -279,7 +267,15 @@ element — `Input`, and the composed `Select` — skip it and expose only
279
267
 
280
268
  Use the web component directly when you are not using React or Preact and a native control does not fit.
281
269
 
282
- The group owns selection and the single tab stop. Put options in `<a-radio-list>`.
270
+ Use `state` for controlled selection or `default-state` for the initial
271
+ uncontrolled selection. The read-only `.value` property returns the applied
272
+ selection. Remove `state` to release control and retain that selection.
273
+ User picks update internal state without rewriting authored attributes.
274
+ Accept a controlled pick through `statechange` by setting `state` to
275
+ `event.detail.next`. An empty string is a valid option value.
276
+
277
+ Put options in `<a-radio-list>` and add `tabindex="0"` to the group for
278
+ keyboard access. The raw group manages focus among its options.
283
279
 
284
280
  ```html
285
281
  <a-radio-group role="radiogroup" tabindex="0" name="plan" default-state="pro">
@@ -20,6 +20,16 @@ facet also opens a dialog containing its search field and options menu. Text and
20
20
  custom facets use dialogs for their editable content. An unfiltered option facet
21
21
  keeps the menu popup pattern.
22
22
 
23
+ Global search matches options across all `single` and `multiple` facets, including
24
+ facets with `filter: false`. A facet's `filter` controls its own search field.
25
+ Each field keeps its query independently. Built-in matching searches `value`,
26
+ `label`, and `hint` without case sensitivity; whitespace in a query matches a
27
+ run of whitespace. A custom `filter` receives the original query, including
28
+ leading and trailing spaces, in both search locations.
29
+ It also runs for an empty per-facet query. A whitespace-only global query keeps
30
+ the facet list visible instead of opening global results. Select's custom
31
+ filter receives a trimmed query; account for this difference when sharing predicates.
32
+
23
33
  Pass `placement` to control where the root facet menu opens relative to its
24
34
  trigger. It uses the same values as `Menu` and still flips or clamps when space
25
35
  is limited. `offset` sets the gap in pixels between the trigger and the menu:
@@ -95,7 +105,7 @@ function Demo() {
95
105
  <SelectFaceted facets={FACETS} value={value} onValueChange={setValue} searchable />
96
106
 
97
107
  {active.length > 0 && (
98
- <div style={{ display: 'flex', flexDirection: 'row', flexWrap: 'wrap', gap: 8, alignItems: 'center' }}>
108
+ <div style={{ display: 'flex', flexDirection: 'row', flexWrap: 'wrap', gap: 8, alignItems: 'center', maxWidth: '100%' }}>
99
109
  {/* Show an editable control or summary for each active facet. */}
100
110
  {active.map((facet) => {
101
111
  // Options facets → an editable Select (single shows the trailing check;
@@ -108,13 +118,13 @@ function Demo() {
108
118
  indicator={facet.kind === 'single' ? 'check' : undefined}
109
119
  options={facet.options}
110
120
  renderOption={facet.renderOption}
111
- value={value[facet.key]}
121
+ value={value[facet.key] ?? (facet.kind === 'single' ? null : [])}
112
122
  onValueChange={(v) => setFacet(facet.key, v)}
113
123
  leading={`${facet.label}:`}
124
+ aria-label={facet.label}
114
125
  filter={facet.filter}
115
126
  clearable
116
- // Chip sizes to its value and caps at a max-width (ellipsizing past it).
117
- style={{ width: 'fit-content', maxWidth: '240px' }}
127
+ className="sf-chip"
118
128
  />
119
129
  )
120
130
 
@@ -134,12 +144,11 @@ function Demo() {
134
144
  leading={`${facet.label}:`}
135
145
  clearable
136
146
  dimActions
147
+ className="sf-chip"
137
148
  onFocus={() => setFocusedKey(facet.key)}
138
149
  onBlur={() => setFocusedKey(null)}
139
150
  onInput={(e) => write(e.currentTarget.value)}
140
151
  onClearInput={() => { setFocusedKey(null); setFacet(facet.key, undefined) }}
141
- // Size the chip to its value, capped at a max-width.
142
- style={{ width: 'fit-content', maxWidth: '240px' }}
143
152
  />
144
153
  )
145
154
  })}
@@ -161,9 +170,17 @@ function Demo() {
161
170
  }
162
171
  ```
163
172
 
173
+ The demo gives editable chips a consistent width, capped by their container.
174
+ Input truncates long values with an ellipsis when the field is unfocused.
175
+
176
+ ```css
177
+ .sf-chip { width: 240px; max-width: 100%; }
178
+ ```
179
+
164
180
  The trigger opens the facet menu. The example shows active values beside it.
165
181
  Option facets use an editable [Select](./select.md) with the facet label in its
166
- `leading` prefix. Recency uses a summary tag and is edited in the facet menu.
182
+ `leading` prefix and `aria-label` as its accessible name. Recency uses a summary
183
+ tag and is edited in the facet menu.
167
184
 
168
185
  ### Custom option content
169
186
 
@@ -503,3 +520,33 @@ It can store a value of type `V`, including an object such as a date range.
503
520
  | `kind` | `'custom'` | Discriminant. |
504
521
  | `render` | `(ctx) => ReactNode` | Renders the editor. `ctx.value` is the current `V`; `ctx.onChange(next)` sets it, and `undefined` clears the facet. `ctx.close()` closes the menu. |
505
522
  | `summary` | `(value: V) => ReactNode` | The chip on the facet's row while a value is set. |
523
+
524
+ ## Styling
525
+
526
+ `size` and `priority` style the default trigger. `tone` and `toneScope` style
527
+ option rows. `className`, `style`, and extra attributes apply to the default
528
+ Button; a custom `renderTrigger` owns its own styling and attributes.
529
+
530
+ SelectFaceted uses external styles for its fixed layout, including the text
531
+ editor's padding. Consumer `style` props, option styles, render-hook styles,
532
+ and custom color or radius props can still produce inline style attributes.
533
+ Server-rendered inline styles are blocked by `style-src-attr 'none'`.
534
+
535
+ The text editor uses a CSS-only `a-select-faceted-text` region in its Menu.
536
+ If you targeted the former `div[data-menu-open]` wrapper, replace that part of
537
+ your selector with `a-select-faceted-text`. Its padding now comes from CSS,
538
+ so selectors that require an inline `style` attribute no longer apply.
539
+ Use your trigger's class and the adjacent Menu to scope its padding. The class
540
+ in this example belongs to the demo; replace it with your own selector. Open
541
+ **Title contains** to see the larger inset.
542
+
543
+ ```tsx
544
+ <SelectFaceted
545
+ className="roomy-text-filter"
546
+ facets={[{ key: 'title', label: 'Title contains', kind: 'text' }]}
547
+ />
548
+ ```
549
+
550
+ ```css
551
+ .roomy-text-filter + a-menu a-select-faceted-text { padding: 8px; }
552
+ ```