@antadesign/anta 0.3.1 → 0.3.3

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 (98) hide show
  1. package/dist/anta_helpers.d.ts +111 -0
  2. package/dist/anta_helpers.js +90 -1
  3. package/dist/calendar-core.d.ts +126 -0
  4. package/dist/calendar-core.js +289 -0
  5. package/dist/components/Button.d.ts +9 -1
  6. package/dist/components/Button.js +12 -18
  7. package/dist/components/Calendar.d.ts +80 -0
  8. package/dist/components/Calendar.js +220 -0
  9. package/dist/components/Checkbox.d.ts +21 -15
  10. package/dist/components/Checkbox.js +17 -7
  11. package/dist/components/Expander.d.ts +7 -1
  12. package/dist/components/Expander.js +4 -2
  13. package/dist/components/Input.d.ts +16 -8
  14. package/dist/components/Input.js +19 -11
  15. package/dist/components/InputDate.d.ts +87 -0
  16. package/dist/components/InputDate.js +278 -0
  17. package/dist/components/InputDate.module.css +1 -0
  18. package/dist/components/Menu.d.ts +5 -1
  19. package/dist/components/Menu.js +6 -2
  20. package/dist/components/MenuItem.d.ts +48 -7
  21. package/dist/components/MenuItem.js +71 -7
  22. package/dist/components/MenuSeparator.d.ts +13 -2
  23. package/dist/components/MenuSeparator.js +12 -2
  24. package/dist/components/Progress.d.ts +4 -1
  25. package/dist/components/Progress.js +4 -3
  26. package/dist/components/RadioGroup.d.ts +17 -15
  27. package/dist/components/RadioGroup.js +8 -8
  28. package/dist/components/Select.d.ts +255 -0
  29. package/dist/components/Select.js +290 -0
  30. package/dist/components/Select.module.css +1 -0
  31. package/dist/components/Tab.d.ts +37 -0
  32. package/dist/components/Tab.js +5 -0
  33. package/dist/components/TabPanel.d.ts +22 -0
  34. package/dist/components/TabPanel.js +5 -0
  35. package/dist/components/Tabs.d.ts +129 -0
  36. package/dist/components/Tabs.js +176 -0
  37. package/dist/components/Tabs.module.css +1 -0
  38. package/dist/components/Tag.d.ts +10 -9
  39. package/dist/components/Tag.js +2 -2
  40. package/dist/components/Text.d.ts +6 -5
  41. package/dist/components/Title.d.ts +4 -2
  42. package/dist/components/Tooltip.d.ts +13 -1
  43. package/dist/components/Tooltip.js +9 -0
  44. package/dist/elements/a-button.css +1 -1
  45. package/dist/elements/a-calendar.css +1 -0
  46. package/dist/elements/a-calendar.d.ts +76 -0
  47. package/dist/elements/a-calendar.js +190 -0
  48. package/dist/elements/a-checkbox.css +1 -1
  49. package/dist/elements/a-checkbox.d.ts +1 -2
  50. package/dist/elements/a-checkbox.js +5 -5
  51. package/dist/elements/a-expander.css +1 -1
  52. package/dist/elements/a-expander.d.ts +16 -5
  53. package/dist/elements/a-expander.js +65 -9
  54. package/dist/elements/a-icon.shapes.css +1 -1
  55. package/dist/elements/a-icon.shapes.d.ts +6 -1
  56. package/dist/elements/a-icon.shapes.js +9 -0
  57. package/dist/elements/a-input.css +1 -1
  58. package/dist/elements/a-input.d.ts +6 -0
  59. package/dist/elements/a-input.js +28 -9
  60. package/dist/elements/a-menu-group.css +1 -1
  61. package/dist/elements/a-menu-item.css +1 -1
  62. package/dist/elements/a-menu-item.d.ts +14 -4
  63. package/dist/elements/a-menu-item.js +17 -0
  64. package/dist/elements/a-menu-separator.css +1 -1
  65. package/dist/elements/a-menu.css +1 -1
  66. package/dist/elements/a-menu.d.ts +51 -8
  67. package/dist/elements/a-menu.js +285 -42
  68. package/dist/elements/a-progress.css +1 -1
  69. package/dist/elements/a-radio-group.d.ts +1 -3
  70. package/dist/elements/a-radio-group.js +13 -13
  71. package/dist/elements/a-radio.css +1 -1
  72. package/dist/elements/a-radio.d.ts +3 -11
  73. package/dist/elements/a-radio.js +3 -34
  74. package/dist/elements/a-tab.css +1 -0
  75. package/dist/elements/a-tab.d.ts +6 -0
  76. package/dist/elements/a-tab.js +15 -0
  77. package/dist/elements/a-tabpanel.css +1 -0
  78. package/dist/elements/a-tabs.css +1 -0
  79. package/dist/elements/a-tabs.d.ts +28 -0
  80. package/dist/elements/a-tabs.js +157 -0
  81. package/dist/elements/a-tag.css +1 -1
  82. package/dist/elements/a-text.css +1 -1
  83. package/dist/elements/a-text.d.ts +14 -13
  84. package/dist/elements/a-text.js +53 -23
  85. package/dist/elements/a-title.css +1 -1
  86. package/dist/elements/a-tooltip.css +1 -1
  87. package/dist/elements/a-tooltip.d.ts +16 -8
  88. package/dist/elements/a-tooltip.js +62 -16
  89. package/dist/elements/index.d.ts +4 -0
  90. package/dist/elements/index.js +10 -0
  91. package/dist/general_types.d.ts +252 -30
  92. package/dist/index.d.ts +15 -1
  93. package/dist/index.js +43 -1
  94. package/dist/jsx-runtime.d.ts +20 -7
  95. package/dist/jsx-runtime.js +6 -0
  96. package/dist/reset.css +1 -1
  97. package/dist/tokens.css +1 -1
  98. package/package.json +4 -2
@@ -1,25 +1,42 @@
1
1
  import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
2
+ import { toneStyle } from "../anta_helpers";
2
3
  const MenuItem = ({
3
4
  icon,
4
5
  label,
6
+ hint,
5
7
  kbd,
6
8
  iconTrailing,
7
9
  disabled,
10
+ selected,
11
+ selectionIndicator,
12
+ indeterminate,
13
+ indicator,
8
14
  tone,
15
+ toneSelected,
9
16
  submenu,
10
17
  value,
11
18
  onSelect,
12
19
  className,
20
+ style,
13
21
  children,
14
22
  ...rest
15
23
  }) => {
24
+ const checkable = selectionIndicator === "checkbox" || selectionIndicator === "radio" || selectionIndicator === "check";
25
+ const role = selectionIndicator === "checkbox" ? "menuitemcheckbox" : selectionIndicator === "radio" || selectionIndicator === "check" ? "menuitemradio" : "menuitem";
26
+ const ariaChecked = !checkable ? void 0 : selectionIndicator === "checkbox" && indeterminate ? "mixed" : selected ? "true" : "false";
27
+ const keepTint = selected && (selectionIndicator === void 0 || selectionIndicator === "check");
28
+ const effectiveTone = selected && toneSelected || tone;
29
+ const toneAttr = effectiveTone && effectiveTone !== "neutral" ? effectiveTone : void 0;
16
30
  return /* @__PURE__ */ jsxs(
17
31
  "a-menu-item",
18
32
  {
19
- role: "menuitem",
33
+ role,
20
34
  tabIndex: 0,
21
35
  disabled: disabled ? "" : void 0,
22
- tone: tone && tone !== "neutral" ? tone : void 0,
36
+ selected: keepTint ? "" : void 0,
37
+ "aria-checked": ariaChecked,
38
+ tone: toneAttr,
39
+ style: toneStyle(effectiveTone, "--menu-item-tone-source", style),
23
40
  submenu: submenu ? "" : void 0,
24
41
  "aria-haspopup": submenu ? "menu" : void 0,
25
42
  "aria-expanded": submenu ? "false" : void 0,
@@ -33,14 +50,61 @@ const MenuItem = ({
33
50
  class: className,
34
51
  ...rest,
35
52
  children: [
53
+ indicator != null ? (
54
+ // `min-height: 1lh` makes the wrapper one text line tall and centres the node
55
+ // in it, so a small indicator aligns with the label's first line in a hinted
56
+ // (top-aligned) row instead of riding at the top.
57
+ /* @__PURE__ */ jsx(
58
+ "span",
59
+ {
60
+ "aria-hidden": "true",
61
+ "data-indicator": "",
62
+ style: { flex: "none", display: "inline-flex", alignItems: "center", minHeight: "1lh", pointerEvents: "none" },
63
+ children: indicator
64
+ }
65
+ )
66
+ ) : selectionIndicator === "checkbox" ? /* @__PURE__ */ jsx(
67
+ "a-checkbox",
68
+ {
69
+ "aria-hidden": "true",
70
+ state: indeterminate ? "indeterminate" : selected ? "checked" : "unchecked",
71
+ tone: toneAttr,
72
+ style: toneStyle(effectiveTone, "--checkbox-tone-source")
73
+ }
74
+ ) : selectionIndicator === "radio" ? (
75
+ // Real boolean, not the ''/undefined presence form: `a-radio` has a
76
+ // `selected` *property* setter (`applyState(!!on)`), so Preact routes the
77
+ // prop through it — `''` would read as false and never select. A boolean
78
+ // drives the property correctly and clears stale state on deselect. (The
79
+ // checkbox above is safe: its `state` is attribute-only, no property.)
80
+ /* @__PURE__ */ jsx(
81
+ "a-radio",
82
+ {
83
+ "aria-hidden": "true",
84
+ selected: !!selected,
85
+ tone: toneAttr,
86
+ style: toneStyle(effectiveTone, "--radio-tone-source")
87
+ }
88
+ )
89
+ ) : null,
36
90
  icon && /* @__PURE__ */ jsx("a-icon", { shape: icon, "aria-hidden": "true" }),
37
- label != null && /* @__PURE__ */ jsx("a-menu-item-label", { children: label }),
91
+ label != null && (hint != null ? (
92
+ // A hint stacks under the label in a column; the icon / kbd / trailing
93
+ // icon stay in the row (the item's `align-items: center` centers them
94
+ // against the two-line block).
95
+ /* @__PURE__ */ jsxs("a-menu-item-text", { children: [
96
+ /* @__PURE__ */ jsx("a-menu-item-label", { children: label }),
97
+ /* @__PURE__ */ jsx("a-menu-item-hint", { children: hint })
98
+ ] })
99
+ ) : /* @__PURE__ */ jsx("a-menu-item-label", { children: label })),
100
+ children,
38
101
  kbd && /* @__PURE__ */ jsx("kbd", { children: kbd }),
39
- /* @__PURE__ */ (() => {
40
- const trailing = submenu ? iconTrailing ?? "chevron-right" : iconTrailing;
102
+ (() => {
103
+ let trailing = submenu ? iconTrailing ?? "chevron-right" : iconTrailing;
104
+ if (!submenu && !iconTrailing && selectionIndicator === "check" && indicator == null)
105
+ trailing = selected ? "check" : "blank";
41
106
  return trailing ? /* @__PURE__ */ jsx("a-icon", { shape: trailing, "aria-hidden": "true" }) : null;
42
- })(),
43
- children
107
+ })()
44
108
  ]
45
109
  }
46
110
  );
@@ -1,14 +1,25 @@
1
1
  import type { BaseProps } from '../general_types';
2
2
  export interface MenuSeparatorProps extends BaseProps {
3
+ /** Optional caption. With content, the separator renders as a small muted text
4
+ * row — a group / subsection name, or a utility message like `Loading…` — instead
5
+ * of a line, and the wrapper flips it to an `aria-live="polite"` status region
6
+ * (`role="status"`) so a changing message is announced. Empty, it's a plain divider. */
7
+ children?: React.ReactNode;
3
8
  }
4
9
  /**
5
- * MenuSeparator — a thin divider between groups of `MenuItem`s.
10
+ * MenuSeparator — a divider between groups of `MenuItem`s, or a small caption row.
11
+ *
12
+ * Empty, it's a thin line. Given text, it becomes a muted caption (a group name or
13
+ * a status message) and turns into an `aria-live="polite"` region — this is what
14
+ * `Select`'s `renderEmpty` uses for its "no results" / "loading" messages.
6
15
  *
7
16
  * @example
8
17
  * ```tsx
9
18
  * <MenuItem label="Edit" />
10
19
  * <MenuSeparator />
11
20
  * <MenuItem tone="critical" label="Delete" />
21
+ *
22
+ * <MenuSeparator>No results</MenuSeparator>
12
23
  * ```
13
24
  */
14
- export declare const MenuSeparator: ({ className, ...rest }: MenuSeparatorProps) => any;
25
+ export declare const MenuSeparator: ({ className, children, ...rest }: MenuSeparatorProps) => any;
@@ -1,6 +1,16 @@
1
1
  import { jsx } from "@antadesign/anta/jsx-runtime";
2
- const MenuSeparator = ({ className, ...rest }) => {
3
- return /* @__PURE__ */ jsx("a-menu-separator", { role: "separator", class: className, ...rest });
2
+ const MenuSeparator = ({ className, children, ...rest }) => {
3
+ const hasContent = !!children && !(typeof children === "string" && children.trim() === "");
4
+ return /* @__PURE__ */ jsx(
5
+ "a-menu-separator",
6
+ {
7
+ role: hasContent ? "status" : "separator",
8
+ "aria-live": hasContent ? "polite" : void 0,
9
+ class: className,
10
+ ...rest,
11
+ children: hasContent ? children : null
12
+ }
13
+ );
4
14
  };
5
15
  export {
6
16
  MenuSeparator
@@ -10,6 +10,9 @@ export interface ProgressProps extends BaseProps {
10
10
  * light/dark automatically.
11
11
  * @defaultValue 'neutral' */
12
12
  tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
13
+ /** Fully-round track (`border-radius: 999px`); the fill is clipped to it. Pass a
14
+ * `number` (px) or a CSS length string for a custom radius. */
15
+ round?: boolean | number | string;
13
16
  /** Text label displayed after the percentage. When you provide custom
14
17
  * `children` (which replace the default label row), `label` is no longer
15
18
  * rendered — but it still supplies the progressbar's accessible name, so
@@ -46,4 +49,4 @@ export interface ProgressProps extends BaseProps {
46
49
  * <Progress value={75} tone="info" label="Processing" />
47
50
  * ```
48
51
  */
49
- export declare const Progress: ({ value, max, tone, label, hint, className, style, children, ...rest }: ProgressProps) => any;
52
+ export declare const Progress: ({ value, max, tone, round, label, hint, className, style, children, ...rest }: ProgressProps) => any;
@@ -1,6 +1,6 @@
1
1
  import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
2
- import { hasChildren, toneStyle } from "../anta_helpers";
3
- const Progress = ({ value, max = 100, tone, label, hint, className, style, children, ...rest }) => {
2
+ import { hasChildren, toneStyle, roundStyle } from "../anta_helpers";
3
+ const Progress = ({ value, max = 100, tone, round, label, hint, className, style, children, ...rest }) => {
4
4
  const percent = max > 0 ? Math.round(Math.min(100, Math.max(0, value / max * 100))) : 0;
5
5
  const clampedValue = max > 0 ? Math.min(max, Math.max(0, value)) : 0;
6
6
  const ariaLabel = [label, `${percent}%`, hint].filter(Boolean).join(" \xB7 ") || void 0;
@@ -10,13 +10,14 @@ const Progress = ({ value, max = 100, tone, label, hint, className, style, child
10
10
  value,
11
11
  max,
12
12
  tone: tone && tone !== "neutral" ? tone : void 0,
13
+ round: round ? "" : void 0,
13
14
  role: "progressbar",
14
15
  "aria-valuenow": clampedValue,
15
16
  "aria-valuemin": 0,
16
17
  "aria-valuemax": max,
17
18
  "aria-label": ariaLabel,
18
19
  class: className,
19
- style: toneStyle(tone, "--progress-tone-source", style),
20
+ style: roundStyle(round, "--progress-round", toneStyle(tone, "--progress-tone-source", style)),
20
21
  ...rest,
21
22
  children: hasChildren(children) ? children : /* @__PURE__ */ jsxs("a-progress-label", { children: [
22
23
  /* @__PURE__ */ jsxs("a-progress-number", { children: [
@@ -8,7 +8,7 @@ type StateDetail = {
8
8
  reason: StateReason;
9
9
  };
10
10
  type StateChangeEvent = CustomEvent<StateDetail>;
11
- /** Snapshot passed as the 2nd argument to `onAnyChange` — the new value plus the
11
+ /** Snapshot passed as the 2nd argument to `onValueChange` — the new value plus the
12
12
  * field name, so you don't poke at `event.target`. Mirrors `Input`/`Checkbox`. */
13
13
  export interface RadioChangeAttrs {
14
14
  value: string | null;
@@ -25,12 +25,12 @@ export interface RadioOption {
25
25
  hint?: React.ReactNode;
26
26
  /** Disable just this option (skipped by keyboard, dropped from the tab order). */
27
27
  disabled?: boolean;
28
- /** Override this one option's tone (defaults to the group's `tone`). */
28
+ /** Override this one option's mark tone (defaults to the group's `tone`). */
29
29
  tone?: "brand" | "neutral" | "info" | "success" | "warning" | "critical" | (string & {});
30
+ /** Override this one option's `toneSelected` (defaults to the group's). */
31
+ toneSelected?: "brand" | "neutral" | "info" | "success" | "warning" | "critical" | (string & {});
30
32
  /** Override this one option's size (defaults to the group's `size`). */
31
33
  size?: "small" | "medium" | "large";
32
- /** Override this one option's priority (defaults to the group's `priority`). */
33
- priority?: "primary" | "secondary";
34
34
  }
35
35
  /** Public props for `<RadioGroup>` — the single-select container. */
36
36
  export interface RadioGroupProps extends Omit<BaseProps, "children" | "onChange"> {
@@ -58,7 +58,7 @@ export interface RadioGroupProps extends Omit<BaseProps, "children" | "onChange"
58
58
  onChange?: (event: Event) => void;
59
59
  /** Like `onChange`, but with a `{ value, name }` snapshot as the 2nd argument —
60
60
  * the ergonomic "just give me the new value" callback (mirrors `Input`). */
61
- onAnyChange?: (event: Event, attrs: RadioChangeAttrs) => void;
61
+ onValueChange?: (event: Event, attrs: RadioChangeAttrs) => void;
62
62
  /** Fired when focus enters the group (any option) — wired to `focusin`, since
63
63
  * focus lands on an individual option, not the group element itself. */
64
64
  onFocus?: (event: FocusEvent) => void;
@@ -78,20 +78,22 @@ export interface RadioGroupProps extends Omit<BaseProps, "children" | "onChange"
78
78
  * the neutral default.
79
79
  * @defaultValue 'neutral' */
80
80
  status?: "neutral" | "brand" | "info" | "success" | "warning" | "critical";
81
- /** Tone applied to every option (an option's own `tone` wins), or any literal
82
- * CSS color for a one-off custom tone. Tints fill, label, hint, and the
83
- * unselected ring border. Named tones track light/dark mode.
81
+ /** Mark tone applied to every option (an option's own `tone` wins), or any literal
82
+ * CSS color for a one-off custom tone. Colours the selected-ring fill + dot *and*
83
+ * the unselected ring border. Named tones track light/dark mode. Use `toneSelected`
84
+ * instead to tone only the selected option and leave the rest neutral. The option
85
+ * text stays neutral — recolour it in plain CSS via the `--text-N-{tone}` tokens.
84
86
  * @defaultValue 'neutral' */
85
87
  tone?: "brand" | "neutral" | "info" | "success" | "warning" | "critical" | (string & {});
88
+ /** Like `tone`, but coloured onto the **selected option only** — every unselected
89
+ * ring stays neutral grey. Applied to every option (an option's own `toneSelected`
90
+ * wins). Prefer this over `tone` when a resting tinted border would read as a
91
+ * validation state.
92
+ * @defaultValue 'neutral' */
93
+ toneSelected?: "brand" | "neutral" | "info" | "success" | "warning" | "critical" | (string & {});
86
94
  /** Size applied to every option (an option's own `size` wins).
87
95
  * @defaultValue 'medium' */
88
96
  size?: "small" | "medium" | "large";
89
- /** Visual priority applied to every option (an option's own `priority` wins).
90
- * `primary` fills the selected ring with the tone colour and draws a white dot;
91
- * `secondary` keeps the ring unfilled and draws the border + dot in the tone
92
- * colour (an outlined look).
93
- * @defaultValue 'primary' */
94
- priority?: "primary" | "secondary";
95
97
  /** Disable the whole group. */
96
98
  disabled?: boolean;
97
99
  /** Layout + arrow-key axis.
@@ -115,5 +117,5 @@ export interface RadioGroupProps extends Omit<BaseProps, "children" | "onChange"
115
117
  *
116
118
  * Requires `@antadesign/anta/elements` (client-side only).
117
119
  */
118
- export declare const RadioGroup: ({ options, value, defaultValue, onStateChange, onChange, onAnyChange, onFocus, onBlur, name, label, hint, status, tone, size, priority, disabled, orientation, className, style, ...rest }: RadioGroupProps) => any;
120
+ export declare const RadioGroup: ({ options, value, defaultValue, onStateChange, onChange, onValueChange, onFocus, onBlur, name, label, hint, status, tone, toneSelected, size, disabled, orientation, className, style, ...rest }: RadioGroupProps) => any;
119
121
  export {};
@@ -11,7 +11,7 @@ const RadioGroup = ({
11
11
  defaultValue,
12
12
  onStateChange,
13
13
  onChange,
14
- onAnyChange,
14
+ onValueChange,
15
15
  onFocus,
16
16
  onBlur,
17
17
  name,
@@ -19,8 +19,8 @@ const RadioGroup = ({
19
19
  hint,
20
20
  status,
21
21
  tone,
22
+ toneSelected,
22
23
  size,
23
- priority,
24
24
  disabled,
25
25
  orientation,
26
26
  className,
@@ -47,9 +47,9 @@ const RadioGroup = ({
47
47
  if (detail.reason === "user" && event.defaultPrevented) return;
48
48
  setInternalValue(detail.next ?? void 0);
49
49
  };
50
- const onchange = onChange || onAnyChange ? (e) => {
50
+ const onchange = onChange || onValueChange ? (e) => {
51
51
  onChange?.(e);
52
- onAnyChange?.(e, radioAttrsOf(e.currentTarget));
52
+ onValueChange?.(e, radioAttrsOf(e.currentTarget));
53
53
  } : void 0;
54
54
  return /* @__PURE__ */ jsxs(
55
55
  "a-radio-group",
@@ -64,8 +64,8 @@ const RadioGroup = ({
64
64
  name,
65
65
  status: status && status !== "neutral" ? status : void 0,
66
66
  tone: tone && tone !== "neutral" ? tone : void 0,
67
+ "tone-selected": toneSelected && toneSelected !== "neutral" ? toneSelected : void 0,
67
68
  size: size && size !== "medium" ? size : void 0,
68
- priority: priority && priority !== "primary" ? priority : void 0,
69
69
  disabled: disabled ? "" : void 0,
70
70
  orientation: orientation && orientation !== "vertical" ? orientation : void 0,
71
71
  onstatechange,
@@ -73,7 +73,7 @@ const RadioGroup = ({
73
73
  onfocusin: onFocus,
74
74
  onfocusout: onBlur,
75
75
  class: className,
76
- style: toneStyle(tone, "--radio-tone-source", style),
76
+ style: toneStyle(toneSelected, "--radio-tone-source", toneStyle(tone, "--radio-tone-source", style)),
77
77
  children: [
78
78
  label && /* @__PURE__ */ jsx("a-radio-group-label", { id: labelId, children: label }),
79
79
  hint && /* @__PURE__ */ jsx("a-radio-group-hint", { id: hintId, children: hint }),
@@ -87,10 +87,10 @@ const RadioGroup = ({
87
87
  "aria-disabled": optDisabled ? "true" : void 0,
88
88
  tabIndex: o.value === tabStopValue ? 0 : -1,
89
89
  tone: o.tone && o.tone !== "neutral" ? o.tone : void 0,
90
+ "tone-selected": o.toneSelected && o.toneSelected !== "neutral" ? o.toneSelected : void 0,
90
91
  size: o.size && o.size !== "medium" ? o.size : void 0,
91
- priority: o.priority && o.priority !== "primary" ? o.priority : void 0,
92
92
  disabled: o.disabled ? "" : void 0,
93
- style: toneStyle(o.tone, "--radio-tone-source"),
93
+ style: toneStyle(o.toneSelected, "--radio-tone-source", toneStyle(o.tone, "--radio-tone-source")),
94
94
  children: [
95
95
  /* @__PURE__ */ jsx("a-radio-label", { children: o.label }),
96
96
  o.hint != null && /* @__PURE__ */ jsx("a-radio-hint", { children: o.hint })
@@ -0,0 +1,255 @@
1
+ import type { BaseProps } from '../general_types';
2
+ import type { IconShape } from '../elements/a-icon.shapes';
3
+ /** One option in a `<Select>`. Pass a bare string as shorthand for
4
+ * `{ value: s, label: s }`. Carries an index signature so you can attach
5
+ * arbitrary fields (a `ranAt` date, a `status`, …) and read them back in
6
+ * `renderOption`; the built-in filter still matches on `value`/`label`/`hint`. */
7
+ export interface SelectOption {
8
+ /** The option's value — its identity and what `onValueChange` reports. */
9
+ value: string;
10
+ /** Visible label. Defaults to `value`. */
11
+ label?: string;
12
+ /** Secondary text under the label (the option row's `hint`). */
13
+ hint?: string;
14
+ /** Leading icon (renders after the selection indicator, if any). */
15
+ icon?: IconShape;
16
+ /** Disable just this option. */
17
+ disabled?: boolean;
18
+ /** Tone for this option's row (label, icon, hint, selected tint, and the
19
+ * checkbox/radio indicator). A named tone or a custom CSS color. */
20
+ tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
21
+ /** Your own data — attach anything and read it in `renderOption`. */
22
+ [key: string]: unknown;
23
+ }
24
+ /** A titled group of options rendered **inline** under a heading (like `MenuGroup`).
25
+ * Selection stays global — a group only organizes; its heading isn't selectable.
26
+ * `disabled` cascades to every descendant. Nest groups / submenus freely. */
27
+ export interface SelectGroup {
28
+ /** The section heading (non-interactive). */
29
+ label: string;
30
+ /** The grouped items — options, or further groups / submenus. */
31
+ options: SelectItem[];
32
+ /** Disable the whole group (cascades to all descendants). */
33
+ disabled?: boolean;
34
+ }
35
+ /** A titled branch whose items live behind a **flyout** (like `MenuItem submenu`).
36
+ * Navigation only — the parent row opens the submenu and is never itself selectable.
37
+ * While a filter query is active the tree flattens and a submenu collapses into a
38
+ * group (its `label` becomes the heading). `disabled` cascades to descendants. */
39
+ export interface SelectSubmenu {
40
+ /** The parent row's label — and the group heading when filtering flattens it. */
41
+ label: string;
42
+ /** Leading icon on the parent row. */
43
+ icon?: IconShape;
44
+ /** The submenu's items — options, or further groups / submenus. */
45
+ submenu: SelectItem[];
46
+ /** Disable the whole branch (cascades to all descendants). */
47
+ disabled?: boolean;
48
+ }
49
+ /** One entry in `options`: a plain option (string shorthand or `SelectOption`), an
50
+ * inline `SelectGroup`, or a flyout `SelectSubmenu`. Discriminated by shape — an
51
+ * `options` array is a group, a `submenu` array is a submenu, else it's an option.
52
+ * (`options` / `submenu` are therefore reserved keys on an option object.) */
53
+ export type SelectItem = string | SelectOption | SelectGroup | SelectSubmenu;
54
+ /** Per-row snapshot passed to `renderOption` / `renderIndicator`. Everything here
55
+ * is known at render time; the combobox "active" cursor is deliberately absent
56
+ * (it's a live element state the DOM owns, not a render-time value). */
57
+ export interface OptionState {
58
+ /** The option's value. */
59
+ value: string;
60
+ /** Whether this row is currently selected. */
61
+ selected: boolean;
62
+ /** Whether this row is disabled. */
63
+ disabled: boolean;
64
+ }
65
+ /** Snapshot passed to `renderEmpty` when the option list (after any active
66
+ * filter) is empty. `query` discriminates the cause: non-empty means the filter
67
+ * hid everything; empty means there were no options to begin with (where the
68
+ * consumer's own external loading state, if any, decides "loading" vs "empty"). */
69
+ export interface EmptyState {
70
+ /** The current filter query, trimmed ('' when there's no filter, nothing typed,
71
+ * or simply no options). */
72
+ query: string;
73
+ }
74
+ /** Snapshot passed to `renderTrigger` so a custom trigger can reflect the current
75
+ * selection and open state. */
76
+ export interface TriggerState {
77
+ /** Whether the menu is open — use it for `aria-expanded` and a chevron. */
78
+ open: boolean;
79
+ /** The current selection: a string (single), a string array (`multiple`), or
80
+ * `undefined` when nothing is chosen. */
81
+ value: string | string[] | undefined;
82
+ /** The resolved option objects for the current selection (empty when none).
83
+ * `selected.length` is the multi-select count. */
84
+ selected: SelectOption[];
85
+ /** Whether the whole select is disabled. */
86
+ disabled: boolean;
87
+ /** The `icon` shape passed to `Select`, if any — hand it to your trigger
88
+ * (e.g. a `Button`'s `icon`) so a custom trigger keeps the same leading glyph. */
89
+ icon?: IconShape;
90
+ }
91
+ /** Snapshot passed as the 2nd argument to `onValueChange` — describes *what*
92
+ * changed, alongside the new full value in the 1st argument. A discriminated
93
+ * union: a row toggle carries `value` + `option`; the "Select all" row carries
94
+ * `all: true` instead. Narrow on `'all' in attrs` before reading `option`. */
95
+ export type SelectChangeAttrs = {
96
+ /** The option value that changed — the chosen value (single) or the toggled
97
+ * row (multiple). */
98
+ value: string;
99
+ /** The resolved option object for `value`. */
100
+ option: SelectOption;
101
+ /** Multiple only: whether the change turned selection **on** (true) or off. */
102
+ selected?: boolean;
103
+ } | {
104
+ /** Marks the change as coming from the "Select all" row (multiple only). */
105
+ all: true;
106
+ /** Whether Select-all turned everything **on** (true) or cleared it. */
107
+ selected: boolean;
108
+ };
109
+ /** Props shared by both selection modes, intersected into `SelectProps`. Exported
110
+ * (and kept as an interface intersected — not a union base via `extends`) so its
111
+ * members read as `Select`'s *own* props in the generated docs, not inherited. */
112
+ export interface SelectCommonProps extends Omit<BaseProps, 'children'> {
113
+ /** The options to choose from — bare strings, `SelectOption` objects, `SelectGroup`s
114
+ * (inline titled sections), or `SelectSubmenu`s (flyout branches). Groups and
115
+ * submenus nest and mix with plain options. Selection stays global (one `value`,
116
+ * leaf options only); a filter query flattens the tree into grouped results. */
117
+ options: SelectItem[];
118
+ /** The per-row mark for **single**-select: `'none'` (a tint-only highlight),
119
+ * `'check'` (a trailing checkmark on the selected row, keeping the tint — the
120
+ * canonical Select look), or `'radio'` (a leading radio on every row).
121
+ * Multi-select always uses checkboxes.
122
+ * @defaultValue none */
123
+ indicator?: 'none' | 'check' | 'radio';
124
+ /** Text shown when nothing is selected. */
125
+ placeholder?: string;
126
+ /** Leading icon shown at the left of the field (the default trigger's `Input`
127
+ * `leading` slot). With a custom `renderTrigger`, it's passed through as
128
+ * `state.icon` instead — the consumer places it. */
129
+ icon?: IconShape;
130
+ /** Field label, above the trigger (Input's `label`). */
131
+ label?: string;
132
+ /** Helper text under the field (Input's `hint`). */
133
+ hint?: string;
134
+ /** Field size.
135
+ * @defaultValue medium */
136
+ size?: 'small' | 'medium' | 'large';
137
+ /** Validation/feedback tone for the field (Input's `status`).
138
+ * @defaultValue neutral */
139
+ status?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical';
140
+ /** Glyph shown before the `hint` when `status` is set (Input's `statusIcon`).
141
+ * Each status has a default; pass a shape to override, or `false` to drop it. */
142
+ statusIcon?: IconShape | (string & {}) | false;
143
+ /** Round the field corners — `true` for fully round, or a number / CSS length. */
144
+ round?: boolean | number | string;
145
+ /** Disable the whole select. */
146
+ disabled?: boolean;
147
+ /** Tone applied to the **selected** row(s) — the whole row takes this tone
148
+ * (label, icon, indicator, and the background tint), like passing `tone` to just
149
+ * the chosen option. A named tone or a custom CSS color. Most visible with the
150
+ * tint-based marks (`indicator` `'none'` / `'check'`); with `'radio'` /
151
+ * `'checkbox'` it tones the label + indicator (those modes have no row tint). */
152
+ toneSelected?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
153
+ /** Add a search field at the top of the menu that filters the options as you
154
+ * type. `true` uses the built-in matcher — a case-insensitive substring of the
155
+ * option's **value / label / hint**. Pass a **function** `(option, query) =>
156
+ * boolean` for custom matching (called per option; return `true` to keep it). */
157
+ filter?: boolean | ((option: SelectOption, query: string) => boolean);
158
+ /** `multiple` only: add a "Select all" row at the top that toggles every enabled
159
+ * option (the currently-visible ones when a `filter` query is active); its box
160
+ * shows the mixed state when only some are selected. */
161
+ selectAll?: boolean;
162
+ /** Label for the `selectAll` row.
163
+ * @defaultValue Select all */
164
+ selectAllLabel?: string;
165
+ /** Render the **content** of each option row yourself, replacing the built-in
166
+ * `label`/`hint`/`icon` layout. Select still supplies the row box, click, ARIA,
167
+ * and the selection indicator — you return only what goes *inside*. Read extra
168
+ * fields off the option (see `SelectOption`'s index signature) plus an
169
+ * `OptionState` (`value`/`selected`/`disabled`). Filtering still works (it
170
+ * matches the option's `value`/`label`/`hint`), but match-highlighting is
171
+ * skipped — your content owns its own display. */
172
+ renderOption?: (option: SelectOption, state: OptionState) => React.ReactNode;
173
+ /** Replace each row's selection **mark** with your own node, drawn at the
174
+ * leading edge. The row stays the control (`role` + `aria-checked` from
175
+ * `indicator` / `selection`); only the drawn mark changes, so pair it with an
176
+ * `indicator` (`'check'` / `'radio'`) or `selection="multiple"` for the
177
+ * semantics. Composes with `renderOption`. */
178
+ renderIndicator?: (state: OptionState) => React.ReactNode;
179
+ /** Render your own trigger in place of the default field. Receives a
180
+ * `TriggerState` (`open` / `value` / `selected` / `disabled` / `icon`) to drive
181
+ * its look. **Return exactly one focusable element** (an Anta `Button`, say) —
182
+ * the menu anchors to it (its own previous DOM sibling) and opens it on click,
183
+ * so a fragment, multiple siblings, or a non-focusable wrapper will misanchor
184
+ * (the menu warns in the console if the trigger has no focusable element). Give
185
+ * the element `aria-haspopup="menu"` plus `aria-expanded={state.open}`. The field
186
+ * props (`label`, `hint`, `size`, `status`, `placeholder`, `round`) don't apply. */
187
+ renderTrigger?: (state: TriggerState) => React.ReactNode;
188
+ /** Render content in the menu body when the (filtered) option list is empty —
189
+ * a "no results" message, a loading indicator (gated on your own external
190
+ * loading state), or a "create from the query" row. Receives an `EmptyState`
191
+ * (`query`, trimmed). There is no built-in empty message: when omitted, an empty
192
+ * list renders nothing. Whatever you return goes where the option rows would —
193
+ * a plain node is inert; return a `MenuItem` (e.g. a "Create" row) to make it
194
+ * focusable and selectable. */
195
+ renderEmpty?: (state: EmptyState) => React.ReactNode;
196
+ }
197
+ /**
198
+ * `<Select>` props. `selection` discriminates the value shape: single mode
199
+ * (`value: string`) or `multiple` (`value: string[]`).
200
+ */
201
+ export type SelectProps = SelectCommonProps & ({
202
+ /** Selection mode. `'single'` (the default) keeps `value` a string and
203
+ * closes the menu on pick. Switch to `'multiple'` for checkboxes + an
204
+ * array value.
205
+ * @defaultValue single */
206
+ selection?: 'single';
207
+ /** Controlled value. When provided, the consumer owns selection: the field
208
+ * follows this prop and a pick only *requests* a change via `onValueChange`
209
+ * (reject by not updating). Leave undefined for uncontrolled. */
210
+ value?: string;
211
+ /** Initial value for the uncontrolled case (the wrapper then owns it). */
212
+ defaultValue?: string;
213
+ /** Fires after the selection changes, with the new value and a
214
+ * `{ value, option }` snapshot. Select has no discrete element state, so
215
+ * there is no cancelable `onStateChange` (see the Input event-model note). */
216
+ onValueChange?: (value: string, attrs: SelectChangeAttrs) => void;
217
+ } | {
218
+ /** Multi-select: checkboxes on every row, the menu stays open while
219
+ * toggling, the field shows an "N selected" count, and `value` is an array. */
220
+ selection: 'multiple';
221
+ /** Controlled values (see the single-select `value` note). */
222
+ value?: string[];
223
+ /** Initial values for the uncontrolled case. */
224
+ defaultValue?: string[];
225
+ /** Fires after any toggle, with the new value array and a `{ value, option,
226
+ * selected }` snapshot of the row that changed (or `{ all: true }` for the
227
+ * Select-all row). */
228
+ onValueChange?: (value: string[], attrs: SelectChangeAttrs) => void;
229
+ });
230
+ /**
231
+ * `<Select>` — a single- or multi-select dropdown, composed from `<Input>` (a
232
+ * read-only trigger) and `<Menu>` (the options). `selection` sets behaviour:
233
+ * `'single'` (default; `value` is a string, menu closes on pick) or `'multiple'`
234
+ * (checkboxes, `value` is a string array, menu stays open while toggling, the
235
+ * field shows an "N selected" count). For single-select, `indicator` picks the
236
+ * per-row mark: `'none'` (tint only, default), `'check'` (trailing checkmark), or
237
+ * `'radio'` (leading radio).
238
+ *
239
+ * Controlled (`value` + `onValueChange`) or uncontrolled (`defaultValue`). There
240
+ * is no `a-select` element — this wrapper is the coordinator; for a non-React
241
+ * equivalent, hand-compose the same pieces (see the docs).
242
+ *
243
+ * Requires `@antadesign/anta/elements` (client-side only).
244
+ *
245
+ * @example
246
+ * ```tsx
247
+ * <Select
248
+ * label="Field"
249
+ * options={['output_text', 'stream', 'container']}
250
+ * defaultValue="stream"
251
+ * onValueChange={(v) => console.log(v)}
252
+ * />
253
+ * ```
254
+ */
255
+ export declare const Select: (props: SelectProps) => any;