@antadesign/anta 0.3.25 → 0.3.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -28
- package/dist/anta_helpers.d.ts +4 -0
- package/dist/anta_helpers.js +17 -3
- package/dist/box-types.d.ts +161 -0
- package/dist/box-types.js +0 -0
- package/dist/bundle.css +1 -1
- package/dist/bundle.js +25 -25
- package/dist/capture-types.d.ts +156 -0
- package/dist/capture-types.js +0 -0
- package/dist/components/Box.d.ts +52 -0
- package/dist/components/Box.js +55 -0
- package/dist/components/Capture.d.ts +39 -0
- package/dist/components/Capture.js +36 -0
- package/dist/components/capture-props.d.ts +30 -0
- package/dist/components/capture-props.js +44 -0
- package/dist/elements/a-avatar.css +1 -1
- package/dist/elements/a-banner.css +1 -1
- package/dist/elements/a-banner.js +4 -4
- package/dist/elements/a-box.css +1 -0
- package/dist/elements/a-box.d.ts +41 -0
- package/dist/elements/a-box.js +584 -0
- package/dist/elements/a-button.css +1 -1
- package/dist/elements/a-calendar.js +2 -2
- package/dist/elements/a-capture.css +1 -0
- package/dist/elements/a-capture.d.ts +10 -0
- package/dist/elements/a-capture.js +24 -0
- package/dist/elements/a-card.css +1 -1
- package/dist/elements/a-checkbox.css +1 -1
- package/dist/elements/a-checkbox.js +4 -4
- package/dist/elements/a-dialog.css +1 -1
- package/dist/elements/a-expander.css +1 -1
- package/dist/elements/a-expander.js +2 -2
- package/dist/elements/a-input-time.css +1 -1
- package/dist/elements/a-input-time.js +3 -3
- package/dist/elements/a-input.css +1 -1
- package/dist/elements/a-input.js +6 -6
- package/dist/elements/a-menu-item.css +1 -1
- package/dist/elements/a-menu-item.js +3 -3
- package/dist/elements/a-menu.css +1 -1
- package/dist/elements/a-menu.js +2 -2
- package/dist/elements/a-radio-group.js +3 -3
- package/dist/elements/a-radio.css +1 -1
- package/dist/elements/a-slider.css +1 -1
- package/dist/elements/a-slider.js +6 -6
- package/dist/elements/a-switch.css +1 -1
- package/dist/elements/a-switch.js +2 -2
- package/dist/elements/a-tabpanel.js +2 -2
- package/dist/elements/a-tabs.css +1 -1
- package/dist/elements/a-tabs.js +6 -6
- package/dist/elements/a-tag.css +1 -1
- package/dist/elements/a-text.css +1 -1
- package/dist/elements/a-title.css +1 -1
- package/dist/elements/a-toast.js +2 -2
- package/dist/elements/a-tooltip.css +1 -1
- package/dist/elements/a-tooltip.d.ts +4 -3
- package/dist/elements/a-tooltip.js +9 -5
- package/dist/elements/capture-input.d.ts +5 -0
- package/dist/elements/capture-input.js +609 -0
- package/dist/elements/index.d.ts +2 -0
- package/dist/elements/index.js +6 -0
- package/dist/general_types.d.ts +70 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +4 -0
- package/dist/jsx-runtime.d.ts +3 -1
- package/docs/accessibility.md +24 -0
- package/docs/changelog.md +45 -3
- package/docs/colors.md +141 -0
- package/docs/comparison.md +463 -28
- package/docs/components/avatar.md +364 -0
- package/docs/components/banner.md +13 -27
- package/docs/components/box.md +354 -0
- package/docs/components/breadcrumbs.md +7 -6
- package/docs/components/button.md +48 -37
- package/docs/components/capture.md +345 -0
- package/docs/components/card.md +17 -38
- package/docs/components/checkbox.md +16 -39
- package/docs/components/dialog.md +14 -36
- package/docs/components/expander.md +15 -40
- package/docs/components/icon.md +111 -9
- package/docs/components/input-autocomplete.md +9 -11
- package/docs/components/input-date.md +33 -23
- package/docs/components/input-time.md +15 -23
- package/docs/components/input.md +27 -76
- package/docs/components/loader.md +7 -5
- package/docs/components/menu.md +73 -77
- package/docs/components/progress.md +10 -14
- package/docs/components/radio.md +17 -36
- package/docs/components/select-faceted.md +7 -25
- package/docs/components/select.md +24 -97
- package/docs/components/slider.md +16 -21
- package/docs/components/steps.md +38 -8
- package/docs/components/switch.md +11 -14
- package/docs/components/tabs.md +52 -40
- package/docs/components/tag.md +11 -22
- package/docs/components/text.md +10 -23
- package/docs/components/title.md +7 -8
- package/docs/components/toaster.md +6 -3
- package/docs/components/tooltip.md +13 -23
- package/docs/index.md +6 -3
- package/docs/install-config.md +24 -0
- package/docs/normalization.md +45 -0
- package/docs/packages/stickers.md +56 -0
- package/docs/theming.md +270 -0
- package/package.json +3 -1
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
# Box
|
|
2
|
+
|
|
3
|
+
`Box` is a DOM container with layout props, overflow states, and browser context
|
|
4
|
+
events. For custom wheel, pointer, and touch handling, use [Capture](./capture.md).
|
|
5
|
+
|
|
6
|
+
## Display
|
|
7
|
+
|
|
8
|
+
Use `display`, `gap`, and `round` for layout and corners. Numeric lengths use
|
|
9
|
+
pixels; strings accept CSS lengths. A bare `round` fully rounds the corners.
|
|
10
|
+
|
|
11
|
+
```tsx
|
|
12
|
+
<Box round={8}><span /></Box>
|
|
13
|
+
<Box display="flex" round={8} gap={6}><span /></Box>
|
|
14
|
+
<Box display="grid" round={8} gap="0.5rem" style={{ gridTemplateColumns: '1fr 1fr' }}><span /></Box>
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Overflow
|
|
18
|
+
|
|
19
|
+
Box reports overflow, clipping, and scrollability as measurements and CSS
|
|
20
|
+
states. Use `observe="size"` to keep CSS states current. `fade` and
|
|
21
|
+
`onMeasureChange` also enable measurement; without these, Box adds no size
|
|
22
|
+
observers.
|
|
23
|
+
|
|
24
|
+
`.edge` is a demo class name. Use your own selector.
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
<Box observe="size" round={8} className="edge" style={{ width: 150 }}>Content that fits.</Box>
|
|
28
|
+
|
|
29
|
+
<Box observe="size" round={8} className="edge" style={{ width: 150, overflow: 'hidden', whiteSpace: 'nowrap' }}>
|
|
30
|
+
A label too long for this box.
|
|
31
|
+
</Box>
|
|
32
|
+
|
|
33
|
+
<Box observe="size" round={8} className="edge" style={{ width: 150, height: 56, overflowY: 'auto' }}>
|
|
34
|
+
One. Two. Three. Four. Five. Six. Seven. Eight. Nine. Ten.
|
|
35
|
+
</Box>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```css
|
|
39
|
+
.edge:state(clipped-x) { border-color: var(--border-3-warning); }
|
|
40
|
+
.edge:state(scrollable-y) { border-color: var(--border-3-info); }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Fading a clipped edge
|
|
44
|
+
|
|
45
|
+
`fade` masks edges with hidden content and removes the mask as scrolling reveals
|
|
46
|
+
them. `fadeSize` sets its depth. It measures on connection, even off screen.
|
|
47
|
+
|
|
48
|
+
```tsx
|
|
49
|
+
const TAGS = ['frontend', 'design-system', 'a11y', 'performance']
|
|
50
|
+
|
|
51
|
+
<Box fade fadeSize={32} round display="flex" gap={6} className="fade-demo" style={{ width: 190, overflowX: 'auto' }}>
|
|
52
|
+
{TAGS.map((t) => <Tag key={t} size="small" label={t} />)}
|
|
53
|
+
</Box>
|
|
54
|
+
|
|
55
|
+
<Box fade fadeSize={32} round={8} className="fade-demo" style={{ width: 190, height: 56, overflowY: 'auto' }}>
|
|
56
|
+
One. Two. Three. Four. Five. Six. Seven. Eight. Nine. Ten. Eleven. Twelve.
|
|
57
|
+
</Box>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
```css
|
|
61
|
+
.fade-demo { flex-wrap: nowrap; padding: 10px; border: 1px solid var(--border-4); }
|
|
62
|
+
.fade-demo a-tag { flex: 0 0 auto; }
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The mask clips to the padding box. It preserves the Box border, shadows, and
|
|
66
|
+
focus ring when no edge is hidden.
|
|
67
|
+
|
|
68
|
+
To style hidden edges without `fade`, use `observe="size"` and the
|
|
69
|
+
`hidden-start-x`, `hidden-end-x`, `hidden-start-y`, or `hidden-end-y` CSS states.
|
|
70
|
+
|
|
71
|
+
### Tooltip on clipped content
|
|
72
|
+
|
|
73
|
+
`Tooltip truncatedOnly` shows when Box clips content on either axis, including
|
|
74
|
+
wrapped children.
|
|
75
|
+
|
|
76
|
+
```tsx
|
|
77
|
+
const TAGS = ['frontend', 'design-system', 'a11y', 'performance']
|
|
78
|
+
|
|
79
|
+
<Box display="flex" round={8} gap={6} className="tag-box" style={{ height: 34 }}>
|
|
80
|
+
{TAGS.map((t) => <Tag key={t} size="small" label={t} />)}
|
|
81
|
+
<Tooltip truncatedOnly>{TAGS.join(' · ')}</Tooltip>
|
|
82
|
+
</Box>
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
```css
|
|
86
|
+
.tag-box { flex-wrap: wrap; padding: 6px; overflow: hidden; }
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Measurements
|
|
90
|
+
|
|
91
|
+
`onMeasureChange` reports one frame after observation starts and when the Box or
|
|
92
|
+
its content changes. `changed` contains changed fields; `current` is the full
|
|
93
|
+
snapshot. Reporting pauses off screen and resumes when Box returns.
|
|
94
|
+
|
|
95
|
+
Resize or scroll the Box to update its measurements.
|
|
96
|
+
|
|
97
|
+
```tsx title="measurechange"
|
|
98
|
+
const [measurement, setMeasurement] = useState<BoxMeasurement | null>(null)
|
|
99
|
+
|
|
100
|
+
<Box
|
|
101
|
+
round={8}
|
|
102
|
+
className="measure-probe-box"
|
|
103
|
+
onMeasureChange={(_, { current }) => setMeasurement(current)}
|
|
104
|
+
>
|
|
105
|
+
<Text size="small" priority="tertiary">Resize or scroll this Box.</Text>
|
|
106
|
+
<div className="measure-probe-wide">wide content, so both axes overflow</div>
|
|
107
|
+
<div className="measure-probe-wide">and a second line, so the vertical axis does too</div>
|
|
108
|
+
<div className="measure-probe-wide">and a third</div>
|
|
109
|
+
</Box>
|
|
110
|
+
|
|
111
|
+
<div className="measure-probe-readout">
|
|
112
|
+
{Object.entries(measurement ?? {}).map(([field, value]) => (
|
|
113
|
+
<Tag key={field} size="small" label={field} value={String(value)} />
|
|
114
|
+
))}
|
|
115
|
+
</div>
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
```css
|
|
119
|
+
.measure-probe-box {
|
|
120
|
+
resize: both;
|
|
121
|
+
overflow: auto;
|
|
122
|
+
inline-size: 320px;
|
|
123
|
+
block-size: 132px;
|
|
124
|
+
min-inline-size: 120px;
|
|
125
|
+
min-block-size: 64px;
|
|
126
|
+
padding: 10px;
|
|
127
|
+
border: 1px solid var(--border-4);
|
|
128
|
+
}
|
|
129
|
+
.measure-probe-wide { inline-size: 520px; padding-block: 6px; }
|
|
130
|
+
.measure-probe-readout { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
See the [measurement fields](#boxmeasurement). Overflow fields map to kebab-case
|
|
134
|
+
CSS states, such as `clippedX` → `:state(clipped-x)`.
|
|
135
|
+
|
|
136
|
+
## Context
|
|
137
|
+
|
|
138
|
+
`onContextChange` reports theme, focus, and browser context as
|
|
139
|
+
`{ changed, current }`. See the [context fields](#boxcontext). For CSS, use
|
|
140
|
+
`:focus-within`, mode classes, and media queries instead.
|
|
141
|
+
|
|
142
|
+
Switch themes, resize, or zoom to update the preview. The `.light` Box keeps its
|
|
143
|
+
local `mode`; `globalMode` follows the document. Browser and OS versions may be
|
|
144
|
+
frozen, so use `pointer`, `hover`, or feature tests to choose behavior.
|
|
145
|
+
|
|
146
|
+
```tsx title="contextchange"
|
|
147
|
+
import { useState } from 'react'
|
|
148
|
+
import { Box, Tag, Text, type BoxContext } from '@antadesign/anta'
|
|
149
|
+
|
|
150
|
+
function ScopedContext() {
|
|
151
|
+
const [context, setContext] = useState<BoxContext | null>(null)
|
|
152
|
+
|
|
153
|
+
return (
|
|
154
|
+
<div className="light">
|
|
155
|
+
<Box display="flex" round={8} gap={6} className="context-probe-box"
|
|
156
|
+
onContextChange={(_, { current }) => setContext(current)}>
|
|
157
|
+
<Text size="small" priority="tertiary">inside a .light scope</Text>
|
|
158
|
+
<Tag size="small" tone="brand" label="mode" value={context?.mode ?? '…'} />
|
|
159
|
+
<Tag size="small" label="globalMode" value={context?.globalMode ?? '…'} />
|
|
160
|
+
</Box>
|
|
161
|
+
</div>
|
|
162
|
+
)
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```css
|
|
167
|
+
.context-probe-box {
|
|
168
|
+
flex-wrap: wrap;
|
|
169
|
+
align-items: center;
|
|
170
|
+
padding: 10px;
|
|
171
|
+
border: 1px solid var(--border-4);
|
|
172
|
+
background: var(--bg-1);
|
|
173
|
+
color: var(--text-1);
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
<a id="canvas"></a>
|
|
178
|
+
|
|
179
|
+
### Canvas-related styles
|
|
180
|
+
|
|
181
|
+
Use `context.font` and `devicePixelRatio` to match canvas text to the DOM.
|
|
182
|
+
The first line is DOM text; the second is drawn on canvas. Switch themes or
|
|
183
|
+
zoom to update both. `context.inset` also reports border and padding when you
|
|
184
|
+
need to align drawing coordinates with the Box's content edge.
|
|
185
|
+
|
|
186
|
+
Set `ctx.font` before spacing and direction. Box assembles `font.shorthand`
|
|
187
|
+
because `getComputedStyle(element).font` can be empty. Stretch and variant caps
|
|
188
|
+
remain separate fields; percentage stretch is invalid in the shorthand.
|
|
189
|
+
|
|
190
|
+
```tsx title="canvas"
|
|
191
|
+
const canvasRef = useRef<HTMLCanvasElement>(null)
|
|
192
|
+
|
|
193
|
+
<Box className="canvas-probe"
|
|
194
|
+
onContextChange={(_, { current }) => {
|
|
195
|
+
const canvas = canvasRef.current
|
|
196
|
+
const ctx = canvas?.getContext('2d')
|
|
197
|
+
if (!canvas || !ctx) return
|
|
198
|
+
|
|
199
|
+
const { font, devicePixelRatio: dpr } = current
|
|
200
|
+
canvas.width = canvas.clientWidth * dpr
|
|
201
|
+
canvas.height = canvas.clientHeight * dpr
|
|
202
|
+
ctx.scale(dpr, dpr)
|
|
203
|
+
|
|
204
|
+
ctx.font = font.shorthand
|
|
205
|
+
ctx.letterSpacing = font.letterSpacing
|
|
206
|
+
ctx.wordSpacing = font.wordSpacing
|
|
207
|
+
ctx.direction = font.direction === 'rtl' ? 'rtl' : 'ltr'
|
|
208
|
+
ctx.fillStyle = font.color
|
|
209
|
+
|
|
210
|
+
ctx.fillText('Matches the DOM', 0, font.lineHeight ?? font.size)
|
|
211
|
+
}}
|
|
212
|
+
>
|
|
213
|
+
<span>Matches the DOM</span>
|
|
214
|
+
<canvas ref={canvasRef} aria-label="Canvas text using the Box font and color" />
|
|
215
|
+
</Box>
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
```css
|
|
219
|
+
.canvas-probe { width: 100%; font-size: 20px; line-height: 32px; color: var(--text-1); }
|
|
220
|
+
.canvas-probe canvas { display: block; width: 100%; height: 48px; }
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Component props
|
|
224
|
+
|
|
225
|
+
| Prop | Type | Default | Description |
|
|
226
|
+
|------|------|---------|-------------|
|
|
227
|
+
| `display?` | BoxDisplay | block | Layout model for the host. All other layout, sizing, mask, and shadow properties stay ordinary `className` / `style` CSS on the Box itself. |
|
|
228
|
+
| `fade?` | boolean | — | Fades out every edge that currently hides clipped content, and drops the fade from an edge once the reader scrolls to it. |
|
|
229
|
+
| `fadeSize?` | number \| string | 24 | Depth of the `fade` gradient. A `number` is pixels; a string is any CSS length. |
|
|
230
|
+
| `gap?` | number \| string | — | Gap between children, matching the CSS `gap` property. A `number` is pixels; a string is any CSS length or two-value gap (`'1rem'`, `'8px 16px'`). Applies while the Box is a flex or grid container. |
|
|
231
|
+
| `observe?` | 'size' \| 'context' \| 'all' | — | What the Box watches, when a handler is not what turns it on. `'size'` keeps the overflow CSS states (`:state(clipped-x)`, `:state(scrollable-y)`, …) current — reach for it when your own CSS is the only reader. `'context'` and `'all'` are there for symmetry; passing `onMeasureChange` or `onContextChange` already turns the matching half on. |
|
|
232
|
+
| `onContextChange?` | (event, detail) => void | — | Fired after Box's browser and local rendering context changes. `detail` contains the changed fields and a full current snapshot. |
|
|
233
|
+
| `onMeasureChange?` | (event, detail) => void | — | Fired after Box geometry or its content-overflow state changes. `detail` contains the changed fields and a full current snapshot. |
|
|
234
|
+
| `round?` | boolean \| number \| string | — | Fully-round corners (`border-radius: 999px`, clamped to the box). Pass a `number` (px) or a CSS length string (`'1rem'`) for a custom radius. Omit for square corners. |
|
|
235
|
+
|
|
236
|
+
### BoxMeasurement
|
|
237
|
+
|
|
238
|
+
| Field | Type | Default | Description |
|
|
239
|
+
|------|------|---------|-------------|
|
|
240
|
+
| `clientHeight` | number | — | |
|
|
241
|
+
| `clientWidth` | number | — | Padding-box dimensions, matching the browser's `clientWidth` / `clientHeight`. |
|
|
242
|
+
| `clippedX` | boolean | — | The exceeded content is visually clipped on this axis. |
|
|
243
|
+
| `clippedY` | boolean | — | |
|
|
244
|
+
| `height` | number | — | |
|
|
245
|
+
| `hiddenEndX` | boolean | — | |
|
|
246
|
+
| `hiddenEndY` | boolean | — | |
|
|
247
|
+
| `hiddenStartX` | boolean | — | Clipped content sits past this specific edge, in logical writing-mode terms. A clipped box that has not been scrolled hides content past its end edge only; scroll it to the end and the hidden content moves to the start. These drive the `fade` mask. |
|
|
248
|
+
| `hiddenStartY` | boolean | — | |
|
|
249
|
+
| `overflowX` | boolean | — | Content exceeds the padding box on this axis, regardless of CSS overflow. |
|
|
250
|
+
| `overflowY` | boolean | — | |
|
|
251
|
+
| `scrollableX` | boolean | — | The exceeded content can be scrolled by the reader on this axis. |
|
|
252
|
+
| `scrollableY` | boolean | — | |
|
|
253
|
+
| `scrollHeight` | number | — | |
|
|
254
|
+
| `scrollLeft` | number | — | Current scroll offset, matching `scrollLeft` / `scrollTop`. |
|
|
255
|
+
| `scrollTop` | number | — | |
|
|
256
|
+
| `scrollWidth` | number | — | Full scrollable-content dimensions, matching `scrollWidth` / `scrollHeight`. |
|
|
257
|
+
| `width` | number | — | Border-box width and height in CSS pixels. |
|
|
258
|
+
|
|
259
|
+
### BoxContext
|
|
260
|
+
|
|
261
|
+
| Field | Type | Default | Description |
|
|
262
|
+
|------|------|---------|-------------|
|
|
263
|
+
| `backgroundColor` | string | — | Resolved `background-color`. Needed when the box's content is drawn somewhere else — an offscreen canvas, a worker, an export — where the box's own background is not behind it. |
|
|
264
|
+
| `browser` | BoxBrowser | — | Browser family. |
|
|
265
|
+
| `browserVersion` | number | — | Browser major version, or `0` when unknown. Minor and patch digits are frozen by every engine, so only the major number is reported. |
|
|
266
|
+
| `devicePixelRatio` | number | — | `window.devicePixelRatio`: CSS pixels per device pixel. `1` on a standard display, `2` on most Retina screens, and a fraction under OS or browser zoom. Live — it re-reports on zoom and when the window moves to a monitor with a different density. |
|
|
267
|
+
| `focusWithin` | boolean | — | Whether focus is on the box or any of its descendants, read from the native `:focus-within`. For CSS, use that pseudo-class directly; this field is for logic that cannot query the DOM. |
|
|
268
|
+
| `font` | BoxFont | — | Resolved text style, ready to hand to a canvas 2D context. |
|
|
269
|
+
| `globalMode` | BoxMode | — | Mode on `<html>`, independent of an enclosing local scope. |
|
|
270
|
+
| `hover` | boolean | — | Whether ordinary hover interaction is available. |
|
|
271
|
+
| `inset` | BoxInset | — | Padding and border widths, for placing content inside the border box. |
|
|
272
|
+
| `mobile` | boolean | — | Whether the browser reports a mobile device. |
|
|
273
|
+
| `mode` | BoxMode | — | Closest scoped Anta mode. A local `.light` can override a dark document. |
|
|
274
|
+
| `os` | BoxOS | — | Operating-system family. |
|
|
275
|
+
| `osVersion` | number | — | Operating-system major version, or `0` when the browser withholds it. Browsers freeze this: every engine reports macOS as `10.15.7` and Windows 11 as `10.0`, so only Android and iOS carry a real number. Treat it as a hint, never as a gate. |
|
|
276
|
+
| `pointer` | BoxPointer | — | Most precise available primary pointer. |
|
|
277
|
+
| `reducedMotion` | boolean | — | Whether the reader asks for reduced motion. |
|
|
278
|
+
| `systemAppearance` | BoxMode | — | Browser / operating-system color preference, independent of Anta classes. |
|
|
279
|
+
|
|
280
|
+
### BoxFont
|
|
281
|
+
|
|
282
|
+
`context.font`, the resolved text style.
|
|
283
|
+
|
|
284
|
+
| Field | Type | Default | Description |
|
|
285
|
+
|------|------|---------|-------------|
|
|
286
|
+
| `color` | string | — | Resolved text color. Canvas: `ctx.fillStyle`. |
|
|
287
|
+
| `direction` | string | — | Canvas: `ctx.direction`. |
|
|
288
|
+
| `family` | string | — | Resolved family list, quoted as the engine reports it. |
|
|
289
|
+
| `featureSettings` | string | — | Canvas 2D consumes neither of these. They are here for text you measure or draw some other way. |
|
|
290
|
+
| `kerning` | string | — | Canvas: `ctx.fontKerning`. |
|
|
291
|
+
| `letterSpacing` | string | — | A length, never `normal` - `normal` is reported as `0px`, which is what `ctx.letterSpacing` accepts. |
|
|
292
|
+
| `lineHeight` | number \| null | — | Line height in CSS pixels, or `null` when it computes to `normal`. Canvas ignores line height in `ctx.font`; this is for laying text out yourself. |
|
|
293
|
+
| `shorthand` | string | — | CSS `font` shorthand, assembled here because every engine returns an empty string for the computed shorthand. `stretch` and `variantCaps` are left out of it deliberately: a percentage `font-stretch` makes every engine reject the whole string and fall back to `10px sans-serif`. Apply those through `ctx.fontStretch` / `ctx.fontVariantCaps` after setting `ctx.font`. |
|
|
294
|
+
| `size` | number | — | Font size in CSS pixels. |
|
|
295
|
+
| `stretch` | string | — | Computed `font-stretch`, a percentage such as `88%`. Canvas: `ctx.fontStretch`. |
|
|
296
|
+
| `style` | string | — | `normal`, `italic`, or an `oblique <angle>`. |
|
|
297
|
+
| `textRendering` | string | — | Canvas: `ctx.textRendering`, which WebKit does not implement. |
|
|
298
|
+
| `variantCaps` | string | — | Canvas: `ctx.fontVariantCaps`. |
|
|
299
|
+
| `variationSettings` | string | — | |
|
|
300
|
+
| `weight` | number | — | Numeric weight, 1-1000. |
|
|
301
|
+
| `wordSpacing` | string | — | Same normalization as `letterSpacing`. Canvas: `ctx.wordSpacing`. |
|
|
302
|
+
|
|
303
|
+
### BoxInset
|
|
304
|
+
|
|
305
|
+
`context.inset`, the distance from the border edge to the content edge.
|
|
306
|
+
|
|
307
|
+
| Field | Type | Default | Description |
|
|
308
|
+
|------|------|---------|-------------|
|
|
309
|
+
| `borderBottom` | number | — | |
|
|
310
|
+
| `borderLeft` | number | — | |
|
|
311
|
+
| `borderRight` | number | — | |
|
|
312
|
+
| `borderTop` | number | — | |
|
|
313
|
+
| `paddingBottom` | number | — | |
|
|
314
|
+
| `paddingLeft` | number | — | |
|
|
315
|
+
| `paddingRight` | number | — | |
|
|
316
|
+
| `paddingTop` | number | — | |
|
|
317
|
+
|
|
318
|
+
## Web component
|
|
319
|
+
|
|
320
|
+
Use `<a-box>` without JSX. Events are non-bubbling `CustomEvent`s with the same
|
|
321
|
+
`detail`. Set `observe="size"`, `"context"`, or `"all"` explicitly; adding a
|
|
322
|
+
listener does not enable observation. A bare `observe` means `"all"`.
|
|
323
|
+
|
|
324
|
+
```html title="a-box"
|
|
325
|
+
<a-box display="grid" gap="8px" round="12px" observe="all"
|
|
326
|
+
style="--box-gap: 8px; --box-round: 12px; padding: 12px; border: 1px solid var(--border-4)">
|
|
327
|
+
<span>Summary content</span>
|
|
328
|
+
<span>Observation enabled</span>
|
|
329
|
+
</a-box>
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Import `@antadesign/anta/elements/a-box` to register the element. Listen for
|
|
333
|
+
`measurechange` and `contextchange` with `addEventListener`.
|
|
334
|
+
`box.measurement`, `box.context`, and `box.isTruncated` read values synchronously.
|
|
335
|
+
|
|
336
|
+
## Styling
|
|
337
|
+
|
|
338
|
+
Your `className` and `style` override `display`, `gap`, and `round` through the
|
|
339
|
+
`anta.components` CSS layer.
|
|
340
|
+
|
|
341
|
+
Without typed CSS `attr()` support, raw `gap`, `round`, and `fade-size` length
|
|
342
|
+
attributes need matching custom properties. The JSX wrapper sets these for you:
|
|
343
|
+
|
|
344
|
+
```html
|
|
345
|
+
<a-box display="flex" gap round fade class="raw-box"
|
|
346
|
+
style="--box-gap: 8px; --box-round: 12px; --box-fade-size: 32px">
|
|
347
|
+
<span>Layout</span><span>Context</span><span>Measurements</span>
|
|
348
|
+
</a-box>
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
```css
|
|
352
|
+
.raw-box { width: 190px; overflow: auto; padding: 12px; border: 1px solid var(--border-4); }
|
|
353
|
+
.raw-box span { flex: 0 0 auto; }
|
|
354
|
+
```
|
|
@@ -111,16 +111,13 @@ Use `copyUrl` to copy `location.href`, `copyNode` to copy a marked rendered
|
|
|
111
111
|
region, or `copy` for a known string. For dynamic text, pass a controlled `copy`
|
|
112
112
|
string and set it from `onCopyRequest`. `onCopied` receives the result.
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
## Component props
|
|
115
115
|
|
|
116
116
|
| Prop | Type | Default | Description |
|
|
117
117
|
|------|------|---------|-------------|
|
|
118
118
|
| `items` | BreadcrumbItem[] | — | Ordered breadcrumb entries. |
|
|
119
|
-
| `itemsBeforeCollapse?` | number | 0 | Number of original items kept before the More control when `maxItems`
|
|
120
|
-
|
|
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. |
|
|
119
|
+
| `itemsBeforeCollapse?` | number | 0 | Number of original items kept before the More control when `maxItems` collapses the trail. The rest of the visible-item budget is kept from the end, so `0` puts More first. |
|
|
120
|
+
| `maxItems?` | number | — | Maximum number of original breadcrumb items left visible. The More control does not count. Omit to keep every item visible. |
|
|
124
121
|
| `moreLabel?` | string | 'Show more breadcrumbs' | Accessible name for the More control. |
|
|
125
122
|
| `paddingless?` | boolean | — | Remove horizontal padding from every visible breadcrumb control. |
|
|
126
123
|
| `priority?` | 'quaternary' \| 'tertiary' | quaternary | Button priority applied to every visible item and the More control. |
|
|
@@ -129,6 +126,8 @@ string and set it from `onCopyRequest`. `onCopied` receives the result.
|
|
|
129
126
|
| `underline?` | 'solid' \| 'dashed' \| 'dotted' | — | Underline style applied to every visible breadcrumb control. |
|
|
130
127
|
| `underlineOnHover?` | boolean | — | Hide the underline at rest and reveal it on hover. |
|
|
131
128
|
|
|
129
|
+
## Web Component
|
|
130
|
+
|
|
132
131
|
`Breadcrumbs` deliberately adds no custom-element behavior: it assembles Anta
|
|
133
132
|
Buttons, an optional Menu, and two light-DOM layout tags. When you are not using
|
|
134
133
|
JSX, import the Breadcrumbs stylesheet and the primitives, then compose the same
|
|
@@ -161,6 +160,8 @@ import '@antadesign/anta/elements'
|
|
|
161
160
|
</a-breadcrumbs>
|
|
162
161
|
```
|
|
163
162
|
|
|
163
|
+
## Styling
|
|
164
|
+
|
|
164
165
|
Use `priority`, `size`, and `separator` before adding CSS. A `className` on
|
|
165
166
|
`Breadcrumbs` lands on the navigation wrapper; item `className` values land on
|
|
166
167
|
their individual Buttons. The composed structure uses light-DOM tags, so plain
|
|
@@ -217,6 +217,8 @@ underline stylistically, it supports three styles — `solid`, `dashed`,
|
|
|
217
217
|
- **`selected`** — toggled-on / pressed visual; shares the active
|
|
218
218
|
state's look. Useful for filter chips and icon toggles.
|
|
219
219
|
|
|
220
|
+
## ButtonCopy
|
|
221
|
+
|
|
220
222
|
`ButtonCopy` is a copy button — a `Button` preset for copy-to-clipboard. It
|
|
221
223
|
composes a plain `<Button>` with a slotted `<a-copy>` element that writes to the
|
|
222
224
|
clipboard when the button is activated. A button with a copy glyph changes the
|
|
@@ -329,57 +331,32 @@ current URL (`copyUrl`).
|
|
|
329
331
|
|------|------|---------|-------------|
|
|
330
332
|
| `copiedLabel?` | string | Copied | Text in the successful no-icon confirmation. |
|
|
331
333
|
| `copy?` | string | — | Text copied to the clipboard on activation. |
|
|
332
|
-
| `copyNode?` | boolean \| string | — | Copy a DOM node as rich text (`text/html`) + plain text. `true` copies
|
|
333
|
-
the nearest ancestor marked `data-copy-source`; a string is a CSS
|
|
334
|
-
selector for an ancestor region (`closest`). The copy control is stripped
|
|
335
|
-
from the copied output. |
|
|
334
|
+
| `copyNode?` | boolean \| string | — | Copy a DOM node as rich text (`text/html`) + plain text. `true` copies the nearest ancestor marked `data-copy-source`; a string is a CSS selector for an ancestor region (`closest`). The copy control is stripped from the copied output. |
|
|
336
335
|
| `copyUrl?` | true | — | Copy the current page URL (`location.href`). |
|
|
337
336
|
| `copyWithUrl?` | boolean | — | Prefix the copied text with `// URL: <current page URL>`. |
|
|
338
337
|
| `disabled?` | boolean | — | Disable the button. |
|
|
339
338
|
| `download?` | string \| boolean | — | Anchor download attribute. Empty string / `true` triggers a download with the resource's default name; a string overrides the filename. |
|
|
340
339
|
| `form?` | string | — | Form id when the button isn't a descendant of its form. |
|
|
341
|
-
| `href?` | string | — | URL to link to. A definite string renders `<a role="button">`; omit it
|
|
342
|
-
(
|
|
343
|
-
|
|
344
|
-
| `icon?` | IconShape | — | Leading icon shape. When set alone (no `label`, no `iconTrailing`, no
|
|
345
|
-
`children`), the button renders as a square icon-only control and
|
|
346
|
-
the wrapper auto-supplies `aria-label={icon}` (override by passing
|
|
347
|
-
your own `aria-label`). |
|
|
348
|
-
| `iconPlacement?` | 'leading' \| 'trailing' \| 'none' | 'leading' | Where the copy glyph sits relative to the label — or `'none'` to omit it.
|
|
349
|
-
Without a glyph, a successful copy shows a small confirmation label near
|
|
350
|
-
the pointer and leaves the button unchanged. |
|
|
340
|
+
| `href?` | string | — | URL to link to. A definite string renders `<a role="button">`; omit it (or pass `undefined`) to render `<a-button>`, so `href={maybeUrl}` degrades to a plain button when the URL is absent. |
|
|
341
|
+
| `icon?` | IconShape | — | Leading icon shape. When set alone (no `label`, no `iconTrailing`, no `children`), the button renders as a square icon-only control and the wrapper auto-supplies `aria-label={icon}` (override by passing your own `aria-label`). |
|
|
342
|
+
| `iconPlacement?` | 'leading' \| 'trailing' \| 'none' | 'leading' | Where the copy glyph sits relative to the label — or `'none'` to omit it. Without a glyph, a successful copy shows a small confirmation label near the pointer and leaves the button unchanged. |
|
|
351
343
|
| `iconTrailing?` | IconShape | — | Trailing icon shape. Renders after `children`, last in the slot order. |
|
|
352
344
|
| `label?` | string | — | Label text. Renders between the leading icon and `children`. |
|
|
353
|
-
| `loading?` | boolean | — | Show a rotating loading indicator. Blocks clicks and keyboard
|
|
354
|
-
activation, and removes the button from the tab order while active. |
|
|
345
|
+
| `loading?` | boolean | — | Show a rotating loading indicator. Blocks clicks and keyboard activation, and removes the button from the tab order while active. |
|
|
355
346
|
| `onClick?` | (e) => void | — | Click handler. |
|
|
356
347
|
| `onCopied?` | (ok) => void | — | Fires after the copy attempt with whether it succeeded. |
|
|
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. |
|
|
348
|
+
| `onCopyRequest?` | () => void | — | Refresh a dynamic `copy` value before activation. Set the new string in application state so the next render updates `copy`. Return values are ignored. Fires on pointerdown and Enter/Space keydown. |
|
|
360
349
|
| `paddingless?` | boolean | — | Drops outer padding to zero. |
|
|
361
350
|
| `ping?` | string | — | Space-separated URLs the browser pings on navigation. |
|
|
362
351
|
| `priority?` | 'primary' \| 'secondary' \| 'tertiary' \| 'quaternary' | secondary | Visual emphasis. |
|
|
363
352
|
| `rel?` | string | — | Anchor rel. |
|
|
364
|
-
| `role?` | string | button | ARIA role override (e.g. `'gridcell'` when a button is a cell in a grid).
|
|
365
|
-
|
|
366
|
-
| `round?` | boolean \| number \| string | — | Fully-round corners — a pill for text buttons, a circle for icon-only ones
|
|
367
|
-
(`border-radius: 999px`, clamped to the element's height). Pass a `number`
|
|
368
|
-
(px) or a CSS length string (`'1rem'`) for a custom radius instead. |
|
|
353
|
+
| `role?` | string | button | ARIA role override (e.g. `'gridcell'` when a button is a cell in a grid). Forwarded to the underlying element. |
|
|
354
|
+
| `round?` | boolean \| number \| string | — | Fully-round corners — a pill for text buttons, a circle for icon-only ones (`border-radius: 999px`, clamped to the element's height). Pass a `number` (px) or a CSS length string (`'1rem'`) for a custom radius instead. |
|
|
369
355
|
| `selected?` | boolean | — | Toggled-on / pressed state, e.g. for filter chips. |
|
|
370
|
-
| `size?` | 'small' \| 'medium' \| 'large' | medium | Size variant. small=24px, medium=28px, large=32px. Omit the
|
|
371
|
-
|
|
372
|
-
identically and emit no DOM attribute. |
|
|
373
|
-
| `tabIndex?` | number | 0 | Tab order. The button is keyboard-focusable by default (`0`) and
|
|
374
|
-
becomes `-1` automatically while `disabled` or `loading` — `<a-button>`
|
|
375
|
-
and `<a role="button">` aren't focusable without an explicit tabindex,
|
|
376
|
-
and a loading button must stay out of the tab order so Enter/Space can't
|
|
377
|
-
fire it mid-flight. |
|
|
356
|
+
| `size?` | 'small' \| 'medium' \| 'large' | medium | Size variant. small=24px, medium=28px, large=32px. Omit the attribute or pass `'medium'` for the default — both render identically and emit no DOM attribute. |
|
|
357
|
+
| `tabIndex?` | number | 0 | Tab order. The button is keyboard-focusable by default (`0`) and becomes `-1` automatically while `disabled` or `loading` — `<a-button>` and `<a role="button">` aren't focusable without an explicit tabindex, and a loading button must stay out of the tab order so Enter/Space can't fire it mid-flight. |
|
|
378
358
|
| `target?` | string | — | Anchor target. |
|
|
379
|
-
| `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | neutral | Semantic tone, or any literal CSS color (`'#ff1493'`, `'rebeccapurple'`)
|
|
380
|
-
for a one-off custom tone. Primary uses the color as-is; secondary,
|
|
381
|
-
tertiary, and quaternary take its hue and pin lightness/chroma to the
|
|
382
|
-
brand curve so any input stays legible. |
|
|
359
|
+
| `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | neutral | Semantic tone, or any literal CSS color (`'#ff1493'`, `'rebeccapurple'`) for a one-off custom tone. Primary uses the color as-is; secondary, tertiary, and quaternary take its hue and pin lightness/chroma to the brand curve so any input stays legible. |
|
|
383
360
|
| `type?` | 'button' \| 'submit' \| 'reset' | — | Form submission type. |
|
|
384
361
|
| `underline?` | 'solid' \| 'dashed' \| 'dotted' | — | Underline style. |
|
|
385
362
|
| `underlineOnHover?` | boolean | — | Hide the underline at rest and reveal it on hover. |
|
|
@@ -405,6 +382,8 @@ split or conditional spread:
|
|
|
405
382
|
<Button href={reportUrl} disabled={!reportUrl} iconTrailing="external-link" label="View report" />
|
|
406
383
|
```
|
|
407
384
|
|
|
385
|
+
### Routing libraries
|
|
386
|
+
|
|
408
387
|
Anta's CSS targets `a-button, a[role="button"][data-anta]` — an anchor (`<a>`)
|
|
409
388
|
with `role="button"`, the `data-anta` opt-in marker, and the right attributes
|
|
410
389
|
gets the styling. That means anta doesn't need an `as` / `asChild` /
|
|
@@ -453,6 +432,8 @@ Usage:
|
|
|
453
432
|
This approach would work for Next.js `<Link>`, TanStack Router, or any
|
|
454
433
|
other routing library.
|
|
455
434
|
|
|
435
|
+
## Special events
|
|
436
|
+
|
|
456
437
|
Beyond a plain click, a `Button` can drive a native form or emit your own
|
|
457
438
|
event:
|
|
458
439
|
|
|
@@ -483,7 +464,35 @@ without taking ownership of `onClick`.
|
|
|
483
464
|
<Button tone="brand" label="Save" data-custom-event="save-clicked" />
|
|
484
465
|
```
|
|
485
466
|
|
|
486
|
-
|
|
467
|
+
## Component props
|
|
468
|
+
|
|
469
|
+
| Prop | Type | Default | Description |
|
|
470
|
+
|------|------|---------|-------------|
|
|
471
|
+
| `disabled?` | boolean | — | Disable the button. |
|
|
472
|
+
| `download?` | string \| boolean | — | Anchor download attribute. Empty string / `true` triggers a download with the resource's default name; a string overrides the filename. |
|
|
473
|
+
| `form?` | string | — | Form id when the button isn't a descendant of its form. |
|
|
474
|
+
| `href?` | string | — | URL to link to. A definite string renders `<a role="button">`; omit it (or pass `undefined`) to render `<a-button>`, so `href={maybeUrl}` degrades to a plain button when the URL is absent. |
|
|
475
|
+
| `icon?` | IconShape | — | Leading icon shape. When set alone (no `label`, no `iconTrailing`, no `children`), the button renders as a square icon-only control and the wrapper auto-supplies `aria-label={icon}` (override by passing your own `aria-label`). |
|
|
476
|
+
| `iconTrailing?` | IconShape | — | Trailing icon shape. Renders after `children`, last in the slot order. |
|
|
477
|
+
| `label?` | string | — | Label text. Renders between the leading icon and `children`. |
|
|
478
|
+
| `loading?` | boolean | — | Show a rotating loading indicator. Blocks clicks and keyboard activation, and removes the button from the tab order while active. |
|
|
479
|
+
| `onClick?` | (e) => void | — | Click handler. |
|
|
480
|
+
| `paddingless?` | boolean | — | Drops outer padding to zero. |
|
|
481
|
+
| `ping?` | string | — | Space-separated URLs the browser pings on navigation. |
|
|
482
|
+
| `priority?` | 'primary' \| 'secondary' \| 'tertiary' \| 'quaternary' | secondary | Visual emphasis. |
|
|
483
|
+
| `rel?` | string | — | Anchor rel. |
|
|
484
|
+
| `role?` | string | button | ARIA role override (e.g. `'gridcell'` when a button is a cell in a grid). Forwarded to the underlying element. |
|
|
485
|
+
| `round?` | boolean \| number \| string | — | Fully-round corners — a pill for text buttons, a circle for icon-only ones (`border-radius: 999px`, clamped to the element's height). Pass a `number` (px) or a CSS length string (`'1rem'`) for a custom radius instead. |
|
|
486
|
+
| `selected?` | boolean | — | Toggled-on / pressed state, e.g. for filter chips. |
|
|
487
|
+
| `size?` | 'small' \| 'medium' \| 'large' | medium | Size variant. small=24px, medium=28px, large=32px. Omit the attribute or pass `'medium'` for the default — both render identically and emit no DOM attribute. |
|
|
488
|
+
| `tabIndex?` | number | 0 | Tab order. The button is keyboard-focusable by default (`0`) and becomes `-1` automatically while `disabled` or `loading` — `<a-button>` and `<a role="button">` aren't focusable without an explicit tabindex, and a loading button must stay out of the tab order so Enter/Space can't fire it mid-flight. |
|
|
489
|
+
| `target?` | string | — | Anchor target. |
|
|
490
|
+
| `tone?` | 'neutral' \| 'brand' \| 'info' \| 'success' \| 'warning' \| 'critical' \| (string & {}) | neutral | Semantic tone, or any literal CSS color (`'#ff1493'`, `'rebeccapurple'`) for a one-off custom tone. Primary uses the color as-is; secondary, tertiary, and quaternary take its hue and pin lightness/chroma to the brand curve so any input stays legible. |
|
|
491
|
+
| `type?` | 'button' \| 'submit' \| 'reset' | — | Form submission type. |
|
|
492
|
+
| `underline?` | 'solid' \| 'dashed' \| 'dotted' | — | Underline style. |
|
|
493
|
+
| `underlineOnHover?` | boolean | — | Hide the underline at rest and reveal it on hover. |
|
|
494
|
+
|
|
495
|
+
## Web Component
|
|
487
496
|
|
|
488
497
|
Use the web component directly when you are not using React or Preact and a native control does not fit.
|
|
489
498
|
|
|
@@ -520,6 +529,8 @@ wrapper sets them for you). A native `<button>` also carries its own default
|
|
|
520
529
|
<button data-anta tone="critical" priority="tertiary">Delete</button>
|
|
521
530
|
```
|
|
522
531
|
|
|
532
|
+
## Styling
|
|
533
|
+
|
|
523
534
|
Reach for the props first: **`tone`** sets the color (any CSS color for a custom
|
|
524
535
|
tone — it derives the whole tone × priority × state curve in oklch), **`priority`**
|
|
525
536
|
the emphasis, **`size`** the dimensions. The focus ring is the global
|