@antadesign/anta 0.3.23 → 0.3.25

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 (89) hide show
  1. package/dist/bundle.css +1 -1
  2. package/dist/bundle.js +32 -25
  3. package/dist/components/Banner.d.ts +10 -10
  4. package/dist/components/Banner.js +3 -1
  5. package/dist/components/Breadcrumbs.css +1 -0
  6. package/dist/components/Breadcrumbs.d.ts +127 -0
  7. package/dist/components/Breadcrumbs.js +145 -0
  8. package/dist/components/Button.d.ts +14 -7
  9. package/dist/components/Button.js +2 -0
  10. package/dist/components/ButtonCopy.d.ts +2 -2
  11. package/dist/components/Input.d.ts +3 -1
  12. package/dist/components/Input.js +2 -0
  13. package/dist/components/InputDate.css +1 -1
  14. package/dist/components/InputTime.d.ts +3 -1
  15. package/dist/components/InputTime.js +2 -0
  16. package/dist/components/MenuItem.d.ts +5 -1
  17. package/dist/components/MenuItem.js +72 -2
  18. package/dist/components/MenuItemCopy.d.ts +16 -5
  19. package/dist/components/MenuItemCopy.js +9 -3
  20. package/dist/components/Steps.css +1 -1
  21. package/dist/components/copy-props.d.ts +3 -4
  22. package/dist/components/select-parts.css +1 -1
  23. package/dist/elements/a-avatar.css +1 -1
  24. package/dist/elements/a-banner.css +1 -1
  25. package/dist/elements/a-banner.js +12 -0
  26. package/dist/elements/a-button.css +1 -1
  27. package/dist/elements/a-calendar.css +1 -1
  28. package/dist/elements/a-card.css +1 -1
  29. package/dist/elements/a-checkbox.css +1 -1
  30. package/dist/elements/a-copy.css +1 -1
  31. package/dist/elements/a-dialog.css +1 -1
  32. package/dist/elements/a-dialog.js +3 -1
  33. package/dist/elements/a-expander.css +1 -1
  34. package/dist/elements/a-icon.css +1 -1
  35. package/dist/elements/a-icon.shapes.css +1 -1
  36. package/dist/elements/a-icon.shapes.d.ts +2 -2
  37. package/dist/elements/a-icon.shapes.js +2 -2
  38. package/dist/elements/a-input-time.css +1 -1
  39. package/dist/elements/a-input-time.d.ts +2 -0
  40. package/dist/elements/a-input-time.js +7 -0
  41. package/dist/elements/a-input.css +1 -1
  42. package/dist/elements/a-input.d.ts +4 -0
  43. package/dist/elements/a-input.js +17 -0
  44. package/dist/elements/a-loader.css +1 -1
  45. package/dist/elements/a-menu-group.css +1 -1
  46. package/dist/elements/a-menu-item.css +1 -1
  47. package/dist/elements/a-menu-separator.css +1 -1
  48. package/dist/elements/a-menu.css +1 -1
  49. package/dist/elements/a-menu.d.ts +4 -4
  50. package/dist/elements/a-menu.js +6 -4
  51. package/dist/elements/a-progress.css +1 -1
  52. package/dist/elements/a-radio-group.css +1 -1
  53. package/dist/elements/a-radio.css +1 -1
  54. package/dist/elements/a-slider.css +1 -1
  55. package/dist/elements/a-switch.css +1 -1
  56. package/dist/elements/a-tab.css +1 -1
  57. package/dist/elements/a-tabpanel.css +1 -1
  58. package/dist/elements/a-tabs.css +1 -1
  59. package/dist/elements/a-tag.css +1 -1
  60. package/dist/elements/a-text.css +1 -1
  61. package/dist/elements/a-title.css +1 -1
  62. package/dist/elements/a-toast.css +1 -1
  63. package/dist/elements/a-toaster.css +1 -1
  64. package/dist/elements/a-tooltip.css +1 -1
  65. package/dist/elements/copy-behavior.d.ts +13 -15
  66. package/dist/general_types.d.ts +12 -4
  67. package/dist/generate-icons.mjs +3 -3
  68. package/dist/index.d.ts +3 -1
  69. package/dist/index.js +2 -0
  70. package/dist/jsx-runtime.d.ts +2 -0
  71. package/dist/reset.css +1 -1
  72. package/dist/search-index.json +0 -0
  73. package/dist/theme-anta.css +1 -1
  74. package/dist/tokens.css +1 -1
  75. package/docs/changelog.md +43 -2
  76. package/docs/comparison.md +8 -3
  77. package/docs/components/banner.md +26 -15
  78. package/docs/components/breadcrumbs.md +177 -0
  79. package/docs/components/button.md +30 -16
  80. package/docs/components/dialog.md +4 -4
  81. package/docs/components/input-time.md +1 -0
  82. package/docs/components/input.md +6 -0
  83. package/docs/components/menu.md +18 -10
  84. package/docs/components/tag.md +47 -0
  85. package/docs/index.md +1 -0
  86. package/docs/install-config.md +58 -13
  87. package/docs/normalization.md +37 -28
  88. package/docs/theming.md +4 -1
  89. package/package.json +2 -2
@@ -0,0 +1,177 @@
1
+ # Breadcrumbs
2
+
3
+ Hierarchy navigation assembled from Anta Buttons. Breadcrumb entries can be
4
+ links, actions, or copy controls. Set `maxItems` to fold one middle range into a
5
+ More menu without measuring the available width.
6
+
7
+ ## Items
8
+
9
+ Pass ordered data through `items`. An `href` renders a native link with the
10
+ Button appearance; omit it for an action button. Each item accepts `label`,
11
+ `icon`, `iconTrailing`, `tone`, `disabled`, `onClick`, `className`, `style`,
12
+ `id`, `title`, and `data-*` / `aria-*` attributes. `size`, priority, and
13
+ underline treatment belong to the whole trail so every visible control retains
14
+ the same height.
15
+
16
+ ```tsx
17
+ <Breadcrumbs
18
+ aria-label="Project location"
19
+ items={[
20
+ { label: 'Home', href: '/', icon: 'home' },
21
+ { label: 'Projects', href: '/projects', icon: 'folder-open', tone: 'brand' },
22
+ { label: 'Refresh', icon: 'refresh', onClick: reload },
23
+ ]}
24
+ />
25
+ ```
26
+
27
+ An item with `current` receives `aria-current="page"`. The current item may
28
+ remain a link when revisiting the page is useful, or it can be an action such as
29
+ copying the current path.
30
+
31
+ ## Priority, size, underline, and padding
32
+
33
+ Breadcrumbs use either `tertiary` or `quaternary` Button priority. `size` drives
34
+ every visible crumb and the More control: small is 24px, medium is 28px, and
35
+ large is 32px. `underline` and `underlineOnHover` forward to each visible Button.
36
+ With `priority="quaternary"` (the default), `paddingless` removes their horizontal
37
+ padding without changing their height, and uses a `0.75ch` gap around separators.
38
+
39
+ ```tsx
40
+ <Breadcrumbs priority="tertiary" size="small" items={items} />
41
+ <Breadcrumbs priority="quaternary" underline="solid" underlineOnHover items={items} />
42
+ <Breadcrumbs paddingless items={items} />
43
+ <Breadcrumbs priority="tertiary" size="large" items={items} />
44
+ ```
45
+
46
+ The default is medium quaternary. `tertiary` adds a hover fill. `quaternary`
47
+ keeps the trail text-only, which suits dense page headers. An underline is
48
+ permanent unless `underlineOnHover` is set. `paddingless` is only available with
49
+ quaternary priority.
50
+
51
+ ## Separators
52
+
53
+ Pass any of `→`, `/`, `•`, or `▸` for a text separator. Pass an
54
+ Anta icon shape for an icon separator. Separators are decorative and hidden from
55
+ assistive technology.
56
+
57
+ ```tsx
58
+ <Breadcrumbs separator="→" items={items} />
59
+ <Breadcrumbs separator="/" items={items} />
60
+ <Breadcrumbs separator="•" items={items} />
61
+ <Breadcrumbs separator="▸" items={items} />
62
+ <Breadcrumbs separator="chevron-right" items={items} />
63
+ ```
64
+
65
+ `chevron-right` is the default. The icon form accepts any registered `IconShape`,
66
+ including icons added by an application through Anta's icon generator. Icon
67
+ separators use no flex gap; text separators keep the configured gap.
68
+
69
+ ## Folding into More
70
+
71
+ `maxItems` limits the number of original breadcrumb entries that remain visible;
72
+ the More control does not count. When folding, `itemsBeforeCollapse` controls
73
+ where More appears. Its default is `0`, so More comes first and the most recent
74
+ items remain visible. The final original item is always kept visible.
75
+
76
+ ```tsx
77
+ // More / Projects / Anta / Button.tsx
78
+ <Breadcrumbs maxItems={3} items={items} />
79
+
80
+ // Home / Workspace / More / src / Button.tsx
81
+ <Breadcrumbs maxItems={4} itemsBeforeCollapse={2} items={items} />
82
+ ```
83
+
84
+ The More trigger is an icon-only Button followed by an Anta `Menu`; it supports
85
+ pointer, keyboard, and outside-dismiss interaction through the existing menu
86
+ primitive. Folded links retain their native link behavior, while folded actions
87
+ become menu selections.
88
+
89
+ ## Copying the current item
90
+
91
+ An item with `copy`, `copyNode`, or `copyUrl` uses `ButtonCopy` while visible and
92
+ `MenuItemCopy` if it is folded. Copy entries cannot combine with `href`. Mark a
93
+ copying final item `current` when it represents the current page.
94
+
95
+ ```tsx
96
+ <Breadcrumbs
97
+ items={[
98
+ { label: 'Home', href: '/' },
99
+ {
100
+ label: 'Button.tsx',
101
+ current: true,
102
+ copy: 'src/components/Button.tsx',
103
+ iconPlacement: 'trailing',
104
+ copiedLabel: 'Path copied',
105
+ },
106
+ ]}
107
+ />
108
+ ```
109
+
110
+ Use `copyUrl` to copy `location.href`, `copyNode` to copy a marked rendered
111
+ region, or `copy` for a known string. For dynamic text, pass a controlled `copy`
112
+ string and set it from `onCopyRequest`. `onCopied` receives the result.
113
+
114
+ ### Props
115
+
116
+ | Prop | Type | Default | Description |
117
+ |------|------|---------|-------------|
118
+ | `items` | BreadcrumbItem[] | — | Ordered breadcrumb entries. |
119
+ | `itemsBeforeCollapse?` | number | 0 | Number of original items kept before the More control when `maxItems`
120
+ collapses the trail. The rest of the visible-item budget is kept from the
121
+ end, so `0` puts More first. |
122
+ | `maxItems?` | number | — | Maximum number of original breadcrumb items left visible. The More
123
+ control does not count. Omit to keep every item visible. |
124
+ | `moreLabel?` | string | 'Show more breadcrumbs' | Accessible name for the More control. |
125
+ | `paddingless?` | boolean | — | Remove horizontal padding from every visible breadcrumb control. |
126
+ | `priority?` | 'quaternary' \| 'tertiary' | quaternary | Button priority applied to every visible item and the More control. |
127
+ | `separator?` | BreadcrumbSeparator | 'chevron-right' | Separator between visible entries. |
128
+ | `size?` | 'small' \| 'medium' \| 'large' | 'medium' | Button size applied to every visible item and the More control. |
129
+ | `underline?` | 'solid' \| 'dashed' \| 'dotted' | — | Underline style applied to every visible breadcrumb control. |
130
+ | `underlineOnHover?` | boolean | — | Hide the underline at rest and reveal it on hover. |
131
+
132
+ `Breadcrumbs` deliberately adds no custom-element behavior: it assembles Anta
133
+ Buttons, an optional Menu, and two light-DOM layout tags. When you are not using
134
+ JSX, import the Breadcrumbs stylesheet and the primitives, then compose the same
135
+ structure yourself. Keep an overflow Menu immediately after its More Button.
136
+
137
+ ```ts
138
+ import '@antadesign/anta/components/Breadcrumbs.css'
139
+ import '@antadesign/anta/elements'
140
+ ```
141
+
142
+ ```html
143
+ <a-breadcrumbs role="navigation" aria-label="Project location" data-paddingless>
144
+ <a href="/" data-anta role="button" priority="quaternary" paddingless>
145
+ <a-button-label>Home</a-button-label>
146
+ </a>
147
+ <a-breadcrumb-separator aria-hidden="true">•</a-breadcrumb-separator>
148
+
149
+ <a-button role="button" tabindex="0" priority="quaternary" paddingless
150
+ aria-label="Show more breadcrumbs" aria-haspopup="menu">
151
+ <a-icon shape="more" aria-hidden="true"></a-icon>
152
+ </a-button>
153
+ <a-menu autowidth>
154
+ <a href="/workspace" data-anta-menu-item role="menuitem"><a-menu-item-label>Workspace</a-menu-item-label></a>
155
+ <a href="/workspace/projects" data-anta-menu-item role="menuitem"><a-menu-item-label>Projects</a-menu-item-label></a>
156
+ </a-menu>
157
+
158
+ <a-breadcrumb-separator aria-hidden="true">•</a-breadcrumb-separator>
159
+ <a href="/workspace/projects/anta" data-anta role="button" priority="quaternary"
160
+ paddingless aria-current="page"><a-button-label>Anta</a-button-label></a>
161
+ </a-breadcrumbs>
162
+ ```
163
+
164
+ Use `priority`, `size`, and `separator` before adding CSS. A `className` on
165
+ `Breadcrumbs` lands on the navigation wrapper; item `className` values land on
166
+ their individual Buttons. The composed structure uses light-DOM tags, so plain
167
+ CSS can style a separator directly.
168
+
169
+ ```tsx
170
+ <Breadcrumbs className="project-breadcrumbs" separator="chevron-right" items={items} />
171
+ ```
172
+
173
+ ```css
174
+ .project-breadcrumbs a-breadcrumb-separator {
175
+ color: var(--text-2);
176
+ }
177
+ ```
@@ -190,11 +190,13 @@ dropped (a valid `0` still renders).
190
190
  <Button tone="brand" priority="tertiary" underline="solid" label="Solid" />
191
191
  <Button tone="brand" priority="tertiary" underline="dashed" label="Dashed" />
192
192
  <Button tone="brand" priority="tertiary" underline="dotted" label="Dotted" />
193
+ <Button tone="brand" priority="quaternary" underline="solid" underlineOnHover label="Hover only" />
193
194
  ```
194
195
 
195
196
  When the button has a [link mode](#link-mode), or you simply want an
196
197
  underline stylistically, it supports three styles — `solid`, `dashed`,
197
- `dotted` (only valid on `priority="tertiary"` / `"quaternary"`).
198
+ `dotted` (only valid on `priority="tertiary"` / `"quaternary"`). Set
199
+ `underlineOnHover` to keep that underline hidden until pointer hover.
198
200
 
199
201
  ## States
200
202
 
@@ -286,11 +288,11 @@ carries a link back to where it came from.
286
288
  <ButtonCopy copy={snippet} copyWithUrl label="Copy snippet" /> {/* snippet + source URL */}
287
289
  ```
288
290
 
289
- ### Lazy content
291
+ ### Copy dynamic text
290
292
 
291
- When the content is expensive to compute or changes over time, keep `copy`
292
- reactive and refresh it in **`onCopyRequest`**, which fires on **pointerdown** —
293
- the click that follows copies the latest value.
293
+ `copy` is a controlled string. Start it at `''`, then set the new text in
294
+ `onCopyRequest`. The next render updates `copy`, and activation writes that value.
295
+ `onCopyRequest` does not return text. It does not add a polling loop.
294
296
 
295
297
  ```tsx
296
298
  const [report, setReport] = useState('')
@@ -298,16 +300,28 @@ const [report, setReport] = useState('')
298
300
  <ButtonCopy
299
301
  copy={report}
300
302
  label="Copy report"
301
- onCopyRequest={() => setReport(generateReport())} // recomputed on pointerdown
303
+ onCopyRequest={() => setReport(generateReport())}
302
304
  />
303
305
  ```
304
306
 
305
- The value is recomputed on pointerdown and read on the click a moment later, so
306
- the pointerdown→click gap absorbs the work — including an update that arrives from
307
- another thread. Only the serializable `copy` string crosses, through the normal
308
- re-render, so this holds in off-UI-thread runtimes (a worker-rendered app) where a
309
- callback couldn't. The clipboard API's user-gesture requirement is preserved
310
- because the write happens on the click.
307
+ `onCopyRequest` fires on pointerdown or Enter/Space keydown, before the click or
308
+ menu selection that writes to the clipboard.
309
+
310
+ #### Why `copy` is controlled
311
+
312
+ In a usual React or Preact app, an `onClick` handler can calculate a string and
313
+ call the Clipboard API itself. `ButtonCopy` also supports applications rendered
314
+ from a worker. The DOM copy control and Clipboard API are on the browser UI
315
+ thread, but the application's JSX code can be elsewhere. A function cannot cross
316
+ that boundary as a callable reference.
317
+
318
+ The request tells the application to calculate the text. Its state update makes
319
+ the renderer send the string as the `copy` attribute. The control then writes that
320
+ attribute during activation, when the browser permits clipboard access. A
321
+ `lazyCopy: () => string` prop could only hide this same state update inside the
322
+ wrapper. A generic return value would also need a defined clipboard format and
323
+ serialization; Anta supports text (`copy`), a DOM region (`copyNode`), and the
324
+ current URL (`copyUrl`).
311
325
 
312
326
  ### Props
313
327
 
@@ -340,10 +354,9 @@ because the write happens on the click.
340
354
  activation, and removes the button from the tab order while active. |
341
355
  | `onClick?` | (e) => void | — | Click handler. |
342
356
  | `onCopied?` | (ok) => void | — | Fires after the copy attempt with whether it succeeded. |
343
- | `onCopyRequest?` | () => void | — | Compute the copy content lazily. Fires on pointerdown / keydown; update
344
- `copy` (a state change) here and the activation copies the latest value.
345
- The gap lets the update land even off the UI thread — only the
346
- serializable `copy` string crosses. |
357
+ | `onCopyRequest?` | () => void | — | Refresh a dynamic `copy` value before activation. Set the new string in
358
+ application state so the next render updates `copy`. Return values are
359
+ ignored. Fires on pointerdown and Enter/Space keydown. |
347
360
  | `paddingless?` | boolean | — | Drops outer padding to zero. |
348
361
  | `ping?` | string | — | Space-separated URLs the browser pings on navigation. |
349
362
  | `priority?` | 'primary' \| 'secondary' \| 'tertiary' \| 'quaternary' | secondary | Visual emphasis. |
@@ -369,6 +382,7 @@ because the write happens on the click.
369
382
  brand curve so any input stays legible. |
370
383
  | `type?` | 'button' \| 'submit' \| 'reset' | — | Form submission type. |
371
384
  | `underline?` | 'solid' \| 'dashed' \| 'dotted' | — | Underline style. |
385
+ | `underlineOnHover?` | boolean | — | Hide the underline at rest and reveal it on hover. |
372
386
 
373
387
  ## Link mode
374
388
 
@@ -193,13 +193,13 @@ destructive button, and it works the same with or without a close button or
193
193
  focusable content. A screen reader announces the dialog by its `header` text
194
194
  (mirrored to the dialog's accessible name), and the ✕ is the last tab stop.
195
195
 
196
- To focus a specific control on open instead (a search field, say), put
197
- `autofocus` on it; the dialog honors that and skips the default. On close, focus
198
- returns to whatever opened the dialog, from the native `<dialog>`.
196
+ To focus a specific control on open instead (a search field, say), pass
197
+ `autoFocus`; the dialog focuses it before returning from the opening interaction.
198
+ On close, focus returns to whatever opened the dialog, from the native `<dialog>`.
199
199
 
200
200
  ```tsx
201
201
  <Dialog header="Rename" footer={…}>
202
- <Input label="Name" autofocus /> {/* focus the field on open */}
202
+ <Input label="Name" autoFocus />
203
203
  </Dialog>
204
204
  ```
205
205
 
@@ -68,6 +68,7 @@ range is clamped to the nearest bound as you step or leave the field, and flags
68
68
 
69
69
  | Prop | Type | Default | Description |
70
70
  |------|------|---------|-------------|
71
+ | `autoFocus?` | boolean | — | Focus this field when its containing `Dialog` opens. |
71
72
  | `children?` | ReactNode | — | Extra content rendered under the field, above the hint (a no-box child like
72
73
  a `<Tooltip>` takes no space and anchors to the field). |
73
74
  | `clearable?` | boolean | — | Show a clear button once the field has a value. |
@@ -431,6 +431,7 @@ wraps to fewer columns as it narrows. Resize the preview to see it reflow.
431
431
  | `autoComplete?` | 'off' \| 'on' \| 'name' \| 'username' \| 'email' \| 'current-password' \| 'new-password' \| 'one-time-code' \| 'tel' \| 'url' \| (string & {}) | — | Native autocomplete token. Overrides the value derived from `type`
432
432
  (`email` / `tel` / `url`) — set it for the cases `type` can't express, e.g.
433
433
  `username`, `current-password`, `new-password`, `one-time-code`, or `off`. |
434
+ | `autoFocus?` | boolean | — | Focus this field when its containing `Dialog` opens. |
434
435
  | `children?` | ReactNode | — | Extra content rendered directly under the field, above the hint/error (it
435
436
  pushes the message down). A no-box child like an Anta `<Tooltip>` takes no
436
437
  space and anchors to the field — consistent with how tooltips attach
@@ -544,6 +545,10 @@ file name, with an Anta-styled chooser button. `submit` and `reset` inputs use t
544
545
  matching Anta button chrome; set `priority="primary"` on a submit control when it
545
546
  is the form's main action.
546
547
 
548
+ `<textarea data-anta>` uses the same field chrome. Set `rows` for its height; one
549
+ field-height is the minimum, and it resizes vertically. Native textareas do not
550
+ autogrow; use Input's [`multiline`](#multiline) instead.
551
+
547
552
  Use `data-anta-size="small"` or `"large"` for field sizing. Native inputs own
548
553
  their `size` attribute, so Anta does not reuse it. `round` and a custom-color
549
554
  `tone` work the same way as Input.
@@ -556,6 +561,7 @@ their `size` attribute, so Anta does not reuse it. `round` and a custom-color
556
561
  <input data-anta round type="url" name="site" placeholder="Rounded URL">
557
562
  <input data-anta type="password" name="password" value="password">
558
563
  <input data-anta tone="rebeccapurple" type="number" name="seats" value="3" min="1">
564
+ <textarea data-anta rows="3" name="notes" placeholder="Notes"></textarea>
559
565
  <input data-anta type="file" name="attachment" accept=".pdf,.docx">
560
566
 
561
567
  <input data-anta type="submit" value="Submit" priority="primary">
@@ -366,11 +366,12 @@ chevron stay centered on the row, so it composes with a trailing counter.
366
366
  </Menu>
367
367
  ```
368
368
 
369
- `MenuItemCopy` is a row that copies to the clipboard when chosen — `copy` for a
370
- literal string, `copyNode` for a DOM region. It composes a `<MenuItem>` with a
371
- slotted `<a-copy>` element that performs the write, and keeps the menu open on
372
- select so the check / retone feedback shows. `onCopied(ok)` fires after each
373
- attempt.
369
+ `MenuItemCopy` is a row that copies to the clipboard when chosen: `copy` for a
370
+ string, `copyNode` for a DOM region, or `copyUrl` for the current URL. It composes
371
+ a `<MenuItem>` with a slotted `<a-copy>` element that performs the write, and
372
+ keeps the menu open on select so the check / retone feedback shows. `onCopied(ok)`
373
+ fires after each attempt. `iconPlacement="trailing"` moves the feedback glyph to
374
+ the end of the row; `"none"` shows a cursor-near confirmation instead.
374
375
 
375
376
  Copy sits alongside normal items, so a "Share" menu can mix a copy-link row with
376
377
  navigating links.
@@ -391,6 +392,7 @@ navigating links.
391
392
  |------|------|---------|-------------|
392
393
  | `children?` | ReactNode | — | Item content. With `label` set, children are extra content — most
393
394
  notably the nested `<Menu>` for a submenu parent. |
395
+ | `copiedLabel?` | string | Copied | Text in the successful no-icon confirmation. |
394
396
  | `copy?` | string | — | Text copied to the clipboard on activation. |
395
397
  | `copyNode?` | boolean \| string | — | Copy a DOM node as rich text (`text/html`) + plain text. `true` copies
396
398
  the nearest ancestor marked `data-copy-source`; a string is a CSS
@@ -404,6 +406,9 @@ navigating links.
404
406
  option `hint`. Requires `label` (it stacks in a column beneath it). Muted
405
407
  (`--text-3`) and tracks the row's `tone`. A string, or any node. |
406
408
  | `icon?` | IconShape | — | Leading icon shape. |
409
+ | `iconPlacement?` | 'leading' \| 'trailing' \| 'none' | 'leading' | Where the copy glyph sits relative to the label — or `'none'` to omit it.
410
+ Without a glyph, a successful copy shows a confirmation label near the
411
+ pointer and leaves the row unchanged. |
407
412
  | `iconTrailing?` | IconShape | — | A trailing icon. On a `submenu` item this **overrides** the default
408
413
  chevron (omit it to keep the chevron); on a normal item it's the trailing
409
414
  glyph (omit for none). |
@@ -416,15 +421,18 @@ navigating links.
416
421
  carries `role` + `aria-checked`; only the drawn mark changes. Suppresses the
417
422
  built-in checkbox / radio and the trailing `check` glyph. The node is made
418
423
  passive (aria-hidden, no pointer events) so the row receives the click. |
419
- | `kbd?` | string | — | A trailing keyboard-shortcut hint, e.g. `"⌘E"`. |
424
+ | `kbd?` | string | — | Trailing shortcut hint, e.g. `"⌘E"`. Anta translates it to
425
+ `aria-keyshortcuts` and hides the visual glyphs from assistive technology.
426
+ Use `+` within a chord and spaces between shortcuts (`"⌘K ⌘S"` becomes
427
+ `"Meta+K Meta+S"`). Pass `aria-keyshortcuts` to override the translation.
428
+ This does not bind the shortcut. |
420
429
  | `label?` | ReactNode | — | The item's text. Usually a string, but any node is accepted — e.g. a filtered
421
430
  `Select` bolds the matched substring. Omit and pass `children` for richer
422
431
  content. |
423
432
  | `onCopied?` | (ok) => void | — | Fires after the copy attempt with whether it succeeded. |
424
- | `onCopyRequest?` | () => void | — | Compute the copy content lazily. Fires on pointerdown / keydown; update
425
- `copy` (a state change) here and the activation copies the latest value.
426
- The gap lets the update land even off the UI thread — only the
427
- serializable `copy` string crosses. |
433
+ | `onCopyRequest?` | () => void | — | Refresh a dynamic `copy` value before activation. Set the new string in
434
+ application state so the next render updates `copy`. Return values are
435
+ ignored. Fires on pointerdown and Enter/Space keydown. |
428
436
  | `onMouseDown?` | (event) => void | — | Raw `mousedown` on the row. Mainly to `preventDefault()` so the row doesn't
429
437
  take focus on a mouse press — e.g. a combobox option keeping focus in its
430
438
  input field while the click still selects. |
@@ -183,3 +183,50 @@ a-tag.badge a-tag-label { font-weight: 600; letter-spacing: 0.15ch; }
183
183
 
184
184
  For a *solid* recolor, prefer `tone` / `priority` — don't reach for the resolved
185
185
  `--tag-bg` / `--tag-border` / `--tag-text` (they're recomputed per priority and tone).
186
+
187
+ ### Interactive tags
188
+
189
+ `Tag` is presentational. Wrap it in an anchor for navigation or a native button
190
+ for an action. The outer control receives focus and keyboard activation.
191
+
192
+ ```tsx
193
+ <a className="tag-link" href="/builds/42">
194
+ <Tag tone="info" icon="external-link" label="Build" value="#42" />
195
+ </a>
196
+ ```
197
+
198
+ ```css
199
+ a.tag-link {
200
+ display: inline-flex;
201
+ text-decoration: none;
202
+ cursor: pointer;
203
+ }
204
+ ```
205
+
206
+ A removable tag has one interactive child: its remove `Button`. Keep the label
207
+ as tag content, give the button an accessible name, and let the segment divider
208
+ separate it. Remove the tag's block padding so the small button keeps its target
209
+ size. The negative focus offset keeps its focus ring inside the tag's clipped edge.
210
+
211
+ ```tsx
212
+ <Tag className="removable-tag" tone="info">
213
+ <span>Frontend</span>
214
+ <Button priority="quaternary" size="small" icon="x" aria-label="Remove Frontend" />
215
+ </Tag>
216
+ ```
217
+
218
+ ```css
219
+ a-tag.removable-tag {
220
+ padding-block: 0;
221
+ }
222
+ a-tag.removable-tag > a-button {
223
+ align-self: stretch;
224
+ }
225
+ a-tag.removable-tag > a-button:focus-visible {
226
+ outline-offset: -2px;
227
+ }
228
+ ```
229
+
230
+ When a tag both opens something and removes it, render two sibling controls in a
231
+ compound layout. Do not place a remove button inside an anchor or button that
232
+ wraps the tag.
package/docs/index.md CHANGED
@@ -25,6 +25,7 @@ Anta is designed for a clean DOM. Prefer the props and attributes exposed by eac
25
25
  - [Progress](./components/progress.md)
26
26
 
27
27
  - [Button](./components/button.md)
28
+ - [Breadcrumbs](./components/breadcrumbs.md)
28
29
  - [Checkbox](./components/checkbox.md)
29
30
  - [Radio](./components/radio.md)
30
31
  - [Switch](./components/switch.md)
@@ -44,7 +44,7 @@ recommended; the reference theme is optional.
44
44
  | Import | Provides | Skip if… |
45
45
  |---|---|---|
46
46
  | `@antadesign/anta/tokens.css` | Six seed tokens, derived role scales (`--bg-1…5`, `--text-1…5`, `--border-1…5`), `.dark`, the 15px root size, and layer order. Override a seed to reskin its tone. | You provide those variables. |
47
- | `@antadesign/anta/reset.css` | A small reset plus Anta's focus, heading, list, and link typography in `@layer anta`. | You use another reset and typography. |
47
+ | `@antadesign/anta/reset.css` | A small reset plus Anta's focus, heading, list, and link typography in `@layer anta.reset`. | You use another reset and typography. |
48
48
  | `@antadesign/anta/elements` | Registers every `<a-*>` element and its CSS. Per-element entries register one; see [Registering elements](#registering-elements). | You render only on the server or register elements individually. |
49
49
  | `@antadesign/anta` | Typed React/Preact wrappers such as `Progress`, `Text`, and `Icon`. | You write `<a-*>` elements directly. |
50
50
  | `@antadesign/anta/bundle.css` | One minified stylesheet containing tokens, reset, element, and JSX-wrapper styles. | You want granular CSS imports. |
@@ -60,9 +60,16 @@ seed-derived default palette or provide your own theme.
60
60
 
61
61
  ### Cascade layers
62
62
 
63
- Anta's reset and element CSS live in `@layer anta`. `tokens.css` declares
64
- `@layer base, anta, components, utilities`, placing Anta above preflight resets
65
- and below your component and utility layers.
63
+ Anta's reset and element CSS use child layers inside `@layer anta`. `tokens.css`
64
+ orders them above preflight resets and below your component and utility layers:
65
+
66
+ ```css
67
+ @layer base, anta, components, utilities;
68
+ @layer anta.reset, anta.components, anta.theme;
69
+ ```
70
+
71
+ `anta.theme` lets the optional reference palette replace component formulas. The
72
+ outer `anta` layer keeps its public cascade position.
66
73
 
67
74
  To change that order, declare it in CSS loaded **before** `tokens.css`. The
68
75
  first declaration fixes a layer's position:
@@ -84,7 +91,7 @@ Token custom properties stay unlayered so they apply everywhere.
84
91
  > Unlayered styles beat layered ones regardless of specificity. This reset
85
92
  > overrides Anta's element defaults. Delete the duplicate, or put your reset in
86
93
  > `@layer base { … }`; `reset.css` already applies the same universal reset in
87
- > `@layer anta`.
94
+ > `@layer anta.reset`.
88
95
 
89
96
  ## Registering elements
90
97
 
@@ -213,25 +220,39 @@ specifier with a bundler or import map.
213
220
 
214
221
  ## Dark mode
215
222
 
216
- Add the `dark` class to any ancestor element:
223
+ For a page-wide dark mode, add `dark` to `html`. The `body` `--bg-2` background
224
+ then paints the browser canvas, and the root controls scrollbar colors:
217
225
 
218
226
  ```html
219
- <div class="dark">
220
- <Progress value={50} />
221
- </div>
227
+ <html class="dark">
228
+ <body>
229
+ <Progress value={50} />
230
+ </body>
231
+ </html>
222
232
  ```
223
233
 
234
+ Use `dark` or `light` on another ancestor to scope its color scheme and palette.
235
+
224
236
  ## Fonts
225
237
 
226
- Anta is designed for a customized TT Interphases Pro, but ships no font binaries. Components use `--sans-serif` and `--monospace` with system fallbacks. `tokens.css` sets a 15px root size (`1rem = 15px`).
238
+ Anta is designed for a customized TT Interphases Pro, but ships no font binaries. Components use `--sans-serif` and `--monospace` with system fallbacks. `tokens.css` sets `1rem` to 15px.
227
239
 
228
- To use your own fonts, register `@font-face` declarations and override the variables:
240
+ Register application-owned fonts, then override the font variables. This example
241
+ uses separate Roman and Italic variable files:
229
242
 
230
243
  ```css
231
244
  @font-face {
232
245
  font-family: "App Sans";
233
- src: url("/path/to/your/sans.woff2") format("woff2");
234
- /* ... */
246
+ src: url("/fonts/app-sans-roman.woff2") format("woff2");
247
+ font-style: normal;
248
+ font-weight: 100 900;
249
+ }
250
+
251
+ @font-face {
252
+ font-family: "App Sans";
253
+ src: url("/fonts/app-sans-italic.woff2") format("woff2");
254
+ font-style: italic;
255
+ font-weight: 100 900;
235
256
  }
236
257
 
237
258
  :root {
@@ -240,6 +261,30 @@ To use your own fonts, register `@font-face` declarations and override the varia
240
261
  }
241
262
  ```
242
263
 
264
+ Anta's semantic italics (`em`, `i`, `var`, and `dt`) select the Italic face.
265
+
266
+ ### Variable slant
267
+
268
+ A variable font with a standard `slnt` axis can provide both instances. Expose it
269
+ through `font-style: oblique` instead of setting `slnt` on italic elements:
270
+
271
+ ```css
272
+ @font-face {
273
+ font-family: "App Variable";
274
+ src: url("/fonts/app-variable.woff2") format("woff2");
275
+ font-style: oblique 0deg 12deg;
276
+ font-weight: 100 900;
277
+ font-stretch: 75% 100%;
278
+ }
279
+
280
+ :root {
281
+ --sans-serif: "App Variable", sans-serif;
282
+ }
283
+ ```
284
+
285
+ The browser selects `0deg` for normal text and `11deg` for semantic italics. Use
286
+ the range your font declares to avoid combining `slnt` with a synthetic oblique.
287
+
243
288
  ## Browser support
244
289
 
245
290
  Anta targets evergreen browsers and ships **no baseline polyfills**. Its floor is [custom-element states](https://developer.mozilla.org/en-US/docs/Web/API/CustomStateSet), used throughout the components for their internal CSS state, alongside the [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API):