@antadesign/anta 0.3.33 → 0.3.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/dist/bundle.css +1 -1
  2. package/dist/bundle.js +21 -41
  3. package/dist/components/Breadcrumbs.d.ts +0 -1
  4. package/dist/components/Breadcrumbs.js +0 -1
  5. package/dist/components/Button.d.ts +2 -3
  6. package/dist/components/InputDate.d.ts +0 -1
  7. package/dist/components/InputDate.js +0 -1
  8. package/dist/components/Select.d.ts +0 -1
  9. package/dist/components/Select.js +0 -1
  10. package/dist/components/SelectFaceted.d.ts +0 -1
  11. package/dist/components/SelectFaceted.js +0 -1
  12. package/dist/components/Steps.d.ts +0 -1
  13. package/dist/components/Steps.js +0 -1
  14. package/dist/components/Tabs.js +2 -1
  15. package/dist/components/Title.d.ts +3 -1
  16. package/dist/elements/a-avatar.css +1 -1
  17. package/dist/elements/a-avatar.js +2 -28
  18. package/dist/elements/a-breadcrumbs.d.ts +1 -0
  19. package/dist/elements/a-breadcrumbs.js +1 -0
  20. package/dist/elements/a-button.css +1 -1
  21. package/dist/elements/a-button.d.ts +8 -6
  22. package/dist/elements/a-dialog.js +3 -1
  23. package/dist/elements/a-input-date.d.ts +1 -0
  24. package/dist/elements/a-input-date.js +1 -0
  25. package/dist/elements/a-input.js +2 -2
  26. package/dist/elements/a-select-faceted.d.ts +1 -0
  27. package/dist/elements/a-select-faceted.js +1 -0
  28. package/dist/elements/a-select.d.ts +1 -0
  29. package/dist/elements/a-select.js +1 -0
  30. package/dist/elements/a-steps.d.ts +1 -0
  31. package/dist/elements/a-steps.js +1 -0
  32. package/dist/elements/a-tabpanel.d.ts +2 -2
  33. package/dist/elements/a-tabpanel.js +13 -3
  34. package/dist/elements/a-tag.d.ts +1 -0
  35. package/dist/elements/a-tag.js +1 -0
  36. package/dist/elements/a-title.d.ts +1 -0
  37. package/dist/elements/a-title.js +1 -0
  38. package/dist/elements/index.d.ts +7 -1
  39. package/dist/elements/index.js +4 -0
  40. package/dist/theme-antithesis.css +1 -1
  41. package/dist/theme-antune.css +1 -1
  42. package/docs/changelog.md +36 -0
  43. package/docs/components/breadcrumbs.md +9 -6
  44. package/docs/components/steps.md +4 -2
  45. package/docs/install-config.md +295 -87
  46. package/docs/packages/plot.md +64 -1
  47. package/docs/theming.md +22 -13
  48. package/package.json +4 -3
@@ -9,55 +9,127 @@ npm install @antadesign/anta # or pnpm / bun
9
9
  Pin an exact version in `package.json` (`"@antadesign/anta": "0.3.16"`) instead
10
10
  of a floating tag such as `"latest"`.
11
11
 
12
- ### Usage
12
+ ### Full bundle
13
+
14
+ Use the full bundle as the default setup. Import the JavaScript entry and its
15
+ stylesheet in your browser app entry:
13
16
 
14
17
  ```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 '@antadesign/anta/theme-antune.css' // optional Antune theme
19
- import { Progress } from '@antadesign/anta'
18
+ import '@antadesign/anta/bundle.css'
19
+ import { Progress } from '@antadesign/anta/bundle'
20
20
 
21
21
  <Progress value={42} label="Uploaded" hint="3 of 7" />
22
22
  ```
23
23
 
24
- ### Full bundle
24
+ `bundle` registers every custom element and exports the JSX wrappers.
25
+ `bundle.css` contains global tokens, the reset, element styles, and composed
26
+ wrapper styles. The JavaScript bundle does not import this stylesheet, so keep
27
+ both imports. Its React peer dependency and Preact configuration are the same
28
+ as the regular JSX entry.
29
+
30
+ Use this pair together. Adding granular element imports also loads their CSS,
31
+ duplicating rules already in `bundle.css`.
25
32
 
26
- For a single minified Anta runtime and stylesheet, use the bundle pair instead
27
- of the separate tokens, reset, elements, and JSX imports:
33
+ ### Granular usage (advanced)
34
+
35
+ Use granular imports to choose which browser elements and styles your app loads,
36
+ or to render JSX on a server or in a worker. Load shared tokens once, optionally
37
+ include the reset, and import the element entries you use:
28
38
 
29
39
  ```tsx
30
- import '@antadesign/anta/bundle.css'
31
- import { Progress } from '@antadesign/anta/bundle'
40
+ import '@antadesign/anta/tokens.css'
41
+ import '@antadesign/anta/reset.css'
42
+ import '@antadesign/anta/elements/a-progress'
43
+ import '@antadesign/anta/elements/a-title'
44
+ import '@antadesign/anta/elements/a-tag'
45
+ import { Progress, Title, Tag } from '@antadesign/anta'
46
+
47
+ <>
48
+ <Title>Uploads</Title>
49
+ <Progress value={42} label="Uploaded" hint="3 of 7" />
50
+ <Tag>In progress</Tag>
51
+ </>
52
+ ```
32
53
 
33
- <Progress value={42} label="Uploaded" hint="3 of 7" />
54
+ Each element entry imports its own CSS for your bundler to include and registers
55
+ its browser class when needed. Title and Tag load only CSS; they have no custom
56
+ element class to register. Element entries do not import global tokens or the reset.
57
+
58
+ JSX wrappers produce `<a-*>` tags and attributes. They do not register browser
59
+ elements or import CSS. Load element entries in the browser's UI thread;
60
+ see [Registering elements](#registering-elements) for server and worker rendering.
61
+
62
+ Composed components have CSS-only entries for their layout styles:
63
+
64
+ | JSX wrapper | UI-side style entry |
65
+ |---|---|
66
+ | `Breadcrumbs` | `@antadesign/anta/elements/a-breadcrumbs` |
67
+ | `Steps` | `@antadesign/anta/elements/a-steps` |
68
+ | `InputDate` | `@antadesign/anta/elements/a-input-date` |
69
+ | `Select` | `@antadesign/anta/elements/a-select` |
70
+ | `SelectFaceted` | `@antadesign/anta/elements/a-select-faceted` |
71
+
72
+ These entries load layout CSS without registering a class or loading nested
73
+ elements. Import the browser elements used by the composition too. For example,
74
+ `Steps` uses Tabs and Tooltip, and may render icons, loaders, or panels depending
75
+ on its props:
76
+
77
+ ```ts
78
+ // Browser UI entry, alongside shared tokens and the optional reset.
79
+ import '@antadesign/anta/elements/a-steps'
80
+ import '@antadesign/anta/elements/a-tabs'
81
+ import '@antadesign/anta/elements/a-tab'
82
+ import '@antadesign/anta/elements/a-tabpanel'
83
+ import '@antadesign/anta/elements/a-tooltip'
84
+ import '@antadesign/anta/elements/a-icon'
85
+ import '@antadesign/anta/elements/a-loader'
34
86
  ```
35
87
 
36
- `bundle` registers every custom element and re-exports the JSX API. Its React
37
- peer dependency and Preact configuration are the same as the regular JSX entry.
88
+ Import `Steps` from `@antadesign/anta` where you render JSX, including in a worker
89
+ or on the server. Select and SelectFaceted share one stylesheet, which bundlers
90
+ include once when both style entries are imported.
38
91
 
39
- ### What you import (and why)
92
+ To load all elements through the separate entries, replace the per-element imports
93
+ with `import '@antadesign/anta/elements'`. Keep the tokens and optional reset.
40
94
 
41
- Tokens, elements, and the JSX layer render a styled component. The reset is
42
- recommended; the reference theme is optional.
95
+ Individual stylesheets are also exported for direct CSS imports. With a bundler
96
+ that supports `?raw`, you can read a stylesheet as text:
43
97
 
44
- | Import | Provides | Skip if… |
45
- |---|---|---|
46
- | `@antadesign/anta/tokens.css` | Six seed tokens, derived role scales (`--bg-1…5`, `--text-1…5`, `--border-1…5`), `.dark` and its `color-scheme`, the 15px root size, and layer order. Override a seed to reskin its tone. | You provide those variables. |
47
- | `@antadesign/anta/reset.css` | A small reset plus Anta's focus, heading, list, and link typography in `@layer anta.reset`. | You use another reset and typography. |
48
- | `@antadesign/anta/elements` | Registers every `<a-*>` element and its CSS. Per-element entries register one; see [Registering elements](#registering-elements). | You render only on the server or register elements individually. |
49
- | `@antadesign/anta` | Typed React/Preact wrappers such as `Progress`, `Text`, and `Icon`. | You write `<a-*>` elements directly. |
50
- | `@antadesign/anta/bundle.css` | One minified stylesheet containing tokens, reset, element, and JSX-wrapper styles. | You want granular CSS imports. |
51
- | `@antadesign/anta/bundle` | One minified ESM runtime that registers every `<a-*>` element and re-exports the JSX API. | You want granular JS imports. |
52
- | `@antadesign/anta/theme-antune.css` *(optional)* | Antune, the hand-tuned reference palette. Import last to replace the seed-derived default. | You want the seed-derived or your own palette. |
53
- | `@antadesign/anta/theme-antithesis.css` *(optional)* | Antithesis: warm color seeds, pill buttons, square text fields, and `1px` tag corners. Import as the only theme. | You want Antune, the seed-derived palette, or your own theme. |
98
+ ```ts
99
+ import titleCss from '@antadesign/anta/elements/a-title.css?raw'
100
+ ```
54
101
 
55
- Load `tokens.css` before element CSS. Elements read its variables; without it,
56
- they render unstyled.
102
+ This returns CSS text; it does not apply styles or register an element.
57
103
 
58
- To use the optional reference palette, import `theme-antune.css` after the element
59
- registration import. It ships in `@antadesign/anta`; omit it to keep the
60
- seed-derived default palette or provide your own theme.
104
+ ### Optional theme
105
+
106
+ Add one optional theme after either the full bundle CSS or the granular styles:
107
+
108
+ ```ts
109
+ import '@antadesign/anta/theme-antune.css'
110
+ ```
111
+
112
+ Use `theme-antithesis.css` for Antithesis, or omit both themes to keep the
113
+ seed-derived default palette. These theme files do not load fonts. Choose fonts
114
+ separately; see [Fonts](#fonts).
115
+
116
+ ### What you import (and why)
117
+
118
+ | Import | Provides |
119
+ |---|---|
120
+ | `@antadesign/anta/bundle` | All browser element definitions and the JSX API in one minified ESM runtime. |
121
+ | `@antadesign/anta/bundle.css` | Global tokens, reset, element, and composed wrapper styles in one minified stylesheet. |
122
+ | `@antadesign/anta/tokens.css` | Shared color roles, fonts, dark-mode support, and layer order for granular usage. |
123
+ | `@antadesign/anta/reset.css` | Optional reset and typography defaults in `@layer anta.reset`. |
124
+ | `@antadesign/anta/elements/a-*` | One element's behavior and CSS, or CSS alone for structural tags and composed layouts. |
125
+ | `@antadesign/anta/elements` | All browser element definitions, element styles, and composed layout styles through separate modules. |
126
+ | `@antadesign/anta` | Typed JSX wrappers for React, Preact, and configured runtimes, without CSS or element registration. |
127
+ | `@antadesign/anta/elements/*.css` | Individual stylesheets without element registration. |
128
+ | `@antadesign/anta/theme-antune.css` | Optional Antune theme. |
129
+ | `@antadesign/anta/theme-antithesis.css` | Optional Antithesis theme. |
130
+
131
+ With granular usage, include `tokens.css` before element styles unless your app
132
+ provides those variables. Elements depend on them for their default appearance.
61
133
 
62
134
  ### Cascade layers
63
135
 
@@ -121,71 +193,176 @@ and your installed Anta version. Web documentation may describe a newer release.
121
193
 
122
194
  ## Registering elements
123
195
 
124
- JSX wrappers render `<a-*>` tags. Register their classes before those tags reach
125
- the DOM. Registration needs `HTMLElement`, so the import is a no-op in Node.js
126
- and Worker threads.
196
+ JSX wrappers render `<a-*>` tags. Load their browser definitions and styles in
197
+ the UI thread before rendering or hydrating those tags. For full bundle usage,
198
+ and hooks:
127
199
 
128
200
  ```ts
129
- import '@antadesign/anta/elements' // auto-registers all elements
201
+ // src/main.tsx (or wherever your root render lives)
202
+ import '@antadesign/anta/bundle.css'
203
+ import '@antadesign/anta/bundle'
204
+ import { createRoot } from 'react-dom/client'
205
+ import App from './App'
206
+ createRoot(document.getElementById('root')!).render(<App />)
130
207
  ```
131
208
 
132
- `/elements` registers everything. Per-element entries register one element and
133
- load only its CSS:
209
+ The JavaScript bundle registers all browser elements. With granular usage, load
210
+ shared tokens, the optional reset, and the entries your app uses:
134
211
 
135
212
  ```ts
136
- import '@antadesign/anta/elements/a-tooltip' // only <a-tooltip> + its CSS
137
- import '@antadesign/anta/elements/a-button' // only <a-button> + its CSS
213
+ import '@antadesign/anta/tokens.css'
214
+ import '@antadesign/anta/reset.css'
215
+ import '@antadesign/anta/elements/a-tooltip' // <a-tooltip> behavior and CSS
216
+ import '@antadesign/anta/elements/a-button' // <a-button> behavior and CSS
217
+ import '@antadesign/anta/elements/a-title' // Title CSS only
218
+ import '@antadesign/anta/elements/a-tag' // Tag CSS only
138
219
  ```
139
220
 
140
- Both are idempotent, side-effect imports and safe during SSR.
221
+ To load all browser elements and layout styles, replace the individual element
222
+ imports with `import '@antadesign/anta/elements'`. Keep the shared tokens and
223
+ optional reset. Registration is idempotent and guarded when `customElements`
224
+ is unavailable. CSS imports need a bundler that handles stylesheets.
141
225
 
142
- Use a static import in your app entry, outside components and hooks:
226
+ Static imports register classes before the app's first client render or
227
+ hydration. Server-rendered HTML can paint before the browser loads JavaScript;
228
+ load its CSS with the initial document, as in the Next.js setup below.
143
229
 
144
- ```ts
145
- // src/main.tsx (or wherever your root render lives)
146
- import '@antadesign/anta/elements'
147
- import { createRoot } from 'react-dom/client'
148
- import App from './App'
149
- createRoot(document.getElementById('root')!).render(<App />)
150
- ```
151
-
152
- Module initialisation registers the classes before the first render, avoiding a
153
- flash of un-upgraded elements.
154
-
155
- > **Why not `useEffect(() => import('@antadesign/anta/elements'), [])`?**
156
- > `useEffect` runs after paint and the import resolves later. The browser can
157
- > paint unregistered elements first. `useLayoutEffect` is still asynchronous and
158
- > warns during SSR hydration.
230
+ > Loading elements in `useEffect` can delay registration until after paint. The
231
+ > dynamic import resolves later, so unregistered elements can appear first.
232
+ > Moving the dynamic import into `useLayoutEffect` still leaves the import
233
+ > asynchronous. Use a static import at the top of the UI entry.
159
234
 
160
235
  Choose the entry point for your runtime:
161
236
 
162
- - **Plain HTML or static sites:** a `<script type="module">` in the document head.
163
- - **Astro or Next.js:** a client-only script. In Astro, use
164
- `<script>import '@antadesign/anta/elements'</script>`; in Next.js, import it
165
- from a `'use client'` file.
237
+ - **Plain HTML or static sites:** a module entry processed by a bundler that
238
+ handles CSS imports; see [Raw web components](#raw-web-components-no-jsx).
239
+ - **Astro:** import the runtime in an Astro-processed `<script>` and the CSS in
240
+ your layout. For full bundle usage, use `bundle` and `bundle.css`.
241
+ - **Next.js:** import the runtime from a `'use client'` file and the CSS from
242
+ your root layout; see [Next.js](#nextjs).
166
243
  - **Worker-rendered UI:** code that runs on the UI thread and initializes the
167
244
  DOM. A Worker has no `HTMLElement`.
168
245
 
246
+ ### Server and worker rendering
247
+
248
+ Import JSX wrappers in the code that renders your UI:
249
+
250
+ ```tsx
251
+ // Server or worker
252
+ import { Button, Title } from '@antadesign/anta'
253
+ ```
254
+
255
+ Load the matching browser definitions and styles in a separate UI entry:
256
+
257
+ ```ts
258
+ // Browser UI thread
259
+ import '@antadesign/anta/tokens.css'
260
+ import '@antadesign/anta/reset.css'
261
+ import '@antadesign/anta/elements/a-button'
262
+ import '@antadesign/anta/elements/a-title'
263
+ ```
264
+
265
+ Rendering a JSX wrapper does not register its browser element. Raw `<a-*>`
266
+ markup uses the same browser entries and can omit the JSX wrappers.
267
+ For a custom JSX runtime, call `configure()` in the process or thread that
268
+ renders the wrappers; see [Framework setup](#framework-setup).
269
+
169
270
  ## Framework setup
170
271
 
171
272
  ### React
172
273
 
173
- Works out of the box.
274
+ React needs no `configure()` call. Load the JavaScript and CSS entries for your
275
+ chosen import strategy before rendering.
276
+
277
+ ### Next.js
278
+
279
+ For the full bundle setup, import its stylesheet in the App Router root layout:
280
+
281
+ ```tsx
282
+ // app/layout.tsx
283
+ import '@antadesign/anta/bundle.css'
284
+ import type { ReactNode } from 'react'
285
+
286
+ export default function Layout({ children }: { children: ReactNode }) {
287
+ return <html lang="en"><body>{children}</body></html>
288
+ }
289
+ ```
290
+
291
+ Import the runtime and JSX wrappers in a Client Component:
292
+
293
+ ```tsx
294
+ // app/page.tsx
295
+ 'use client'
296
+
297
+ import { useState } from 'react'
298
+ import { Button, Title } from '@antadesign/anta/bundle'
299
+
300
+ export default function Page() {
301
+ const [count, setCount] = useState(0)
302
+ return <>
303
+ <Title>Anta in Next.js</Title>
304
+ <Button label={`Count: ${count}`} onClick={() => setCount(value => value + 1)} />
305
+ </>
306
+ }
307
+ ```
308
+
309
+ Next.js prerenders Client Components on the server for the initial page load.
310
+ `'use client'` marks the client/server module boundary; it does not disable
311
+ server rendering. Anta guards element registration when browser APIs are absent
312
+ and registers the elements when the client module runs before hydration.
313
+
314
+ For granular usage, replace the layout's bundle stylesheet with shared tokens
315
+ and the optional reset:
316
+
317
+ ```ts
318
+ // app/layout.tsx imports
319
+ import '@antadesign/anta/tokens.css'
320
+ import '@antadesign/anta/reset.css'
321
+ ```
322
+
323
+ Keep the same page component and replace its imports with:
324
+
325
+ ```ts
326
+ // app/page.tsx
327
+ 'use client'
328
+
329
+ import { useState } from 'react'
330
+ import '@antadesign/anta/elements/a-button'
331
+ import '@antadesign/anta/elements/a-title'
332
+ import { Button, Title } from '@antadesign/anta'
333
+ ```
334
+
335
+ Both setups work with Next.js's default Turbopack bundler.
174
336
 
175
337
  ### Preact with compat
176
338
 
177
- If your bundler aliases `react` to `preact/compat`, Anta works without setup.
339
+ If your bundler aliases `react` to `preact/compat`, Anta needs no `configure()`
340
+ call. Load the entries for your chosen import strategy. The Vite Preact preset
341
+ provides these runtime aliases.
178
342
 
179
343
  ### Preact without compat
180
344
 
181
- Call `configure()` before rendering any anta components:
345
+ If `react` is not aliased to `preact/compat`, pass Preact's JSX factory and hooks
346
+ to `configure()` before rendering Anta components. For full bundle usage:
182
347
 
183
348
  ```ts
184
- import { configure } from '@antadesign/anta'
349
+ import '@antadesign/anta/bundle.css'
350
+ import { configure } from '@antadesign/anta/bundle'
185
351
  import { h, Fragment } from 'preact'
186
- configure(h, Fragment)
352
+ import { useState, useId, useMemo, useRef, useLayoutEffect } from 'preact/hooks'
353
+ import { useSyncExternalStore } from 'preact/compat'
354
+
355
+ configure(h, Fragment, {
356
+ useState, useId, useMemo, useRef, useLayoutEffect, useSyncExternalStore,
357
+ })
187
358
  ```
188
359
 
360
+ Import JSX wrappers from `@antadesign/anta/bundle` with this setup. For granular
361
+ usage, import both `configure` and the wrappers from `@antadesign/anta` and load
362
+ the UI entries separately. The root package and the prebuilt bundle each have
363
+ their own renderer configuration, so use `configure` from the same entry as
364
+ your wrappers. The explicit `preact/compat` hook import does not require an alias.
365
+
189
366
  ### TypeScript: typing raw `<a-*>` tags in JSX
190
367
 
191
368
  JSX wrappers such as `<Button>` and `<Progress>` need no extra typing. Configure
@@ -233,43 +410,69 @@ upgrades; there is no per-tag list to maintain.
233
410
 
234
411
  ### Raw web components (no JSX)
235
412
 
236
- Elements also work in plain HTML. Registration loads their CSS; resolve the bare
237
- specifier with a bundler or import map.
413
+ Elements also work in plain HTML without JSX wrappers. This example requires a
414
+ bundler that processes module scripts and CSS imports:
238
415
 
239
416
  ```html
240
417
  <script type="module">
241
- import '@antadesign/anta/elements'
418
+ import '@antadesign/anta/tokens.css'
419
+ import '@antadesign/anta/reset.css'
420
+ import '@antadesign/anta/elements/a-progress'
242
421
  </script>
243
422
 
244
423
  <a-progress value="42" max="100" tone="info"></a-progress>
245
424
  ```
246
425
 
426
+ An import map resolves module names but does not process the plain CSS imports
427
+ in Anta's element entries. When serving native modules without a bundler, use
428
+ a separately prepared JavaScript entry and linked stylesheets.
429
+
247
430
  ## Dark mode
248
431
 
249
- For a page-wide dark mode, add `dark` to `html`. The `body` `--bg-2` background
250
- then paints the browser canvas, and the root controls scrollbar colors:
432
+ For a page-wide dark mode, add `dark` to `html`. Shared tokens switch the palette
433
+ and root color scheme, including scrollbar colors. The reset, included in
434
+ `bundle.css` or loaded separately as `reset.css`, paints `body` with `--bg-2`:
251
435
 
252
436
  ```html
253
437
  <html class="dark">
254
438
  <body>
255
- <Progress value={50} />
439
+ <a-progress value="50"></a-progress>
256
440
  </body>
257
441
  </html>
258
442
  ```
259
443
 
260
444
  Use `dark` or `light` on another ancestor to scope its color scheme and palette.
445
+ If you omit the reset, set your app's background and text color in your own CSS,
446
+ for example with `--bg-2` and `--text-2`.
261
447
 
262
448
  ## Fonts
263
449
 
264
- Without an optional theme, `tokens.css` defines system stacks in `--sans-serif`,
265
- `--serif`, and `--monospace`. Reference themes register hosted fonts and replace
266
- some of those same variables. Components and theme rules decide which stack to
267
- use. Theme-free components do not force font-specific stylistic sets or
268
- variable-font axes. `tokens.css` also sets `1rem` to 15px.
450
+ Anta works with system fonts without any font downloads. `tokens.css`, also
451
+ included in `bundle.css`, defines system stacks in `--sans-serif`, `--serif`,
452
+ and `--monospace`, and sets `1rem` to 15px. The optional themes keep those stacks
453
+ and do not register font faces or request font files. Components and theme rules
454
+ choose which stack to use.
455
+
456
+ Use fonts from Google Fonts or host font files in your application. Manage font
457
+ loading in a separate application stylesheet such as `fonts.css`, and import it
458
+ after the Anta styles and optional theme:
459
+
460
+ ```ts
461
+ import '@antadesign/anta/bundle.css'
462
+ import '@antadesign/anta/theme-antune.css' // Optional
463
+ import './fonts.css'
464
+ ```
269
465
 
270
- Register application-owned fonts and redefine the variables in CSS loaded after
271
- the Anta styles and optional theme. This example uses separate Roman and Italic
272
- variable files:
466
+ With granular usage, load `fonts.css` after `tokens.css`, your element styles,
467
+ and the optional theme. Anta.design also loads its reference fonts through a
468
+ separate stylesheet. That setup is an example, and is not imported by the
469
+ package. See [Font examples](./theming.md#fonts-in-a-theme) for that setup and
470
+ Google Fonts examples.
471
+
472
+ Register your fonts and override only the stacks you want to change. Keep
473
+ fallback families after each custom font name. This `fonts.css` example uses
474
+ separate Roman and Italic variable files and keeps the default serif and
475
+ monospace stacks:
273
476
 
274
477
  ```css
275
478
  @font-face {
@@ -277,6 +480,7 @@ variable files:
277
480
  src: url("/fonts/app-sans-roman.woff2") format("woff2");
278
481
  font-style: normal;
279
482
  font-weight: 100 900;
483
+ font-display: swap;
280
484
  }
281
485
 
282
486
  @font-face {
@@ -284,19 +488,22 @@ variable files:
284
488
  src: url("/fonts/app-sans-italic.woff2") format("woff2");
285
489
  font-style: italic;
286
490
  font-weight: 100 900;
491
+ font-display: swap;
287
492
  }
288
493
 
289
494
  :root {
290
- --sans-serif: "App Sans", sans-serif;
291
- --serif: Georgia, serif;
292
- --monospace: ui-monospace, monospace;
495
+ --sans-serif: "App Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
293
496
  }
294
497
  ```
295
498
 
296
- Place this application stylesheet after `theme-antune.css` or
297
- `theme-antithesis.css`, not before it. When all stylesheets are in the document
298
- head, the override applies before the first paint. Anta's semantic italics
299
- (`em`, `i`, `var`, and `dt`) select the Italic face.
499
+ [Font display](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@font-face/font-display)
500
+ with `swap` shows fallback text while the custom font loads, then switches to
501
+ that font when it is ready. If the font fails to load, the browser keeps using a
502
+ fallback family. The variables remain valid in either case.
503
+
504
+ Anta's reset styles semantic italics (`em`, `i`, `var`, and `dt`) to select the
505
+ Italic face. If you omit the reset, your application or the browser's default
506
+ rules provide those styles.
300
507
 
301
508
  ### Variable slant
302
509
 
@@ -310,6 +517,7 @@ through `font-style: oblique` instead of setting `slnt` on italic elements:
310
517
  font-style: oblique 0deg 12deg;
311
518
  font-weight: 100 900;
312
519
  font-stretch: 75% 100%;
520
+ font-display: swap;
313
521
  }
314
522
 
315
523
  :root {
@@ -680,7 +680,7 @@ Scatter arguments
680
680
  | `x?` | [`FieldArg`](#data-fields) | `'x'` | Horizontal field name or accessor. |
681
681
  | `y?` | [`FieldArg`](#data-fields) | `'y'` | Vertical field name or accessor. |
682
682
  | `color?` | [`ColorArg`](#series-colors) | Black | Series color; theme pairs provide separate light and dark colors. |
683
- | `size?` | `number \| ((row, index) => number)` | `5` | Mark diameter in pixels, or a per-row accessor. A row’s `size` takes precedence. |
683
+ | `size?` | `number \| ((row, index, viewport) => number)` | `5` | [Mark diameter](#size) in pixels, or a per-row accessor. A row’s `size` takes precedence. |
684
684
  | [`mark?`](#mark-shapes) | `MarkShape` | `'circle'` | Mark shape: circle, square, diamond, or triangle. |
685
685
  | [`stroke?`](#strokes) | `StrokeArg` | None | Outline color and optional width. |
686
686
  | [`tooltip?`](#tooltips) | `TooltipArg` | None | Use `true` for the default tooltip, or a callback for custom content. |
@@ -3086,6 +3086,7 @@ to continuous axes.
3086
3086
  |---|---|---|
3087
3087
  | `x` | `AxisViewport \| null` | Current horizontal viewport, or `null` for a categorical axis. |
3088
3088
  | `y` | `AxisViewport \| null` | Current vertical viewport, or `null` for a categorical axis. |
3089
+ | `zoom_factor` | `{ x: number; y: number }` | Per-axis gesture magnification, initially 1; preserved during pan, resize, and data-domain changes. |
3089
3090
 
3090
3091
  Each `AxisViewport` contains:
3091
3092
 
@@ -3096,6 +3097,68 @@ Each `AxisViewport` contains:
3096
3097
 
3097
3098
  ## Configuration details
3098
3099
 
3100
+ ### Size
3101
+
3102
+ Scatter `size` accepts a fixed pixel diameter or a pure accessor returning a number.
3103
+ The accessor receives `(row, index, viewport)`, so you can combine data and viewport
3104
+ without storing zoom in application state.
3105
+
3106
+ Hold **Ctrl** and scroll near **50**. The first series stays at 4px. The other series
3107
+ alternate between 2px and 4px based on their data, then grow with horizontal zoom,
3108
+ at different rates, up to 16px. Hold **Ctrl** and drag to pan; **Reset zoom** restores
3109
+ the starting sizes.
3110
+
3111
+ ```ts
3112
+ import { scatter, type PlotArgs } from '@antadesign/plot'
3113
+ import '@antadesign/plot/elements/a-plot'
3114
+ import type { APlotElement } from '@antadesign/plot/browser'
3115
+
3116
+ export function viewportSizes(): PlotArgs<Node> {
3117
+ const labels = ['Fixed 4px', 'Data + gradual zoom', 'Data + faster zoom']
3118
+ const positions = [0, 10, 25, 40, 45, 48, 49, 49.5, 49.75, 50, 50.25, 50.5, 51, 52, 55, 60, 75, 90, 100]
3119
+ const rows = (label: string) => positions.map((x, i) => ({ x, y: label, weight: i % 2 ? 4 : 2 }))
3120
+ return {
3121
+ height: 260,
3122
+ margin: { top: 24, right: 20, bottom: 48, left: 160 },
3123
+ axis: { x: { min: 0, max: 100, label: 'Zoom near 50' }, y: { categories: labels, label: '' } },
3124
+ background: { light: '#ffffff', dark: '#202124' },
3125
+ chrome_color: { light: '#64748b', dark: '#cbd5e1' },
3126
+ grid: false,
3127
+ zoom_pan: { x: true, y: false, modifier: true },
3128
+ series: [
3129
+ scatter<Node>({ data: rows(labels[0]), size: 4,
3130
+ color: { light: '#64748b', dark: '#cbd5e1' }, tooltip: true }),
3131
+ scatter<Node>({ data: rows(labels[1]),
3132
+ size: (row, index, viewport) => Math.min(16, Number(row.weight) * viewport.zoom_factor.x ** 0.25),
3133
+ color: { light: '#7c3aed', dark: '#c4b5fd' }, tooltip: true }),
3134
+ scatter<Node>({ data: rows(labels[2]),
3135
+ size: (row, index, viewport) => Math.min(16, Number(row.weight) * viewport.zoom_factor.x ** 0.5),
3136
+ color: { light: '#c2410c', dark: '#fdba74' }, tooltip: true }),
3137
+ ],
3138
+ }
3139
+ }
3140
+
3141
+ const plot = document.createElement('a-plot') as APlotElement
3142
+ plot.plotArgs = viewportSizes()
3143
+ document.body.append(plot)
3144
+ ```
3145
+
3146
+ `viewport` has the same shape as [Viewport changes](#viewport-changes): `x` and `y`
3147
+ contain visible and full domains (`null` for a categorical axis), and `zoom_factor.x` and
3148
+ `zoom_factor.y` contain gesture magnification. Each starts at 1. Panning, resizing, and
3149
+ data-domain changes preserve magnification. Reset and new keyed viewport requests
3150
+ establish factor 1 on their affected axes. Zooming out beyond a requested initial
3151
+ window can yield factors below 1. Use `Math.max(viewport.zoom_factor.x, viewport.zoom_factor.y)`
3152
+ to follow the more magnified axis.
3153
+
3154
+ Size accessors run during composition, including zoom and pan, rather than when
3155
+ the series is constructed. Keep them pure and inexpensive. Existing accessors
3156
+ that only read the row or index remain valid. Returned sizes must be finite and
3157
+ non-negative; invalid results report a composition error and retain the previous
3158
+ plot. Numeric row `size` fields take precedence, and the index stays tied to the
3159
+ original input row after category filtering. Drawing, hit testing, and highlights
3160
+ reuse the composed sizes. Other series' size options and font sizes remain numeric.
3161
+
3099
3162
  ### Font
3100
3163
 
3101
3164
  `font` on the plot supplies shared text settings. `title.font`,
package/docs/theming.md CHANGED
@@ -14,7 +14,8 @@ import '@antadesign/anta/theme-antune.css' // Choose one theme included in the p
14
14
 
15
15
  ## Fonts in a theme
16
16
 
17
- Without a reference theme, `tokens.css` defines three system font stacks:
17
+ Anta's themes do not load fonts. `tokens.css` defines three system font stacks,
18
+ which the optional themes preserve:
18
19
 
19
20
  ```css
20
21
  :root, .light {
@@ -27,14 +28,14 @@ Without a reference theme, `tokens.css` defines three system font stacks:
27
28
  ```
28
29
 
29
30
  Components and theme rules choose which variable to use. For example, body text
30
- can use `--sans-serif` while a particular title style uses `--serif`. Without a
31
- theme, Anta does not force font-specific stylistic sets or variable-font axes.
31
+ can use `--sans-serif` while a particular title style uses `--serif`. Package
32
+ styles do not force font-specific stylistic sets or variable-font axes.
32
33
 
33
- You can register your fonts and redefine the stacks in a custom theme stylesheet
34
- such as `theme.css`:
34
+ Host your font files in your application and register them in a separate
35
+ stylesheet such as `fonts.css`. Load it after Anta's styles and optional theme:
35
36
 
36
37
  ```css
37
- /* theme.css */
38
+ /* fonts.css */
38
39
  @font-face {
39
40
  font-family: "App Sans";
40
41
  src: url("/fonts/app-sans.woff2") format("woff2");
@@ -50,13 +51,12 @@ such as `theme.css`:
50
51
  }
51
52
  ```
52
53
 
53
- The **Antune** and **Antithesis** themes included with Anta use custom fonts that
54
- require separate licenses. If your application does not have those licenses,
55
- redefine all three font variables as shown above.
54
+ Alternatively, use the [Google Fonts CSS API](https://developers.google.com/fonts/docs/css2)
55
+ to load your chosen families. This example includes regular and italic styles:
56
56
 
57
57
  ```css
58
- /* theme.css */
59
- @import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;600&family=JetBrains+Mono:wght@400;600&family=Source+Serif+4:wght@400;600&display=swap");
58
+ /* fonts.css: place @import before other rules. */
59
+ @import url("https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400;0,600;1,400;1,600&family=JetBrains+Mono:ital,wght@0,400;0,600;1,400;1,600&family=Source+Serif+4:ital,wght@0,400;0,600;1,400;1,600&display=swap");
60
60
 
61
61
  :root {
62
62
  --sans-serif: "Inter", sans-serif;
@@ -65,8 +65,17 @@ redefine all three font variables as shown above.
65
65
  }
66
66
  ```
67
67
 
68
- After you redefine these three variables, the theme fonts are not used or
69
- downloaded (exactly what we want in this case).
68
+ Choose the styles and weights your app uses. Loading Google Fonts makes requests
69
+ to Google's servers; self-host font files when you need all assets on your own
70
+ origin.
71
+
72
+ The anta.design website loads its reference fonts through separate
73
+ [Antune font CSS](https://anta.design/themes/fonts-antune.css) and
74
+ [Antithesis font CSS](https://anta.design/themes/fonts-antithesis.css). These
75
+ site stylesheets show the website's font-face declarations, font stacks, and
76
+ font-specific axis settings. They are examples of application font setup and
77
+ are not imported by the published themes. Use your own font stylesheet and
78
+ font sources in your application.
70
79
 
71
80
  <a id="color-seeds"></a>
72
81