@antadesign/anta 0.3.17 → 0.3.19
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 +38 -242
- package/dist/components/Input.d.ts +4 -1
- package/dist/components/Input.js +2 -0
- package/dist/components/InputDate.css +1 -0
- package/dist/components/InputDate.d.ts +1 -0
- package/dist/components/InputDate.js +5 -5
- package/dist/components/Loader.d.ts +39 -0
- package/dist/components/Loader.js +33 -0
- package/dist/components/Menu.d.ts +5 -1
- package/dist/components/Menu.js +3 -2
- package/dist/components/Progress.d.ts +17 -8
- package/dist/components/Progress.js +12 -9
- package/dist/components/Select.d.ts +1 -0
- package/dist/components/Select.js +9 -13
- package/dist/components/SelectFaceted.d.ts +1 -0
- package/dist/components/SelectFaceted.js +29 -23
- package/dist/components/select-parts.css +1 -0
- package/dist/elements/a-button.css +1 -1
- package/dist/elements/a-icon.d.ts +1 -0
- package/dist/elements/a-icon.js +1 -0
- package/dist/elements/a-input.css +1 -1
- package/dist/elements/a-loader.css +1 -0
- package/dist/elements/a-loader.d.ts +12 -0
- package/dist/elements/a-loader.js +15 -0
- package/dist/elements/a-menu.js +12 -0
- package/dist/elements/a-progress.css +1 -1
- package/dist/elements/a-progress.js +32 -2
- package/dist/elements/a-slider.css +1 -1
- package/dist/elements/a-tabs.css +1 -1
- package/dist/elements/a-tabs.d.ts +3 -0
- package/dist/elements/a-tabs.js +40 -1
- package/dist/elements/index.d.ts +1 -0
- package/dist/elements/index.js +3 -0
- package/dist/general_types.d.ts +27 -2
- package/dist/index.d.ts +6 -1
- package/dist/index.js +2 -0
- package/dist/jsx-runtime.d.ts +11 -1
- package/dist/reset.css +1 -1
- package/dist/theme-anta.css +1 -1
- package/docs/accessibility.md +34 -0
- package/docs/changelog.md +551 -0
- package/docs/colors.md +42 -0
- package/docs/comparison.md +28 -0
- package/docs/components/banner.md +267 -0
- package/docs/components/button.md +603 -0
- package/docs/components/card.md +322 -0
- package/docs/components/checkbox.md +297 -0
- package/docs/components/dialog.md +314 -0
- package/docs/components/expander.md +529 -0
- package/docs/components/icon.md +155 -0
- package/docs/components/input-autocomplete.md +101 -0
- package/docs/components/input-date.md +406 -0
- package/docs/components/input-time.md +174 -0
- package/docs/components/input.md +610 -0
- package/docs/components/loader.md +139 -0
- package/docs/components/menu.md +447 -0
- package/docs/components/progress.md +182 -0
- package/docs/components/radio.md +369 -0
- package/docs/components/select-faceted.md +456 -0
- package/docs/components/select.md +931 -0
- package/docs/components/slider.md +142 -0
- package/docs/components/switch.md +198 -0
- package/docs/components/tabs.md +471 -0
- package/docs/components/tag.md +185 -0
- package/docs/components/text.md +148 -0
- package/docs/components/title.md +146 -0
- package/docs/components/toaster.md +313 -0
- package/docs/components/tooltip.md +177 -0
- package/docs/credits.md +22 -0
- package/docs/index.md +52 -0
- package/docs/install-config.md +240 -0
- package/docs/normalization.md +105 -0
- package/docs/overview.md +10 -0
- package/docs/packages/stickers.md +187 -0
- package/docs/packages/table.md +153 -0
- package/docs/theming.md +13 -0
- package/package.json +10 -6
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# Tooltip
|
|
2
|
+
|
|
3
|
+
A small floating bubble that describes the element it's placed inside. Render
|
|
4
|
+
`<Tooltip>` as a child of the element it annotates — it doesn't affect that
|
|
5
|
+
element's layout, and its content can be anything.
|
|
6
|
+
|
|
7
|
+
It shows on hover (after a short `delay`) and on keyboard focus, and dismisses
|
|
8
|
+
on mouse leave, blur, Esc, or when the anchor scrolls away. On touch
|
|
9
|
+
devices — where there's no hover and a tap shouldn't surface it — it opens on
|
|
10
|
+
**press-and-hold** and lingers briefly after you lift, so it stays readable. By
|
|
11
|
+
default the bubble is **pinned** under the anchor; pass `follow` to make it
|
|
12
|
+
**track the cursor** (fading out as the cursor moves away), or `interactive` to
|
|
13
|
+
make it hoverable and clickable (for content like links).
|
|
14
|
+
|
|
15
|
+
When the anchor implements **`getAnchorRect(): DOMRect`**, the bubble positions
|
|
16
|
+
against that rect instead of the anchor's full box. Anta's `Input` reports its
|
|
17
|
+
field box, so a tooltip on an `<Input>` points at the field, not the surrounding
|
|
18
|
+
label or hint.
|
|
19
|
+
|
|
20
|
+
## Examples
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
// Place <Tooltip> inside the element it describes; hover or focus the anchor.
|
|
24
|
+
// Pinned under the anchor by default — prefer the top side here (auto-flips
|
|
25
|
+
// down when there's no room).
|
|
26
|
+
<span style={{ cursor: 'help' }}>
|
|
27
|
+
Status
|
|
28
|
+
<Tooltip placement="top">Last checked 2 minutes ago</Tooltip>
|
|
29
|
+
</span>
|
|
30
|
+
|
|
31
|
+
// A near-instant tooltip on a keyboard-focusable button. Never use delay={0} — use ~50.
|
|
32
|
+
<Button priority="tertiary" underline="dashed" label="Focus me with the keyboard">
|
|
33
|
+
<Tooltip delay={50}>Shows on focus, dismiss with Esc</Tooltip>
|
|
34
|
+
</Button>
|
|
35
|
+
|
|
36
|
+
// `follow` tracks the cursor and fades by distance as you move away.
|
|
37
|
+
<Button label="Follow the cursor">
|
|
38
|
+
<Tooltip follow>Tracks the pointer, fades as you leave</Tooltip>
|
|
39
|
+
</Button>
|
|
40
|
+
|
|
41
|
+
// Rich content — render anything.
|
|
42
|
+
<Button icon="info">
|
|
43
|
+
<Tooltip placement="top">
|
|
44
|
+
<strong>Heads up</strong> — this action can't be undone
|
|
45
|
+
</Tooltip>
|
|
46
|
+
</Button>
|
|
47
|
+
|
|
48
|
+
// Interactive: the bubble becomes hoverable + clickable, so its content
|
|
49
|
+
// (links, buttons) works. Always pinned — a bubble that follows the cursor
|
|
50
|
+
// can't be entered, so `interactive` ignores `follow`. Move from the anchor
|
|
51
|
+
// into the bubble to click; press Esc to dismiss.
|
|
52
|
+
<Button label="Interact">
|
|
53
|
+
<Tooltip interactive placement="top">
|
|
54
|
+
See the <a href="/guide">full guide</a> for details
|
|
55
|
+
</Tooltip>
|
|
56
|
+
</Button>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
The underlying `<a-tooltip>` works in plain HTML too, as a child of any element:
|
|
60
|
+
|
|
61
|
+
```html
|
|
62
|
+
<button>
|
|
63
|
+
Publish
|
|
64
|
+
<a-tooltip>Makes the draft public</a-tooltip>
|
|
65
|
+
</button>
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Adjacent and nested tooltips
|
|
69
|
+
|
|
70
|
+
Only one tooltip shows at a time. Moving between **adjacent** anchors hands off
|
|
71
|
+
cleanly — the outgoing bubble cross-fades out as the next fades in (no blink).
|
|
72
|
+
With `follow` tooltips (used below to show it), the outgoing bubble also keeps
|
|
73
|
+
trailing the cursor and fades by distance from its anchor (transparent by ~100px
|
|
74
|
+
away), so a near hop reads as a smooth cross-fade and a far one is already gone.
|
|
75
|
+
With **nested** anchors, the inner (descendant) tooltip wins while you're over
|
|
76
|
+
it, and the outer takes back over when you leave. Hover the examples to feel it.
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
// Adjacent — moving from one to the next cross-fades, no blink. `follow` adds
|
|
80
|
+
// the cursor-trailing + distance fade so the hand-off is most visible.
|
|
81
|
+
<Button label="First"><Tooltip follow>First tooltip</Tooltip></Button>
|
|
82
|
+
<Button label="Second"><Tooltip follow>Second tooltip</Tooltip></Button>
|
|
83
|
+
|
|
84
|
+
// Nested — wrap stray text in a <span> so the tooltip stays a direct child of
|
|
85
|
+
// the box (its anchor). The inner tooltip wins while you're over the inner button.
|
|
86
|
+
<div tabIndex={0}>
|
|
87
|
+
<span>Outer box</span>
|
|
88
|
+
<Tooltip follow>Outer tooltip</Tooltip>
|
|
89
|
+
<Button label="Inner button"><Tooltip follow>Inner tooltip</Tooltip></Button>
|
|
90
|
+
</div>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Show only when truncated
|
|
94
|
+
|
|
95
|
+
Pass **`truncatedOnly`** and the tooltip appears only when its target's text is
|
|
96
|
+
actually ellipsized — a label that fits gets no tooltip. The check is a UI-thread
|
|
97
|
+
layout read, re-measured on each hover (so resizing the container flips it live). By
|
|
98
|
+
default it measures the nearest Anta ellipsizing label (`a-tab-label` /
|
|
99
|
+
`a-button-label`) inside the anchor, then the anchor itself; point it elsewhere with
|
|
100
|
+
**`truncatedSelector`**. Hover both — only the clipped one reveals its full text:
|
|
101
|
+
|
|
102
|
+
```tsx
|
|
103
|
+
{/* Only the clipped span shows a tooltip. The anchor IS the clipping box here,
|
|
104
|
+
so no selector is needed; inside a tab or <Button> the default finds the label. */}
|
|
105
|
+
<span style={{ maxWidth: 130, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
|
|
106
|
+
A long label that gets truncated
|
|
107
|
+
<Tooltip truncatedOnly>A long label that gets truncated</Tooltip>
|
|
108
|
+
</span>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Empty tooltips
|
|
112
|
+
|
|
113
|
+
A tooltip with nothing to show — no element children and no non-whitespace text —
|
|
114
|
+
doesn't open, so `<Tooltip>{maybeEmpty}</Tooltip>` never flashes a blank bubble. This
|
|
115
|
+
is automatic (no prop) and re-checked on each hover, so a tooltip whose content
|
|
116
|
+
arrives later works normally; a bubble whose content is cleared while it's open
|
|
117
|
+
closes itself. Content that's a single icon or image (an element, no text) still
|
|
118
|
+
shows.
|
|
119
|
+
|
|
120
|
+
### Props
|
|
121
|
+
|
|
122
|
+
| Prop | Type | Default | Description |
|
|
123
|
+
|------|------|---------|-------------|
|
|
124
|
+
| `children?` | ReactNode | — | Tooltip content. Renders anything — text, markup, an icon + text.
|
|
125
|
+
Lives in the light DOM, so it's styleable with your own plain CSS. |
|
|
126
|
+
| `delay?` | number | 300 | Show delay in milliseconds after hover / focus. Never use `0` — use
|
|
127
|
+
~`50` for a near-instant tooltip (0 has caused issues in practice). |
|
|
128
|
+
| `follow?` | boolean | — | Follow the cursor instead of pinning under the anchor. The bubble is
|
|
129
|
+
pinned (anchored beneath the target) by default; pass `follow` for the
|
|
130
|
+
cursor-tracking behaviour, which fades by distance as the cursor leaves. |
|
|
131
|
+
| `interactive?` | boolean | — | Make the bubble hoverable and clickable — enables pointer events and
|
|
132
|
+
keeps it open while the cursor is over it, so its content (links,
|
|
133
|
+
buttons) can be interacted with. Always pinned (an interactive bubble
|
|
134
|
+
can't follow the cursor, even with `follow`). |
|
|
135
|
+
| `placement?` | 'top' \| 'bottom' | bottom | Which side of the anchor the bubble prefers. Auto-flips to the other
|
|
136
|
+
side when there isn't room. |
|
|
137
|
+
| `round?` | boolean \| number \| string | — | Round the bubble to a 20px radius (matching a round menu). Pass a `number`
|
|
138
|
+
(px) or a CSS length string for a custom radius. |
|
|
139
|
+
| `truncatedOnly?` | boolean | — | Only show when the target is actually truncated (its text overflows and is
|
|
140
|
+
ellipsized); a label that fits gets no tooltip. The check is a UI-thread
|
|
141
|
+
layout read, re-measured on each show. By default it measures the nearest
|
|
142
|
+
Anta ellipsizing label part (`<a-tab-label>` / `<a-button-label>`) inside
|
|
143
|
+
the anchor, then the anchor itself — override with `truncatedSelector`. |
|
|
144
|
+
| `truncatedSelector?` | string | — | CSS selector (resolved within the anchor) for the element whose overflow
|
|
145
|
+
decides whether a `truncatedOnly` tooltip shows. |
|
|
146
|
+
|
|
147
|
+
Use this when you are not using the React or Preact wrapper and a native HTML control does not fit: construct the equivalent Anta web component from the elements below.
|
|
148
|
+
|
|
149
|
+
Place `<a-tooltip>` inside the element it describes.
|
|
150
|
+
|
|
151
|
+
```html
|
|
152
|
+
<a-button role="button" tabindex="0" priority="secondary">
|
|
153
|
+
<a-button-label>Publish</a-button-label>
|
|
154
|
+
<a-tooltip>Make the draft public</a-tooltip>
|
|
155
|
+
</a-button>
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The bubble lives in shadow DOM and is exposed as a single **part** — style the box
|
|
159
|
+
(background, frost, shadow, radius, padding, a border) with `::part(bubble)`. Its
|
|
160
|
+
*content* is slotted light DOM with a **normalized text baseline** (Anta body
|
|
161
|
+
typography), so it ignores the anchor's styling; to restyle the text, put a class on
|
|
162
|
+
the content you pass to `<Tooltip>` and target that (a rule on the content wins over
|
|
163
|
+
the baseline). Both together — hover the button to see it; the classes are just for
|
|
164
|
+
the demo:
|
|
165
|
+
|
|
166
|
+
```css
|
|
167
|
+
/* the bubble box — a shadow part */
|
|
168
|
+
a-tooltip.fancy::part(bubble) {
|
|
169
|
+
background: #1a161d;
|
|
170
|
+
border-radius: 10px;
|
|
171
|
+
padding: 8px 12px;
|
|
172
|
+
box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
|
|
173
|
+
backdrop-filter: none; /* opt out of the frost */
|
|
174
|
+
}
|
|
175
|
+
/* the slotted content — a class on what you pass to <Tooltip> */
|
|
176
|
+
.tip-rich { color: #fff; font-size: 15px; font-weight: 600; letter-spacing: 0.01em; }
|
|
177
|
+
```
|
package/docs/credits.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Credits
|
|
2
|
+
|
|
3
|
+
## Consumers
|
|
4
|
+
|
|
5
|
+
Anta is the design system behind Antithesis, its primary and main consumer.
|
|
6
|
+
|
|
7
|
+
## Maintainers
|
|
8
|
+
|
|
9
|
+
- Vlad Korobov — designer, engineer, manager
|
|
10
|
+
- Ksenia Toloknova — lead designer
|
|
11
|
+
- Leonid Kniazev — contributing designer
|
|
12
|
+
- Vehbi Karaagac — engineer
|
|
13
|
+
|
|
14
|
+
## Icons
|
|
15
|
+
|
|
16
|
+
Anta's icon set is built on the shoulders of several excellent open-source icon libraries. We're grateful to the maintainers and contributors of these projects:
|
|
17
|
+
|
|
18
|
+
- Lucide — the modern, beautifully consistent icon family that supplies the majority of Anta's icons (ISC license).
|
|
19
|
+
- Feather — the predecessor that Lucide forked from; a portion of icons trace their lineage back to Cole Bemis's original strokes (MIT license).
|
|
20
|
+
- Blueprint by Palantir — additional product-UI glyphs covering domains the previous two don't (Apache License 2.0).
|
|
21
|
+
|
|
22
|
+
Full license texts and per-icon attribution are reproduced verbatim in the package's NOTICES.md.
|
package/docs/index.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Anta documentation
|
|
2
|
+
|
|
3
|
+
Anta is designed for a clean DOM. Prefer the props and attributes exposed by each component over custom `className` or `style` definitions. Learn about Anta components from the documentation links and use them whenever they meet the need. For example, use `<Title>` instead of `<h1>` through `<h6>`, `<Text>` instead of a styled `<div>` or `<p>`, and `<Tooltip>` instead of an element's `title` attribute. Refer to each component's documentation page to learn about configuration, customization, and styling.
|
|
4
|
+
|
|
5
|
+
## Documentation
|
|
6
|
+
|
|
7
|
+
- [Overview](./overview.md)
|
|
8
|
+
- [Comparison](./comparison.md)
|
|
9
|
+
- [Install & Config](./install-config.md)
|
|
10
|
+
- [Normalization](./normalization.md)
|
|
11
|
+
- [Colors](./colors.md)
|
|
12
|
+
- [Theming](./theming.md)
|
|
13
|
+
- [Accessibility](./accessibility.md)
|
|
14
|
+
- [Credits](./credits.md)
|
|
15
|
+
- [Changelog](./changelog.md)
|
|
16
|
+
|
|
17
|
+
## Components
|
|
18
|
+
|
|
19
|
+
- [Title](./components/title.md)
|
|
20
|
+
- [Text](./components/text.md)
|
|
21
|
+
- [Tag](./components/tag.md)
|
|
22
|
+
- [Tooltip](./components/tooltip.md)
|
|
23
|
+
- [Icon](./components/icon.md)
|
|
24
|
+
- [Loader](./components/loader.md)
|
|
25
|
+
- [Progress](./components/progress.md)
|
|
26
|
+
|
|
27
|
+
- [Button](./components/button.md)
|
|
28
|
+
- [Checkbox](./components/checkbox.md)
|
|
29
|
+
- [Radio](./components/radio.md)
|
|
30
|
+
- [Switch](./components/switch.md)
|
|
31
|
+
- [Slider](./components/slider.md)
|
|
32
|
+
- [Tabs](./components/tabs.md)
|
|
33
|
+
|
|
34
|
+
- [Expander](./components/expander.md)
|
|
35
|
+
- [Menu](./components/menu.md)
|
|
36
|
+
|
|
37
|
+
- [Input](./components/input.md)
|
|
38
|
+
- [InputAutocomplete](./components/input-autocomplete.md)
|
|
39
|
+
- [InputDate](./components/input-date.md)
|
|
40
|
+
- [InputTime](./components/input-time.md)
|
|
41
|
+
- [Select](./components/select.md)
|
|
42
|
+
- [SelectFaceted](./components/select-faceted.md)
|
|
43
|
+
|
|
44
|
+
- [Banner](./components/banner.md)
|
|
45
|
+
- [Card](./components/card.md)
|
|
46
|
+
- [Dialog](./components/dialog.md)
|
|
47
|
+
- [Toaster](./components/toaster.md)
|
|
48
|
+
|
|
49
|
+
## Packages
|
|
50
|
+
|
|
51
|
+
- [Table](./packages/table.md)
|
|
52
|
+
- [Stickers](./packages/stickers.md)
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
# Install & Config
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm install @antadesign/anta # or pnpm / bun
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Pin an exact version in `package.json` (`"@antadesign/anta": "0.3.16"`) instead
|
|
10
|
+
of a floating tag such as `"latest"`.
|
|
11
|
+
|
|
12
|
+
### Usage
|
|
13
|
+
|
|
14
|
+
```tsx
|
|
15
|
+
import '@antadesign/anta/tokens.css' // CSS custom properties
|
|
16
|
+
import '@antadesign/anta/reset.css' // reset and typography defaults
|
|
17
|
+
import '@antadesign/anta/elements' // registers <a-*> elements
|
|
18
|
+
import { Progress } from '@antadesign/anta'
|
|
19
|
+
|
|
20
|
+
<Progress value={42} label="Uploaded" hint="3 of 7" />
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### What you import (and why)
|
|
24
|
+
|
|
25
|
+
Tokens, elements, and the JSX layer render a styled component. The reset is
|
|
26
|
+
recommended; the reference theme is optional.
|
|
27
|
+
|
|
28
|
+
| Import | Provides | Skip if… |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `@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. |
|
|
31
|
+
| `@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. |
|
|
32
|
+
| `@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. |
|
|
33
|
+
| `@antadesign/anta` | Typed React/Preact wrappers such as `Progress`, `Text`, and `Icon`. | You write `<a-*>` elements directly. |
|
|
34
|
+
| `@antadesign/anta/theme-anta.css` *(optional)* | The hand-tuned reference palette. Import last to replace the seed-derived default. | You want the seed-derived or your own palette. |
|
|
35
|
+
|
|
36
|
+
Load `tokens.css` before element CSS. Elements read its variables; without it,
|
|
37
|
+
they render unstyled.
|
|
38
|
+
|
|
39
|
+
### Cascade layers
|
|
40
|
+
|
|
41
|
+
Anta's reset and element CSS live in `@layer anta`. `tokens.css` declares
|
|
42
|
+
`@layer base, anta, components, utilities`, placing Anta above preflight resets
|
|
43
|
+
and below your component and utility layers.
|
|
44
|
+
|
|
45
|
+
To change that order, declare it in CSS loaded **before** `tokens.css`. The
|
|
46
|
+
first declaration fixes a layer's position:
|
|
47
|
+
|
|
48
|
+
```css
|
|
49
|
+
/* your global.css, loaded before anta */
|
|
50
|
+
@layer reset, anta, my-components, utilities;
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Token custom properties stay unlayered so they apply everywhere.
|
|
54
|
+
|
|
55
|
+
> **Gotcha: an unlayered hard reset defeats Anta's element rules.**
|
|
56
|
+
>
|
|
57
|
+
> ```css
|
|
58
|
+
> *, *::before, *::after { box-sizing: border-box; }
|
|
59
|
+
> * { margin: 0; }
|
|
60
|
+
> ```
|
|
61
|
+
>
|
|
62
|
+
> Unlayered styles beat layered ones regardless of specificity. This reset
|
|
63
|
+
> overrides Anta's element defaults. Delete the duplicate, or put your reset in
|
|
64
|
+
> `@layer base { … }`; `reset.css` already applies the same universal reset in
|
|
65
|
+
> `@layer anta`.
|
|
66
|
+
|
|
67
|
+
## Registering elements
|
|
68
|
+
|
|
69
|
+
JSX wrappers render `<a-*>` tags. Register their classes before those tags reach
|
|
70
|
+
the DOM. Registration needs `HTMLElement`, so the import is a no-op in Node.js
|
|
71
|
+
and Worker threads.
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import '@antadesign/anta/elements' // auto-registers all elements
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`/elements` registers everything. Per-element entries register one element and
|
|
78
|
+
load only its CSS:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import '@antadesign/anta/elements/a-tooltip' // only <a-tooltip> + its CSS
|
|
82
|
+
import '@antadesign/anta/elements/a-button' // only <a-button> + its CSS
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Both are idempotent, side-effect imports and safe during SSR.
|
|
86
|
+
|
|
87
|
+
Use a static import in your app entry, outside components and hooks:
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
// src/main.tsx (or wherever your root render lives)
|
|
91
|
+
import '@antadesign/anta/elements'
|
|
92
|
+
import { createRoot } from 'react-dom/client'
|
|
93
|
+
import App from './App'
|
|
94
|
+
createRoot(document.getElementById('root')!).render(<App />)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Module initialisation registers the classes before the first render, avoiding a
|
|
98
|
+
flash of un-upgraded elements.
|
|
99
|
+
|
|
100
|
+
> **Why not `useEffect(() => import('@antadesign/anta/elements'), [])`?**
|
|
101
|
+
> `useEffect` runs after paint and the import resolves later. The browser can
|
|
102
|
+
> paint unregistered elements first. `useLayoutEffect` is still asynchronous and
|
|
103
|
+
> warns during SSR hydration.
|
|
104
|
+
|
|
105
|
+
Choose the entry point for your runtime:
|
|
106
|
+
|
|
107
|
+
- **Plain HTML or static sites:** a `<script type="module">` in the document head.
|
|
108
|
+
- **Astro or Next.js:** a client-only script. In Astro, use
|
|
109
|
+
`<script>import '@antadesign/anta/elements'</script>`; in Next.js, import it
|
|
110
|
+
from a `'use client'` file.
|
|
111
|
+
- **Worker-rendered UI:** the UI-thread bootstrap that owns the DOM. A Worker
|
|
112
|
+
has no `HTMLElement`.
|
|
113
|
+
|
|
114
|
+
## Framework setup
|
|
115
|
+
|
|
116
|
+
### React
|
|
117
|
+
|
|
118
|
+
Works out of the box.
|
|
119
|
+
|
|
120
|
+
### Preact with compat
|
|
121
|
+
|
|
122
|
+
If your bundler aliases `react` to `preact/compat`, Anta works without setup.
|
|
123
|
+
|
|
124
|
+
### Preact without compat
|
|
125
|
+
|
|
126
|
+
Call `configure()` before rendering any anta components:
|
|
127
|
+
|
|
128
|
+
```ts
|
|
129
|
+
import { configure } from '@antadesign/anta'
|
|
130
|
+
import { h, Fragment } from 'preact'
|
|
131
|
+
configure(h, Fragment)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### TypeScript: typing raw `<a-*>` tags in JSX
|
|
135
|
+
|
|
136
|
+
JSX wrappers such as `<Button>` and `<Progress>` need no extra typing. Configure
|
|
137
|
+
JSX only when you write raw `<a-*>` tags.
|
|
138
|
+
|
|
139
|
+
**Option A (preferred)** — point JSX types at Anta in `tsconfig.json`:
|
|
140
|
+
|
|
141
|
+
```jsonc
|
|
142
|
+
{ "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "@antadesign/anta" } }
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Every `a-*` tag type-checks, standard HTML tags keep working, and importing
|
|
146
|
+
`@antadesign/stickers` adds its tags automatically.
|
|
147
|
+
|
|
148
|
+
**Option B** — if `jsxImportSource` cannot change, merge Anta's tag map into
|
|
149
|
+
your JSX namespace with `AntaIntrinsicElements` (and `StickerIntrinsicElements`
|
|
150
|
+
when needed):
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
import type { AntaIntrinsicElements } from '@antadesign/anta'
|
|
154
|
+
import type { StickerIntrinsicElements } from '@antadesign/stickers' // only if you use stickers
|
|
155
|
+
|
|
156
|
+
declare global {
|
|
157
|
+
namespace JSX {
|
|
158
|
+
interface IntrinsicElements extends AntaIntrinsicElements, StickerIntrinsicElements {}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
With `@types/react` 18+ and `jsx: "react-jsx"`, JSX is module-scoped. Extend
|
|
164
|
+
the `react` module instead:
|
|
165
|
+
|
|
166
|
+
```ts
|
|
167
|
+
import type { AntaIntrinsicElements } from '@antadesign/anta'
|
|
168
|
+
|
|
169
|
+
declare module 'react' {
|
|
170
|
+
namespace JSX {
|
|
171
|
+
interface IntrinsicElements extends AntaIntrinsicElements {}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Both options reject unknown tags and invalid props. New tags arrive with Anta
|
|
177
|
+
upgrades; there is no per-tag list to maintain.
|
|
178
|
+
|
|
179
|
+
### Raw web components (no JSX)
|
|
180
|
+
|
|
181
|
+
Elements also work in plain HTML. Registration loads their CSS; resolve the bare
|
|
182
|
+
specifier with a bundler or import map.
|
|
183
|
+
|
|
184
|
+
```html
|
|
185
|
+
<script type="module">
|
|
186
|
+
import '@antadesign/anta/elements'
|
|
187
|
+
</script>
|
|
188
|
+
|
|
189
|
+
<a-progress value="42" max="100" tone="info"></a-progress>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Dark mode
|
|
193
|
+
|
|
194
|
+
Add the `dark` class to any ancestor element:
|
|
195
|
+
|
|
196
|
+
```html
|
|
197
|
+
<div class="dark">
|
|
198
|
+
<Progress value={50} />
|
|
199
|
+
</div>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
## Fonts
|
|
203
|
+
|
|
204
|
+
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`).
|
|
205
|
+
|
|
206
|
+
To use the Antithesis fonts, register your own `@font-face` declarations and override the variables:
|
|
207
|
+
|
|
208
|
+
```css
|
|
209
|
+
@font-face {
|
|
210
|
+
font-family: "Antithesis sans";
|
|
211
|
+
src: url("/path/to/your/sans.woff2") format("woff2");
|
|
212
|
+
/* ... */
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
:root {
|
|
216
|
+
--sans-serif: "Antithesis sans", sans-serif;
|
|
217
|
+
--monospace: "Antithesis mono", monospace;
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Browser support
|
|
222
|
+
|
|
223
|
+
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):
|
|
224
|
+
|
|
225
|
+
| Browser | Minimum version |
|
|
226
|
+
| --- | --- |
|
|
227
|
+
| Chrome / Edge | 125 (May 2024) |
|
|
228
|
+
| Safari | 17.4 (Mar 2024) |
|
|
229
|
+
| Firefox | 126 (May 2024) |
|
|
230
|
+
|
|
231
|
+
This is [Baseline 2024](https://web.dev/baseline). Anta also relies on relative
|
|
232
|
+
OKLCH, `:has()`, `dvh`, cascade layers, and constructable shadow DOM. Older
|
|
233
|
+
browsers can fail hard, including `:state()` being unrecognized or
|
|
234
|
+
`showPopover()` throwing. Gate Anta on your own support matrix when you support
|
|
235
|
+
older browsers.
|
|
236
|
+
|
|
237
|
+
Two features progressively enhance with fallbacks: `checkVisibility()` falls
|
|
238
|
+
back to `getClientRects()`, and typed CSS `attr()` supports raw
|
|
239
|
+
`<a-icon size>` in Chrome 133+ and Safari 18.2+. Elsewhere use `<Icon size>`
|
|
240
|
+
or `--icon-size`.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Normalization
|
|
2
|
+
|
|
3
|
+
Anta ships an opinionated reset + typography baseline in **`reset.css`**, so plain
|
|
4
|
+
HTML (`<h2>`, `<ul>`, `<a>`, `<table>`…) renders in the same visual language as the
|
|
5
|
+
components — no per-page restyling to make prose match a `<Title>` or a `<Table>`.
|
|
6
|
+
|
|
7
|
+
It's a **separate import**, and every rule lives in a single cascade layer
|
|
8
|
+
(`@layer anta`), so it's easy to layer your own reset around it or override any
|
|
9
|
+
piece. If you'd rather bring your own reset, just don't import this one.
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
import '@antadesign/anta/tokens.css' // design tokens
|
|
13
|
+
import '@antadesign/anta/reset.css' // ← this page (optional)
|
|
14
|
+
import '@antadesign/anta/elements' // web components (client-side only)
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## What it normalizes
|
|
18
|
+
|
|
19
|
+
### Structural reset
|
|
20
|
+
|
|
21
|
+
- `box-sizing: border-box` on every element (and `::before` / `::after`).
|
|
22
|
+
- `margin: 0` on everything — apps build spacing from explicit values.
|
|
23
|
+
- Replaced elements (`img`, `picture`, `video`, `canvas`, `svg`) → `display: block` + `max-width: 100%`, so a stray large asset can't blow out the layout.
|
|
24
|
+
- Form controls (`input`, `button`, `textarea`, `select`) → `font: inherit`.
|
|
25
|
+
- Keyboard-focused elements → a 1px `--focus-ring` outline. Component-specific
|
|
26
|
+
focus styles keep their own geometry.
|
|
27
|
+
- `overflow-wrap: break-word` on paragraphs + headings; `text-wrap: pretty` on `<p>` and `text-wrap: balance` on headings.
|
|
28
|
+
|
|
29
|
+
### Typography (Anta's opinion)
|
|
30
|
+
|
|
31
|
+
This is **not** a neutral normalize — these defaults make raw markup match the components.
|
|
32
|
+
|
|
33
|
+
- **Headings** adopt the exact scale of `<Title level={n}>` — `h1`–`h6` sizes, line-heights, weight `≈585`, `letter-spacing: 0`, color `--text-1` (kept in lockstep with `a-title.css`) — plus per-level block margins for document rhythm. Those margins live only on the raw headings: `<Title>` itself is margin-free and leaves spacing to its container, so running prose gets the rhythm while the component stays neutral.
|
|
34
|
+
- `strong` → `font-weight: 600`.
|
|
35
|
+
- `dfn` (defined term) → non-italic, with a dotted underline at half the surrounding text's strength (`3px` offset) in place of the UA italic. No `cursor: help` — that's for where the term is actually hoverable.
|
|
36
|
+
- Inline `code` → `line-height: 1em` so it doesn't inflate the line box of surrounding prose.
|
|
37
|
+
- **Lists** (`ul` / `ol`): `3ch` left padding so markers hug the text; a small bottom margin between items; markers toned to `--text-5`.
|
|
38
|
+
- `menu` is stripped to a clean semantic container (no disc markers / default padding).
|
|
39
|
+
- **Links** get `--link-color` with a hairline underline (75% alpha, `0.5px`); hover only thickens it to `1px` (no color repaint). Anchor-buttons (`<a role="button">`) are excluded so they keep button styling.
|
|
40
|
+
- `::selection` → the focus-ring colour, tuned per theme (20% alpha in light, 30% in dark).
|
|
41
|
+
- **Tables**: `border-collapse`, `tabular-nums`, and a polite cell baseline; opt into a framed look with `<table data-bordered>` (outer frame + column dividers + rounded corners).
|
|
42
|
+
|
|
43
|
+
Everything above is defined in `src/reset.css`, inside `@layer anta` — read that file
|
|
44
|
+
for the authoritative set (it's short and commented). The headings block is duplicated
|
|
45
|
+
in `src/elements/a-title.css`; the two are kept in sync.
|
|
46
|
+
|
|
47
|
+
## Cascade layers — how to override
|
|
48
|
+
|
|
49
|
+
Anta declares this layer order once (in `tokens.css`):
|
|
50
|
+
|
|
51
|
+
```css
|
|
52
|
+
@layer base, anta, components, utilities;
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Everything Anta ships — this reset **and** the element styles — lives in **`@layer anta`**. That placement is deliberate:
|
|
56
|
+
|
|
57
|
+
- **Above `base`** — a framework preflight you drop into `@layer base` (e.g. Tailwind) won't wipe Anta's typography.
|
|
58
|
+
- **Below `components` and `utilities`** — your own component or utility CSS overrides Anta with no specificity battles.
|
|
59
|
+
- **Unlayered CSS beats every layer** — so any plain rule you write already wins over Anta's reset, no `!important` needed.
|
|
60
|
+
|
|
61
|
+
> **Gotcha — don't re-add a _universal_ hard reset unlayered.** Overriding a
|
|
62
|
+
> *specific* element unlayered is the intended escape hatch (below). But a blanket
|
|
63
|
+
> `* { margin: 0 }` / `*, *::before, *::after { box-sizing: border-box }` left
|
|
64
|
+
> **unlayered** also outranks Anta's *per-element* defaults — its `p`, `caption`,
|
|
65
|
+
> and `ul / ol` margins — because unlayered wins over `@layer anta` regardless of
|
|
66
|
+
> specificity. Anta already runs that universal `*` reset itself, inside
|
|
67
|
+
> `@layer anta`, so the copy-pasted duplicate is redundant *and* harmful: delete it,
|
|
68
|
+
> or if you keep your own reset wrap it in `@layer base { … }` (below `anta`) so
|
|
69
|
+
> Anta's element defaults still apply.
|
|
70
|
+
|
|
71
|
+
### Override one thing
|
|
72
|
+
|
|
73
|
+
Write the rule unlayered (or in a layer after `anta`) — targeting a **specific** element, not `*`:
|
|
74
|
+
|
|
75
|
+
```css
|
|
76
|
+
/* wins over Anta's @layer anta reset — no !important */
|
|
77
|
+
h2 { letter-spacing: -0.01em; }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Bring your own reset
|
|
81
|
+
|
|
82
|
+
Because `reset.css` is a separate import, you can simply **not import it** and let your
|
|
83
|
+
own reset govern typography — keep the tokens and elements:
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
import '@antadesign/anta/tokens.css' // keep — tokens
|
|
87
|
+
import '@antadesign/anta/elements' // keep — components
|
|
88
|
+
// no '@antadesign/anta/reset.css' // your reset is in charge
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**One dependency to keep:** Anta's elements don't set their own `box-sizing` — they
|
|
92
|
+
assume the global `* { box-sizing: border-box }` that this reset provides. Every common
|
|
93
|
+
reset (normalize.css, Tailwind's preflight, etc.) sets it too, so swapping resets is
|
|
94
|
+
normally seamless; but if yours doesn't, keep that one rule or component padding,
|
|
95
|
+
`max-width`, and icon-button sizing will be slightly off.
|
|
96
|
+
|
|
97
|
+
Or import both and override only the pieces you want (unlayered, or in a later layer).
|
|
98
|
+
|
|
99
|
+
## Why it's opinionated
|
|
100
|
+
|
|
101
|
+
A blank-slate reset would leave headings, lists, links, and tables looking like raw
|
|
102
|
+
browser defaults — out of step with the components beside them. Anta's reset instead
|
|
103
|
+
gives plain markup the same baseline as `<Title>`, `<Table>`, and the link styles, so a
|
|
104
|
+
page mixing prose and components reads as one system. When you want a clean slate, opt
|
|
105
|
+
out above.
|
package/docs/overview.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
Anta is Antithesis's design system. It combines global CSS tokens,
|
|
4
|
+
framework-agnostic declarative web components, and JSX wrappers for dynamic
|
|
5
|
+
state and conditional composition.
|
|
6
|
+
|
|
7
|
+
Components use an attribute-driven DOM instead of utility-class stacks and
|
|
8
|
+
wrapper elements. Web components never mutate their own attributes, so they
|
|
9
|
+
work with Worker-driven UIs and other reactive renderers. JSX wrappers provide
|
|
10
|
+
the React and Preact integration layer.
|