@antadesign/anta 0.3.24 → 0.3.26
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/dist/anta_helpers.js +3 -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 +26 -25
- package/dist/components/Banner.d.ts +10 -10
- package/dist/components/Banner.js +3 -1
- package/dist/components/Box.d.ts +37 -0
- package/dist/components/Box.js +63 -0
- package/dist/components/Breadcrumbs.css +1 -1
- package/dist/components/ButtonCopy.d.ts +2 -2
- package/dist/components/InputDate.css +1 -1
- package/dist/components/MenuItem.d.ts +5 -1
- package/dist/components/MenuItem.js +72 -2
- package/dist/components/MenuItemCopy.d.ts +2 -2
- package/dist/components/Steps.css +1 -1
- package/dist/components/copy-props.d.ts +3 -4
- package/dist/components/select-parts.css +1 -1
- package/dist/elements/a-avatar.css +1 -1
- package/dist/elements/a-banner.css +1 -1
- package/dist/elements/a-banner.js +16 -4
- package/dist/elements/a-box.css +1 -0
- package/dist/elements/a-box.d.ts +41 -0
- package/dist/elements/a-box.js +576 -0
- package/dist/elements/a-button.css +1 -1
- package/dist/elements/a-calendar.css +1 -1
- package/dist/elements/a-calendar.js +2 -2
- package/dist/elements/a-card.css +1 -1
- package/dist/elements/a-checkbox.css +1 -1
- package/dist/elements/a-copy.css +1 -1
- 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-icon.css +1 -1
- package/dist/elements/a-icon.shapes.css +1 -1
- 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 +14 -6
- package/dist/elements/a-loader.css +1 -1
- package/dist/elements/a-menu-group.css +1 -1
- package/dist/elements/a-menu-item.css +1 -1
- package/dist/elements/a-menu-item.js +3 -3
- package/dist/elements/a-menu-separator.css +1 -1
- package/dist/elements/a-menu.css +1 -1
- package/dist/elements/a-menu.d.ts +4 -4
- package/dist/elements/a-menu.js +8 -6
- package/dist/elements/a-progress.css +1 -1
- package/dist/elements/a-radio-group.css +1 -1
- 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-switch.css +1 -1
- package/dist/elements/a-switch.js +2 -2
- package/dist/elements/a-tab.css +1 -1
- package/dist/elements/a-tabpanel.css +1 -1
- 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.css +1 -1
- package/dist/elements/a-toast.js +2 -2
- package/dist/elements/a-toaster.css +1 -1
- 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/copy-behavior.d.ts +13 -15
- package/dist/elements/index.d.ts +1 -0
- package/dist/elements/index.js +3 -0
- package/dist/general_types.d.ts +42 -4
- package/dist/generate-icons.mjs +3 -3
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/jsx-runtime.d.ts +2 -1
- package/dist/reset.css +1 -1
- package/dist/theme-anta.css +1 -1
- package/dist/tokens.css +1 -1
- package/docs/changelog.md +42 -1
- package/docs/components/avatar.md +368 -0
- package/docs/components/banner.md +26 -15
- package/docs/components/box.md +282 -0
- package/docs/components/breadcrumbs.md +2 -2
- package/docs/components/button.md +26 -15
- package/docs/components/input.md +5 -0
- package/docs/components/menu.md +14 -11
- package/docs/components/tag.md +47 -0
- package/docs/index.md +4 -3
- package/docs/install-config.md +58 -13
- package/docs/normalization.md +37 -28
- package/docs/theming.md +4 -1
- package/package.json +2 -2
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
# Banner
|
|
2
2
|
|
|
3
|
-
A full-width
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
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
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
twice the resting height of `Progress`. It's **borderless by default**; add a rule
|
|
11
|
-
under it or an outline around it with `border-bottom-width` / `border-width`, the
|
|
12
|
-
same opt-in as `Progress` ([Styling](#styling)).
|
|
8
|
+
`Banner` is borderless. Set `border-bottom-width` for a rule or `border-width` for
|
|
9
|
+
an outline ([Styling](#styling)).
|
|
13
10
|
|
|
14
11
|
## Tone
|
|
15
12
|
|
|
@@ -49,11 +46,24 @@ pass a `number` (px) or a CSS length string for a custom radius.
|
|
|
49
46
|
<Banner round={12} tone="success" message="A custom 12px radius." />
|
|
50
47
|
```
|
|
51
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`.
|
|
61
|
+
|
|
52
62
|
## Message and content
|
|
53
63
|
|
|
54
|
-
`message` is the leading content
|
|
55
|
-
|
|
56
|
-
|
|
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.
|
|
57
67
|
|
|
58
68
|
```tsx
|
|
59
69
|
<Banner tone="info" message="Deployment complete.">
|
|
@@ -192,6 +202,8 @@ through `dismissed` instead.
|
|
|
192
202
|
|------|------|---------|-------------|
|
|
193
203
|
| `actions?` | ReactNode | — | Trailing controls (buttons, links) rendered as a compact row after the
|
|
194
204
|
message and `children`. |
|
|
205
|
+
| `align?` | 'start' \| 'center' | 'start' | Positions the content row. `'start'` aligns it to the inline edge; `'center'`
|
|
206
|
+
centers it. Wrapped message text follows the selected alignment. |
|
|
195
207
|
| `children?` | ReactNode | — | Free content placed BETWEEN the message and the actions. |
|
|
196
208
|
| `closable?` | boolean | true | Whether the trailing ✕ dismiss button is present. `false` removes it — drive
|
|
197
209
|
dismissal yourself (a controlled `dismissed`, or your own control) instead.
|
|
@@ -202,8 +214,7 @@ through `dismissed` instead.
|
|
|
202
214
|
not updating). **Requires `onDismiss`** — controlled mode never self-hides, so
|
|
203
215
|
without a handler to set `dismissed` the ✕ can't close the banner. Leave
|
|
204
216
|
undefined for uncontrolled. |
|
|
205
|
-
| `message?` | ReactNode | — | Leading message
|
|
206
|
-
Centered in the bar, followed by `children` and then `actions`. |
|
|
217
|
+
| `message?` | ReactNode | — | Leading message: a string at the banner type scale or any node. |
|
|
207
218
|
| `onDismiss?` | () => void | — | Fired when the user dismisses the banner (clicks ✕). Uncontrolled, the banner
|
|
208
219
|
hides itself and this notifies. Controlled, use it to accept the
|
|
209
220
|
request — set `dismissed` to `true` (or ignore to reject); pair it with
|
|
@@ -257,7 +268,7 @@ banner's border matches its tone with no extra work.
|
|
|
257
268
|
<Banner round tone="success" message="A full outline on a round banner." style={{ borderWidth: 1 }} />
|
|
258
269
|
```
|
|
259
270
|
|
|
260
|
-
The host `a-banner` **is** the
|
|
271
|
+
The host `a-banner` **is** the bar — its surface, text, border, and layout
|
|
261
272
|
are all plain CSS on the host (`@layer anta`, so an un-layered rule of yours wins
|
|
262
273
|
without `!important`). For the individual regions, `<a-banner>` exposes
|
|
263
274
|
`::part(message)` / `::part(content)` / `::part(actions)` / `::part(close)`.
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
# Box
|
|
2
|
+
|
|
3
|
+
`Box` is a DOM container that adds layout props, overflow states, and browser
|
|
4
|
+
context events.
|
|
5
|
+
|
|
6
|
+
## Display
|
|
7
|
+
|
|
8
|
+
`display` and `gap` set the matching CSS properties. A numeric `gap` uses
|
|
9
|
+
pixels. A string accepts any CSS length.
|
|
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
|
+
`round` accepts the same values. Pass `round` for fully rounded corners. Omit
|
|
18
|
+
it for square corners.
|
|
19
|
+
|
|
20
|
+
`display`, `gap`, and `round` use the `anta.components` layer. Your
|
|
21
|
+
`className` and `style` override them.
|
|
22
|
+
|
|
23
|
+
## Overflow
|
|
24
|
+
|
|
25
|
+
Box reports when content exceeds its bounds (`overflowX` and `overflowY`), when
|
|
26
|
+
CSS clips it (`clippedX` and `clippedY`), and when it can scroll (`scrollableX`
|
|
27
|
+
and `scrollableY`). It exposes each measurement as a CSS state, so CSS can react
|
|
28
|
+
without JSX state or a measurement ref.
|
|
29
|
+
|
|
30
|
+
A Box measures for `fade`, `onMeasureChange`, or `observe="size"`. Use
|
|
31
|
+
`observe="size"` when CSS reads its states. A Box with none of these attaches no
|
|
32
|
+
observers. Measurement pauses off screen, except `fade`, which measures on
|
|
33
|
+
connection so it can paint its mask.
|
|
34
|
+
|
|
35
|
+
`observe` accepts `"size"`, `"context"`, or `"all"`. A bare `observe` means
|
|
36
|
+
`"all"`. The JSX `Box` derives the needed value from its handlers. When you use
|
|
37
|
+
`a-box` directly, set it yourself; `addEventListener` does not start reporting:
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<a-box observe="size">Content</a-box>
|
|
41
|
+
<a-box observe="all">Content</a-box>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
The attribute works with listeners added before upgrade, removed with `once` or
|
|
45
|
+
`AbortSignal`, and replaced during React renders.
|
|
46
|
+
|
|
47
|
+
`.edge` is a demo class name. Use your own selector.
|
|
48
|
+
|
|
49
|
+
```tsx
|
|
50
|
+
<Box observe="size" round={8} className="edge" style={{ width: 150 }}>Content that fits.</Box>
|
|
51
|
+
|
|
52
|
+
<Box observe="size" round={8} className="edge" style={{ width: 150, overflow: 'hidden', whiteSpace: 'nowrap' }}>
|
|
53
|
+
A label too long for this box.
|
|
54
|
+
</Box>
|
|
55
|
+
|
|
56
|
+
<Box observe="size" round={8} className="edge" style={{ width: 150, height: 56, overflowY: 'auto' }}>
|
|
57
|
+
One. Two. Three. Four. Five. Six. Seven. Eight. Nine. Ten.
|
|
58
|
+
</Box>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
```css
|
|
62
|
+
.edge:state(clipped-x) { border-color: var(--border-3-warning); }
|
|
63
|
+
.edge:state(scrollable-y) { border-color: var(--border-3-info); }
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Fading a clipped edge
|
|
67
|
+
|
|
68
|
+
`fade` masks each edge that hides content. Scrolling moves the mask to the edge
|
|
69
|
+
that still hides content and removes it at the end. `fadeSize` sets its depth.
|
|
70
|
+
|
|
71
|
+
```tsx
|
|
72
|
+
<Box fade fadeSize={32} round display="flex" gap={6} style={{ overflowX: 'auto' }}>
|
|
73
|
+
{TAGS.map((t) => <Tag key={t} size="small" label={t} />)}
|
|
74
|
+
</Box>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
The mask clips to the padding box. It preserves the Box border, shadows, and
|
|
78
|
+
focus ring when no edge is hidden.
|
|
79
|
+
|
|
80
|
+
The four edge states are `hidden-start-x`, `hidden-end-x`, `hidden-start-y`, and
|
|
81
|
+
`hidden-end-y`. Use `hiddenStartX` and its siblings in JSX. To style the states
|
|
82
|
+
without `fade`, add `observe="size"`.
|
|
83
|
+
|
|
84
|
+
```css
|
|
85
|
+
/* <Box observe="size" className="my-box"> */
|
|
86
|
+
.my-box:state(hidden-end-x) {
|
|
87
|
+
mask-image: linear-gradient(to right, black calc(100% - 2rem), transparent);
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Tooltip on clipped content
|
|
92
|
+
|
|
93
|
+
`Tooltip truncatedOnly` uses Box's `isTruncated` getter. It shows when the Box
|
|
94
|
+
clips on either axis, including wrapped children.
|
|
95
|
+
|
|
96
|
+
```tsx
|
|
97
|
+
const TAGS = ['frontend', 'design-system', 'a11y', 'performance']
|
|
98
|
+
|
|
99
|
+
<Box display="flex" round={8} gap={6} className="tag-box" style={{ height: 34 }}>
|
|
100
|
+
{TAGS.map((t) => <Tag key={t} size="small" label={t} />)}
|
|
101
|
+
<Tooltip truncatedOnly>{TAGS.join(' · ')}</Tooltip>
|
|
102
|
+
</Box>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
```css
|
|
106
|
+
.tag-box { flex-wrap: wrap; padding: 6px; overflow: hidden; }
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Measurements
|
|
110
|
+
|
|
111
|
+
`measurechange` fires one frame after observation starts and after the Box or its
|
|
112
|
+
content changes. `changed` contains the moved fields, and `current` is the full
|
|
113
|
+
snapshot. The event pauses off screen and reports again when the Box returns.
|
|
114
|
+
|
|
115
|
+
```tsx title="measurechange"
|
|
116
|
+
<Box
|
|
117
|
+
style={{ maxWidth: 210, overflow: 'hidden', whiteSpace: 'nowrap' }}
|
|
118
|
+
onMeasureChange={(_, { changed, current }) => {
|
|
119
|
+
// changed → { clippedX: true, scrollWidth: 412 }
|
|
120
|
+
if (changed.clippedX) setShowOverflowHint(current.clippedX)
|
|
121
|
+
}}
|
|
122
|
+
>
|
|
123
|
+
Long account name
|
|
124
|
+
</Box>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
The preview updates as you resize or scroll the Box. Tags mark `true` values.
|
|
128
|
+
|
|
129
|
+
[`BoxMeasurement`](#boxmeasurement) lists every field. Box maps each overflow
|
|
130
|
+
field to a kebab-case CSS state, such as `overflow-x`, `clipped-y`,
|
|
131
|
+
`scrollable-x`, and `hidden-end-y`. These states are not host attributes. They
|
|
132
|
+
remain current only while `fade`, `observe="size"`, or `onMeasureChange` enables
|
|
133
|
+
measurement.
|
|
134
|
+
|
|
135
|
+
## Context
|
|
136
|
+
|
|
137
|
+
`contextchange` uses the same `{ changed, current }` shape. Boxes share one
|
|
138
|
+
context observer per window, which stops when the last context reader
|
|
139
|
+
disconnects.
|
|
140
|
+
|
|
141
|
+
[`BoxContext`](#boxcontext) lists every field. `contextchange` sets no CSS
|
|
142
|
+
states. Use `:focus-within`, mode classes, and media queries when CSS is the
|
|
143
|
+
reader.
|
|
144
|
+
|
|
145
|
+
Every value in the following preview is live. Switch the site theme, resize the
|
|
146
|
+
window, zoom the page, or use a touch device. Treat `osVersion` and
|
|
147
|
+
`browserVersion` as hints because browsers freeze parts of these values. Use
|
|
148
|
+
`pointer`, `hover`, or a feature test to gate behavior. The second Box is in a
|
|
149
|
+
`.light` scope, so its `mode` remains `light` on a dark page while `globalMode`
|
|
150
|
+
follows the document.
|
|
151
|
+
|
|
152
|
+
`context.font` is the Box's resolved text style, `context.inset` measures from
|
|
153
|
+
the border edge to the content edge, and `devicePixelRatio` provides the canvas
|
|
154
|
+
scale. Use them to align canvas text with the DOM.
|
|
155
|
+
|
|
156
|
+
`measurement` cannot derive the inset: `width` is the border box, and
|
|
157
|
+
`clientWidth` is the padding box.
|
|
158
|
+
|
|
159
|
+
Set `ctx.font` from `font.shorthand` first. Chromium and Firefox reset
|
|
160
|
+
`fontStretch`, `fontVariantCaps`, `fontKerning`, and `textRendering` when
|
|
161
|
+
`ctx.font` changes. `stretch` and `variantCaps` stay out of the shorthand because
|
|
162
|
+
a percentage `font-stretch` invalidates it.
|
|
163
|
+
|
|
164
|
+
```tsx title="canvas"
|
|
165
|
+
<Box
|
|
166
|
+
onContextChange={(_, { current }) => {
|
|
167
|
+
const canvas = canvasRef.current
|
|
168
|
+
const ctx = canvas?.getContext('2d')
|
|
169
|
+
if (!ctx) return
|
|
170
|
+
|
|
171
|
+
const { font, devicePixelRatio: dpr } = current
|
|
172
|
+
canvas.width = 300 * dpr
|
|
173
|
+
canvas.height = 80 * dpr
|
|
174
|
+
ctx.scale(dpr, dpr)
|
|
175
|
+
|
|
176
|
+
ctx.font = font.shorthand
|
|
177
|
+
ctx.fontStretch = font.stretch
|
|
178
|
+
ctx.fontVariantCaps = font.variantCaps
|
|
179
|
+
ctx.fontKerning = font.kerning
|
|
180
|
+
ctx.textRendering = font.textRendering
|
|
181
|
+
ctx.letterSpacing = font.letterSpacing
|
|
182
|
+
ctx.wordSpacing = font.wordSpacing
|
|
183
|
+
ctx.direction = font.direction
|
|
184
|
+
ctx.fillStyle = font.color
|
|
185
|
+
|
|
186
|
+
const x = current.inset.borderLeft + current.inset.paddingLeft
|
|
187
|
+
const y = current.inset.borderTop + current.inset.paddingTop
|
|
188
|
+
ctx.fillText('Matches the DOM', x, y + (font.lineHeight ?? font.size))
|
|
189
|
+
}}
|
|
190
|
+
>
|
|
191
|
+
<canvas ref={canvasRef} />
|
|
192
|
+
</Box>
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
`getComputedStyle(element).font` is empty in Chromium, Firefox, and WebKit, so
|
|
196
|
+
Box assembles the shorthand.
|
|
197
|
+
|
|
198
|
+
```tsx title="contextchange"
|
|
199
|
+
<Box onContextChange={(_, { changed, current }) => {
|
|
200
|
+
if (changed.mode) updatePreviewTheme(current.mode)
|
|
201
|
+
if (changed.focusWithin) announceFocus(current.focusWithin)
|
|
202
|
+
}}>
|
|
203
|
+
<span>Preview content</span>
|
|
204
|
+
</Box>
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Props
|
|
208
|
+
|
|
209
|
+
| Prop | Type | Default | Description |
|
|
210
|
+
|------|------|---------|-------------|
|
|
211
|
+
| `display?` | BoxDisplay | block | Layout model for the host. All other layout, sizing, mask, and shadow
|
|
212
|
+
properties stay ordinary `className` / `style` CSS on the Box itself. |
|
|
213
|
+
| `fade?` | boolean | — | Fades out every edge that currently hides clipped content, and drops the
|
|
214
|
+
fade from an edge once the reader scrolls to it. |
|
|
215
|
+
| `fadeSize?` | number \| string | 24 | Depth of the `fade` gradient. A `number` is pixels; a string is any CSS
|
|
216
|
+
length. |
|
|
217
|
+
| `gap?` | number \| string | — | Gap between children, matching the CSS `gap` property. A `number` is
|
|
218
|
+
pixels; a string is any CSS length or two-value gap (`'1rem'`,
|
|
219
|
+
`'8px 16px'`). Applies while the Box is a flex or grid container. |
|
|
220
|
+
| `observe?` | 'size' \| 'context' \| 'all' | — | What the Box watches, when a handler is not what turns it on. `'size'`
|
|
221
|
+
keeps the overflow CSS states (`:state(clipped-x)`, `:state(scrollable-y)`,
|
|
222
|
+
…) current — reach for it when your own CSS is the only reader. `'context'`
|
|
223
|
+
and `'all'` are there for symmetry; passing `onMeasureChange` or
|
|
224
|
+
`onContextChange` already turns the matching half on. |
|
|
225
|
+
| `onContextChange?` | (event, detail) => void | — | Fired after Box's browser and local rendering context changes. `detail`
|
|
226
|
+
contains the changed fields and a full current snapshot. |
|
|
227
|
+
| `onMeasureChange?` | (event, detail) => void | — | Fired after Box geometry or its content-overflow state changes. `detail`
|
|
228
|
+
contains the changed fields and a full current snapshot. |
|
|
229
|
+
| `round?` | boolean \| number \| string | — | Fully-round corners (`border-radius: 999px`, clamped to the box). Pass a
|
|
230
|
+
`number` (px) or a CSS length string (`'1rem'`) for a custom radius. Omit
|
|
231
|
+
for square corners. |
|
|
232
|
+
|
|
233
|
+
### BoxMeasurement
|
|
234
|
+
|
|
235
|
+
The `measurechange` payload, as `changed` (only what moved) and `current` (the
|
|
236
|
+
whole snapshot).
|
|
237
|
+
|
|
238
|
+
### BoxContext
|
|
239
|
+
|
|
240
|
+
The `contextchange` payload, in the same two shapes.
|
|
241
|
+
|
|
242
|
+
### BoxFont
|
|
243
|
+
|
|
244
|
+
`context.font`, the resolved text style.
|
|
245
|
+
|
|
246
|
+
### BoxInset
|
|
247
|
+
|
|
248
|
+
`context.inset`, the distance from the border edge to the content edge.
|
|
249
|
+
|
|
250
|
+
Use `<a-box>` when you assemble DOM without a JSX wrapper. Both events are
|
|
251
|
+
ordinary, non-bubbling `CustomEvent`s carrying the same detail object.
|
|
252
|
+
|
|
253
|
+
```html title="a-box"
|
|
254
|
+
<a-box display="grid" gap="8px" round="12px" observe="all" id="summary"
|
|
255
|
+
style="overflow: auto; max-height: 16rem">
|
|
256
|
+
<p>Summary content</p>
|
|
257
|
+
</a-box>
|
|
258
|
+
|
|
259
|
+
<script type="module">
|
|
260
|
+
import '@antadesign/anta/elements/a-box'
|
|
261
|
+
|
|
262
|
+
const box = document.querySelector('#summary')
|
|
263
|
+
box.addEventListener('measurechange', ({ detail }) => {
|
|
264
|
+
console.log(detail.changed, detail.current.scrollableY)
|
|
265
|
+
})
|
|
266
|
+
box.addEventListener('contextchange', ({ detail }) => {
|
|
267
|
+
console.log(detail.changed, detail.current.mode)
|
|
268
|
+
})
|
|
269
|
+
</script>
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
`gap`, `round`, and `fade-size` read their length through typed `attr()`, which
|
|
273
|
+
today only Chrome supports. The matching custom properties in the host's inline
|
|
274
|
+
style work everywhere and take precedence, so that is what the JSX wrapper sets:
|
|
275
|
+
|
|
276
|
+
```html
|
|
277
|
+
<a-box gap round fade
|
|
278
|
+
style="--box-gap: 8px; --box-round: 12px; --box-fade-size: 32px">Content</a-box>
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
`box.measurement`, `box.context`, and `box.isTruncated` read the same values
|
|
282
|
+
synchronously.
|
|
@@ -108,8 +108,8 @@ copying final item `current` when it represents the current page.
|
|
|
108
108
|
```
|
|
109
109
|
|
|
110
110
|
Use `copyUrl` to copy `location.href`, `copyNode` to copy a marked rendered
|
|
111
|
-
region, or `copy` for a known string.
|
|
112
|
-
|
|
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
113
|
|
|
114
114
|
### Props
|
|
115
115
|
|
|
@@ -288,11 +288,11 @@ carries a link back to where it came from.
|
|
|
288
288
|
<ButtonCopy copy={snippet} copyWithUrl label="Copy snippet" /> {/* snippet + source URL */}
|
|
289
289
|
```
|
|
290
290
|
|
|
291
|
-
###
|
|
291
|
+
### Copy dynamic text
|
|
292
292
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
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.
|
|
296
296
|
|
|
297
297
|
```tsx
|
|
298
298
|
const [report, setReport] = useState('')
|
|
@@ -300,16 +300,28 @@ const [report, setReport] = useState('')
|
|
|
300
300
|
<ButtonCopy
|
|
301
301
|
copy={report}
|
|
302
302
|
label="Copy report"
|
|
303
|
-
onCopyRequest={() => setReport(generateReport())}
|
|
303
|
+
onCopyRequest={() => setReport(generateReport())}
|
|
304
304
|
/>
|
|
305
305
|
```
|
|
306
306
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
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`).
|
|
313
325
|
|
|
314
326
|
### Props
|
|
315
327
|
|
|
@@ -342,10 +354,9 @@ because the write happens on the click.
|
|
|
342
354
|
activation, and removes the button from the tab order while active. |
|
|
343
355
|
| `onClick?` | (e) => void | — | Click handler. |
|
|
344
356
|
| `onCopied?` | (ok) => void | — | Fires after the copy attempt with whether it succeeded. |
|
|
345
|
-
| `onCopyRequest?` | () => void | — |
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
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. |
|
|
349
360
|
| `paddingless?` | boolean | — | Drops outer padding to zero. |
|
|
350
361
|
| `ping?` | string | — | Space-separated URLs the browser pings on navigation. |
|
|
351
362
|
| `priority?` | 'primary' \| 'secondary' \| 'tertiary' \| 'quaternary' | secondary | Visual emphasis. |
|
package/docs/components/input.md
CHANGED
|
@@ -545,6 +545,10 @@ file name, with an Anta-styled chooser button. `submit` and `reset` inputs use t
|
|
|
545
545
|
matching Anta button chrome; set `priority="primary"` on a submit control when it
|
|
546
546
|
is the form's main action.
|
|
547
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
|
+
|
|
548
552
|
Use `data-anta-size="small"` or `"large"` for field sizing. Native inputs own
|
|
549
553
|
their `size` attribute, so Anta does not reuse it. `round` and a custom-color
|
|
550
554
|
`tone` work the same way as Input.
|
|
@@ -557,6 +561,7 @@ their `size` attribute, so Anta does not reuse it. `round` and a custom-color
|
|
|
557
561
|
<input data-anta round type="url" name="site" placeholder="Rounded URL">
|
|
558
562
|
<input data-anta type="password" name="password" value="password">
|
|
559
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>
|
|
560
565
|
<input data-anta type="file" name="attachment" accept=".pdf,.docx">
|
|
561
566
|
|
|
562
567
|
<input data-anta type="submit" value="Submit" priority="primary">
|
package/docs/components/menu.md
CHANGED
|
@@ -366,12 +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
|
|
370
|
-
|
|
371
|
-
slotted `<a-copy>` element that performs the write, and
|
|
372
|
-
select so the check / retone feedback shows. `onCopied(ok)`
|
|
373
|
-
attempt. `iconPlacement="trailing"` moves the feedback glyph to
|
|
374
|
-
row; `"none"` shows a cursor-near confirmation instead.
|
|
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.
|
|
375
375
|
|
|
376
376
|
Copy sits alongside normal items, so a "Share" menu can mix a copy-link row with
|
|
377
377
|
navigating links.
|
|
@@ -421,15 +421,18 @@ navigating links.
|
|
|
421
421
|
carries `role` + `aria-checked`; only the drawn mark changes. Suppresses the
|
|
422
422
|
built-in checkbox / radio and the trailing `check` glyph. The node is made
|
|
423
423
|
passive (aria-hidden, no pointer events) so the row receives the click. |
|
|
424
|
-
| `kbd?` | string | — |
|
|
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. |
|
|
425
429
|
| `label?` | ReactNode | — | The item's text. Usually a string, but any node is accepted — e.g. a filtered
|
|
426
430
|
`Select` bolds the matched substring. Omit and pass `children` for richer
|
|
427
431
|
content. |
|
|
428
432
|
| `onCopied?` | (ok) => void | — | Fires after the copy attempt with whether it succeeded. |
|
|
429
|
-
| `onCopyRequest?` | () => void | — |
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
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. |
|
|
433
436
|
| `onMouseDown?` | (event) => void | — | Raw `mousedown` on the row. Mainly to `preventDefault()` so the row doesn't
|
|
434
437
|
take focus on a mouse press — e.g. a combobox option keeping focus in its
|
|
435
438
|
input field while the click still selects. |
|
package/docs/components/tag.md
CHANGED
|
@@ -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
|
@@ -21,6 +21,7 @@ Anta is designed for a clean DOM. Prefer the props and attributes exposed by eac
|
|
|
21
21
|
- [Tag](./components/tag.md)
|
|
22
22
|
- [Tooltip](./components/tooltip.md)
|
|
23
23
|
- [Icon](./components/icon.md)
|
|
24
|
+
- [Avatar](./components/avatar.md)
|
|
24
25
|
- [Loader](./components/loader.md)
|
|
25
26
|
- [Progress](./components/progress.md)
|
|
26
27
|
|
|
@@ -33,9 +34,6 @@ Anta is designed for a clean DOM. Prefer the props and attributes exposed by eac
|
|
|
33
34
|
- [Tabs](./components/tabs.md)
|
|
34
35
|
- [Steps](./components/steps.md)
|
|
35
36
|
|
|
36
|
-
- [Expander](./components/expander.md)
|
|
37
|
-
- [Menu](./components/menu.md)
|
|
38
|
-
|
|
39
37
|
- [Input](./components/input.md)
|
|
40
38
|
- [InputAutocomplete](./components/input-autocomplete.md)
|
|
41
39
|
- [InputDate](./components/input-date.md)
|
|
@@ -43,10 +41,13 @@ Anta is designed for a clean DOM. Prefer the props and attributes exposed by eac
|
|
|
43
41
|
- [Select](./components/select.md)
|
|
44
42
|
- [SelectFaceted](./components/select-faceted.md)
|
|
45
43
|
|
|
44
|
+
- [Box](./components/box.md)
|
|
46
45
|
- [Banner](./components/banner.md)
|
|
47
46
|
- [Card](./components/card.md)
|
|
48
47
|
- [Dialog](./components/dialog.md)
|
|
49
48
|
- [Toaster](./components/toaster.md)
|
|
49
|
+
- [Expander](./components/expander.md)
|
|
50
|
+
- [Menu](./components/menu.md)
|
|
50
51
|
|
|
51
52
|
## Packages
|
|
52
53
|
|