@antadesign/anta 0.3.15 → 0.3.17

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 (54) hide show
  1. package/README.md +75 -45
  2. package/dist/anta_helpers.d.ts +8 -13
  3. package/dist/anta_helpers.js +11 -3
  4. package/dist/components/Banner.js +1 -0
  5. package/dist/components/ButtonCopy.d.ts +9 -6
  6. package/dist/components/ButtonCopy.js +5 -3
  7. package/dist/components/Card.js +1 -15
  8. package/dist/components/InputAutocomplete.js +1 -1
  9. package/dist/components/InputTime.d.ts +5 -4
  10. package/dist/components/Slider.d.ts +89 -0
  11. package/dist/components/Slider.js +144 -0
  12. package/dist/components/Switch.d.ts +68 -0
  13. package/dist/components/Switch.js +90 -0
  14. package/dist/components/copy-props.d.ts +2 -0
  15. package/dist/components/copy-props.js +2 -1
  16. package/dist/elements/a-banner.css +1 -1
  17. package/dist/elements/a-button.css +1 -1
  18. package/dist/elements/a-card.css +1 -1
  19. package/dist/elements/a-checkbox.css +1 -1
  20. package/dist/elements/a-copy.d.ts +1 -1
  21. package/dist/elements/a-copy.js +103 -69
  22. package/dist/elements/a-dialog.css +1 -1
  23. package/dist/elements/a-dialog.js +1 -1
  24. package/dist/elements/a-expander.css +1 -1
  25. package/dist/elements/a-icon.css +1 -1
  26. package/dist/elements/a-icon.shapes.css +1 -1
  27. package/dist/elements/a-icon.shapes.d.ts +3 -1
  28. package/dist/elements/a-icon.shapes.js +4 -0
  29. package/dist/elements/a-input-time.css +1 -1
  30. package/dist/elements/a-input-time.js +298 -377
  31. package/dist/elements/a-input.css +1 -1
  32. package/dist/elements/a-input.d.ts +0 -3
  33. package/dist/elements/a-input.js +16 -46
  34. package/dist/elements/a-progress.css +1 -1
  35. package/dist/elements/a-progress.js +2 -0
  36. package/dist/elements/a-radio.css +1 -1
  37. package/dist/elements/a-slider.css +1 -0
  38. package/dist/elements/a-slider.d.ts +24 -0
  39. package/dist/elements/a-slider.js +479 -0
  40. package/dist/elements/a-switch.css +1 -0
  41. package/dist/elements/a-switch.d.ts +31 -0
  42. package/dist/elements/a-switch.js +109 -0
  43. package/dist/elements/a-tabs.css +1 -1
  44. package/dist/elements/a-tag.css +1 -1
  45. package/dist/elements/a-tooltip.css +1 -1
  46. package/dist/elements/copy-behavior.d.ts +3 -3
  47. package/dist/elements/index.d.ts +2 -0
  48. package/dist/elements/index.js +6 -0
  49. package/dist/general_types.d.ts +98 -4
  50. package/dist/index.d.ts +4 -0
  51. package/dist/index.js +4 -0
  52. package/dist/jsx-runtime.d.ts +6 -1
  53. package/dist/theme-anta.css +1 -1
  54. package/package.json +2 -2
package/README.md CHANGED
@@ -10,45 +10,51 @@ One constraint shapes the architecture. Antithesis runs most of its UI in a Work
10
10
  npm install @antadesign/anta # or pnpm / bun
11
11
  ```
12
12
 
13
- Pin an exact version in your `package.json` (`"@antadesign/anta": "0.3.12"`) rather than a floating tag like `"latest"`, which can change between installs.
13
+ Pin an exact version in `package.json` (`"@antadesign/anta": "0.3.16"`) instead
14
+ of a floating tag such as `"latest"`.
14
15
 
15
16
  ### Usage
16
17
 
17
18
  ```tsx
18
- import '@antadesign/anta/tokens.css' // CSS custom properties (colors, sizes, fonts)
19
- import '@antadesign/anta/reset.css' // small reset + Anta's typography opinions
20
- import '@antadesign/anta/elements' // registers <a-progress> et al.
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
21
22
  import { Progress } from '@antadesign/anta'
22
23
 
23
- <Progress value={42} label="uploaded.." hint="3 of 7" />
24
+ <Progress value={42} label="Uploaded" hint="3 of 7" />
24
25
  ```
25
26
 
26
27
  ### What you import (and why)
27
28
 
28
- Five imports, listed in the order you'd add them. Tokens + elements + the JSX layer render a styled component; the reset is recommended; the theme is opt-in.
29
+ Tokens, elements, and the JSX layer render a styled component. The reset is
30
+ recommended; the reference theme is optional.
29
31
 
30
32
  | Import | Provides | Skip if… |
31
33
  |---|---|---|
32
- | `@antadesign/anta/tokens.css` | The CSS custom properties: six tone seeds (`--anta-seed-neutral`, `--anta-seed-brand`, …), the role scales derived from them (`--bg-1…5`, `--text-1…5`, `--border-1…5`), the `.dark` ancestor toggle, and the base `font-size: 15px`. Also declares the `@layer base, anta, components, utilities` order. Override a seed to reskin its whole tone. | You're supplying your own values for the same variables. |
33
- | `@antadesign/anta/reset.css` | Small modern reset (box-sizing, margins, form-control font inheritance) plus Anta's typography for headings, lists, and links. Lives in `@layer anta`. | You already have a reset and don't want Anta's typography defaults. |
34
- | `@antadesign/anta/elements` | Side-effect import: registers every `<a-*>` element and attaches its CSS (also `@layer anta`). Per-element entries register just one — see [Registering elements](#registering-elements). | You render only on the server, or you import per-element entries instead. |
35
- | `@antadesign/anta` | The JSX wrappers (`Progress`, `Text`, `Icon`, …): typed React/Preact components that emit `<a-*>` tags. | You write the `<a-*>` elements by hand. |
36
- | `@antadesign/anta/theme-anta.css` *(optional)* | Anta's hand-tuned reference palette. The default palette is seed-derived; import this last for the exact hand-tuned values. | The seed-derived default, or your own palette, is what you want. |
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. |
37
39
 
38
- The order matters at the top: the element CSS reads `var(--text-1)`, `var(--bg-2)`, and friends, and only `tokens.css` defines them. Skip the tokens import and components render unstyled.
40
+ Load `tokens.css` before element CSS. Elements read its variables; without it,
41
+ they render unstyled.
39
42
 
40
43
  ### Cascade layers
41
44
 
42
- Anta's reset and element CSS live in `@layer anta`. `tokens.css` pre-declares `@layer base, anta, components, utilities;`: Anta's defaults sit above preflight resets (Tailwind's `@layer base`, Normalize) and below your `@layer components` rules and utility frameworks.
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.
43
48
 
44
- For a different order, declare it in your own CSS loaded **before** `tokens.css` — the first mention of each layer name fixes its position:
49
+ To change that order, declare it in CSS loaded **before** `tokens.css`. The
50
+ first declaration fixes a layer's position:
45
51
 
46
52
  ```css
47
53
  /* your global.css, loaded before anta */
48
54
  @layer reset, anta, my-components, utilities;
49
55
  ```
50
56
 
51
- CSS custom properties (the `:root { --… }` declarations in `tokens.css`) stay unlayered so they take effect everywhere unconditionally.
57
+ Token custom properties stay unlayered so they apply everywhere.
52
58
 
53
59
  > **Gotcha: an unlayered hard reset defeats Anta's element rules.**
54
60
  >
@@ -57,26 +63,32 @@ CSS custom properties (the `:root { --… }` declarations in `tokens.css`) stay
57
63
  > * { margin: 0; }
58
64
  > ```
59
65
  >
60
- > Unlayered styles beat layered ones regardless of specificity, so this common copy-paste outranks every per-element default Anta ships (`p` margins, list padding, and the rest). `reset.css` already does the same universal reset inside `@layer anta` — delete the duplicate from your global CSS, or wrap your own reset in `@layer base { … }` so Anta's element rules still win.
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`.
61
70
 
62
71
  ## Registering elements
63
72
 
64
- The JSX wrappers render `<a-*>` tags, and the classes behind those tags must be registered **before** they appear in the DOM. Registration needs `HTMLElement`, which exists only in the UI thread of a real browser; in Node.js (SSR) and Worker threads the import is a silent no-op that costs nothing but bundle size.
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.
65
76
 
66
77
  ```ts
67
78
  import '@antadesign/anta/elements' // auto-registers all elements
68
79
  ```
69
80
 
70
- **Register only what you use.** `/elements` registers everything; per-element entry points register one element and load just its CSS, keeping unused elements (and their dependencies) out of your bundle:
81
+ `/elements` registers everything. Per-element entries register one element and
82
+ load only its CSS:
71
83
 
72
84
  ```ts
73
85
  import '@antadesign/anta/elements/a-tooltip' // only <a-tooltip> + its CSS
74
86
  import '@antadesign/anta/elements/a-button' // only <a-button> + its CSS
75
87
  ```
76
88
 
77
- Both forms are side-effect imports, idempotent, and SSR-safe.
89
+ Both are idempotent, side-effect imports and safe during SSR.
78
90
 
79
- The cleanest pattern is a static import at your app's entry file, outside any component or hook:
91
+ Use a static import in your app entry, outside components and hooks:
80
92
 
81
93
  ```ts
82
94
  // src/main.tsx (or wherever your root render lives)
@@ -86,18 +98,22 @@ import App from './App'
86
98
  createRoot(document.getElementById('root')!).render(<App />)
87
99
  ```
88
100
 
89
- Bundlers resolve this at module-init time, so the element classes are registered before anything renders: no flash of un-upgraded elements.
101
+ Module initialisation registers the classes before the first render, avoiding a
102
+ flash of un-upgraded elements.
90
103
 
91
104
  > **Why not `useEffect(() => import('@antadesign/anta/elements'), [])`?**
92
- > `useEffect` fires after paint and the dynamic import resolves later still, so the browser paints unregistered elements (which collapse to nothing) until the upgrade catches up. `useLayoutEffect` doesn't help: the import is still async, and it warns during SSR hydration.
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.
93
108
 
94
- Where the static import goes depends on the runtime:
109
+ Choose the entry point for your runtime:
95
110
 
96
- **Plain HTML / static sites** — a `<script type="module">` tag in the document head.
97
-
98
- **SSR frameworks (Astro, Next.js)** — a script the framework ships only to the client. In Astro: `<script>import '@antadesign/anta/elements'</script>` (Astro `<script>` tags are client-side by default). In Next.js: a top-level import in a `'use client'` file, which only enters the client chunk.
99
-
100
- **UI in a Worker thread (the Antithesis setup)** — the UI-thread bootstrap, the script that owns the real DOM. The Worker has no `HTMLElement`, so the import must not run there.
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`.
101
117
 
102
118
  ## Framework setup
103
119
 
@@ -107,7 +123,7 @@ Works out of the box.
107
123
 
108
124
  ### Preact with compat
109
125
 
110
- If your bundler aliases `react` → `preact/compat`, anta works automatically — no extra setup.
126
+ If your bundler aliases `react` to `preact/compat`, Anta works without setup.
111
127
 
112
128
  ### Preact without compat
113
129
 
@@ -121,17 +137,21 @@ configure(h, Fragment)
121
137
 
122
138
  ### TypeScript: typing raw `<a-*>` tags in JSX
123
139
 
124
- If you only use the JSX wrappers (`<Button>`, `<Progress>`, …) you need no setup — they're typed like any React component. This section is only for writing the raw `<a-*>` tags directly in JSX.
140
+ JSX wrappers such as `<Button>` and `<Progress>` need no extra typing. Configure
141
+ JSX only when you write raw `<a-*>` tags.
125
142
 
126
- **Option A (preferred)** — point your JSX types at anta in `tsconfig.json`:
143
+ **Option A (preferred)** — point JSX types at Anta in `tsconfig.json`:
127
144
 
128
145
  ```jsonc
129
146
  { "compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "@antadesign/anta" } }
130
147
  ```
131
148
 
132
- Every `a-*` tag type-checks, all standard HTML tags keep working, and importing anything from `@antadesign/stickers` adds the sticker tags automatically.
149
+ Every `a-*` tag type-checks, standard HTML tags keep working, and importing
150
+ `@antadesign/stickers` adds its tags automatically.
133
151
 
134
- **Option B** — if you can't change `jsxImportSource` (a shared tsconfig, Emotion's `@emotion/react` source), merge anta's tag map into your JSX namespace yourself: anta exports it as `AntaIntrinsicElements` (and `@antadesign/stickers` as `StickerIntrinsicElements`), one `extends` in any `.d.ts` your tsconfig covers:
152
+ **Option B** — if `jsxImportSource` cannot change, merge Anta's tag map into
153
+ your JSX namespace with `AntaIntrinsicElements` (and `StickerIntrinsicElements`
154
+ when needed):
135
155
 
136
156
  ```ts
137
157
  import type { AntaIntrinsicElements } from '@antadesign/anta'
@@ -144,7 +164,8 @@ declare global {
144
164
  }
145
165
  ```
146
166
 
147
- On modern `@types/react` (≥18) with `jsx: "react-jsx"`, the JSX namespace is module-scoped and the global declaration above is silently ignored — target the `react` module instead:
167
+ With `@types/react` 18+ and `jsx: "react-jsx"`, JSX is module-scoped. Extend
168
+ the `react` module instead:
148
169
 
149
170
  ```ts
150
171
  import type { AntaIntrinsicElements } from '@antadesign/anta'
@@ -156,11 +177,13 @@ declare module 'react' {
156
177
  }
157
178
  ```
158
179
 
159
- Either way the tags stay fully typed — unknown `a-*` tags and wrong prop types are still errors. New tags arrive automatically when you upgrade anta; there's no per-tag list to maintain.
180
+ Both options reject unknown tags and invalid props. New tags arrive with Anta
181
+ upgrades; there is no per-tag list to maintain.
160
182
 
161
183
  ### Raw web components (no JSX)
162
184
 
163
- The elements work in plain HTML; registering them also loads their CSS. The bare specifier needs a bundler or an import map to resolve.
185
+ Elements also work in plain HTML. Registration loads their CSS; resolve the bare
186
+ specifier with a bundler or import map.
164
187
 
165
188
  ```html
166
189
  <script type="module">
@@ -182,7 +205,7 @@ Add the `dark` class to any ancestor element:
182
205
 
183
206
  ## Fonts
184
207
 
185
- 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 reference families through the `--sans-serif` and `--monospace` variables and fall back to system stacks. The base size is `font-size: 15px` on `:root` (so `1rem = 15px`), a deliberate step down from the browser's 16px for Antithesis's information-dense layouts. Both live in `tokens.css`.
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`).
186
209
 
187
210
  To use the Antithesis fonts, register your own `@font-face` declarations and override the variables:
188
211
 
@@ -201,14 +224,21 @@ To use the Antithesis fonts, register your own `@font-face` declarations and ove
201
224
 
202
225
  ## Browser support
203
226
 
204
- Anta targets evergreen browsers and ships **no polyfills and no feature detection** for its baseline. The floor is set by the [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API) (used by `<a-menu>` and `<a-tooltip>` for top-layer rendering):
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):
205
228
 
206
229
  | Browser | Minimum version |
207
230
  | --- | --- |
208
- | Chrome / Edge | 114 (May 2023) |
209
- | Safari | 17 (Sep 2023) |
210
- | Firefox | 125 (Apr 2024) |
211
-
212
- This corresponds roughly to [Baseline 2024](https://web.dev/baseline). Within that floor, anta freely relies on: `popover` / `showPopover()` / `:popover-open`, `color-mix(in oklch, …)` and relative `oklch(from …)` colors, `:has()`, `dvh` units, CSS cascade layers, and constructable shadow DOM. On an older browser these fail hard (e.g. `showPopover()` throws) — there is no degraded mode by design; gate anta usage on your own support matrix instead.
213
-
214
- Two features are used as **progressive enhancement** with explicit fallbacks: `checkVisibility()` (falls back to `getClientRects()`), and CSS typed `attr()` for `<a-icon size>` (Chrome 133+ / Safari 18.2+; elsewhere use the `<Icon size>` wrapper or the `--icon-size` variable, see the `a-icon` docs).
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`.
@@ -34,7 +34,7 @@ export declare function wrapLabel(kids: React.ReactNode, tag: string): React.Rea
34
34
  * `CustomEvent` in a synthetic event (`.nativeEvent`); Preact passes it directly. `D`
35
35
  * is the per-component `detail` vocabulary. Pair with `nativeStateChange` to unwrap.
36
36
  * Exported so the stateful wrappers (`Banner`, and future ones) don't each re-declare
37
- * this union — the CLAUDE.md "reuse shared wrapper helpers" rule.
37
+ * this union — the AGENTS.md "reuse shared wrapper helpers" rule.
38
38
  */
39
39
  export type StateChangeEvent<D> = CustomEvent<D> | {
40
40
  nativeEvent: CustomEvent<D>;
@@ -73,18 +73,13 @@ export declare const NAMED_TONES: Set<string>;
73
73
  * derives the fill/text/border curve in oklch. Named tones return `base` unchanged.
74
74
  */
75
75
  export declare function toneStyle(tone: string | undefined, varName: string, base?: React.CSSProperties): React.CSSProperties | undefined;
76
- /**
77
- * Inline-style helper for a valued `round` — the polymorphic corner-radius prop
78
- * (`true` = fully round, a `number`/length = a custom radius). Mirrors `toneStyle`:
79
- * a custom value is handed to the element via `varName` (e.g. `--button-round`), so
80
- * the element's CSS resolves `border-radius: var(--{c}-round, <default>)`. This is
81
- * the portable path — the element's `attr(round type(<length>), …)` default only
82
- * resolves on newer engines, exactly like the tone-source `attr()`.
83
- *
84
- * A `number` becomes `<n>px`; a non-empty `string` is used verbatim (so `'1rem'` /
85
- * `'50%'` work). `true` / `false` / `undefined` add nothing (presence alone → the
86
- * element's default full-round). Returns `base` unchanged when there's no value.
87
- */
76
+ /** Converts a numeric or string length to CSS text. Numbers become pixels. */
77
+ export declare function cssLength(length: number | string | undefined): string | undefined;
78
+ /** Adds a CSS length to an inline custom property. Numbers become pixels; a
79
+ * non-empty string is used verbatim. Returns `base` unchanged when absent. */
80
+ export declare function lengthStyle(length: number | string | undefined, varName: string, base?: React.CSSProperties): React.CSSProperties | undefined;
81
+ /** Inline-style helper for a valued `round`. Its boolean form leaves the
82
+ * element's default full-round radius in place. */
88
83
  export declare function roundStyle(round: boolean | number | string | undefined, varName: string, base?: React.CSSProperties): React.CSSProperties | undefined;
89
84
  /**
90
85
  * Presence flag for a `round` attribute: `''` when a radius applies, else
@@ -40,10 +40,16 @@ const NAMED_TONES = /* @__PURE__ */ new Set([
40
40
  function toneStyle(tone, varName, base) {
41
41
  return tone != null && !NAMED_TONES.has(tone) ? { ...base, [varName]: tone } : base;
42
42
  }
43
+ function cssLength(length) {
44
+ if (typeof length === "number") return `${length}px`;
45
+ return length || void 0;
46
+ }
47
+ function lengthStyle(length, varName, base) {
48
+ const value = cssLength(length);
49
+ return value ? { ...base, [varName]: value } : base;
50
+ }
43
51
  function roundStyle(round, varName, base) {
44
- if (typeof round === "number") return { ...base, [varName]: `${round}px` };
45
- if (typeof round === "string" && round !== "") return { ...base, [varName]: round };
46
- return base;
52
+ return lengthStyle(typeof round === "number" || typeof round === "string" ? round : void 0, varName, base);
47
53
  }
48
54
  function roundAttr(round) {
49
55
  return round || round === 0 ? "" : void 0;
@@ -145,10 +151,12 @@ export {
145
151
  NAMED_TONES,
146
152
  SelectableChildElement,
147
153
  anchorRect,
154
+ cssLength,
148
155
  hasChildren,
149
156
  installDismissTrigger,
150
157
  isInsideOpenMenu,
151
158
  isMenuOpen,
159
+ lengthStyle,
152
160
  nativeStateChange,
153
161
  parseOpenState,
154
162
  roundAttr,
@@ -55,6 +55,7 @@ const Banner = ({
55
55
  {
56
56
  priority: "quaternary",
57
57
  icon: "x",
58
+ round,
58
59
  tone,
59
60
  "aria-label": "Dismiss",
60
61
  "data-custom-event": "dismissrequest"
@@ -20,11 +20,14 @@ export type ButtonCopyProps = ButtonProps & {
20
20
  form?: never;
21
21
  iconTrailing?: never;
22
22
  } & CopyTarget & {
23
- /** Where the copy glyph sits relative to the label — or `'none'` to omit it,
24
- * in which case the feedback is a ghost of the label floating up (`toast`)
25
- * plus a brief success / failure tone flash.
23
+ /** Where the copy glyph sits relative to the label — or `'none'` to omit it.
24
+ * Without a glyph, a successful copy shows a small confirmation label near
25
+ * the pointer and leaves the button unchanged.
26
26
  * @defaultValue 'leading' */
27
27
  iconPlacement?: 'leading' | 'trailing' | 'none';
28
+ /** Text in the successful no-icon confirmation.
29
+ * @defaultValue Copied */
30
+ copiedLabel?: string;
28
31
  };
29
32
  /**
30
33
  * Copy button — a `Button` preset for copy-to-clipboard. Set `copy` for a literal
@@ -37,7 +40,7 @@ export type ButtonCopyProps = ButtonProps & {
37
40
  * copy glyph to a check (success) or ✕ (failure) and retones to `success` /
38
41
  * `critical` for ~2s (a re-render, no element state — see `useCopyFeedback`).
39
42
  * `iconPlacement` puts that glyph leading (default), trailing, or `'none'`; with
40
- * `'none'` the `<a-copy>` floats a ghost of the label upward instead.
43
+ * `'none'`, `<a-copy>` shows its `Copied` confirmation instead.
41
44
  *
42
45
  * With a `label` it's a labeled button; without one it's an icon-only copy button
43
46
  * (named "Copy" for assistive tech). Everything else is a normal `Button` prop —
@@ -48,9 +51,9 @@ export type ButtonCopyProps = ButtonProps & {
48
51
  * <ButtonCopy copy="npm i @antadesign/anta" label="Copy install" />
49
52
  * <ButtonCopy copy="https://anta.design" /> // icon-only
50
53
  * <ButtonCopy copy={code} label="Copy" iconPlacement="trailing" />
51
- * <ButtonCopy copy={code} label="Copy snippet" iconPlacement="none" /> // ghost feedback
54
+ * <ButtonCopy copy={code} label="Copy snippet" iconPlacement="none" copiedLabel="Copied" />
52
55
  * <ButtonCopy copyNode=".snippet" label="Copy block" priority="tertiary" />
53
56
  * <ButtonCopy copyUrl label="Copy link" /> // copies location.href
54
57
  * ```
55
58
  */
56
- export declare const ButtonCopy: ({ icon, iconPlacement, tone, onCopied, onCopyRequest, copy, copyNode, copyUrl, copyWithUrl, label, children, "aria-label": ariaLabel, ...rest }: ButtonCopyProps) => any;
59
+ export declare const ButtonCopy: ({ icon, iconPlacement, copiedLabel, tone, onCopied, onCopyRequest, copy, copyNode, copyUrl, copyWithUrl, label, children, "aria-label": ariaLabel, ...rest }: ButtonCopyProps) => any;
@@ -5,6 +5,7 @@ import { copyElementProps, isNodeCopy } from "./copy-props";
5
5
  const ButtonCopy = ({
6
6
  icon,
7
7
  iconPlacement = "leading",
8
+ copiedLabel,
8
9
  tone,
9
10
  onCopied,
10
11
  onCopyRequest,
@@ -28,15 +29,16 @@ const ButtonCopy = ({
28
29
  copyWithUrl,
29
30
  onCopyRequest,
30
31
  onCopied: handleCopied,
31
- // Ghost feedback only makes sense when there's no glyph to swap.
32
- toast: iconPlacement === "none"
32
+ // The top-layer confirmation only appears when there is no glyph to swap.
33
+ toast: iconPlacement === "none",
34
+ copiedLabel
33
35
  });
34
36
  return /* @__PURE__ */ jsxs(
35
37
  Button,
36
38
  {
37
39
  ...iconSlot,
38
40
  label,
39
- tone: shownTone,
41
+ tone: iconPlacement === "none" ? tone : shownTone,
40
42
  "aria-label": ariaLabel ?? (hasText ? void 0 : "Copy"),
41
43
  "data-copy-node-button": isNodeCopy({ copyNode }) ? "" : void 0,
42
44
  ...rest,
@@ -57,21 +57,7 @@ const Card = ({
57
57
  (typeof icon === "string" ? (
58
58
  // A shape string → the icon centered in a circular chip, sized per the
59
59
  // card via --card-icon-size (32 / 40 / 44 for small / medium / large).
60
- /* @__PURE__ */ jsx(
61
- "div",
62
- {
63
- slot: "icon",
64
- style: {
65
- width: "var(--card-icon-size, 40px)",
66
- height: "var(--card-icon-size, 40px)",
67
- borderRadius: "50%",
68
- background: "var(--card-icon-bg)",
69
- display: "grid",
70
- placeItems: "center"
71
- },
72
- children: /* @__PURE__ */ jsx(Icon, { shape: icon })
73
- }
74
- )
60
+ /* @__PURE__ */ jsx("a-card-icon-chip", { slot: "icon", children: /* @__PURE__ */ jsx(Icon, { shape: icon }) })
75
61
  ) : (
76
62
  // Any node → used as-is (no chip).
77
63
  /* @__PURE__ */ jsx("div", { slot: "icon", children: icon })
@@ -54,7 +54,7 @@ const InputAutocomplete = (props) => {
54
54
  setOpen(true);
55
55
  },
56
56
  onKeyDown: (e) => {
57
- if (e.key === "Enter") setOpen(false);
57
+ if (e.key === "Enter" && !e.defaultPrevented) setOpen(false);
58
58
  }
59
59
  }
60
60
  ),
@@ -84,10 +84,11 @@ export interface InputTimeProps extends BaseProps, DOMEventHandlers {
84
84
  /**
85
85
  * `<InputTime>` — a segmented wall-clock time field. One boxed input (matching
86
86
  * the other inputs) with separate hour / minute / (12-hour) AM-PM sections that
87
- * behave as one control: each is a `role="spinbutton"` — ↑/↓ steps with wrap,
88
- * ←/→ moves between them, typing digits auto-advances, and AM/PM toggles with
89
- * ↑/↓ or `a`/`p`. Renders an `<a-input-time>` web component that owns the
90
- * segments, keyboard, and form value (via `ElementInternals`).
87
+ * behave as one control: each is a native text input — ↑/↓ steps with wrap,
88
+ * ←/→ crosses segments at caret boundaries, typing digits auto-advances, and
89
+ * AM/PM accepts its locale text or `a`/`p`. Renders an `<a-input-time>` web
90
+ * component that owns the segments, navigation, and form value (via
91
+ * `ElementInternals`).
91
92
  *
92
93
  * The clock and layout follow the locale (`en-US` → 12-hour, most others 24),
93
94
  * overridable with `hour12`. The value is a 24-hour `"HH:mm"` string; controlled
@@ -0,0 +1,89 @@
1
+ import type { BaseProps, DOMEventHandlers } from '../general_types';
2
+ /** A text marker displayed below the slider rail. Markers are labels only; they
3
+ * do not add dots or ticks to the rail. */
4
+ export interface SliderMarker {
5
+ value: number;
6
+ label: React.ReactNode;
7
+ }
8
+ /** Snapshot passed to `onValueChange` and `onValueCommit`. */
9
+ export interface SliderChangeAttrs {
10
+ value: number;
11
+ min: number;
12
+ max: number;
13
+ step: number;
14
+ name?: string;
15
+ }
16
+ export interface SliderProps extends BaseProps, DOMEventHandlers {
17
+ /** Visible field label, shown above the rail. A string supplies the slider's
18
+ * accessible name; give a rich label an explicit `aria-label`. */
19
+ label?: React.ReactNode;
20
+ /** Controlled value. Update it from `onValueChange`. */
21
+ value?: number;
22
+ /** Initial uncontrolled value.
23
+ * @defaultValue 0 */
24
+ defaultValue?: number;
25
+ /** Lowest permitted value.
26
+ * @defaultValue 0 */
27
+ min?: number;
28
+ /** Highest permitted value.
29
+ * @defaultValue 100 */
30
+ max?: number;
31
+ /** Smallest keyboard and drag increment.
32
+ * @defaultValue 1 */
33
+ step?: number;
34
+ /** Form field name. The current numeric value submits under this name. */
35
+ name?: string;
36
+ /** Disables pointer and keyboard interaction. */
37
+ disabled?: boolean;
38
+ /** Colour of the filled rail. Pass a named tone or a literal CSS colour for a
39
+ * one-off custom tone. The unfilled rail stays neutral.
40
+ * @defaultValue 'neutral' */
41
+ tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
42
+ /** Colour of the thumb stroke. Pass a named tone or a literal CSS colour for a
43
+ * one-off custom tone. Omit it to keep the thumb neutral.
44
+ * @defaultValue 'neutral' */
45
+ thumbTone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
46
+ /** Size variant. small=24px, medium=28px, large=32px tall.
47
+ * @defaultValue 'medium' */
48
+ size?: 'small' | 'medium' | 'large';
49
+ /** Thickness of both rail segments. Numbers use pixels; strings are CSS
50
+ * lengths. Keep it no larger than the thumb diameter.
51
+ * @defaultValue 2 */
52
+ trackSize?: number | string;
53
+ /** Diameter of the thumb. Numbers use pixels; strings are CSS lengths. Keep
54
+ * it at least as large as `trackSize`.
55
+ * @defaultValue 18 */
56
+ thumbSize?: number | string;
57
+ /** Fill the thumb with its resolved border colour. This follows `thumbTone`
58
+ * and interactive states.
59
+ * @defaultValue false */
60
+ thumbFill?: boolean;
61
+ /** Fully round the rail and thumb. Pass a number (px) or CSS length string
62
+ * for a shared custom radius. */
63
+ round?: boolean | number | string;
64
+ /** Where the live value appears. `end` puts it at the right edge of the label
65
+ * row. `inline` renders `Label: value`. `thumb` keeps it above the thumb.
66
+ * @defaultValue 'end' */
67
+ valueDisplay?: 'end' | 'inline' | 'thumb' | 'none';
68
+ /** Text inserted before the live numeric value, such as `$`. */
69
+ valuePrefix?: string;
70
+ /** Text inserted after the live numeric value, such as `%` or `°C`. */
71
+ valueSuffix?: string;
72
+ /** Compact text labels positioned below the rail. They do not add dots or
73
+ * ticks to the rail. */
74
+ markers?: SliderMarker[];
75
+ /** Track press behaviour. `drag-only` starts a relative grab from the current
76
+ * value; `jump` first moves to the press position.
77
+ * @defaultValue 'drag-only' */
78
+ trackClick?: 'drag-only' | 'jump';
79
+ /** Fires on every keyboard or pointer value change. */
80
+ onValueChange?: (event: any, attrs: SliderChangeAttrs) => void;
81
+ /** Fires after a drag ends and after each keyboard value change. */
82
+ onValueCommit?: (event: any, attrs: SliderChangeAttrs) => void;
83
+ }
84
+ /**
85
+ * Slider selects one numeric value from a range. Pressing anywhere on its rail
86
+ * starts a relative drag by default, so the thumb never jumps to the press point.
87
+ * Requires `@antadesign/anta/elements` on the client.
88
+ */
89
+ export declare const Slider: ({ label, value, defaultValue, min: minProp, max: maxProp, step: stepProp, name, disabled, tone, thumbTone, size, trackSize, thumbSize, thumbFill, round, valueDisplay, valuePrefix, valueSuffix, markers, trackClick, onInput, onChange, onValueChange, onValueCommit, className, style, children, tabIndex, ...rest }: SliderProps) => any;