@antadesign/anta 0.3.19 → 0.3.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/anta_helpers.d.ts +11 -2
- package/dist/anta_helpers.js +9 -0
- package/dist/components/Banner.d.ts +3 -3
- package/dist/components/Button.d.ts +1 -1
- package/dist/components/Calendar.d.ts +11 -12
- package/dist/components/Card.d.ts +1 -1
- package/dist/components/Card.js +1 -1
- package/dist/components/Checkbox.d.ts +8 -9
- package/dist/components/Dialog.d.ts +1 -1
- package/dist/components/Expander.d.ts +5 -6
- package/dist/components/Input.d.ts +2 -2
- package/dist/components/Input.js +1 -1
- package/dist/components/InputAutocomplete.d.ts +8 -8
- package/dist/components/InputAutocomplete.js +24 -18
- package/dist/components/InputTime.d.ts +3 -3
- package/dist/components/InputTime.js +1 -1
- package/dist/components/Menu.d.ts +2 -2
- package/dist/components/MenuItem.d.ts +1 -1
- package/dist/components/MenuItem.js +1 -1
- package/dist/components/Progress.d.ts +1 -1
- package/dist/components/RadioGroup.d.ts +14 -15
- package/dist/components/RadioGroup.js +5 -2
- package/dist/components/Select.d.ts +33 -40
- package/dist/components/Select.js +6 -2
- package/dist/components/SelectFaceted.d.ts +27 -33
- package/dist/components/SelectFaceted.js +5 -1
- package/dist/components/Slider.d.ts +5 -5
- package/dist/components/Switch.d.ts +4 -4
- package/dist/components/TabPanel.d.ts +1 -2
- package/dist/components/TabPanel.js +0 -1
- package/dist/components/Tabs.d.ts +9 -9
- package/dist/components/Tabs.js +5 -2
- package/dist/components/Text.d.ts +5 -3
- package/dist/components/Text.js +7 -3
- package/dist/components/Title.d.ts +1 -1
- package/dist/components/Toaster.d.ts +1 -1
- package/dist/components/Tooltip.d.ts +1 -1
- package/dist/elements/a-card.css +1 -1
- package/dist/elements/a-dialog.css +1 -1
- package/dist/elements/a-expander.css +1 -1
- package/dist/elements/a-expander.d.ts +1 -0
- package/dist/elements/a-expander.js +12 -2
- package/dist/elements/a-menu.d.ts +1 -8
- package/dist/elements/a-menu.js +1 -40
- package/dist/elements/a-progress.css +1 -1
- package/dist/elements/a-text.d.ts +4 -0
- package/dist/elements/a-text.js +10 -3
- package/dist/elements/a-tooltip.css +1 -1
- package/dist/elements/a-tooltip.d.ts +8 -1
- package/dist/elements/a-tooltip.js +88 -15
- package/dist/elements/index.d.ts +1 -1
- package/dist/general_types.d.ts +33 -22
- package/dist/index.d.ts +3 -3
- package/dist/theme-anta.css +1 -1
- package/docs/accessibility.md +4 -4
- package/docs/changelog.md +40 -13
- package/docs/comparison.md +1 -1
- package/docs/components/banner.md +17 -17
- package/docs/components/button.md +6 -6
- package/docs/components/card.md +5 -6
- package/docs/components/checkbox.md +17 -18
- package/docs/components/dialog.md +2 -2
- package/docs/components/expander.md +27 -30
- package/docs/components/icon.md +1 -1
- package/docs/components/input-autocomplete.md +15 -16
- package/docs/components/input-date.md +54 -59
- package/docs/components/input-time.md +7 -7
- package/docs/components/input.md +14 -14
- package/docs/components/menu.md +72 -8
- package/docs/components/progress.md +2 -2
- package/docs/components/radio.md +28 -25
- package/docs/components/select-faceted.md +95 -100
- package/docs/components/select.md +113 -115
- package/docs/components/slider.md +15 -10
- package/docs/components/switch.md +13 -13
- package/docs/components/tabs.md +23 -23
- package/docs/components/tag.md +5 -5
- package/docs/components/text.md +31 -7
- package/docs/components/title.md +1 -1
- package/docs/components/toaster.md +4 -4
- package/docs/components/tooltip.md +2 -2
- package/docs/credits.md +0 -4
- package/docs/index.md +1 -1
- package/docs/install-config.md +12 -7
- package/docs/normalization.md +6 -9
- package/docs/overview.md +1 -1
- package/docs/packages/stickers.md +1 -1
- package/docs/theming.md +15 -0
- package/package.json +3 -8
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @antadesign/anta
|
|
2
2
|
|
|
3
|
-
**Anta** is
|
|
3
|
+
**Anta** is an opinionated design system. It provides
|
|
4
4
|
design tokens, declarative web components, and typed JSX wrappers. Use the same
|
|
5
5
|
components in React, Preact via compat, plain HTML, and custom JSX runtimes via
|
|
6
6
|
`configure()`.
|
package/dist/anta_helpers.d.ts
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import type { IconShape } from "./elements/a-icon.shapes";
|
|
2
|
+
import type { OptionPresentationProps } from "./general_types";
|
|
2
3
|
export declare function hasChildren(children: React.ReactNode): boolean;
|
|
4
|
+
/**
|
|
5
|
+
* Select the safe presentation attributes from a data-rendered option. Option
|
|
6
|
+
* objects often carry application data, so wrappers must never spread them onto
|
|
7
|
+
* their rendered element. Menu rows also own `data-menu-*`: those attributes
|
|
8
|
+
* control closing and combobox navigation, and letting an option replace them
|
|
9
|
+
* would desynchronize its selection behavior.
|
|
10
|
+
*/
|
|
11
|
+
export declare function optionPresentationAttrs(option: OptionPresentationProps, menu?: boolean): OptionPresentationProps;
|
|
3
12
|
/**
|
|
4
13
|
* Normalize a wrapper's label content the way `Button` / `Tabs` do: a bare string
|
|
5
14
|
* or number becomes a `<tag>` — the ellipsis-capable label part (`a-button-label`,
|
|
@@ -65,10 +74,10 @@ export declare function parseOpenState(v: string | null): 'open' | 'closed';
|
|
|
65
74
|
* (e.g. skipping `[disabled]` triggers) lands for every element at once. */
|
|
66
75
|
export declare function installDismissTrigger(host: HTMLElement, attr: string, onDismiss: () => void): void;
|
|
67
76
|
/** The six named tones every toned component shares. Anything else is a literal
|
|
68
|
-
* CSS
|
|
77
|
+
* CSS color the element resolves through its `--{component}-tone-source` var. */
|
|
69
78
|
export declare const NAMED_TONES: Set<string>;
|
|
70
79
|
/**
|
|
71
|
-
* Inline-style helper for a custom (non-named) tone: hands the literal
|
|
80
|
+
* Inline-style helper for a custom (non-named) tone: hands the literal color to
|
|
72
81
|
* the element via `varName` (e.g. `--radio-tone-source`) so the element's CSS
|
|
73
82
|
* derives the fill/text/border curve in oklch. Named tones return `base` unchanged.
|
|
74
83
|
*/
|
package/dist/anta_helpers.js
CHANGED
|
@@ -2,6 +2,14 @@ import { jsx, useState, useMemo } from "./jsx-runtime";
|
|
|
2
2
|
function hasChildren(children) {
|
|
3
3
|
return Array.isArray(children) ? children.length > 0 : children != null;
|
|
4
4
|
}
|
|
5
|
+
function optionPresentationAttrs(option, menu = false) {
|
|
6
|
+
const attrs = {};
|
|
7
|
+
for (const [name, value] of Object.entries(option)) {
|
|
8
|
+
if (name === "className" || name === "style" || name.startsWith("data-") && (!menu || !name.startsWith("data-menu-") && name !== "data-anta-menu-item"))
|
|
9
|
+
attrs[name] = value;
|
|
10
|
+
}
|
|
11
|
+
return attrs;
|
|
12
|
+
}
|
|
5
13
|
function wrapLabel(kids, tag) {
|
|
6
14
|
if (kids == null) return kids;
|
|
7
15
|
const arr = Array.isArray(kids) ? kids : [kids];
|
|
@@ -158,6 +166,7 @@ export {
|
|
|
158
166
|
isMenuOpen,
|
|
159
167
|
lengthStyle,
|
|
160
168
|
nativeStateChange,
|
|
169
|
+
optionPresentationAttrs,
|
|
161
170
|
parseOpenState,
|
|
162
171
|
roundAttr,
|
|
163
172
|
roundStyle,
|
|
@@ -12,7 +12,7 @@ export interface BannerProps extends BaseProps {
|
|
|
12
12
|
children?: React.ReactNode;
|
|
13
13
|
/** Semantic tone, or any literal CSS color (`'#ff1493'`, `'rebeccapurple'`) for
|
|
14
14
|
* a one-off custom tone. Named tones re-point the surface, text, and border
|
|
15
|
-
*
|
|
15
|
+
* color (used if you opt into a border); a custom color keeps its hue while
|
|
16
16
|
* lightness/chroma are pinned. `'neutral'` (the default) is the same as omitting it.
|
|
17
17
|
* @defaultValue 'neutral' */
|
|
18
18
|
tone?: "neutral" | "brand" | "info" | "success" | "warning" | "critical" | (string & {});
|
|
@@ -22,7 +22,7 @@ export interface BannerProps extends BaseProps {
|
|
|
22
22
|
round?: boolean | number | string;
|
|
23
23
|
/** Whether the trailing ✕ dismiss button is present. `false` removes it — drive
|
|
24
24
|
* dismissal yourself (a controlled `dismissed`, or your own control) instead.
|
|
25
|
-
* It
|
|
25
|
+
* It removes the built-in ✕ without making the banner un-dismissible.
|
|
26
26
|
* @defaultValue true */
|
|
27
27
|
closable?: boolean;
|
|
28
28
|
/** ARIA role for the strip host. `'status'` (a polite live region, so the notice
|
|
@@ -39,7 +39,7 @@ export interface BannerProps extends BaseProps {
|
|
|
39
39
|
/** Initial dismissed state for the uncontrolled case (read once on mount). */
|
|
40
40
|
defaultDismissed?: boolean;
|
|
41
41
|
/** Fired when the user dismisses the banner (clicks ✕). Uncontrolled, the banner
|
|
42
|
-
* hides itself and this
|
|
42
|
+
* hides itself and this notifies. Controlled, use it to accept the
|
|
43
43
|
* request — set `dismissed` to `true` (or ignore to reject); pair it with
|
|
44
44
|
* `dismissed`, or the banner can't be closed. */
|
|
45
45
|
onDismiss?: () => void;
|
|
@@ -58,7 +58,7 @@ export type ContentMode = {
|
|
|
58
58
|
* don't carry anchor props. (Copy is no longer a Button concern — `ButtonCopy`
|
|
59
59
|
* composes a `<a-copy>` child; see `copy-props.ts`.)
|
|
60
60
|
*
|
|
61
|
-
* `href` is **optional
|
|
61
|
+
* `href` is **optional**, so you can pass a conditional URL: `href={maybeUrl}`
|
|
62
62
|
* (`string | undefined`) type-checks, and a falsy href degrades to a plain
|
|
63
63
|
* button — a definite string renders `<a role="button">`, an absent / `undefined`
|
|
64
64
|
* href renders `<a-button>`, mirroring the `href != null` runtime check. Keeping
|
|
@@ -14,8 +14,8 @@ export interface CalendarChangeAttrs {
|
|
|
14
14
|
}
|
|
15
15
|
/** Public props for `<Calendar>` — the single-date month grid. */
|
|
16
16
|
export interface CalendarProps extends Omit<BaseProps, "children" | "onChange"> {
|
|
17
|
-
/** Controlled selected date — ISO `YYYY-MM-DD`. When provided, the
|
|
18
|
-
* selection: the grid follows this prop and a pick only *requests* a change via
|
|
17
|
+
/** Controlled selected date — ISO `YYYY-MM-DD`. When provided, the application
|
|
18
|
+
* controls selection: the grid follows this prop and a pick only *requests* a change via
|
|
19
19
|
* `onStateChange`. Leave undefined for uncontrolled. */
|
|
20
20
|
value?: string;
|
|
21
21
|
/** Initial selected date for the uncontrolled case (ISO `YYYY-MM-DD`). */
|
|
@@ -53,23 +53,22 @@ export interface CalendarProps extends Omit<BaseProps, "children" | "onChange">
|
|
|
53
53
|
/** Fired *after* the selection changes (post-apply). Not cancelable; for a
|
|
54
54
|
* controlled calendar it fires once you've updated `value`. */
|
|
55
55
|
onChange?: (event: Event) => void;
|
|
56
|
-
/** Like `onChange`, but with a `{ value, name }` snapshot
|
|
57
|
-
*
|
|
56
|
+
/** Like `onChange`, but with a `{ value, name }` snapshot as the second argument,
|
|
57
|
+
* matching `Input`. */
|
|
58
58
|
onValueChange?: (event: Event, attrs: CalendarChangeAttrs) => void;
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
|
-
* `<Calendar>`
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* `selected` state, toned `brand` so the active date reads in the brand color.
|
|
61
|
+
* `<Calendar>` is a single-date month grid. It uses Anta components in light DOM.
|
|
62
|
+
* Days and the previous/next chevrons are `<Button>`s, so they use the design
|
|
63
|
+
* system's button states. A selected day is a `tertiary` Button in its `selected`
|
|
64
|
+
* state, using the `brand` tone so the active date uses the brand color.
|
|
66
65
|
* All date math runs on the Temporal engine
|
|
67
66
|
* (`@antadesign/anta` exports `buildMonth` & friends), and the value is an ISO
|
|
68
67
|
* `YYYY-MM-DD` string.
|
|
69
68
|
*
|
|
70
|
-
* The grid lives in a form-associated `<a-calendar>` element
|
|
71
|
-
* submitted value
|
|
72
|
-
* keyboard, and roving `tabindex
|
|
69
|
+
* The grid lives in a form-associated `<a-calendar>` element, which manages the
|
|
70
|
+
* submitted value, reset, and restore. The wrapper manages view month, selection,
|
|
71
|
+
* keyboard, and roving `tabindex`. The month switcher
|
|
73
72
|
* is a sibling rendered *outside* the grid, so it can be extended (month/year
|
|
74
73
|
* pickers) independently.
|
|
75
74
|
*
|
|
@@ -93,7 +93,7 @@ export interface CardProps extends BaseProps {
|
|
|
93
93
|
* @example Link card
|
|
94
94
|
* ```tsx
|
|
95
95
|
* <Card href="/docs/ci" header="CI integration guide">
|
|
96
|
-
*
|
|
96
|
+
* Connect your CI pipeline in a few minutes.
|
|
97
97
|
* </Card>
|
|
98
98
|
* ```
|
|
99
99
|
*/
|
package/dist/components/Card.js
CHANGED
|
@@ -75,7 +75,7 @@ const Card = ({
|
|
|
75
75
|
/* @__PURE__ */ jsx(Text, { slot: "header", size: "small", priority: "tertiary", tone: toneAttr, children: subtitle }),
|
|
76
76
|
typeof children === "string" || typeof children === "number" ? (
|
|
77
77
|
// A string / number body becomes a <Text> at secondary priority (text-2,
|
|
78
|
-
// the body
|
|
78
|
+
// the body color) — stated explicitly rather than leaning on the default —
|
|
79
79
|
// following the card's tone and size. Anything else is a node the caller
|
|
80
80
|
// owns, passed through untouched.
|
|
81
81
|
/* @__PURE__ */ jsx(Text, { priority: "secondary", tone: toneAttr, size, children })
|
|
@@ -37,7 +37,7 @@ export interface CheckboxProps extends BaseProps {
|
|
|
37
37
|
* visual precedence; clicking it requests `true`. */
|
|
38
38
|
checked?: CheckboxValue;
|
|
39
39
|
/** Initial checked state for an uncontrolled checkbox. Read once; later
|
|
40
|
-
* changes ignored
|
|
40
|
+
* changes are ignored and the element updates its state after interaction.
|
|
41
41
|
* @defaultValue false */
|
|
42
42
|
defaultChecked?: CheckboxValue;
|
|
43
43
|
/** Disable the checkbox (no interaction, dropped from the tab order). */
|
|
@@ -51,16 +51,16 @@ export interface CheckboxProps extends BaseProps {
|
|
|
51
51
|
/** Value submitted with the form when checked — like a native checkbox.
|
|
52
52
|
* @defaultValue "on" */
|
|
53
53
|
value?: string;
|
|
54
|
-
/**
|
|
54
|
+
/** Color of the **mark** in every state — the checked-box fill *and* the
|
|
55
55
|
* unselected box border. A named tone or any literal CSS color (`'#ff1493'`,
|
|
56
56
|
* `'rebeccapurple'`) for a one-off custom tone. Named tones track light/dark mode
|
|
57
|
-
* automatically; a custom
|
|
57
|
+
* automatically; a custom color keeps its hue + chroma and pins lightness to the
|
|
58
58
|
* fill curve. Use `toneSelected` instead to tone only the checked mark and leave
|
|
59
|
-
* the empty box neutral. The label + hint stay neutral —
|
|
59
|
+
* the empty box neutral. The label + hint stay neutral — recolor them in plain
|
|
60
60
|
* CSS via the theme-aware `--text-N-{tone}` tokens.
|
|
61
61
|
* @defaultValue 'neutral' */
|
|
62
62
|
tone?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
|
|
63
|
-
/** Like `tone`, but
|
|
63
|
+
/** Like `tone`, but colored onto the **checked mark only** — the empty box stays
|
|
64
64
|
* neutral grey until it's checked. Prefer this over `tone` when a resting tinted
|
|
65
65
|
* border would read as a validation state. Same value set as `tone`; if both are
|
|
66
66
|
* set, `tone` governs the off-state border and `toneSelected` the checked fill.
|
|
@@ -82,13 +82,12 @@ export interface CheckboxProps extends BaseProps {
|
|
|
82
82
|
* checkbox this fires once you've updated `checked`. */
|
|
83
83
|
onChange?: (event: Event) => void;
|
|
84
84
|
/** Like `onChange`, but with a `{ checked, indeterminate, name, value }` snapshot
|
|
85
|
-
* as the
|
|
86
|
-
* (mirrors `Input`'s `onValueChange`). */
|
|
85
|
+
* as the second argument, matching `Input`'s `onValueChange`. */
|
|
87
86
|
onValueChange?: (event: Event, attrs: CheckboxChangeAttrs) => void;
|
|
88
87
|
}
|
|
89
88
|
/**
|
|
90
|
-
* Checkbox. Renders an `<a-checkbox>` web component that
|
|
91
|
-
* state;
|
|
89
|
+
* Checkbox. Renders an `<a-checkbox>` web component that provides visual
|
|
90
|
+
* state; use `checked` with `onStateChange` for controlled use, or
|
|
92
91
|
* `defaultChecked`. Label is `label` (or `children`); `hint` adds secondary
|
|
93
92
|
* text under the label. Requires `@antadesign/anta/elements`.
|
|
94
93
|
*
|
|
@@ -18,7 +18,7 @@ export interface DialogProps extends Omit<BaseProps, "title"> {
|
|
|
18
18
|
position?: "center" | "left" | "right" | "top" | "bottom" | "fullscreen";
|
|
19
19
|
/** Whether the top-right ✕ button is present. It's one way to close the dialog,
|
|
20
20
|
* alongside Esc, the backdrop, a `data-dialog-close` / footer action, and your
|
|
21
|
-
* own code; `false`
|
|
21
|
+
* own code; `false` removes the ✕ without making the dialog unclosable.
|
|
22
22
|
* @defaultValue true */
|
|
23
23
|
closable?: boolean;
|
|
24
24
|
/** Turn off light-dismiss: a backdrop click and Esc no longer close the dialog.
|
|
@@ -44,10 +44,9 @@ export interface ExpanderProps extends Omit<BaseProps, "title"> {
|
|
|
44
44
|
* `number` (px) or CSS length string for a *fixed* radius that overrides the
|
|
45
45
|
* measurement (and skips it) in both states. */
|
|
46
46
|
round?: boolean | number | string;
|
|
47
|
-
/** Controlled open state. When provided, the consumer owns open/close
|
|
48
|
-
* the
|
|
49
|
-
*
|
|
50
|
-
* not updating). Leave undefined for uncontrolled. */
|
|
47
|
+
/** Controlled open state. When provided, the consumer owns open/close. Selecting
|
|
48
|
+
* the summary requests a change through `onStateChange`; omit `open` for
|
|
49
|
+
* uncontrolled use. */
|
|
51
50
|
open?: boolean;
|
|
52
51
|
/** Initial open state for the uncontrolled case. */
|
|
53
52
|
defaultOpen?: boolean;
|
|
@@ -64,12 +63,12 @@ export interface ExpanderProps extends Omit<BaseProps, "title"> {
|
|
|
64
63
|
/**
|
|
65
64
|
* `<Expander>` — a collapsible disclosure section.
|
|
66
65
|
*
|
|
67
|
-
* A pure, stateless pass-through to `<a-expander>`: the element
|
|
66
|
+
* A pure, stateless pass-through to `<a-expander>`: the element handles all
|
|
68
67
|
* interaction (toggle, keyboard, ARIA, animation), so the wrapper holds
|
|
69
68
|
* no state and grabs no ref — it only maps props to attributes (safe
|
|
70
69
|
* wherever the host DOM is reconciled, incl. off the UI thread).
|
|
71
70
|
*
|
|
72
|
-
* Uncontrolled (`defaultOpen`): the element
|
|
71
|
+
* Uncontrolled (`defaultOpen`): the element updates its open state. The wrapper
|
|
73
72
|
* emits `default-state="open"` — never `state` — so the DOM carries no stale
|
|
74
73
|
* controlled attribute. Controlled (`open` + `onStateChange`): the wrapper
|
|
75
74
|
* emits `state="open" | "closed"`; the element treats the attribute as the
|
|
@@ -19,7 +19,7 @@ export interface InputChangeAttrs {
|
|
|
19
19
|
export interface InputProps extends BaseProps, DOMEventHandlers {
|
|
20
20
|
/** Extra content rendered directly under the field, above the hint/error (it
|
|
21
21
|
* pushes the message down). A no-box child like an Anta `<Tooltip>` takes no
|
|
22
|
-
* space and
|
|
22
|
+
* space and anchors to the field — consistent with how tooltips attach
|
|
23
23
|
* to any other element. Use the named `leading` / `trailing` props for
|
|
24
24
|
* in-field content. */
|
|
25
25
|
children?: React.ReactNode;
|
|
@@ -41,7 +41,7 @@ export interface InputProps extends BaseProps, DOMEventHandlers {
|
|
|
41
41
|
* success → `circle-check`, info → `info`, brand → `circle-small-solid`); pass a
|
|
42
42
|
* shape to override, or `false` to drop it. `neutral` has no default glyph. */
|
|
43
43
|
statusIcon?: IconShape | (string & {}) | false;
|
|
44
|
-
/** Custom accent
|
|
44
|
+
/** Custom accent color — any literal CSS color tints the resting + hover
|
|
45
45
|
* border (focus ring stays the global `--focus-ring`). For consistency with the
|
|
46
46
|
* other controls' custom-tone knob; a `status` still overrides for validation. */
|
|
47
47
|
tone?: string;
|
package/dist/components/Input.js
CHANGED
|
@@ -126,7 +126,7 @@ const Input = ({
|
|
|
126
126
|
label != null && (isStringish(label) ? /* @__PURE__ */ jsx("span", { slot: "label", children: label }) : /* @__PURE__ */ jsx("span", { slot: "label", style: { display: "contents" }, children: label })),
|
|
127
127
|
resolvedLeading != null && /* @__PURE__ */ jsx("span", { slot: "leading", style: { display: "contents" }, children: resolvedLeading }),
|
|
128
128
|
resolvedClearable && // A real <a-button> (light DOM → fully styled, keyboard-focusable) in
|
|
129
|
-
// the element's `clear` slot — the element
|
|
129
|
+
// the element's `clear` slot — the element controls its visibility (shown
|
|
130
130
|
// only when filled + editable). It fires the bubbling `clearrequest`
|
|
131
131
|
// event via a-button's global listener, so clearing works even without
|
|
132
132
|
// framework hydration; the element turns that into clearclick→clear().
|
|
@@ -8,7 +8,7 @@ export interface InputAutocompleteProps extends Omit<BaseProps, 'children'> {
|
|
|
8
8
|
/** Controlled value: the field's text, a **free** string not constrained to a
|
|
9
9
|
* suggestion. Leave undefined for uncontrolled. */
|
|
10
10
|
value?: string;
|
|
11
|
-
/** Initial value for
|
|
11
|
+
/** Initial value for uncontrolled use. */
|
|
12
12
|
defaultValue?: string;
|
|
13
13
|
/** Fires as the text changes (typing, picking a suggestion, or clearing) with
|
|
14
14
|
* the new field text. */
|
|
@@ -17,8 +17,8 @@ export interface InputAutocompleteProps extends Omit<BaseProps, 'children'> {
|
|
|
17
17
|
onSelect?: (option: SelectOption) => void;
|
|
18
18
|
/** How suggestions match the text. `true` uses the built-in case-insensitive
|
|
19
19
|
* substring match on `value` / `label` / `hint`; a function `(option, query) =>
|
|
20
|
-
* boolean`
|
|
21
|
-
*
|
|
20
|
+
* boolean` uses a custom matcher; `false` shows `suggestions` unchanged for
|
|
21
|
+
* application-provided async or remote filtering.
|
|
22
22
|
* @defaultValue true */
|
|
23
23
|
filter?: boolean | ((option: SelectOption, query: string) => boolean);
|
|
24
24
|
/** Placeholder text. */
|
|
@@ -30,7 +30,7 @@ export interface InputAutocompleteProps extends Omit<BaseProps, 'children'> {
|
|
|
30
30
|
status?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical';
|
|
31
31
|
/** Status icon override, or `false` to drop it. */
|
|
32
32
|
statusIcon?: IconShape | (string & {}) | false;
|
|
33
|
-
/** Custom accent
|
|
33
|
+
/** Custom accent color — a named tone or any CSS color. */
|
|
34
34
|
tone?: string;
|
|
35
35
|
/** Show a clear button while the field has text. */
|
|
36
36
|
clearable?: boolean;
|
|
@@ -48,10 +48,10 @@ export interface InputAutocompleteProps extends Omit<BaseProps, 'children'> {
|
|
|
48
48
|
trailing?: React.ReactNode;
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
51
|
-
* `<InputAutocomplete>`
|
|
52
|
-
*
|
|
53
|
-
* the
|
|
54
|
-
*
|
|
51
|
+
* `<InputAutocomplete>` is a text field with a suggestion dropdown. Its value is
|
|
52
|
+
* a free-form string. Text not in the list remains valid, and choosing a
|
|
53
|
+
* suggestion fills the field. Use `Select` with `filter` when the value must be
|
|
54
|
+
* one of the options.
|
|
55
55
|
*
|
|
56
56
|
* Controlled (`value` + `onValueChange`) or uncontrolled (`defaultValue`).
|
|
57
57
|
* Requires `@antadesign/anta/elements` (client-side only).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
2
|
import { useState, useMemo, useId } from "../jsx-runtime";
|
|
3
|
-
import { nativeStateChange } from "../anta_helpers";
|
|
3
|
+
import { nativeStateChange, optionPresentationAttrs } from "../anta_helpers";
|
|
4
4
|
import { normalizeOpt, matchQueryRegex, matchesQuery, highlight } from "./select-options";
|
|
5
5
|
import { Input } from "./Input";
|
|
6
6
|
import { Menu } from "./Menu";
|
|
@@ -69,23 +69,29 @@ const InputAutocomplete = (props) => {
|
|
|
69
69
|
if (!next) setActiveId(null);
|
|
70
70
|
},
|
|
71
71
|
onactivedescendant: (e) => setActiveId(nativeStateChange(e).detail?.id ?? null),
|
|
72
|
-
children: visible.map((opt, i) =>
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
72
|
+
children: visible.map((opt, i) => {
|
|
73
|
+
const { className: optionClassName, style: optionStyle, ...optionAttrs } = optionPresentationAttrs(opt, true);
|
|
74
|
+
return /* @__PURE__ */ jsx(
|
|
75
|
+
MenuItem,
|
|
76
|
+
{
|
|
77
|
+
...optionAttrs,
|
|
78
|
+
id: `${rid}-o${i}`,
|
|
79
|
+
role: "option",
|
|
80
|
+
"aria-selected": activeId === `${rid}-o${i}` ? "true" : "false",
|
|
81
|
+
icon: opt.icon,
|
|
82
|
+
label: highlight(opt.label ?? opt.value, queryRe),
|
|
83
|
+
hint: opt.hint ? highlight(opt.hint, queryRe) : opt.hint,
|
|
84
|
+
tone: opt.tone,
|
|
85
|
+
disabled: opt.disabled,
|
|
86
|
+
value: opt.value,
|
|
87
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
88
|
+
onSelect: () => pick(opt),
|
|
89
|
+
className: optionClassName,
|
|
90
|
+
style: optionStyle
|
|
91
|
+
},
|
|
92
|
+
`${rid}-${opt.value}-${i}`
|
|
93
|
+
);
|
|
94
|
+
})
|
|
89
95
|
}
|
|
90
96
|
)
|
|
91
97
|
] });
|
|
@@ -16,7 +16,7 @@ export interface InputTimeChangeAttrs {
|
|
|
16
16
|
}
|
|
17
17
|
export interface InputTimeProps extends BaseProps, DOMEventHandlers {
|
|
18
18
|
/** Extra content rendered under the field, above the hint (a no-box child like
|
|
19
|
-
* a `<Tooltip>` takes no space and
|
|
19
|
+
* a `<Tooltip>` takes no space and anchors to the field). */
|
|
20
20
|
children?: React.ReactNode;
|
|
21
21
|
/** Field label, shown above the control and used as the segment group's
|
|
22
22
|
* accessible name. */
|
|
@@ -29,7 +29,7 @@ export interface InputTimeProps extends BaseProps, DOMEventHandlers {
|
|
|
29
29
|
/** Glyph before the `hint` when `status` is set (per-status default; pass a
|
|
30
30
|
* shape to override, or `false` to drop it). */
|
|
31
31
|
statusIcon?: IconShape | (string & {}) | false;
|
|
32
|
-
/** Custom accent
|
|
32
|
+
/** Custom accent color — any literal CSS color tints the resting + hover
|
|
33
33
|
* border (focus ring stays `--focus-ring`); `status` overrides for validation. */
|
|
34
34
|
tone?: string;
|
|
35
35
|
/** Size variant. small=24px, medium=28px, large=32px tall.
|
|
@@ -87,7 +87,7 @@ export interface InputTimeProps extends BaseProps, DOMEventHandlers {
|
|
|
87
87
|
* behave as one control: each is a native text input — ↑/↓ steps with wrap,
|
|
88
88
|
* ←/→ crosses segments at caret boundaries, typing digits auto-advances, and
|
|
89
89
|
* AM/PM accepts its locale text or `a`/`p`. Renders an `<a-input-time>` web
|
|
90
|
-
* component that
|
|
90
|
+
* component that manages the segments, navigation, and form value (via
|
|
91
91
|
* `ElementInternals`).
|
|
92
92
|
*
|
|
93
93
|
* The clock and layout follow the locale (`en-US` → 12-hour, most others 24),
|
|
@@ -79,7 +79,7 @@ const InputTime = ({
|
|
|
79
79
|
children: [
|
|
80
80
|
label != null && (isStringish(label) ? /* @__PURE__ */ jsx("span", { slot: "label", children: label }) : /* @__PURE__ */ jsx("span", { slot: "label", style: { display: "contents" }, children: label })),
|
|
81
81
|
icon !== false && /* @__PURE__ */ jsx("span", { slot: "leading", style: { display: "contents" }, children: /* @__PURE__ */ jsx(Icon, { shape: icon ?? "clock" }) }),
|
|
82
|
-
clearable && // Real <a-button> in the element's `clear` slot; the element
|
|
82
|
+
clearable && // Real <a-button> in the element's `clear` slot; the element controls its
|
|
83
83
|
// visibility (shown only when filled). It fires `clearrequest`, which the
|
|
84
84
|
// element turns into clear(). CONTRACT: `data-custom-event` MUST match
|
|
85
85
|
// CLEAR_TRIGGER in src/elements/a-input-time.ts (string duplicated, not
|
|
@@ -57,7 +57,7 @@ export interface MenuProps extends BaseProps {
|
|
|
57
57
|
/** Combobox-mode cursor report (raw element event). Fires when the active
|
|
58
58
|
* option changes as arrow keys move the cursor while focus stays in a
|
|
59
59
|
* `[data-menu-search]` filter field; `detail.id` is the active option's `id`
|
|
60
|
-
* (`null` when none). The reactive layer that
|
|
60
|
+
* (`null` when none). The reactive layer that renders the field reflects this
|
|
61
61
|
* onto its `aria-activedescendant` — the element can't write that light-DOM
|
|
62
62
|
* attribute itself. Passed straight through to the element. */
|
|
63
63
|
onactivedescendant?: (e: CustomEvent<{
|
|
@@ -78,7 +78,7 @@ export interface MenuProps extends BaseProps {
|
|
|
78
78
|
*
|
|
79
79
|
* Open state is uncontrolled by default — listen for `onStateChange`
|
|
80
80
|
* (`detail: { next, prev }`) to observe it, or pass `open` to control it. You
|
|
81
|
-
* can also
|
|
81
|
+
* can also keep a `ref` and call `.open()` / `.close()` / `.toggle()`.
|
|
82
82
|
* Selecting a `MenuItem` closes the menu;
|
|
83
83
|
* arbitrary injected content does not. Add `data-menu-open` to any item /
|
|
84
84
|
* container to keep it open, or `data-menu-close` to a custom element to let it
|
|
@@ -111,7 +111,7 @@ export type MenuItemActionMode = {
|
|
|
111
111
|
* `selectionIndicator` to keep the semantics — the row stays the control and
|
|
112
112
|
* carries `role` + `aria-checked`; only the drawn mark changes. Suppresses the
|
|
113
113
|
* built-in checkbox / radio and the trailing `check` glyph. The node is made
|
|
114
|
-
* passive (aria-hidden, no pointer events) so the row
|
|
114
|
+
* passive (aria-hidden, no pointer events) so the row receives the click. */
|
|
115
115
|
indicator?: React.ReactNode;
|
|
116
116
|
};
|
|
117
117
|
export type MenuItemProps = MenuItemCommonProps & (MenuItemLinkMode | MenuItemActionMode);
|
|
@@ -81,7 +81,7 @@ const MenuItem = ({
|
|
|
81
81
|
...rest,
|
|
82
82
|
children: [
|
|
83
83
|
indicator != null ? (
|
|
84
|
-
// `min-height: 1lh` makes the wrapper one text line tall and
|
|
84
|
+
// `min-height: 1lh` makes the wrapper one text line tall and centers the node
|
|
85
85
|
// in it, so a small indicator aligns with the label's first line in a hinted
|
|
86
86
|
// (top-aligned) row instead of riding at the top.
|
|
87
87
|
/* @__PURE__ */ jsx(
|
|
@@ -6,7 +6,7 @@ export interface ProgressProps extends BaseProps {
|
|
|
6
6
|
/** Upper bound of the range.
|
|
7
7
|
* @defaultValue 100 */
|
|
8
8
|
max?: number;
|
|
9
|
-
/**
|
|
9
|
+
/** Color variant, or any literal CSS color for a one-off custom tone (the
|
|
10
10
|
* surface / indicator / text are derived from it in oklch). Named tones track
|
|
11
11
|
* light/dark automatically.
|
|
12
12
|
* @defaultValue 'neutral' */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BaseProps } from "../general_types";
|
|
1
|
+
import type { BaseProps, OptionPresentationProps } from "../general_types";
|
|
2
2
|
/** The element's `statechange` payload. `next`/`prev` are values (`null` = nothing
|
|
3
3
|
* selected); `reason` distinguishes a user pick from a form reset / bfcache restore. */
|
|
4
4
|
type StateReason = "user" | "reset" | "restore";
|
|
@@ -15,7 +15,7 @@ export interface RadioChangeAttrs {
|
|
|
15
15
|
name?: string;
|
|
16
16
|
}
|
|
17
17
|
/** One option in a `<RadioGroup>`. The wrapper renders an `<a-radio>` per entry. */
|
|
18
|
-
export interface RadioOption {
|
|
18
|
+
export interface RadioOption extends OptionPresentationProps {
|
|
19
19
|
/** This option's identity and the value submitted when it's selected.
|
|
20
20
|
* Must be unique within the group (a dev-only warning fires on duplicates). */
|
|
21
21
|
value: string;
|
|
@@ -37,12 +37,11 @@ export interface RadioGroupProps extends Omit<BaseProps, "children" | "onChange"
|
|
|
37
37
|
/** The options. The wrapper renders one `<a-radio>` per entry and computes its
|
|
38
38
|
* `selected` / roving `tabindex` / `role` declaratively. */
|
|
39
39
|
options: RadioOption[];
|
|
40
|
-
/** Controlled selected value.
|
|
41
|
-
*
|
|
42
|
-
*
|
|
40
|
+
/** Controlled selected value. The group follows this prop and reports a
|
|
41
|
+
* requested change through `onStateChange`. Leave it undefined for
|
|
42
|
+
* uncontrolled use. */
|
|
43
43
|
value?: string;
|
|
44
|
-
/** Initial selected value for
|
|
45
|
-
* selection in local state). */
|
|
44
|
+
/** Initial selected value for uncontrolled use. */
|
|
46
45
|
defaultValue?: string;
|
|
47
46
|
/** Fired whenever selection changes — event-first. `detail` is
|
|
48
47
|
* `{ next, prev, reason }`: `next`/`prev` are values (`null` = nothing selected);
|
|
@@ -56,8 +55,8 @@ export interface RadioGroupProps extends Omit<BaseProps, "children" | "onChange"
|
|
|
56
55
|
* counterpart to `onStateChange`). Not cancelable; for a controlled group it
|
|
57
56
|
* fires once you've updated `value`. */
|
|
58
57
|
onChange?: (event: Event) => void;
|
|
59
|
-
/** Like `onChange`, but with a `{ value, name }` snapshot as the
|
|
60
|
-
*
|
|
58
|
+
/** Like `onChange`, but with a `{ value, name }` snapshot as the second argument,
|
|
59
|
+
* matching `Input`. */
|
|
61
60
|
onValueChange?: (event: Event, attrs: RadioChangeAttrs) => void;
|
|
62
61
|
/** Fired when focus enters the group (any option) — wired to `focusin`, since
|
|
63
62
|
* focus lands on an individual option, not the group element itself. */
|
|
@@ -73,19 +72,19 @@ export interface RadioGroupProps extends Omit<BaseProps, "children" | "onChange"
|
|
|
73
72
|
* the options) — typically instructional copy. Per-option helper text goes on
|
|
74
73
|
* the option's own `hint` instead. */
|
|
75
74
|
hint?: string;
|
|
76
|
-
/** Validation/feedback tone for the group `hint` —
|
|
75
|
+
/** Validation/feedback tone for the group `hint` — recolors it (same tone set
|
|
77
76
|
* as `Input`'s `status`). Use `critical` for an error message, etc.; omit for
|
|
78
77
|
* the neutral default.
|
|
79
78
|
* @defaultValue 'neutral' */
|
|
80
79
|
status?: "neutral" | "brand" | "info" | "success" | "warning" | "critical";
|
|
81
80
|
/** Mark tone applied to every option (an option's own `tone` wins), or any literal
|
|
82
|
-
* CSS color for a one-off custom tone.
|
|
81
|
+
* CSS color for a one-off custom tone. Colors the selected-ring fill + dot *and*
|
|
83
82
|
* the unselected ring border. Named tones track light/dark mode. Use `toneSelected`
|
|
84
83
|
* instead to tone only the selected option and leave the rest neutral. The option
|
|
85
|
-
* text stays neutral —
|
|
84
|
+
* text stays neutral — recolor it in plain CSS via the `--text-N-{tone}` tokens.
|
|
86
85
|
* @defaultValue 'neutral' */
|
|
87
86
|
tone?: "brand" | "neutral" | "info" | "success" | "warning" | "critical" | (string & {});
|
|
88
|
-
/** Like `tone`, but
|
|
87
|
+
/** Like `tone`, but colored onto the **selected option only** — every unselected
|
|
89
88
|
* ring stays neutral grey. Applied to every option (an option's own `toneSelected`
|
|
90
89
|
* wins). Prefer this over `tone` when a resting tinted border would read as a
|
|
91
90
|
* validation state.
|
|
@@ -104,8 +103,8 @@ export interface RadioGroupProps extends Omit<BaseProps, "children" | "onChange"
|
|
|
104
103
|
* `<RadioGroup>` — a single-select radio control, rendered from `options`.
|
|
105
104
|
*
|
|
106
105
|
* This wrapper is convenience over the web components: it renders an `<a-radio>`
|
|
107
|
-
* per option and
|
|
108
|
-
*
|
|
106
|
+
* per option and manages the two **declarative** DOM concerns the elements
|
|
107
|
+
* deliberately do not touch: the roving **`tabindex`** (so keyboard Tab
|
|
109
108
|
* lands on the right option) and each radio's **`role`**. Selection itself lives
|
|
110
109
|
* in `<a-radio-group>` off-DOM (it sets each radio's `selected` property), so the
|
|
111
110
|
* elements never mutate the DOM; this wrapper just reflects the current value into
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
2
|
import { useId, useState } from "../jsx-runtime";
|
|
3
|
-
import { nativeStateChange, toneStyle } from "../anta_helpers";
|
|
3
|
+
import { nativeStateChange, optionPresentationAttrs, toneStyle } from "../anta_helpers";
|
|
4
4
|
const radioAttrsOf = (el) => ({
|
|
5
5
|
value: el?.value ?? null,
|
|
6
6
|
name: el?.getAttribute?.("name") ?? void 0
|
|
@@ -79,9 +79,11 @@ const RadioGroup = ({
|
|
|
79
79
|
hint && /* @__PURE__ */ jsx("a-radio-group-hint", { id: hintId, children: hint }),
|
|
80
80
|
/* @__PURE__ */ jsx("a-radio-list", { children: options.map((o) => {
|
|
81
81
|
const optDisabled = disabled || o.disabled;
|
|
82
|
+
const { className: optionClassName, style: optionStyle, ...optionAttrs } = optionPresentationAttrs(o);
|
|
82
83
|
return /* @__PURE__ */ jsxs(
|
|
83
84
|
"a-radio",
|
|
84
85
|
{
|
|
86
|
+
...optionAttrs,
|
|
85
87
|
role: "radio",
|
|
86
88
|
value: o.value,
|
|
87
89
|
"aria-disabled": optDisabled ? "true" : void 0,
|
|
@@ -90,7 +92,8 @@ const RadioGroup = ({
|
|
|
90
92
|
"tone-selected": o.toneSelected && o.toneSelected !== "neutral" ? o.toneSelected : void 0,
|
|
91
93
|
size: o.size && o.size !== "medium" ? o.size : void 0,
|
|
92
94
|
disabled: o.disabled ? "" : void 0,
|
|
93
|
-
|
|
95
|
+
class: optionClassName,
|
|
96
|
+
style: toneStyle(o.toneSelected, "--radio-tone-source", toneStyle(o.tone, "--radio-tone-source", optionStyle)),
|
|
94
97
|
children: [
|
|
95
98
|
/* @__PURE__ */ jsx("a-radio-label", { children: o.label }),
|
|
96
99
|
o.hint != null && /* @__PURE__ */ jsx("a-radio-hint", { children: o.hint })
|