@antadesign/anta 0.3.18 → 0.3.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -242
- package/dist/anta_helpers.d.ts +2 -2
- 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 +6 -3
- package/dist/components/Input.js +3 -1
- package/dist/components/InputAutocomplete.d.ts +8 -8
- package/dist/components/InputDate.css +1 -0
- package/dist/components/InputDate.d.ts +1 -0
- package/dist/components/InputDate.js +5 -5
- package/dist/components/InputTime.d.ts +3 -3
- package/dist/components/InputTime.js +1 -1
- package/dist/components/Menu.d.ts +7 -3
- package/dist/components/Menu.js +3 -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 +12 -13
- package/dist/components/Select.d.ts +32 -38
- package/dist/components/Select.js +9 -13
- package/dist/components/SelectFaceted.d.ts +28 -33
- package/dist/components/SelectFaceted.js +29 -23
- package/dist/components/Slider.d.ts +5 -5
- package/dist/components/Switch.d.ts +4 -4
- package/dist/components/Tabs.d.ts +7 -7
- 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/components/select-parts.css +1 -0
- 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-input.css +1 -1
- package/dist/elements/a-menu.js +12 -0
- package/dist/elements/a-progress.css +1 -1
- package/dist/elements/a-slider.css +1 -1
- package/dist/elements/a-tabs.css +1 -1
- package/dist/elements/a-tabs.d.ts +3 -0
- package/dist/elements/a-tabs.js +40 -1
- package/dist/elements/a-tooltip.css +1 -1
- package/dist/elements/a-tooltip.d.ts +1 -1
- package/dist/elements/a-tooltip.js +1 -1
- package/dist/elements/index.d.ts +1 -1
- package/dist/general_types.d.ts +24 -22
- package/dist/index.d.ts +3 -3
- package/dist/jsx-runtime.d.ts +9 -0
- package/docs/accessibility.md +34 -0
- package/docs/changelog.md +561 -0
- package/docs/colors.md +42 -0
- package/docs/comparison.md +28 -0
- package/docs/components/banner.md +267 -0
- package/docs/components/button.md +603 -0
- package/docs/components/card.md +321 -0
- package/docs/components/checkbox.md +296 -0
- package/docs/components/dialog.md +314 -0
- package/docs/components/expander.md +526 -0
- package/docs/components/icon.md +155 -0
- package/docs/components/input-autocomplete.md +100 -0
- package/docs/components/input-date.md +401 -0
- package/docs/components/input-time.md +174 -0
- package/docs/components/input.md +610 -0
- package/docs/components/loader.md +139 -0
- package/docs/components/menu.md +511 -0
- package/docs/components/progress.md +182 -0
- package/docs/components/radio.md +368 -0
- package/docs/components/select-faceted.md +451 -0
- package/docs/components/select.md +926 -0
- package/docs/components/slider.md +147 -0
- package/docs/components/switch.md +198 -0
- package/docs/components/tabs.md +471 -0
- package/docs/components/tag.md +185 -0
- package/docs/components/text.md +148 -0
- package/docs/components/title.md +146 -0
- package/docs/components/toaster.md +313 -0
- package/docs/components/tooltip.md +177 -0
- package/docs/credits.md +18 -0
- package/docs/index.md +52 -0
- package/docs/install-config.md +240 -0
- package/docs/normalization.md +102 -0
- package/docs/overview.md +10 -0
- package/docs/packages/stickers.md +187 -0
- package/docs/packages/table.md +153 -0
- package/docs/theming.md +13 -0
- package/package.json +10 -6
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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("
|
|
183
|
+
time && /* @__PURE__ */ jsxs("a-input-date-time-container", { children: [
|
|
184
184
|
/* @__PURE__ */ jsx(
|
|
185
185
|
InputTime,
|
|
186
186
|
{
|
|
@@ -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
|
|
@@ -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,
|
|
@@ -53,7 +57,7 @@ export interface MenuProps extends BaseProps {
|
|
|
53
57
|
/** Combobox-mode cursor report (raw element event). Fires when the active
|
|
54
58
|
* option changes as arrow keys move the cursor while focus stays in a
|
|
55
59
|
* `[data-menu-search]` filter field; `detail.id` is the active option's `id`
|
|
56
|
-
* (`null` when none). The reactive layer that
|
|
60
|
+
* (`null` when none). The reactive layer that renders the field reflects this
|
|
57
61
|
* onto its `aria-activedescendant` — the element can't write that light-DOM
|
|
58
62
|
* attribute itself. Passed straight through to the element. */
|
|
59
63
|
onactivedescendant?: (e: CustomEvent<{
|
|
@@ -74,7 +78,7 @@ export interface MenuProps extends BaseProps {
|
|
|
74
78
|
*
|
|
75
79
|
* Open state is uncontrolled by default — listen for `onStateChange`
|
|
76
80
|
* (`detail: { next, prev }`) to observe it, or pass `open` to control it. You
|
|
77
|
-
* can also
|
|
81
|
+
* can also keep a `ref` and call `.open()` / `.close()` / `.toggle()`.
|
|
78
82
|
* Selecting a `MenuItem` closes the menu;
|
|
79
83
|
* arbitrary injected content does not. Add `data-menu-open` to any item /
|
|
80
84
|
* container to keep it open, or `data-menu-close` to a custom element to let it
|
|
@@ -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;
|
package/dist/components/Menu.js
CHANGED
|
@@ -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
|
}
|
|
@@ -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' */
|
|
@@ -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,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
|
|
@@ -34,7 +35,7 @@ export interface SelectOption<V extends OptionValue = string> {
|
|
|
34
35
|
* hint for the Alt/Option-click "select only this" accelerator; set `tooltip`
|
|
35
36
|
* to override that, or `''` to suppress it. */
|
|
36
37
|
tooltip?: React.ReactNode;
|
|
37
|
-
/**
|
|
38
|
+
/** Additional application data. Read it in `renderOption`. */
|
|
38
39
|
[key: string]: unknown;
|
|
39
40
|
}
|
|
40
41
|
/** A titled group of options rendered **inline** under a heading (like `MenuGroup`).
|
|
@@ -163,10 +164,9 @@ export interface SelectCommonProps<V extends OptionValue = string> extends Omit<
|
|
|
163
164
|
* `leading` slot). With a custom `renderTrigger`, it's passed through as
|
|
164
165
|
* `state.icon` instead — the consumer places it. */
|
|
165
166
|
icon?: IconShape;
|
|
166
|
-
/**
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
* one alongside. Ignored with a custom `renderTrigger`. */
|
|
167
|
+
/** Content for the default trigger's `leading` slot, such as a key prefix
|
|
168
|
+
* before the value. It replaces the icon derived from `icon`. Include an
|
|
169
|
+
* `<Icon>` in this content when both are needed. Ignored by `renderTrigger`. */
|
|
170
170
|
leading?: React.ReactNode;
|
|
171
171
|
/** Field label, above the trigger (Input's `label`). */
|
|
172
172
|
label?: string;
|
|
@@ -196,11 +196,10 @@ export interface SelectCommonProps<V extends OptionValue = string> extends Omit<
|
|
|
196
196
|
* option's **value / label / hint**. Pass a **function** `(option, query) =>
|
|
197
197
|
* boolean` for custom matching (called per option; return `true` to keep it). */
|
|
198
198
|
filter?: boolean | ((option: SelectOption<V>, query: string) => boolean);
|
|
199
|
-
/** `multiple` only: a "Select all" row
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
203
|
-
* isolate accelerator it gates).
|
|
199
|
+
/** `multiple` only: shows a "Select all" row that toggles every enabled option,
|
|
200
|
+
* or only the visible options when a filter query is active. Its checkbox is
|
|
201
|
+
* mixed when some options are selected. It is on by default. Set it to `false`
|
|
202
|
+
* to remove the row and the Alt/Option-click shortcut that selects only one row.
|
|
204
203
|
* @defaultValue true */
|
|
205
204
|
selectAll?: boolean;
|
|
206
205
|
/** Label for the `selectAll` row.
|
|
@@ -213,13 +212,12 @@ export interface SelectCommonProps<V extends OptionValue = string> extends Omit<
|
|
|
213
212
|
/** Label for the `clearable` footer row.
|
|
214
213
|
* @defaultValue Clear */
|
|
215
214
|
clearLabel?: string;
|
|
216
|
-
/**
|
|
217
|
-
*
|
|
218
|
-
*
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
* matches the
|
|
222
|
-
* skipped — your content owns its own display. */
|
|
215
|
+
/** Replaces the built-in `label`, `hint`, and `icon` layout for each option row.
|
|
216
|
+
* Select still supplies the row container, click handling, ARIA attributes, and
|
|
217
|
+
* selection indicator. Read extra option fields through `SelectOption`'s index
|
|
218
|
+
* signature. `state` contains `value`, `selected`, and `disabled`. Filtering
|
|
219
|
+
* still matches the option's `value`, `label`, and `hint`, but Select cannot
|
|
220
|
+
* highlight matches within the returned content. */
|
|
223
221
|
renderOption?: (option: SelectOption<V>, state: OptionState<V>) => React.ReactNode;
|
|
224
222
|
/** Replace each row's selection **mark** with your own node, drawn at the
|
|
225
223
|
* leading edge. The row stays the control (`role` + `aria-checked` from
|
|
@@ -245,16 +243,15 @@ export interface SelectCommonProps<V extends OptionValue = string> extends Omit<
|
|
|
245
243
|
* the single-label case built-in). For rich content (chips, multiple nodes)
|
|
246
244
|
* use `renderTrigger`, which replaces the whole field. */
|
|
247
245
|
renderSummary?: (selected: SelectOption<V>[]) => string | undefined;
|
|
248
|
-
/**
|
|
249
|
-
*
|
|
250
|
-
*
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
*
|
|
254
|
-
*
|
|
255
|
-
*
|
|
256
|
-
*
|
|
257
|
-
* only — put your own on the element you return. */
|
|
246
|
+
/** Replaces the default field with a trigger returned from this function.
|
|
247
|
+
* Receives `open`, `value`, `selected`, `disabled`, and `icon`. Return exactly
|
|
248
|
+
* one focusable element, such as an Anta `Button`. The menu is positioned
|
|
249
|
+
* relative to that element and opens when it is clicked. Do not return a
|
|
250
|
+
* fragment, multiple siblings, or a non-focusable wrapper. Add
|
|
251
|
+
* `aria-haspopup="menu"` and `aria-expanded={state.open}` to the element.
|
|
252
|
+
* Field props (`label`, `hint`, `size`, `status`, `placeholder`, and `round`) and
|
|
253
|
+
* `className` / `style` apply only to the default field. Add styling and
|
|
254
|
+
* attributes to the returned element instead. */
|
|
258
255
|
renderTrigger?: (state: TriggerState<V>) => React.ReactNode;
|
|
259
256
|
/** Render content in the menu body when the (filtered) option list is empty —
|
|
260
257
|
* a "no results" message, a loading indicator (gated on your own external
|
|
@@ -275,13 +272,10 @@ export type SelectProps<V extends OptionValue = string> = SelectCommonProps<V> &
|
|
|
275
272
|
* array value.
|
|
276
273
|
* @defaultValue single */
|
|
277
274
|
selection?: 'single';
|
|
278
|
-
/** Controlled value
|
|
279
|
-
*
|
|
280
|
-
* *requests* a change via `onValueChange` (reject by not updating). Leave
|
|
281
|
-
* undefined for uncontrolled. */
|
|
275
|
+
/** Controlled value: the selected option's `value`. Update it through
|
|
276
|
+
* `onValueChange`. Leave it undefined for uncontrolled use. */
|
|
282
277
|
value?: V;
|
|
283
|
-
/** Initial
|
|
284
|
-
* wrapper then owns it. */
|
|
278
|
+
/** Initial selected option value for uncontrolled use. */
|
|
285
279
|
defaultValue?: V;
|
|
286
280
|
/** Fires after the selection changes, with the new value and a
|
|
287
281
|
* `{ value, option }` snapshot. Select has no discrete element state, so
|
|
@@ -351,17 +345,17 @@ export type SelectedItem<V extends OptionValue = string> = SelectedOption<V> | S
|
|
|
351
345
|
*/
|
|
352
346
|
export declare function optionsWithSelection<V extends OptionValue = string>(options: SelectItem<V>[], values: V | V[] | undefined): SelectedItem<V>[];
|
|
353
347
|
/**
|
|
354
|
-
* `<Select>`
|
|
355
|
-
* read-only trigger
|
|
348
|
+
* `<Select>` lets people choose one or more options from a dropdown. It uses an
|
|
349
|
+
* `<Input>` as its read-only trigger and a `<Menu>` for its options. `selection` sets behavior:
|
|
356
350
|
* `'single'` (default; `value` is a string, menu closes on pick) or `'multiple'`
|
|
357
351
|
* (checkboxes, `value` is a string array, menu stays open while toggling, the
|
|
358
352
|
* field shows an "N selected" count). For single-select, `indicator` picks the
|
|
359
353
|
* per-row mark: `'none'` (tint only, default), `'check'` (trailing checkmark), or
|
|
360
354
|
* `'radio'` (leading radio).
|
|
361
355
|
*
|
|
362
|
-
*
|
|
363
|
-
* is no `a-select` element
|
|
364
|
-
*
|
|
356
|
+
* Use `value` with `onValueChange` to control the selection, or use
|
|
357
|
+
* `defaultValue` for uncontrolled use. There is no `a-select` element. See the
|
|
358
|
+
* docs for the equivalent markup without React or Preact.
|
|
365
359
|
*
|
|
366
360
|
* Requires `@antadesign/anta/elements` (client-side only).
|
|
367
361
|
*
|
|
@@ -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
|
|
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
|
-
//
|
|
273
|
-
//
|
|
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 applies 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("
|
|
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__ */
|
|
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,10 +2,10 @@ 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
|
-
/** The facet's
|
|
7
|
-
*
|
|
8
|
-
* `facets`. */
|
|
7
|
+
/** The key for this facet's value in the record. `onValueChange` reports it as
|
|
8
|
+
* `attrs.facet`. It must be unique across `facets`. */
|
|
9
9
|
key: string;
|
|
10
10
|
/** The facet's row label in the menu. */
|
|
11
11
|
label: string;
|
|
@@ -62,9 +62,8 @@ export interface SelectFacetCustomContext<V> {
|
|
|
62
62
|
/** Close the whole filter menu (e.g. after applying from a custom editor). */
|
|
63
63
|
close: () => void;
|
|
64
64
|
}
|
|
65
|
-
/**
|
|
66
|
-
*
|
|
67
|
-
* numeric comparator, …). */
|
|
65
|
+
/** A custom editor and value type for values the built-in kinds do not cover,
|
|
66
|
+
* including objects such as date ranges and numeric comparisons. */
|
|
68
67
|
export interface SelectFacetCustom<V = unknown> extends FacetBase {
|
|
69
68
|
kind: 'custom';
|
|
70
69
|
/** Render the facet's editor inside its flyout. The returned node stays
|
|
@@ -74,11 +73,11 @@ export interface SelectFacetCustom<V = unknown> extends FacetBase {
|
|
|
74
73
|
* string or any node). Called only when the value is set. */
|
|
75
74
|
summary: (value: V) => React.ReactNode;
|
|
76
75
|
}
|
|
77
|
-
/** One
|
|
76
|
+
/** One filter category, discriminated by `kind`. */
|
|
78
77
|
export type SelectFacet = SelectFacetSingle | SelectFacetMultiple | SelectFacetText | SelectFacetCustom;
|
|
79
78
|
/** The filter value: a facet key → that facet's value. Per kind: an option value
|
|
80
79
|
* (`string` / `number` / `boolean`) for `single`, a `string` for `text`, an array for
|
|
81
|
-
* `multiple`, or
|
|
80
|
+
* `multiple`, or a `V` value for `custom`. Values are stored and reported unchanged.
|
|
82
81
|
* Typed loosely as `unknown` since facets in one control can hold different value
|
|
83
82
|
* types; narrow per facet when you read it. A cleared facet is absent from the record. */
|
|
84
83
|
export type SelectFacetedValue = Record<string, unknown>;
|
|
@@ -110,7 +109,7 @@ export interface SelectFacetedTriggerState {
|
|
|
110
109
|
disabled: boolean;
|
|
111
110
|
}
|
|
112
111
|
export interface SelectFacetedProps extends Omit<BaseProps, 'children'> {
|
|
113
|
-
/**
|
|
112
|
+
/** Categories to filter by. Each facet has a `kind` that determines its editor. */
|
|
114
113
|
facets: SelectFacet[];
|
|
115
114
|
/** Preferred placement of the root filter menu relative to its trigger. The
|
|
116
115
|
* menu auto-flips vertically and clamps horizontally when needed.
|
|
@@ -119,11 +118,10 @@ export interface SelectFacetedProps extends Omit<BaseProps, 'children'> {
|
|
|
119
118
|
/** Gap in pixels between the trigger and the filter menu.
|
|
120
119
|
* @defaultValue 4 */
|
|
121
120
|
offset?: number;
|
|
122
|
-
/** Controlled value
|
|
123
|
-
*
|
|
124
|
-
* not updating). Leave undefined for uncontrolled. */
|
|
121
|
+
/** Controlled value record, keyed by facet. When provided, update it through
|
|
122
|
+
* `onValueChange`. Leave it undefined for uncontrolled use. */
|
|
125
123
|
value?: SelectFacetedValue;
|
|
126
|
-
/** Initial value for
|
|
124
|
+
/** Initial value for uncontrolled use. */
|
|
127
125
|
defaultValue?: SelectFacetedValue;
|
|
128
126
|
/** Fires after any facet changes. `value` is the whole new record (a facet key →
|
|
129
127
|
* that facet's value; a cleared facet is absent). `attrs` says what changed:
|
|
@@ -146,14 +144,13 @@ export interface SelectFacetedProps extends Omit<BaseProps, 'children'> {
|
|
|
146
144
|
disabled?: boolean;
|
|
147
145
|
/** Tone applied to a selected option row in the facet flyouts (label, selected
|
|
148
146
|
* tint, and the check / checkbox indicator). A named tone or a custom CSS
|
|
149
|
-
*
|
|
147
|
+
* color, matching `Select`'s `toneSelected`. Defaults to a neutral selection. */
|
|
150
148
|
toneSelected?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
|
|
151
|
-
/**
|
|
152
|
-
* `single`
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
* built-in substring match. */
|
|
149
|
+
/** Adds a search field at the top of the root menu. It searches the options of
|
|
150
|
+
* every `single` and `multiple` facet in one list. For example, "alice" can
|
|
151
|
+
* appear under application-defined Assignee and Owner facets. `text` and
|
|
152
|
+
* `custom` facets remain available when the search is empty. Each facet uses
|
|
153
|
+
* its `filter` function when supplied, or the built-in substring match. */
|
|
157
154
|
searchable?: boolean;
|
|
158
155
|
/** Placeholder for the global search field.
|
|
159
156
|
* @defaultValue Filter… */
|
|
@@ -164,22 +161,20 @@ export interface SelectFacetedProps extends Omit<BaseProps, 'children'> {
|
|
|
164
161
|
/** Label for the "Clear all" row.
|
|
165
162
|
* @defaultValue Clear all */
|
|
166
163
|
clearAllLabel?: string;
|
|
167
|
-
/**
|
|
168
|
-
* `SelectFacetedTriggerState
|
|
169
|
-
* menu
|
|
170
|
-
* `aria-haspopup="menu"`
|
|
171
|
-
*
|
|
172
|
-
*
|
|
164
|
+
/** Replaces the default `Button` with a trigger returned from this function.
|
|
165
|
+
* Receives a `SelectFacetedTriggerState`. Return exactly one focusable element:
|
|
166
|
+
* the menu is positioned relative to that element and opens when it is clicked.
|
|
167
|
+
* Add `aria-haspopup="menu"` and `aria-expanded={state.open}` to the returned
|
|
168
|
+
* element. `className`, `style`, and other trigger props apply only to the
|
|
169
|
+
* default Button, so add styling and attributes to the returned element. */
|
|
173
170
|
renderTrigger?: (state: SelectFacetedTriggerState) => React.ReactNode;
|
|
174
171
|
}
|
|
175
172
|
/**
|
|
176
|
-
* `<SelectFaceted>`
|
|
177
|
-
*
|
|
178
|
-
* `'single'
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
* `Record<facetKey, value>`, so the same option value under two facets stays
|
|
182
|
-
* distinct.
|
|
173
|
+
* `<SelectFaceted>` filters a result set by categories called facets. Its
|
|
174
|
+
* trigger opens a facet menu, and each facet opens a control for its value.
|
|
175
|
+
* The available kinds are `'single'`, `'multiple'`, `'text'`, and `'custom'`.
|
|
176
|
+
* The value is a `Record<facetKey, value>`, so values under different facet
|
|
177
|
+
* keys stay distinct.
|
|
183
178
|
*
|
|
184
179
|
* Controlled (`value` + `onValueChange`) or uncontrolled (`defaultValue`).
|
|
185
180
|
* There is no `a-select-faceted` element — this wrapper is the coordinator.
|