@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
@@ -1,93 +1,26 @@
1
1
  # Banner
2
2
 
3
- A full-width notice for an announcement, status change, or promotion. `Banner`
4
- renders an `<a-banner>` with `message`, optional `children`, `actions`, and a dismiss
5
- control. Content starts at the inline edge; pass `align="center"` to center it
6
- ([Align](#align)). `closable` defaults to `true`.
7
-
8
- `Banner` is borderless. Set `border-bottom-width` for a rule or `border-width` for
9
- an outline ([Styling](#styling)).
10
-
11
- ## Tone
12
-
13
- Pick a semantic `tone` to tint the surface and text together — and the ✕ adopts the
14
- same tone (it also sets the border color, used if you opt into a border). The set
15
- matches `Expander` / `Tag`: `neutral` (the default) plus `brand`, `info`, `success`,
16
- `warning`, and `critical`. Color comes from the theme tokens, so every tone tracks
17
- light and dark mode automatically.
18
-
19
- ```tsx
20
- <Banner tone="neutral" message="Neutral — a plain notice." /> {/* neutral is the default */}
21
- <Banner tone="brand" message="Brand — a product announcement." />
22
- <Banner tone="info" message="Info — a new release is available." />
23
- <Banner tone="success" message="Success — your changes were saved." />
24
- <Banner tone="warning" message="Warning — your trial ends in 3 days." />
25
- <Banner tone="critical" message="Critical — the last deploy failed." />
26
- ```
27
-
28
- `tone` also accepts **any literal CSS color** for a one-off tint — the hue is kept
29
- while lightness and chroma are pinned to the named-tone curve (and re-tuned for
30
- dark mode), the same mechanism as `Expander` / `Tag`:
31
-
32
- ```tsx
33
- <Banner tone="#ff1493" message="…" />
34
- <Banner tone="rebeccapurple" message="…" />
35
- ```
36
-
37
- ## Round
38
-
39
- `round` rounds the corners for a **standalone** banner that floats inside a
40
- container, rather than the edge-to-edge strip. It stays borderless (add
41
- `border-width` for an outline). Bare `round` clamps to a stadium (half the height);
42
- pass a `number` (px) or a CSS length string for a custom radius.
43
-
44
- ```tsx
45
- <Banner round tone="info" message="A rounded, standalone banner." />
46
- <Banner round={12} tone="success" message="A custom 12px radius." />
47
- ```
48
-
49
- ## Align
50
-
51
- `align` places the content row. `start` (the default) aligns it to the inline edge
52
- and reserves space for the dismiss control. `center` centers it in the bar. Wrapped
53
- message text follows the selected alignment.
54
-
55
- ```tsx
56
- <Banner tone="info" message="Start-aligned content." /> {/* start is the default */}
57
- <Banner align="center" tone="info" message="Centered content." />
58
- ```
59
-
60
- The layout follows `direction: rtl`.
3
+ Use Banner for announcements, status changes, and notices that need an action.
4
+ Its full-width surface keeps the message visible without opening a dialog.
5
+ Add supporting content and actions, or let the reader dismiss the notice.
61
6
 
62
7
  ## Message and content
63
8
 
64
- `message` is the leading content: a string at the banner type scale or any node.
65
- `children` sit between the message and actions, for example a chip, link, or
66
- secondary line.
9
+ Pass `message` for the notice and `children` for supporting information such as a
10
+ link, a timestamp, or a tag. Text messages use Banner's type scale. Pass your own
11
+ markup when the message needs a different presentation.
67
12
 
68
13
  ```tsx
69
14
  <Banner tone="info" message="Deployment complete.">
70
- <Text size="small" priority="tertiary">· 2 minutes ago</Text>
15
+ <Text size="small" priority="tertiary">2 minutes ago</Text>
71
16
  </Banner>
72
17
  ```
73
18
 
74
19
  ## Actions
75
20
 
76
- Pass `actions` to render trailing controls — buttons, links — as a compact row
77
- after the message and children. Keep them small; the banner is a single line.
78
- Give each action the banner's `tone` so the controls read as part of the strip.
79
-
80
- ```tsx
81
- <Banner
82
- tone="brand"
83
- message="Upgrade to Pro for unlimited runs."
84
- actions={<Button size="small" priority="secondary" tone="brand" label="Upgrade" />}
85
- />
86
- ```
87
-
88
- Stack several actions by priority in one banner: a `primary` call to action, a
89
- `secondary` alternative, and a low-emphasis `tertiary` choice, all sharing the
90
- banner's tone.
21
+ Use `actions` for controls related to the notice. Multiple actions form a compact
22
+ row after the message and supporting content. Give controls the notice's tone to
23
+ keep their emphasis consistent.
91
24
 
92
25
  ```tsx
93
26
  <Banner
@@ -96,105 +29,73 @@ banner's tone.
96
29
  actions={
97
30
  <>
98
31
  <Button size="small" priority="primary" tone="info" label="Update now" />
99
- <Button size="small" priority="secondary" tone="info" label="Release notes" />
100
- <Button size="small" priority="tertiary" tone="info" label="Later" />
32
+ <Button size="small" priority="tertiary" tone="info" label="Release notes" href="/changelog/" />
101
33
  </>
102
34
  }
103
35
  />
104
36
  ```
105
37
 
106
- ## Dismiss
107
-
108
- A banner is **closable** by default: a full-height ✕ on the right edge dismisses it.
109
- It rests dimmed and brightens when you hover or focus it (the `Input` `dim-actions`
110
- affordance). On dismiss the bar collapses its height and fades out, clipped to the
111
- box (instant under `prefers-reduced-motion`).
38
+ ## Tone
112
39
 
113
- Leave it *uncontrolled* and the banner hides itself when the ✕ is clicked (try it):
40
+ Use `tone` to identify the kind of notice. The surface, text, and dismiss control
41
+ share the tone and follow the surrounding light or dark theme.
114
42
 
115
43
  ```tsx
116
- {/* uncontrolled — the ✕ self-dismisses */}
117
- <Banner tone="success" message="Dismiss me — I'll disappear." />
44
+ <Banner message="A scheduled maintenance window is coming up." />
45
+ <Banner tone="brand" message="Introducing the new workspace." />
46
+ <Banner tone="info" message="A new release is available." />
47
+ <Banner tone="success" message="Your changes were saved." />
48
+ <Banner tone="warning" message="Your trial ends in 3 days." />
49
+ <Banner tone="critical" message="The last deployment failed." />
118
50
  ```
119
51
 
120
- Set `closable={false}` to drop the built-in ✕ — for a permanent banner, or when you
121
- drive dismissal from your own control.
52
+ ## Round
53
+
54
+ Add `round` when the notice sits inside a container. Pass a number or a CSS length
55
+ for a custom radius. Banner is borderless by default; add a border with CSS when
56
+ the notice needs a visible edge.
122
57
 
123
58
  ```tsx
124
- <Banner tone="warning" message="A permanent notice — no dismiss button." closable={false} />
59
+ <Banner round tone="info" message="A standalone notice." />
60
+ <Banner round={12} tone="success" message="A notice with a 12px radius." />
125
61
  ```
126
62
 
127
- ## Dismiss from an action
63
+ ## Align
128
64
 
129
- Give any control inside the banner **`data-banner-dismiss`** and it dismisses the
130
- banner on click, through the same state contract as the ✕ — for an action that
131
- closes the banner as it runs (an "Undo", a "Got it"). Try it:
65
+ Content starts at the inline edge. Pass `align="center"` to center it. Long
66
+ messages wrap, and message text follows the selected alignment. The layout also
67
+ follows `direction: rtl`.
132
68
 
133
69
  ```tsx
134
- <Banner
135
- tone="success"
136
- message="Draft saved."
137
- actions={<Button size="small" priority="secondary" tone="success" label="Undo" onClick={undo} data-banner-dismiss />}
138
- />
70
+ <Banner tone="info" message="Scheduled maintenance starts tonight. Save your work before the workspace becomes temporarily unavailable." />
71
+ <Banner align="center" tone="info" message="Scheduled maintenance starts tonight. Save your work before the workspace becomes temporarily unavailable." />
139
72
  ```
140
73
 
141
- It's matched by presence on the nearest banner, so it works on any activated
142
- control — `Button`, a plain `<a>`, or a `MenuItem` inside a dropdown — and from the
143
- keyboard, since Enter/Space activation is a real click. Put it on the **terminal**
144
- control, not a dropdown *trigger* (which would dismiss the banner as the menu opens):
74
+ ## Dismiss
75
+
76
+ Select **Dismiss** or focus it and press Enter or Space to hide the notice.
77
+ Banner fades and collapses using the browser's supported transitions. Reduced
78
+ motion makes dismissal immediate.
145
79
 
146
80
  ```tsx
147
- <Banner
148
- message="Export ready."
149
- actions={
150
- <Menu trigger={<Button size="small" label="Download" iconTrailing="chevron-down" />}>
151
- <MenuItem label="As CSV" onClick={csv} data-banner-dismiss />
152
- <MenuItem label="As JSON" onClick={json} data-banner-dismiss />
153
- </Menu>
154
- }
155
- />
81
+ <Banner tone="success" message="Your changes were saved. You can dismiss this notice." />
82
+ <Banner tone="warning" message="A notice without a built-in dismiss control." closable={false} />
156
83
  ```
157
84
 
158
- In controlled mode the click *requests* a dismiss like the ✕ does — drive the
159
- result through `dismissed` (below).
85
+ Give an action `data-banner-dismiss` to request dismissal when it runs. Put the
86
+ attribute on the final action, such as **Got it**, rather than on a menu trigger.
87
+ Try **Remind me later** in the Playground.
160
88
 
161
89
  ## Controlled vs uncontrolled
162
90
 
163
- Dismissal follows Anta's shared **state contract**. For uncontrolled use, pass
164
- `defaultDismissed`; clicking ✕ then dismisses the banner. For controlled use,
165
- pass `dismissed` and `onDismiss`. The banner follows `dismissed` and reports a
166
- dismissal request when ✕ is clicked. Update `dismissed` to accept the request,
167
- or leave it unchanged to reject it. The wrapper uses booleans, while the element
168
- uses a `state` string (`closed` means dismissed):
91
+ Use `dismissed` when your application needs to accept or reject a dismissal, save
92
+ it, or show the notice again. Update it in `onDismiss` to accept the request.
93
+ Leave it unchanged to reject. The demonstration counts requests so you can see
94
+ rejection without hiding the notice.
169
95
 
170
- | | `<Banner>` (JSX) | `<a-banner>` (element) |
171
- |---|---|---|
172
- | **Uncontrolled** | `defaultDismissed` | `default-state="open" \| "closed"` |
173
- | **Controlled** | `dismissed` + `onDismiss` | `state="open" \| "closed"` + `statechange` |
174
- | **Change signal** | `onDismiss()`, fired on a dismiss request | `statechange`, a cancelable `CustomEvent<{ next, prev }>` of `'open'` / `'closed'` |
175
-
176
- Controlling it is how you persist a dismissal (write it to storage) or re-show the
177
- banner later. The element never self-applies in controlled mode: set `dismissed` to
178
- `true` to accept the request, or do nothing to reject.
179
-
180
- ```tsx
181
- // controlled — persist the dismissal across reloads
182
- const [hidden, setHidden] = useState(() => localStorage.getItem('release-banner') === 'hidden')
183
- <Banner
184
- tone="info"
185
- message="A new release is available."
186
- dismissed={hidden}
187
- onDismiss={() => {
188
- setHidden(true)
189
- localStorage.setItem('release-banner', 'hidden')
190
- }}
191
- />
192
- ```
193
-
194
- At the element level `statechange` is **cancelable** and fires *before* the banner
195
- applies anything, so a vanilla `<a-banner>` listener can `preventDefault()` a
196
- dismiss. The `<Banner>` wrapper's `onDismiss` is notification-only — drive rejection
197
- through `dismissed` instead.
96
+ Without `dismissed`, Banner owns its visibility. `defaultDismissed` chooses its
97
+ initial visibility. Dismissal hides the rendered notice and retains its children
98
+ in the DOM.
198
99
 
199
100
  ## Component props
200
101
 
@@ -202,63 +103,92 @@ through `dismissed` instead.
202
103
  |------|------|---------|-------------|
203
104
  | `actions?` | ReactNode | — | Trailing controls (buttons, links) rendered as a compact row after the message and `children`. |
204
105
  | `align?` | 'start' \| 'center' | 'start' | Positions the content row. `'start'` aligns it to the inline edge; `'center'` centers it. Wrapped message text follows the selected alignment. |
205
- | `children?` | ReactNode | — | Free content placed BETWEEN the message and the actions. |
206
- | `closable?` | boolean | true | Whether the trailing ✕ dismiss button is present. `false` removes it — drive dismissal yourself (a controlled `dismissed`, or your own control) instead. It removes the built-in ✕ without making the banner un-dismissible. |
106
+ | `children?` | ReactNode | — | Supporting content between the message and actions. |
107
+ | `closable?` | boolean | true | Show the built-in Dismiss control. Set false when the notice is permanent or another action requests dismissal through `data-banner-dismiss`. |
207
108
  | `defaultDismissed?` | boolean | — | Initial dismissed state for the uncontrolled case (read once on mount). |
208
- | `dismissed?` | boolean | — | Controlled dismissed state. When provided, the consumer owns visibility: the banner follows this prop only, and clicking ✕ *requests* dismissal (reject by not updating). **Requires `onDismiss`** — controlled mode never self-hides, so without a handler to set `dismissed` the ✕ can't close the banner. Leave undefined for uncontrolled. |
109
+ | `dismissed?` | boolean | — | Controlled visibility. Set true in `onDismiss` to accept a request, or keep false to reject it. Set false to show the notice again. Dismissal hides the host and retains its children; it does not unmount them. |
209
110
  | `message?` | ReactNode | — | Leading message: a string at the banner type scale or any node. |
210
- | `onDismiss?` | () => void | — | Fired when the user dismisses the banner (clicks ✕). Uncontrolled, the banner hides itself and this notifies. Controlled, use it to accept the request — set `dismissed` to `true` (or ignore to reject); pair it with `dismissed`, or the banner can't be closed. |
211
- | `role?` | string | 'status' | ARIA role for the strip host. `'status'` (a polite live region, so the notice reaches assistive tech) by default; pass `'alert'` for an urgent notice that should interrupt, or a landmark role. |
111
+ | `onDismiss?` | () => void | — | Dismissal request from the close control or a `data-banner-dismiss` action. Controlled Banner stays visible until `dismissed` changes. Uncontrolled Banner applies an uncanceled request itself. |
112
+ | `role?` | string | 'status' | Host role. Use 'status' for polite announcements or 'alert' for urgent ones. |
212
113
  | `round?` | boolean \| number \| string | — | Rounded corners for a standalone, floating banner (`border-radius: 999px`, which clamps to a stadium) instead of the edge-to-edge strip. Still borderless by default. Pass a `number` (px) or a CSS length string for a custom radius. |
213
- | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Semantic tone, or any literal CSS color (`'#ff1493'`, `'rebeccapurple'`) for a one-off custom tone. Named tones re-point the surface, text, and border color (used if you opt into a border); a custom color keeps its hue while lightness/chroma are pinned. `'neutral'` (the default) is the same as omitting it. |
114
+ | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Semantic tone or a CSS color. Colors the surface, text, border, and dismiss control. Custom colors use an inline CSS variable; under a CSP that blocks style attributes, provide that variable through external CSS instead. |
214
115
 
215
116
  ## Web Component
216
117
 
217
- Use the web component directly when you are not using React or Preact and a native control does not fit.
218
-
219
- Slots hold the message, actions, and close control. A close button dispatches
220
- `dismissrequest` through `data-custom-event`.
118
+ Supply the light-DOM regions and the attributes your application needs. Use
119
+ `a-banner-message` for Banner's text scale and boxless `a-banner-content` for
120
+ custom message markup or supporting content. Put actions in one
121
+ `a-banner-actions` region and the close Button in `a-banner-close`.
221
122
 
222
123
  ```html
223
124
  <a-banner role="status" tone="info">
224
- <a-banner-message slot="message">A new version is ready to install.</a-banner-message>
225
- <a-button slot="actions" role="button" tabindex="0" size="small" priority="primary" tone="info">
226
- <a-button-label>Update now</a-button-label>
227
- </a-button>
228
- <a-button slot="close" role="button" tabindex="0" priority="quaternary" tone="info"
229
- aria-label="Dismiss" data-custom-event="dismissrequest"><a-icon shape="x" aria-hidden="true"></a-icon></a-button>
125
+ <a-banner-message>A new release is available.</a-banner-message>
126
+ <a-banner-actions>
127
+ <a-button role="button" tabindex="0" size="small" tone="info" data-banner-dismiss>
128
+ <a-button-label>Got it</a-button-label>
129
+ </a-button>
130
+ </a-banner-actions>
131
+ <a-banner-close>
132
+ <a-button role="button" tabindex="0" priority="quaternary" tone="info"
133
+ aria-label="Dismiss" data-custom-event="dismissrequest">
134
+ <a-icon shape="x" aria-hidden="true"></a-icon>
135
+ </a-button>
136
+ </a-banner-close>
230
137
  </a-banner>
231
138
  ```
232
139
 
140
+ External CSS renders Banner before registration. Browser dismissal needs
141
+ `@antadesign/anta/elements/a-banner` and `@antadesign/anta/elements/a-button`;
142
+ load `@antadesign/anta/elements/a-icon` for the close icon. The full bundle
143
+ includes these entries.
144
+
145
+ `state="open"` or `state="closed"` controls visibility. Without `state`,
146
+ `default-state` seeds visibility once; an omitted default shows the notice.
147
+ `statechange` is a cancelable request with serializable `{ next, prev }` detail.
148
+ Call `preventDefault()` to reject an uncontrolled request. In controlled mode,
149
+ update `state` to accept it or leave it unchanged to reject. Set `state="open"`
150
+ to restore visibility. Nested Banners handle their own dismissal.
151
+
152
+ Omit unused regions. CSS hides an empty actions region. Whitespace counts as
153
+ content, so omit a whitespace-only region or author `hidden`. JSX omits absent
154
+ actions and whitespace-only string actions. Banner never changes your markup.
155
+
156
+ Named tones and boolean `round` need no inline styles. Custom colors and lengths
157
+ use JSX-owned CSS variables. For raw HTML, supply `--banner-tone-source` or
158
+ `--banner-round` through your stylesheet on browsers without typed CSS `attr()`.
159
+ A CSP that blocks style attributes also requires these values in external CSS.
160
+
161
+ Banner now uses explicit regions instead of shadow slots. Group raw actions in
162
+ `a-banner-actions` and replace `::part()` overrides with direct region selectors.
163
+
233
164
  ## Styling
234
165
 
235
- Reach for the props first: **`tone`** sets the color (any CSS color for a custom
236
- tone — it derives the surface, text, and border color in oklch), **`round`** the
237
- corners. The one knob worth keeping is **`--banner-tone-source`** — the color a
238
- custom `tone` derives from, so set it to drive the palette from your own variable.
239
- Everything else is plain CSS on the host: `min-height` for a taller bar, a
240
- `border-*-width` for a rule or outline (below).
166
+ Use `tone` for color and `round` for corners. `--banner-tone-source` connects a
167
+ custom tone to an application color. Customize the surface and regions with
168
+ plain CSS. Unlayered rules override Anta's defaults without `!important`.
241
169
 
242
- ```tsx
243
- <Banner tone="#e0457b" message="Custom" />
170
+ The classes in these examples identify the demonstrations. Substitute your own
171
+ selectors in your application.
172
+
173
+ Connect a custom tone to your application color through external CSS.
174
+
175
+ ```css
176
+ .notice-color { --banner-tone-source: #e0457b; }
244
177
  ```
245
178
 
246
- **Add a border.** The banner is borderless by default, but its border style and
247
- color are preset at `0` width (the `Progress` reset), so you opt in by setting only
248
- the **width** — `border-bottom-width` for a rule under the strip, `border-width` for
249
- a full outline. The color is already tone-aware (`--banner-border`), so a toned
250
- banner's border matches its tone with no extra work.
179
+ Add a rule or an outline by setting its width. Banner supplies the tone-aware
180
+ border color.
251
181
 
252
- ```tsx
253
- <Banner tone="info" message="A rule under the strip." style={{ borderBottomWidth: 1 }} />
254
- <Banner round tone="success" message="A full outline on a round banner." style={{ borderWidth: 1 }} />
182
+ ```css
183
+ .notice-rule { border-bottom-width: 1px; }
184
+ .notice-outline { border-width: 1px; }
255
185
  ```
256
186
 
257
- The host `a-banner` **is** the bar — its surface, text, border, and layout
258
- are all plain CSS on the host (`@layer anta`, so an un-layered rule of yours wins
259
- without `!important`). For the individual regions, `<a-banner>` exposes
260
- `::part(message)` / `::part(content)` / `::part(actions)` / `::part(close)`.
187
+ Change height, message type, or action spacing through the host and its direct
188
+ regions. Direct-child selectors keep nested Banners independent.
261
189
 
262
- ```tsx
263
- <Banner tone="info" message="A taller bar." style={{ minHeight: 56 }} />
190
+ ```css
191
+ .notice-custom { min-height: 56px; }
192
+ .notice-custom > a-banner-message { font-size: 16px; }
193
+ .notice-custom > a-banner-actions { gap: 8px; }
264
194
  ```
@@ -160,14 +160,17 @@ string and set it from `onCopyRequest`. `onCopied` receives the result.
160
160
 
161
161
  ## Web Component
162
162
 
163
- `Breadcrumbs` deliberately adds no custom-element behavior: it assembles Anta
164
- Buttons, an optional Menu, and two light-DOM layout tags. When you are not using
165
- JSX, import the Breadcrumbs stylesheet and the primitives, then compose the same
166
- structure yourself. Keep an overflow Menu immediately after its More Button.
163
+ `Breadcrumbs` assembles Anta Buttons, an optional Menu, and two light-DOM layout
164
+ tags. Load its CSS-only entry and the browser primitives in the UI thread. When
165
+ you are not using JSX, compose the same structure yourself. Keep an overflow Menu
166
+ immediately after its More Button.
167
167
 
168
168
  ```ts
169
- import '@antadesign/anta/components/Breadcrumbs.css'
170
- import '@antadesign/anta/elements'
169
+ import '@antadesign/anta/elements/a-breadcrumbs'
170
+ import '@antadesign/anta/elements/a-button'
171
+ import '@antadesign/anta/elements/a-icon'
172
+ import '@antadesign/anta/elements/a-menu'
173
+ import '@antadesign/anta/elements/a-menu-item'
171
174
  ```
172
175
 
173
176
  ```html
@@ -358,6 +358,25 @@ submit a surrounding form. Use `type="submit"` or `type="reset"` for form action
358
358
  <button type="button" data-anta disabled>Unavailable</button>
359
359
  ```
360
360
 
361
+ ### Copy feedback
362
+
363
+ Put `<a-copy>` directly inside an activatable control. Add `toast` for the
364
+ floating success confirmation and `copied-label` to change its text. The
365
+ confirmation uses a manual shadow popover, escapes clipping ancestors, and lets
366
+ pointer events pass through. Style it with `a-copy::part(feedback)`.
367
+
368
+ ```html
369
+ <button type="button" data-anta>
370
+ Copy command
371
+ <a-copy copy="npm i @antadesign/anta" toast copied-label="Copied"></a-copy>
372
+ </button>
373
+ ```
374
+
375
+ `copyrequest` asks for a controlled `copy` refresh before activation.
376
+ `copydone` reports `{ ok: boolean }` after the clipboard attempt. Both events
377
+ are non-bubbling. Full-bundle imports and the granular `elements/a-copy` entry
378
+ include feedback styling. Under CSP, load their emitted CSS from an allowed URL.
379
+
361
380
  ## Styling
362
381
 
363
382
  Use `tone`, `priority`, `size`, and `round` before adding custom CSS. For a
@@ -375,3 +394,6 @@ a-button.checkout {
375
394
  a-button.checkout:hover { background: #5931c4; }
376
395
  a-button.checkout:active { background: #48269f; }
377
396
  ```
397
+
398
+ Style the copy confirmation with `a-copy::part(feedback)`. If you customize
399
+ `display`, use `a-copy::part(feedback):popover-open` so closed popovers stay hidden.
@@ -14,13 +14,12 @@ rest of Anta.
14
14
  ## Anatomy
15
15
 
16
16
  A card is three stacked sections — `header`, body (`children`), `footer` — plus an
17
- optional full-bleed `media` region. Each is optional and an empty one reserves no
18
- space. Spacing comes from one `--card-padding`: the outer inset and the body→footer
17
+ optional full-bleed `media` region. Each is optional; omit unused regions. Spacing comes from one `--card-padding`: the outer inset and the body→footer
19
18
  gap are a full `--card-padding`, and the header sits a half-step closer to its body
20
19
  (`--card-padding / 2`). A string `header` becomes a `<Title>` and a string body a
21
20
  `<Text>`; pass your own node (`<Title>`, `<Text>`, a layout) to take over. An
22
21
  optional `subtitle` renders under the title as smaller text (`<Text size="small">`). There's
23
- no dedicated actions slot: lay out header controls (a button, a tag) inside the
22
+ no dedicated actions region: lay out header controls (a button, a tag) inside the
24
23
  `header` itself.
25
24
 
26
25
  ```tsx
@@ -105,9 +104,9 @@ match:
105
104
 
106
105
  ## Round
107
106
 
108
- `round` softens the corners. A `number` (px) or CSS length sets a custom radius —
109
- the usual choice for a card (`round="0"` squares them); bare `round` goes fully
110
- round (`999px`, clamped to the box). Omit it for the default (`--card-radius`, 8px).
107
+ Omit `round` to use the theme's corner radius. Pass a `number` (px) or CSS length
108
+ to set a fixed radius; `round={0}` makes the corners square. Bare `round` makes
109
+ the card fully round, clamped to its box.
111
110
 
112
111
  ```tsx
113
112
  <Card round={16} header="Custom radius">…</Card>
@@ -116,7 +115,7 @@ round (`999px`, clamped to the box). Omit it for the default (`--card-radius`, 8
116
115
 
117
116
  ## Header controls
118
117
 
119
- There is no dedicated actions slot. To place a control in the top-right of the
118
+ There is no dedicated actions region. To place a control in the top-right of the
120
119
  header, pass a layout node as `header`. For example, use a flex row containing
121
120
  the title and a "more" button. That layout determines where both items appear.
122
121
 
@@ -168,8 +167,8 @@ and clips to the corners. `mediaPosition` places it on the `top` (the default),
168
167
 
169
168
  Give a card an `href` and the whole thing becomes a link — a single focusable
170
169
  anchor, keyboard-activatable, with the `hover` lift and inset focus ring. The
171
- accessible name comes from the header (falling back to the body, then the URL), so
172
- a screen reader announces one concise link instead of the whole card's text. A
170
+ default accessible name uses a text header or body. Custom nodes use their native
171
+ content name; pass `aria-label` or `aria-labelledby` to choose a shorter name. A
173
172
  link card is display content: keep interactive controls (buttons, nested links)
174
173
  out of it — its text is non-selectable and the whole surface navigates.
175
174
 
@@ -213,7 +212,7 @@ it also blocks navigation until the load resolves.
213
212
  | `children?` | ReactNode | — | The card body. A string is wrapped in a `<Text>` at secondary priority, following the card's `tone` and `size`; pass your own nodes to take over. |
214
213
  | `footer?` | ReactNode | — | Footer content, usually action buttons. Rendered as a **left-aligned** row (wraps under pressure) — the opposite of `Dialog`'s right-aligned footer. |
215
214
  | `header?` | ReactNode | — | Header content, in the top zone. A string is wrapped in a `<Title>` — a real heading in the document outline, tinted to match `tone`, at a level that tracks `size` (small → 5, medium → 4, large → 3). Pass your own node (`<Title level={2}>`, an `<h2>`) for a different level or styling. Omit for no header. |
216
- | `href?` | string | — | Turn the whole card into a link. The card renders a focusable anchor and its accessible name comes from `header` → body → this URL (override with `aria-label`). A link card is display content — don't nest interactive controls inside it. |
215
+ | `href?` | string | — | Turn the whole card into a native link. ARIA props and `tabIndex` apply to that anchor. A text header or body supplies its default name; custom content uses the native content name. Override with `aria-label` or `aria-labelledby`. Linked cards must not contain interactive controls. |
217
216
  | `icon?` | (string & {}) \| string \| number \| bigint \| boolean \| ReactElement \| Iterable \| ReactPortal \| Promise \| null | — | Leading visual for the header, laid out to the left of the `header` / `subtitle` as one aligned row (so it doesn't sit inline in the title, where it mis-aligns). A **string** is an icon shape, rendered as an `<Icon>` inside a circular chip (sized per the card via `--card-icon-size`); pass an `<img>`, initials (`<Text>`), or any node to use it as-is. Omit for none. |
218
217
  | `loading?` | boolean | — | Loading state — dims the card with a skeleton pulse, sets `aria-busy`, and (in link mode) blocks navigation. |
219
218
  | `media?` | ReactNode | — | Media (image, illustration) rendered full-bleed to the card edge, clipped to its corners. Position it with `mediaPosition`. |
@@ -228,22 +227,67 @@ it also blocks navigation until the load resolves.
228
227
  | `target?` | string | — | Anchor target (only with `href`). |
229
228
  | `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | 'neutral' | Semantic tone, or any literal CSS color (`'#ff1493'`, `'rebeccapurple'`) for a one-off custom tone. Named tones re-point the surface + text; a custom color keeps its hue while lightness/chroma are pinned. `'neutral'` (the default) is the same as omitting it. |
230
229
 
231
- ## Web Component
230
+ ## HTML
232
231
 
233
- Use the web component directly when you are not using React or Preact and a native control does not fit.
232
+ Use the same structural tags in raw HTML. Card has no element class or registration
233
+ step. Omit unused regions. For a linked card, put its media and content inside
234
+ a native anchor directly under `a-card`. Raw authors own that anchor's URL, ARIA,
235
+ and loading updates.
234
236
 
235
- Slots hold media, header, and footer content. Unslotted content is the card body.
237
+ ```html
238
+ <a-card>
239
+ <a-card-content>
240
+ <a-card-header>
241
+ <a-card-title>
242
+ <a-title level="5" role="heading" aria-level="5">Release notes</a-title>
243
+ </a-card-title>
244
+ </a-card-header>
245
+ <a-card-body>
246
+ <a-text>Put body content inside a-card-body.</a-text>
247
+ </a-card-body>
248
+ <a-card-footer>
249
+ <a-button role="button" tabindex="0" size="small">
250
+ <a-button-label>Read more</a-button-label>
251
+ </a-button>
252
+ </a-card-footer>
253
+ </a-card-content>
254
+ </a-card>
255
+ ```
256
+
257
+ ## Migrate from shadow parts
258
+
259
+ The JSX props remain available. Card now emits structural tags instead of flat
260
+ slot markup. Raw HTML authors must add those regions explicitly. Replace
261
+ `::part(body)` with a selector for `a-card-body`, and make the same replacement
262
+ for the other regions. Direct child paths keep an outer Card's overrides from
263
+ reaching a nested Card.
264
+
265
+ Navigation attributes belong on a native `<a data-anta-card-link>` directly
266
+ under `a-card`. Its `a-card-layout` child arranges media and content independently
267
+ of generic link display rules. JSX creates this structure automatically. Raw
268
+ link Cards use:
236
269
 
237
270
  ```html
238
271
  <a-card>
239
- <a-title slot="header" level="5" role="heading" aria-level="5">Release notes</a-title>
240
- <a-text>Everything without a slot attribute becomes the body.</a-text>
241
- <a-button slot="footer" role="button" tabindex="0" size="small">
242
- <a-button-label>Read more</a-button-label>
243
- </a-button>
272
+ <a data-anta-card-link href="/guide">
273
+ <a-card-layout>
274
+ <a-card-content>
275
+ <a-card-body>Read the guide</a-card-body>
276
+ </a-card-content>
277
+ </a-card-layout>
278
+ </a>
244
279
  </a-card>
245
280
  ```
246
281
 
282
+ Changing `href` or `loading` on a raw `a-card` no longer updates a link. The JSX
283
+ wrapper renders those updates from props. `aria-*` props and `tabIndex` apply to
284
+ the anchor in link mode and to `a-card` otherwise. A text header or body supplies
285
+ the default link label; custom content uses its native accessible name unless you
286
+ provide `aria-label` or `aria-labelledby`.
287
+
288
+ `ACardElement` and `register_a_card` are removed. The granular element entry loads
289
+ CSS only; bundle usage still pairs JavaScript and CSS for other Anta components.
290
+
247
291
  ## Styling
248
292
 
249
293
  Reach for the props first: **`tone`** sets the color (any CSS color for a custom
@@ -268,12 +312,14 @@ either way:
268
312
  </Card>
269
313
  ```
270
314
 
271
- For everything else, `<a-card>` exposes shadow **parts** —
272
- `::part(container)` (the box / anchor), `::part(media)`, `::part(content)`,
273
- `::part(header)` (the icon + text zone), `::part(icon)`, `::part(title)` (the
274
- title / subtitle text column), `::part(body)`, `::part(footer)` — which you style
275
- directly. Each section carries its own `--card-padding`, so a divider on
276
- `::part(header)` reads as a true section rule.
315
+ Card's layout, focus ring, selected ring, and loading animation use external CSS
316
+ and work with `style-src 'self'`. Custom tones and custom radii can produce inline
317
+ styles in server-rendered JSX and need separate CSP handling.
318
+
319
+ Card renders its complete light-DOM structure immediately. Its regions are
320
+ `a-card-layout` in link mode, `a-card-media`, `a-card-content`, `a-card-header`,
321
+ `a-card-icon`, `a-card-title`, `a-card-body`, and `a-card-footer`. Use child selectors to style
322
+ these tags. Card needs no shadow parts or pre-upgrade layout.
277
323
 
278
324
  Each example keeps its CSS in a `<style>` **inside** its own preview, targeting a
279
325
  demo class on that preview's card — so the rule you read is literally in the
@@ -282,18 +328,18 @@ your own selector.
282
328
 
283
329
  **Scroll a capped body.** The card never scrolls, and the body doesn't by default.
284
330
  When you cap the card's height and want the body to scroll instead of the card
285
- growing, that's one line on `::part(body)`:
331
+ growing, that's one line on `a-card-body`:
286
332
 
287
333
  ```css
288
334
  /* cap the card's height, then let the body scroll */
289
335
  a-card.scrollable { height: 160px; }
290
- a-card.scrollable::part(body) { overflow: auto; }
336
+ a-card.scrollable > a-card-content > a-card-body { overflow: auto; }
291
337
  ```
292
338
 
293
- **Separate the header** with a divider by styling `::part(header)`:
339
+ **Separate the header** with a divider by styling `a-card-header`:
294
340
 
295
341
  ```css
296
- a-card.divided::part(header) {
342
+ a-card.divided > a-card-content > a-card-header {
297
343
  padding-bottom: 8px;
298
344
  border-bottom: 1px solid var(--border-5);
299
345
  }