@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.
Files changed (77) hide show
  1. package/README.md +38 -242
  2. package/dist/components/Input.d.ts +4 -1
  3. package/dist/components/Input.js +2 -0
  4. package/dist/components/InputDate.css +1 -0
  5. package/dist/components/InputDate.d.ts +1 -0
  6. package/dist/components/InputDate.js +5 -5
  7. package/dist/components/Loader.d.ts +39 -0
  8. package/dist/components/Loader.js +33 -0
  9. package/dist/components/Menu.d.ts +5 -1
  10. package/dist/components/Menu.js +3 -2
  11. package/dist/components/Progress.d.ts +17 -8
  12. package/dist/components/Progress.js +12 -9
  13. package/dist/components/Select.d.ts +1 -0
  14. package/dist/components/Select.js +9 -13
  15. package/dist/components/SelectFaceted.d.ts +1 -0
  16. package/dist/components/SelectFaceted.js +29 -23
  17. package/dist/components/select-parts.css +1 -0
  18. package/dist/elements/a-button.css +1 -1
  19. package/dist/elements/a-icon.d.ts +1 -0
  20. package/dist/elements/a-icon.js +1 -0
  21. package/dist/elements/a-input.css +1 -1
  22. package/dist/elements/a-loader.css +1 -0
  23. package/dist/elements/a-loader.d.ts +12 -0
  24. package/dist/elements/a-loader.js +15 -0
  25. package/dist/elements/a-menu.js +12 -0
  26. package/dist/elements/a-progress.css +1 -1
  27. package/dist/elements/a-progress.js +32 -2
  28. package/dist/elements/a-slider.css +1 -1
  29. package/dist/elements/a-tabs.css +1 -1
  30. package/dist/elements/a-tabs.d.ts +3 -0
  31. package/dist/elements/a-tabs.js +40 -1
  32. package/dist/elements/index.d.ts +1 -0
  33. package/dist/elements/index.js +3 -0
  34. package/dist/general_types.d.ts +27 -2
  35. package/dist/index.d.ts +6 -1
  36. package/dist/index.js +2 -0
  37. package/dist/jsx-runtime.d.ts +11 -1
  38. package/dist/reset.css +1 -1
  39. package/dist/theme-anta.css +1 -1
  40. package/docs/accessibility.md +34 -0
  41. package/docs/changelog.md +551 -0
  42. package/docs/colors.md +42 -0
  43. package/docs/comparison.md +28 -0
  44. package/docs/components/banner.md +267 -0
  45. package/docs/components/button.md +603 -0
  46. package/docs/components/card.md +322 -0
  47. package/docs/components/checkbox.md +297 -0
  48. package/docs/components/dialog.md +314 -0
  49. package/docs/components/expander.md +529 -0
  50. package/docs/components/icon.md +155 -0
  51. package/docs/components/input-autocomplete.md +101 -0
  52. package/docs/components/input-date.md +406 -0
  53. package/docs/components/input-time.md +174 -0
  54. package/docs/components/input.md +610 -0
  55. package/docs/components/loader.md +139 -0
  56. package/docs/components/menu.md +447 -0
  57. package/docs/components/progress.md +182 -0
  58. package/docs/components/radio.md +369 -0
  59. package/docs/components/select-faceted.md +456 -0
  60. package/docs/components/select.md +931 -0
  61. package/docs/components/slider.md +142 -0
  62. package/docs/components/switch.md +198 -0
  63. package/docs/components/tabs.md +471 -0
  64. package/docs/components/tag.md +185 -0
  65. package/docs/components/text.md +148 -0
  66. package/docs/components/title.md +146 -0
  67. package/docs/components/toaster.md +313 -0
  68. package/docs/components/tooltip.md +177 -0
  69. package/docs/credits.md +22 -0
  70. package/docs/index.md +52 -0
  71. package/docs/install-config.md +240 -0
  72. package/docs/normalization.md +105 -0
  73. package/docs/overview.md +10 -0
  74. package/docs/packages/stickers.md +187 -0
  75. package/docs/packages/table.md +153 -0
  76. package/docs/theming.md +13 -0
  77. package/package.json +10 -6
package/README.md CHANGED
@@ -1,244 +1,40 @@
1
1
  # @antadesign/anta
2
2
 
3
- <a href="https://antithesis.com" target="_blank" rel="noopener noreferrer">Antithesis</a> design system, **Anta**, has three layers: global CSS tokens with swappable themes, framework-agnostic web components that work in plain HTML, and JSX wrappers for React and Preact.
4
-
5
- One constraint shapes the architecture. Antithesis runs most of its UI in a Worker thread, driven by a custom reactive engine, and a component that mutates its own attributes would desync the Worker from the UI thread. So Anta's web components are **fully declarative**: they never touch their own attributes, and internal state lives in Shadow DOM, invisible to the outer document. The components carry the styling without imposing a framework, and most are stateless; the JSX wrappers exist for dynamic state and conditional rendering.
6
-
7
- ## Installation
8
-
9
- ```sh
10
- npm install @antadesign/anta # or pnpm / bun
11
- ```
12
-
13
- Pin an exact version in `package.json` (`"@antadesign/anta": "0.3.16"`) instead
14
- of a floating tag such as `"latest"`.
15
-
16
- ### Usage
17
-
18
- ```tsx
19
- import '@antadesign/anta/tokens.css' // CSS custom properties
20
- import '@antadesign/anta/reset.css' // reset and typography defaults
21
- import '@antadesign/anta/elements' // registers <a-*> elements
22
- import { Progress } from '@antadesign/anta'
23
-
24
- <Progress value={42} label="Uploaded" hint="3 of 7" />
25
- ```
26
-
27
- ### What you import (and why)
28
-
29
- Tokens, elements, and the JSX layer render a styled component. The reset is
30
- recommended; the reference theme is optional.
31
-
32
- | Import | Provides | Skip if… |
33
- |---|---|---|
34
- | `@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. |
35
- | `@antadesign/anta/reset.css` | A small reset plus Anta's heading, list, and link typography in `@layer anta`. | You use another reset and typography. |
36
- | `@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. |
37
- | `@antadesign/anta` | Typed React/Preact wrappers such as `Progress`, `Text`, and `Icon`. | You write `<a-*>` elements directly. |
38
- | `@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. |
39
-
40
- Load `tokens.css` before element CSS. Elements read its variables; without it,
41
- they render unstyled.
42
-
43
- ### Cascade layers
44
-
45
- Anta's reset and element CSS live in `@layer anta`. `tokens.css` declares
46
- `@layer base, anta, components, utilities`, placing Anta above preflight resets
47
- and below your component and utility layers.
48
-
49
- To change that order, declare it in CSS loaded **before** `tokens.css`. The
50
- first declaration fixes a layer's position:
51
-
52
- ```css
53
- /* your global.css, loaded before anta */
54
- @layer reset, anta, my-components, utilities;
55
- ```
56
-
57
- Token custom properties stay unlayered so they apply everywhere.
58
-
59
- > **Gotcha: an unlayered hard reset defeats Anta's element rules.**
60
- >
61
- > ```css
62
- > *, *::before, *::after { box-sizing: border-box; }
63
- > * { margin: 0; }
64
- > ```
65
- >
66
- > Unlayered styles beat layered ones regardless of specificity. This reset
67
- > overrides Anta's element defaults. Delete the duplicate, or put your reset in
68
- > `@layer base { … }`; `reset.css` already applies the same universal reset in
69
- > `@layer anta`.
70
-
71
- ## Registering elements
72
-
73
- JSX wrappers render `<a-*>` tags. Register their classes before those tags reach
74
- the DOM. Registration needs `HTMLElement`, so the import is a no-op in Node.js
75
- and Worker threads.
76
-
77
- ```ts
78
- import '@antadesign/anta/elements' // auto-registers all elements
79
- ```
80
-
81
- `/elements` registers everything. Per-element entries register one element and
82
- load only its CSS:
83
-
84
- ```ts
85
- import '@antadesign/anta/elements/a-tooltip' // only <a-tooltip> + its CSS
86
- import '@antadesign/anta/elements/a-button' // only <a-button> + its CSS
87
- ```
88
-
89
- Both are idempotent, side-effect imports and safe during SSR.
90
-
91
- Use a static import in your app entry, outside components and hooks:
92
-
93
- ```ts
94
- // src/main.tsx (or wherever your root render lives)
95
- import '@antadesign/anta/elements'
96
- import { createRoot } from 'react-dom/client'
97
- import App from './App'
98
- createRoot(document.getElementById('root')!).render(<App />)
99
- ```
100
-
101
- Module initialisation registers the classes before the first render, avoiding a
102
- flash of un-upgraded elements.
103
-
104
- > **Why not `useEffect(() => import('@antadesign/anta/elements'), [])`?**
105
- > `useEffect` runs after paint and the import resolves later. The browser can
106
- > paint unregistered elements first. `useLayoutEffect` is still asynchronous and
107
- > warns during SSR hydration.
108
-
109
- Choose the entry point for your runtime:
110
-
111
- - **Plain HTML or static sites:** a `<script type="module">` in the document head.
112
- - **Astro or Next.js:** a client-only script. In Astro, use
113
- `<script>import '@antadesign/anta/elements'</script>`; in Next.js, import it
114
- from a `'use client'` file.
115
- - **Worker-rendered UI:** the UI-thread bootstrap that owns the DOM. A Worker
116
- has no `HTMLElement`.
117
-
118
- ## Framework setup
119
-
120
- ### React
121
-
122
- Works out of the box.
123
-
124
- ### Preact with compat
125
-
126
- If your bundler aliases `react` to `preact/compat`, Anta works without setup.
127
-
128
- ### Preact without compat
129
-
130
- Call `configure()` before rendering any anta components:
131
-
132
- ```ts
133
- import { configure } from '@antadesign/anta'
134
- import { h, Fragment } from 'preact'
135
- configure(h, Fragment)
136
- ```
137
-
138
- ### TypeScript: typing raw `<a-*>` tags in JSX
139
-
140
- JSX wrappers such as `<Button>` and `<Progress>` need no extra typing. Configure
141
- JSX only when you write raw `<a-*>` tags.
142
-
143
- **Option A (preferred)** — point JSX types at Anta in `tsconfig.json`:
144
-
145
- ```jsonc
146
- { "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "@antadesign/anta" } }
147
- ```
148
-
149
- Every `a-*` tag type-checks, standard HTML tags keep working, and importing
150
- `@antadesign/stickers` adds its tags automatically.
151
-
152
- **Option B** — if `jsxImportSource` cannot change, merge Anta's tag map into
153
- your JSX namespace with `AntaIntrinsicElements` (and `StickerIntrinsicElements`
154
- when needed):
155
-
156
- ```ts
157
- import type { AntaIntrinsicElements } from '@antadesign/anta'
158
- import type { StickerIntrinsicElements } from '@antadesign/stickers' // only if you use stickers
159
-
160
- declare global {
161
- namespace JSX {
162
- interface IntrinsicElements extends AntaIntrinsicElements, StickerIntrinsicElements {}
163
- }
164
- }
165
- ```
166
-
167
- With `@types/react` 18+ and `jsx: "react-jsx"`, JSX is module-scoped. Extend
168
- the `react` module instead:
169
-
170
- ```ts
171
- import type { AntaIntrinsicElements } from '@antadesign/anta'
172
-
173
- declare module 'react' {
174
- namespace JSX {
175
- interface IntrinsicElements extends AntaIntrinsicElements {}
176
- }
177
- }
178
- ```
179
-
180
- Both options reject unknown tags and invalid props. New tags arrive with Anta
181
- upgrades; there is no per-tag list to maintain.
182
-
183
- ### Raw web components (no JSX)
184
-
185
- Elements also work in plain HTML. Registration loads their CSS; resolve the bare
186
- specifier with a bundler or import map.
187
-
188
- ```html
189
- <script type="module">
190
- import '@antadesign/anta/elements'
191
- </script>
192
-
193
- <a-progress value="42" max="100" tone="info"></a-progress>
194
- ```
195
-
196
- ## Dark mode
197
-
198
- Add the `dark` class to any ancestor element:
199
-
200
- ```html
201
- <div class="dark">
202
- <Progress value={50} />
203
- </div>
204
- ```
205
-
206
- ## Fonts
207
-
208
- Anta is designed for a customized <a href="https://typetype.org/fonts/tt-interphases-pro" target="_blank" rel="noopener noreferrer">TT Interphases Pro</a>, but ships no font binaries. Components use `--sans-serif` and `--monospace` with system fallbacks. `tokens.css` sets a 15px root size (`1rem = 15px`).
209
-
210
- To use the Antithesis fonts, register your own `@font-face` declarations and override the variables:
211
-
212
- ```css
213
- @font-face {
214
- font-family: "Antithesis sans";
215
- src: url("/path/to/your/sans.woff2") format("woff2");
216
- /* ... */
217
- }
218
-
219
- :root {
220
- --sans-serif: "Antithesis sans", sans-serif;
221
- --monospace: "Antithesis mono", monospace;
222
- }
223
- ```
224
-
225
- ## Browser support
226
-
227
- 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):
228
-
229
- | Browser | Minimum version |
230
- | --- | --- |
231
- | Chrome / Edge | 125 (May 2024) |
232
- | Safari | 17.4 (Mar 2024) |
233
- | Firefox | 126 (May 2024) |
234
-
235
- This is [Baseline 2024](https://web.dev/baseline). Anta also relies on relative
236
- OKLCH, `:has()`, `dvh`, cascade layers, and constructable shadow DOM. Older
237
- browsers can fail hard, including `:state()` being unrecognized or
238
- `showPopover()` throwing. Gate Anta on your own support matrix when you support
239
- older browsers.
240
-
241
- Two features progressively enhance with fallbacks: `checkVisibility()` falls
242
- back to `getClientRects()`, and typed CSS `attr()` supports raw
243
- `<a-icon size>` in Chrome 133+ and Safari 18.2+. Elsewhere use `<Icon size>`
244
- or `--icon-size`.
3
+ **Anta** is [Antithesis](https://antithesis.com)'s design system. It provides
4
+ design tokens, declarative web components, and typed JSX wrappers. Use the same
5
+ components in React, Preact via compat, plain HTML, and custom JSX runtimes via
6
+ `configure()`.
7
+
8
+ ## Documentation for coding agents
9
+
10
+ Start with [`./docs/index.md`](./docs/index.md). This path is relative to the
11
+ root of the installed Anta package, not to the consuming application.
12
+
13
+ This package includes version-specific documentation inside the installed npm
14
+ package.
15
+
16
+ Example:
17
+
18
+ ```text
19
+ node_modules/
20
+ └── @antadesign/
21
+ └── anta/
22
+ ├── README.md
23
+ ├── docs/
24
+ │ ├── index.md
25
+ │ ├── install-config.md
26
+ │ ├── theming.md
27
+ │ └── components/
28
+ │ ├── button.md
29
+ │ ├── dialog.md
30
+ │ └── ...
31
+ └── dist/
32
+ ```
33
+
34
+ When working with Anta components:
35
+
36
+ 1. Read `./docs/index.md` from the installed `@antadesign/anta` package.
37
+ 2. Open only the documentation relevant to the component or feature you are using.
38
+ 3. Do **not** guess component names, props, or behavior from similarly named component libraries (e.g. MUI, Chakra UI, Radix UI, Mantine, shadcn/ui, Ant Design, etc.).
39
+ 4. Use the installed package's TypeScript declarations (`*.d.ts`) as the source of truth for the installed package version.
40
+ 5. If the Markdown documentation and TypeScript declarations disagree, prefer the TypeScript declarations, as they always correspond to the installed version.
@@ -92,6 +92,9 @@ export interface InputProps extends BaseProps, DOMEventHandlers {
92
92
  name?: string;
93
93
  /** Placeholder shown when empty. */
94
94
  placeholder?: string;
95
+ /** Ellipsize an overflowing single-line value. Read-only inputs already do
96
+ * this; use `truncate` when an editable field should keep the same treatment. */
97
+ truncate?: boolean;
95
98
  /** Disable the field. */
96
99
  disabled?: boolean;
97
100
  /** Make the field read-only. */
@@ -167,4 +170,4 @@ export interface InputProps extends BaseProps, DOMEventHandlers {
167
170
  * <Input label="Email" type="email" placeholder="you@example.com" clearable />
168
171
  * ```
169
172
  */
170
- export declare const Input: ({ label, hint, status, statusIcon, tone, size, round, value, defaultValue, multiline, rows, maxRows, clearable, leading, trailing, type, autoComplete, inputMode, name, placeholder, disabled, readOnly, required, dimActions, spellCheck, maxLength, minLength, pattern, min, max, step, onInput, onChange, onValueChange, onClearClick, onClearInput, children, className, style, ...rest }: InputProps) => any;
173
+ export declare const Input: ({ label, hint, status, statusIcon, tone, size, round, value, defaultValue, multiline, rows, maxRows, clearable, leading, trailing, type, autoComplete, inputMode, name, placeholder, truncate, disabled, readOnly, required, dimActions, spellCheck, maxLength, minLength, pattern, min, max, step, onInput, onChange, onValueChange, onClearClick, onClearInput, children, className, style, ...rest }: InputProps) => any;
@@ -51,6 +51,7 @@ const Input = ({
51
51
  inputMode,
52
52
  name,
53
53
  placeholder,
54
+ truncate,
54
55
  disabled,
55
56
  readOnly,
56
57
  required,
@@ -93,6 +94,7 @@ const Input = ({
93
94
  type: !multiline && rows == null ? nativeType : void 0,
94
95
  name,
95
96
  placeholder,
97
+ truncate: presence(truncate),
96
98
  disabled: presence(disabled),
97
99
  readonly: presence(readOnly),
98
100
  required: presence(required),
@@ -0,0 +1 @@
1
+ @layer anta{a-input-date-time-container{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:6px;padding-top:8px;border-top:1px solid var(--border-3)}}
@@ -1,6 +1,7 @@
1
1
  import type { BaseProps } from '../general_types';
2
2
  import type { IconShape } from '../elements/a-icon.shapes';
3
3
  import { type MenuProps } from './Menu';
4
+ import './InputDate.css';
4
5
  /** Snapshot passed as the 2nd argument to `onValueChange` — the new ISO value
5
6
  * (`''` when cleared) plus the field name (mirrors `Input` / `Calendar`). */
6
7
  export interface InputDateChangeAttrs {
@@ -1,5 +1,4 @@
1
1
  import { Fragment, jsx, jsxs } from "@antadesign/anta/jsx-runtime";
2
- import cn from "clsx";
3
2
  import { useMemo, useState } from "../jsx-runtime";
4
3
  import { Temporal } from "temporal-polyfill";
5
4
  import {
@@ -18,7 +17,7 @@ import { Calendar } from "./Calendar";
18
17
  import { Button } from "./Button";
19
18
  import { Icon } from "./Icon";
20
19
  import { InputTime } from "./InputTime";
21
- import styles from "./InputDate.module.css";
20
+ import "./InputDate.css";
22
21
  const InputDate = ({
23
22
  value,
24
23
  defaultValue,
@@ -147,7 +146,8 @@ const InputDate = ({
147
146
  if (resolve(e.currentTarget.value)) setOpen(false);
148
147
  }
149
148
  },
150
- className: cn(styles.dateField, className),
149
+ truncate: true,
150
+ className,
151
151
  style,
152
152
  ...rest
153
153
  }
@@ -159,7 +159,7 @@ const InputDate = ({
159
159
  placement: placement ?? "bottom-start",
160
160
  offset,
161
161
  autoWidth: true,
162
- className: styles.calendarMenu,
162
+ inset: 8,
163
163
  onStateChange: (_e, { next }) => setOpen(next),
164
164
  children: /* @__PURE__ */ jsxs("div", { "data-menu-open": "", children: [
165
165
  /* @__PURE__ */ jsx(
@@ -180,7 +180,7 @@ const InputDate = ({
180
180
  }
181
181
  }
182
182
  ),
183
- time && /* @__PURE__ */ jsxs("div", { className: styles.timeRow, children: [
183
+ time && /* @__PURE__ */ jsxs("a-input-date-time-container", { children: [
184
184
  /* @__PURE__ */ jsx(
185
185
  InputTime,
186
186
  {
@@ -0,0 +1,39 @@
1
+ import type { BaseProps } from '../general_types';
2
+ export interface LoaderProps extends BaseProps {
3
+ /** Current progress value. Omit this prop, or pass `false`, for an
4
+ * indeterminate rotating gradient. */
5
+ value?: number | false;
6
+ /** Upper bound of the range.
7
+ * @defaultValue 100 */
8
+ max?: number;
9
+ /** Width and height in pixels.
10
+ * @defaultValue 16 */
11
+ size?: number;
12
+ /** Seconds per rotation. Pass a positive number.
13
+ * @defaultValue 0.75 */
14
+ speed?: number;
15
+ /** Accessible name for a standalone loader. Without a label, the loader is
16
+ * decorative so nearby status text remains the single announcement. */
17
+ label?: string;
18
+ }
19
+ /**
20
+ * Animated, icon-sized feedback for loading work.
21
+ *
22
+ * Omit `value` for the rotating gradient. Pass `value` to fill a static circle
23
+ * to the current proportion. `shape="loader"` provides the indeterminate
24
+ * visual for string-only icon props such as `Button`'s `icon`.
25
+ *
26
+ * Requires `@antadesign/anta/elements` to be imported (client-side only) to
27
+ * register the underlying custom element.
28
+ *
29
+ * @example Indeterminate
30
+ * ```tsx
31
+ * <Loader label="Loading results" />
32
+ * ```
33
+ *
34
+ * @example Determinate
35
+ * ```tsx
36
+ * <Loader value={42} label="Uploading files" />
37
+ * ```
38
+ */
39
+ export declare const Loader: ({ value, max, size, speed, label, className, style, ...rest }: LoaderProps) => any;
@@ -0,0 +1,33 @@
1
+ import { jsx } from "@antadesign/anta/jsx-runtime";
2
+ const Loader = ({ value, max = 100, size, speed, label, className, style, ...rest }) => {
3
+ const determinate = typeof value === "number" && Number.isFinite(value);
4
+ const safeMax = Number.isFinite(max) && max > 0 ? max : 100;
5
+ const clampedValue = determinate ? Math.min(safeMax, Math.max(0, value)) : void 0;
6
+ const percentage = clampedValue != null ? clampedValue / safeMax * 100 : void 0;
7
+ const computedStyle = {
8
+ ...style,
9
+ ...size != null ? { ["--loader-size"]: `${size}px` } : {},
10
+ ...!determinate && speed != null && Number.isFinite(speed) && speed > 0 ? { ["--loader-speed"]: `${speed}s` } : {},
11
+ ...percentage != null ? { ["--loader-value"]: `${percentage}%` } : {}
12
+ };
13
+ const a11y = label != null ? {
14
+ role: "progressbar",
15
+ "aria-label": label,
16
+ "aria-valuenow": determinate ? clampedValue : void 0,
17
+ "aria-valuemin": determinate ? 0 : void 0,
18
+ "aria-valuemax": determinate ? safeMax : void 0
19
+ } : { "aria-hidden": "true" };
20
+ return /* @__PURE__ */ jsx(
21
+ "a-loader",
22
+ {
23
+ ...determinate ? { value: clampedValue } : {},
24
+ class: className,
25
+ style: computedStyle,
26
+ ...a11y,
27
+ ...rest
28
+ }
29
+ );
30
+ };
31
+ export {
32
+ Loader
33
+ };
@@ -28,6 +28,10 @@ export interface MenuProps extends BaseProps {
28
28
  * content menu under a wide trigger (e.g. a calendar below a full-width field)
29
29
  * so it wraps its content and left-aligns under the trigger. */
30
30
  autoWidth?: boolean;
31
+ /** Inner inset for the scroll body and named header/footer content. A number is
32
+ * pixels; a CSS length string is used as written.
33
+ * @defaultValue 4 */
34
+ inset?: number | string;
31
35
  /** Controlled open state. Omit for the default **uncontrolled** menu (it
32
36
  * opens/closes itself via its triggers). Pass a boolean to **control** it:
33
37
  * the menu's visibility follows `open`, and user dismiss (Esc, outside-click,
@@ -92,4 +96,4 @@ export interface MenuProps extends BaseProps {
92
96
  * </Menu>
93
97
  * ```
94
98
  */
95
- export declare const Menu: ({ placement, context, coord, nohover, offset, autoWidth, open, onStateChange, round, role, className, style, children, ...rest }: MenuProps) => any;
99
+ export declare const Menu: ({ placement, context, coord, nohover, offset, autoWidth, inset, open, onStateChange, round, role, className, style, children, ...rest }: MenuProps) => any;
@@ -1,5 +1,5 @@
1
1
  import { jsx } from "@antadesign/anta/jsx-runtime";
2
- import { nativeStateChange, roundStyle, roundAttr } from "../anta_helpers";
2
+ import { nativeStateChange, lengthStyle, roundStyle, roundAttr } from "../anta_helpers";
3
3
  const Menu = ({
4
4
  placement,
5
5
  context,
@@ -7,6 +7,7 @@ const Menu = ({
7
7
  nohover,
8
8
  offset,
9
9
  autoWidth,
10
+ inset,
10
11
  open,
11
12
  onStateChange,
12
13
  round,
@@ -38,7 +39,7 @@ const Menu = ({
38
39
  role,
39
40
  "aria-orientation": "vertical",
40
41
  class: className,
41
- style: roundStyle(round, "--menu-round", style),
42
+ style: lengthStyle(inset, "--menu-padding", roundStyle(round, "--menu-round", style)),
42
43
  ...rest,
43
44
  children
44
45
  }
@@ -1,7 +1,8 @@
1
1
  import type { BaseProps } from "../general_types";
2
2
  export interface ProgressProps extends BaseProps {
3
- /** Current progress value. Negative values are clamped to 0. */
4
- value: number;
3
+ /** Current progress value. Omit this prop, or pass `false`, to show
4
+ * indeterminate progress. Negative values are clamped to 0. */
5
+ value?: number | false;
5
6
  /** Upper bound of the range.
6
7
  * @defaultValue 100 */
7
8
  max?: number;
@@ -10,20 +11,23 @@ export interface ProgressProps extends BaseProps {
10
11
  * light/dark automatically.
11
12
  * @defaultValue 'neutral' */
12
13
  tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
14
+ /** Size variant. Scales the track and the default label row together.
15
+ * @defaultValue medium */
16
+ size?: 'small' | 'medium' | 'large';
13
17
  /** Fully-round track (`border-radius: 999px`); the fill is clipped to it. Pass a
14
18
  * `number` (px) or a CSS length string for a custom radius. */
15
19
  round?: boolean | number | string;
16
- /** Text label displayed after the percentage. When you provide custom
17
- * `children` (which replace the default label row), `label` is no longer
18
- * rendered — but it still supplies the progressbar's accessible name, so
19
- * pass it for screen readers to announce more than the bare percentage. */
20
+ /** Text label displayed after the percentage, or on its own for
21
+ * indeterminate progress. When you provide custom `children` (which replace
22
+ * the default label row), `label` is no longer rendered — but it still
23
+ * supplies the progressbar's accessible name. */
20
24
  label?: string;
21
25
  /** Right-aligned hint text (e.g. "3 of 7"). Like `label`, it's not rendered
22
26
  * when custom `children` are provided but still feeds the accessible name. */
23
27
  hint?: string;
24
28
  }
25
29
  /**
26
- * Progress indicator for displaying task completion.
30
+ * Progress indicator for task completion and indeterminate work.
27
31
  *
28
32
  * Renders an `<a-progress>` web component with an optional label area
29
33
  * showing percentage, text label, and hint.
@@ -44,9 +48,14 @@ export interface ProgressProps extends BaseProps {
44
48
  * <Progress value={42} label="Uploading files..." hint="3 of 7" />
45
49
  * ```
46
50
  *
51
+ * @example Indeterminate
52
+ * ```tsx
53
+ * <Progress label="Preparing upload..." />
54
+ * ```
55
+ *
47
56
  * @example Info tone
48
57
  * ```tsx
49
58
  * <Progress value={75} tone="info" label="Processing" />
50
59
  * ```
51
60
  */
52
- export declare const Progress: ({ value, max, tone, round, label, hint, className, style, children, ...rest }: ProgressProps) => any;
61
+ export declare const Progress: ({ value, max, tone, size, round, label, hint, className, style, children, ...rest }: ProgressProps) => any;
@@ -1,26 +1,29 @@
1
1
  import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
2
2
  import { hasChildren, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
3
- const Progress = ({ value, max = 100, tone, round, label, hint, className, style, children, ...rest }) => {
4
- const percent = max > 0 ? Math.round(Math.min(100, Math.max(0, value / max * 100))) : 0;
5
- const clampedValue = max > 0 ? Math.min(max, Math.max(0, value)) : 0;
6
- const ariaLabel = [label, `${percent}%`, hint].filter(Boolean).join(" \xB7 ") || void 0;
3
+ const Progress = ({ value, max = 100, tone, size, round, label, hint, className, style, children, ...rest }) => {
4
+ const indeterminate = value == null || value === false;
5
+ const numericValue = typeof value === "number" ? value : 0;
6
+ const percent = max > 0 ? Math.round(Math.min(100, Math.max(0, numericValue / max * 100))) : 0;
7
+ const clampedValue = max > 0 ? Math.min(max, Math.max(0, numericValue)) : 0;
8
+ const ariaLabel = [label, !indeterminate && `${percent}%`, hint].filter(Boolean).join(" \xB7 ") || (indeterminate ? "Loading" : void 0);
7
9
  return /* @__PURE__ */ jsx(
8
10
  "a-progress",
9
11
  {
10
- value,
12
+ value: indeterminate ? false : numericValue,
11
13
  max,
12
14
  tone: tone && tone !== "neutral" ? tone : void 0,
15
+ size: size && size !== "medium" ? size : void 0,
13
16
  round: roundAttr(round),
14
17
  role: "progressbar",
15
- "aria-valuenow": clampedValue,
16
- "aria-valuemin": 0,
17
- "aria-valuemax": max,
18
+ "aria-valuenow": indeterminate ? void 0 : clampedValue,
19
+ "aria-valuemin": indeterminate ? void 0 : 0,
20
+ "aria-valuemax": indeterminate ? void 0 : max,
18
21
  "aria-label": ariaLabel,
19
22
  class: className,
20
23
  style: roundStyle(round, "--progress-round", toneStyle(tone, "--progress-tone-source", style)),
21
24
  ...rest,
22
25
  children: hasChildren(children) ? children : /* @__PURE__ */ jsxs("a-progress-label", { children: [
23
- /* @__PURE__ */ jsxs("a-progress-number", { children: [
26
+ !indeterminate && /* @__PURE__ */ jsxs("a-progress-number", { children: [
24
27
  percent,
25
28
  "%"
26
29
  ] }),
@@ -1,6 +1,7 @@
1
1
  import type { BaseProps } from '../general_types';
2
2
  import type { IconShape } from '../elements/a-icon.shapes';
3
3
  import { type MenuProps } from './Menu';
4
+ import './select-parts.css';
4
5
  /** The type an option `value` may take: `string`, `number`, or `boolean`. Selection
5
6
  * compares values with `===`. Object-shaped values are out of scope; give the option a
6
7
  * stable primitive `value` and read the object back off `attrs.option` (or, in
@@ -9,7 +9,7 @@ import { MenuItem } from "./MenuItem";
9
9
  import { MenuGroup } from "./MenuGroup";
10
10
  import { MenuSeparator } from "./MenuSeparator";
11
11
  import { Tooltip } from "./Tooltip";
12
- import styles from "./Select.module.css";
12
+ import "./select-parts.css";
13
13
  function optionsWithSelection(options, values) {
14
14
  const set = new Set(values == null ? [] : Array.isArray(values) ? values : [values]);
15
15
  const state = (on, total) => on === 0 ? "none" : on === total ? "all" : "some";
@@ -269,16 +269,9 @@ const Select = (props) => {
269
269
  "aria-haspopup": "menu",
270
270
  "aria-expanded": open ? "true" : "false",
271
271
  trailing: (
272
- // Chevron rotates down → up when open (spacing + rotation in the CSS
273
- // module, matching the Input "Select dropdown" example).
274
- /* @__PURE__ */ jsx(
275
- Icon,
276
- {
277
- shape: "chevron-down",
278
- className: open ? `${styles.chevron} ${styles.open}` : styles.chevron,
279
- style: statusColor ? { color: statusColor } : void 0
280
- }
281
- )
272
+ // The named tag owns the select-specific rotation while the icon remains
273
+ // a normal currentColor glyph.
274
+ /* @__PURE__ */ jsx("a-select-chevron", { open: open ? "" : void 0, style: statusColor ? { color: statusColor } : void 0, children: /* @__PURE__ */ jsx(Icon, { shape: "chevron-down" }) })
282
275
  ),
283
276
  className,
284
277
  style,
@@ -302,7 +295,7 @@ const Select = (props) => {
302
295
  filtering && // `slot="header"` pins the field in the Menu's fixed header region (above
303
296
  // the scrolling options); `data-menu-search` puts the menu in combobox
304
297
  // mode — it focuses this field on open and drives an active-option cursor.
305
- /* @__PURE__ */ jsx("div", { className: styles.filter, slot: "header", "data-menu-open": "", children: /* @__PURE__ */ jsx(
298
+ /* @__PURE__ */ jsx("a-select-header", { slot: "header", "data-menu-open": "", children: /* @__PURE__ */ jsx(
306
299
  Input,
307
300
  {
308
301
  "data-menu-search": "",
@@ -332,7 +325,10 @@ const Select = (props) => {
332
325
  ] }),
333
326
  visibleLeaves.length === 0 ? renderEmpty?.({ query: q }) : flattening ? renderFlat() : renderTree(options, false),
334
327
  clearable && selectedValues.length > 0 && // Pinned in the footer so it never scrolls away in a long / filtered list.
335
- /* @__PURE__ */ jsx("div", { slot: "footer", className: styles.footer, children: /* @__PURE__ */ jsx(MenuItem, { icon: "x", label: clearLabel, "data-menu-open": "", onSelect: clear }) })
328
+ /* @__PURE__ */ jsxs(Fragment, { children: [
329
+ /* @__PURE__ */ jsx(MenuSeparator, { slot: "footer" }),
330
+ /* @__PURE__ */ jsx("a-select-footer", { slot: "footer", children: /* @__PURE__ */ jsx(MenuItem, { icon: "x", label: clearLabel, "data-menu-open": "", onSelect: clear }) })
331
+ ] })
336
332
  ]
337
333
  }
338
334
  )
@@ -2,6 +2,7 @@ import type { BaseProps } from '../general_types';
2
2
  import type { IconShape } from '../elements/a-icon.shapes';
3
3
  import type { OptionValue, SelectItem, SelectOption } from './Select';
4
4
  import { type MenuProps } from './Menu';
5
+ import './select-parts.css';
5
6
  interface FacetBase {
6
7
  /** The facet's namespace — the key its value is stored under in the value
7
8
  * record, and what `onValueChange`'s `attrs.facet` reports. Unique across