@antadesign/anta 0.3.27 → 0.3.29

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 (162) hide show
  1. package/NOTICES.md +32 -1
  2. package/dist/anta_helpers.d.ts +25 -0
  3. package/dist/anta_helpers.js +28 -0
  4. package/dist/box-observation.d.ts +8 -0
  5. package/dist/box-observation.js +41 -0
  6. package/dist/box-types.d.ts +2 -0
  7. package/dist/bundle.css +1 -1
  8. package/dist/bundle.js +77 -46
  9. package/dist/components/Banner.js +2 -2
  10. package/dist/components/Box.d.ts +28 -12
  11. package/dist/components/Box.js +18 -11
  12. package/dist/components/Breadcrumbs.css +1 -1
  13. package/dist/components/Button.js +2 -2
  14. package/dist/components/Calendar.js +3 -5
  15. package/dist/components/Card.js +2 -2
  16. package/dist/components/Checkbox.d.ts +12 -13
  17. package/dist/components/Checkbox.js +5 -13
  18. package/dist/components/Expander.js +2 -2
  19. package/dist/components/Input.d.ts +8 -2
  20. package/dist/components/Input.js +6 -2
  21. package/dist/components/InputAutocomplete.js +3 -12
  22. package/dist/components/InputDate.css +1 -1
  23. package/dist/components/InputDate.js +2 -0
  24. package/dist/components/InputTime.js +2 -2
  25. package/dist/components/Loader.js +2 -1
  26. package/dist/components/Menu.d.ts +4 -4
  27. package/dist/components/Menu.js +1 -1
  28. package/dist/components/MenuItem.d.ts +7 -8
  29. package/dist/components/MenuItem.js +4 -4
  30. package/dist/components/Panel.d.ts +17 -0
  31. package/dist/components/Panel.js +22 -0
  32. package/dist/components/Progress.js +2 -2
  33. package/dist/components/RadioGroup.d.ts +14 -14
  34. package/dist/components/RadioGroup.js +7 -23
  35. package/dist/components/Select.d.ts +26 -21
  36. package/dist/components/Select.js +51 -38
  37. package/dist/components/SelectFaceted.d.ts +24 -11
  38. package/dist/components/SelectFaceted.js +65 -44
  39. package/dist/components/Slider.js +3 -3
  40. package/dist/components/Steps.css +1 -1
  41. package/dist/components/Switch.d.ts +10 -11
  42. package/dist/components/Switch.js +3 -11
  43. package/dist/components/TabPanel.d.ts +3 -8
  44. package/dist/components/TabPanel.js +2 -1
  45. package/dist/components/Tabs.d.ts +2 -2
  46. package/dist/components/Tabs.js +4 -3
  47. package/dist/components/Tag.d.ts +7 -9
  48. package/dist/components/Tag.js +2 -2
  49. package/dist/components/Text.js +2 -2
  50. package/dist/components/Title.js +2 -2
  51. package/dist/components/Tooltip.d.ts +1 -1
  52. package/dist/components/Tooltip.js +1 -1
  53. package/dist/components/select-parts.css +1 -1
  54. package/dist/elements/a-avatar.css +1 -1
  55. package/dist/elements/a-banner.css +1 -1
  56. package/dist/elements/a-box.css +1 -1
  57. package/dist/elements/a-box.d.ts +6 -6
  58. package/dist/elements/a-box.js +74 -23
  59. package/dist/elements/a-button.css +1 -1
  60. package/dist/elements/a-button.d.ts +16 -10
  61. package/dist/elements/a-button.js +64 -1
  62. package/dist/elements/a-calendar.css +1 -1
  63. package/dist/elements/a-capture.css +1 -1
  64. package/dist/elements/a-card.css +1 -1
  65. package/dist/elements/a-checkbox.css +1 -1
  66. package/dist/elements/a-checkbox.d.ts +3 -0
  67. package/dist/elements/a-checkbox.js +17 -1
  68. package/dist/elements/a-copy.css +1 -1
  69. package/dist/elements/a-dialog.css +1 -1
  70. package/dist/elements/a-expander.css +1 -1
  71. package/dist/elements/a-expander.js +1 -0
  72. package/dist/elements/a-icon.css +1 -1
  73. package/dist/elements/a-icon.shapes.css +1 -1
  74. package/dist/elements/a-input-time.css +1 -1
  75. package/dist/elements/a-input-time.d.ts +8 -0
  76. package/dist/elements/a-input-time.js +120 -15
  77. package/dist/elements/a-input.css +1 -1
  78. package/dist/elements/a-input.d.ts +27 -1
  79. package/dist/elements/a-input.js +180 -41
  80. package/dist/elements/a-loader.css +1 -1
  81. package/dist/elements/a-menu-group.css +1 -1
  82. package/dist/elements/a-menu-item.css +1 -1
  83. package/dist/elements/a-menu-item.js +1 -0
  84. package/dist/elements/a-menu-separator.css +1 -1
  85. package/dist/elements/a-menu.css +1 -1
  86. package/dist/elements/a-menu.d.ts +8 -13
  87. package/dist/elements/a-menu.js +146 -45
  88. package/dist/elements/a-panel.css +1 -0
  89. package/dist/elements/a-panel.d.ts +16 -0
  90. package/dist/elements/a-panel.js +153 -0
  91. package/dist/elements/a-progress.css +1 -1
  92. package/dist/elements/a-radio-group.css +1 -1
  93. package/dist/elements/a-radio.css +1 -1
  94. package/dist/elements/a-radio.d.ts +4 -0
  95. package/dist/elements/a-radio.js +18 -0
  96. package/dist/elements/a-slider.css +1 -1
  97. package/dist/elements/a-slider.d.ts +1 -0
  98. package/dist/elements/a-slider.js +3 -6
  99. package/dist/elements/a-switch.css +1 -1
  100. package/dist/elements/a-switch.d.ts +3 -0
  101. package/dist/elements/a-switch.js +17 -1
  102. package/dist/elements/a-tab.css +1 -1
  103. package/dist/elements/a-tabpanel.css +1 -1
  104. package/dist/elements/a-tabs.css +1 -1
  105. package/dist/elements/a-tag.css +1 -1
  106. package/dist/elements/a-text.css +1 -1
  107. package/dist/elements/a-text.js +1 -0
  108. package/dist/elements/a-title.css +1 -1
  109. package/dist/elements/a-toast.css +1 -1
  110. package/dist/elements/a-toaster.css +1 -1
  111. package/dist/elements/a-tooltip.css +1 -1
  112. package/dist/elements/a-tooltip.d.ts +3 -4
  113. package/dist/elements/a-tooltip.js +30 -8
  114. package/dist/elements/focus.d.ts +9 -0
  115. package/dist/elements/focus.js +41 -0
  116. package/dist/elements/index.d.ts +1 -0
  117. package/dist/elements/index.js +3 -0
  118. package/dist/elements/panel-focus.d.ts +10 -0
  119. package/dist/elements/panel-focus.js +86 -0
  120. package/dist/elements/shadow-aria.d.ts +10 -0
  121. package/dist/elements/shadow-aria.js +155 -0
  122. package/dist/general_types.d.ts +70 -42
  123. package/dist/generate-icons.mjs +3 -0
  124. package/dist/index.d.ts +5 -2
  125. package/dist/index.js +2 -0
  126. package/dist/jsx-runtime.d.ts +10 -1
  127. package/dist/reset.css +1 -1
  128. package/dist/theme-antithesis.css +1 -0
  129. package/dist/theme-antune.css +1 -0
  130. package/dist/tokens.css +1 -1
  131. package/docs/accessibility.md +4 -2
  132. package/docs/changelog.md +135 -0
  133. package/docs/colors.md +7 -7
  134. package/docs/comparison.md +2 -2
  135. package/docs/components/box.md +98 -34
  136. package/docs/components/breadcrumbs.md +75 -6
  137. package/docs/components/button.md +2 -2
  138. package/docs/components/capture.md +8 -8
  139. package/docs/components/checkbox.md +21 -16
  140. package/docs/components/input-autocomplete.md +6 -0
  141. package/docs/components/input-date.md +8 -2
  142. package/docs/components/input.md +99 -40
  143. package/docs/components/menu.md +5 -6
  144. package/docs/components/panel.md +189 -0
  145. package/docs/components/radio.md +16 -13
  146. package/docs/components/select-faceted.md +58 -2
  147. package/docs/components/select.md +72 -59
  148. package/docs/components/steps.md +4 -4
  149. package/docs/components/switch.md +16 -10
  150. package/docs/components/tabs.md +21 -8
  151. package/docs/components/tag.md +5 -3
  152. package/docs/components/tooltip.md +6 -4
  153. package/docs/index.md +1 -0
  154. package/docs/install-config.md +23 -12
  155. package/docs/normalization.md +6 -4
  156. package/docs/theming.md +95 -17
  157. package/package.json +8 -4
  158. package/dist/components/InputDate.module.css +0 -1
  159. package/dist/components/Select.module.css +0 -1
  160. package/dist/components/SelectFaceted.module.css +0 -1
  161. package/dist/search-index.json +0 -0
  162. package/dist/theme-anta.css +0 -1
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
2
- import { nativeStateChange, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
2
+ import { nativeStateChange, neutralToneAttr, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
3
3
  import { Button } from "./Button";
4
4
  const Banner = ({
5
5
  message,
@@ -29,7 +29,7 @@ const Banner = ({
29
29
  {
30
30
  state: controlled ? dismissed ? "closed" : "open" : void 0,
31
31
  "default-state": !controlled ? defaultDismissed ? "closed" : "open" : void 0,
32
- tone: tone && tone !== "neutral" ? tone : void 0,
32
+ tone: neutralToneAttr(tone),
33
33
  align: align === "center" ? "center" : void 0,
34
34
  round: roundAttr(round),
35
35
  role,
@@ -1,9 +1,9 @@
1
- import type { BoxContextChange, BoxDisplay, BoxMeasurementChange } from '../box-types';
1
+ import type { BoxContextChange, BoxDisplay, BoxMeasurementChange, BoxObservation } from '../box-types';
2
2
  import type { BaseProps } from '../general_types';
3
3
  /** JSX props for the observing light-DOM `<a-box>` container. */
4
4
  export interface BoxProps extends BaseProps {
5
- /** Layout model for the host. All other layout, sizing, mask, and shadow
6
- * properties stay ordinary `className` / `style` CSS on the Box itself.
5
+ /** Layout model for the host. Sizing, alignment, mask, and shadow properties
6
+ * stay ordinary `className` / `style` CSS on the Box itself.
7
7
  * @defaultValue block */
8
8
  display?: BoxDisplay;
9
9
  /** Fully-round corners (`border-radius: 999px`, clamped to the box). Pass a
@@ -14,12 +14,28 @@ export interface BoxProps extends BaseProps {
14
14
  * pixels; a string is any CSS length or two-value gap (`'1rem'`,
15
15
  * `'8px 16px'`). Applies while the Box is a flex or grid container. */
16
16
  gap?: number | string;
17
- /** What the Box watches, when a handler is not what turns it on. `'size'`
18
- * keeps the overflow CSS states (`:state(clipped-x)`, `:state(scrollable-y)`,
19
- * …) current — reach for it when your own CSS is the only reader. `'context'`
20
- * and `'all'` are there for symmetry; passing `onMeasureChange` or
21
- * `onContextChange` already turns the matching half on. */
22
- observe?: 'size' | 'context' | 'all';
17
+ /** Inner spacing, matching CSS `padding`. Numbers are pixels; strings accept
18
+ * CSS shorthand, percentages, and custom properties. Omission adds no style. */
19
+ padding?: number | string;
20
+ /** Outer spacing, matching CSS `margin`. Numbers are pixels; strings accept
21
+ * CSS shorthand, `auto`, negative lengths, and custom properties.
22
+ * Omission adds no style. */
23
+ margin?: number | string;
24
+ /** One selection or an array of selections, in any order. `'size'` watches width
25
+ * and height; `'context'` watches rendering context; `'overflow'` watches
26
+ * content dimensions and clipping. `'edges'` reports which edges hide content;
27
+ * `'scroll'` reports offsets, potentially every frame; `'all'` selects everything.
28
+ * Selections are independent: use `['size', 'edges']` to combine them.
29
+ * A measurement handler implies `'size'` when no measurement is selected;
30
+ * a context handler adds `'context'`. Size skips content and scroll observers;
31
+ * overflow adds content observation; hidden edges and scroll add scroll reads.
32
+ * Without handlers or `fade`, omission stays idle. */
33
+ observe?: BoxObservation | readonly BoxObservation[];
34
+ /** Minimum interval between measurement events, in milliseconds. The first
35
+ * report has no added delay; a trailing report delivers the latest values.
36
+ * Active observers and CSS clipping states are not throttled.
37
+ * @defaultValue 0 */
38
+ throttle?: number;
23
39
  /** Fades out every edge that currently hides clipped content, and drops the
24
40
  * fade from an edge once the reader scrolls to it. */
25
41
  fade?: boolean;
@@ -27,8 +43,8 @@ export interface BoxProps extends BaseProps {
27
43
  * length.
28
44
  * @defaultValue 24 */
29
45
  fadeSize?: number | string;
30
- /** Fired after Box geometry or its content-overflow state changes. `detail`
31
- * contains the changed fields and a full current snapshot. */
46
+ /** Fired when a selected measurement field changes. `detail` contains all
47
+ * fields changed since the last event and a full current snapshot. */
32
48
  onMeasureChange?: (event: CustomEvent<BoxMeasurementChange>, detail: BoxMeasurementChange) => void;
33
49
  /** Fired after Box's browser and local rendering context changes. `detail`
34
50
  * contains the changed fields and a full current snapshot. */
@@ -49,4 +65,4 @@ export interface BoxProps extends BaseProps {
49
65
  * </Box>
50
66
  * ```
51
67
  */
52
- export declare const Box: ({ display, round, gap, observe, fade, fadeSize, onMeasureChange, onContextChange, className, style, children, ...rest }: BoxProps) => any;
68
+ export declare const Box: ({ display, round, gap, padding, margin, observe, throttle, fade, fadeSize, onMeasureChange, onContextChange, className, style, children, ...rest }: BoxProps) => any;
@@ -6,19 +6,22 @@ import {
6
6
  roundAttr,
7
7
  roundStyle
8
8
  } from "../anta_helpers";
9
+ import { boxObservation } from "../box-observation";
9
10
  function observeAttr(observe, onMeasureChange, onContextChange) {
10
- const size = observe === "size" || observe === "all" || onMeasureChange != null;
11
- const context = observe === "context" || observe === "all" || onContextChange != null;
12
- if (size && context) return "all";
13
- if (size) return "size";
14
- if (context) return "context";
15
- return void 0;
11
+ const tokens = [...new Set(observe == null ? [] : typeof observe === "string" ? [observe] : observe)];
12
+ const { fields, context } = boxObservation(tokens.join(" ") || null);
13
+ if (onMeasureChange != null && fields.size === 0) tokens.push("size");
14
+ if (onContextChange != null && !context) tokens.push("context");
15
+ return tokens.join(" ") || void 0;
16
16
  }
17
17
  const Box = ({
18
18
  display,
19
19
  round,
20
20
  gap,
21
+ padding,
22
+ margin,
21
23
  observe,
24
+ throttle,
22
25
  fade,
23
26
  fadeSize,
24
27
  onMeasureChange,
@@ -28,23 +31,27 @@ const Box = ({
28
31
  children,
29
32
  ...rest
30
33
  }) => {
34
+ let boxStyle = roundStyle(round, "--box-round", style);
35
+ boxStyle = lengthStyle(gap, "--box-gap", boxStyle);
36
+ boxStyle = lengthStyle(padding, "--box-padding", boxStyle);
37
+ boxStyle = lengthStyle(margin, "--box-margin", boxStyle);
38
+ boxStyle = lengthStyle(fade ? fadeSize : void 0, "--box-fade-size", boxStyle);
31
39
  return /* @__PURE__ */ jsx(
32
40
  "a-box",
33
41
  {
34
42
  display: display === "block" ? void 0 : display,
35
43
  round: roundAttr(round),
36
44
  gap: gap != null ? "" : void 0,
45
+ padding: padding != null ? "" : void 0,
46
+ margin: margin != null ? "" : void 0,
37
47
  observe: observeAttr(observe, onMeasureChange, onContextChange),
48
+ throttle,
38
49
  fade: fade ? "" : void 0,
39
50
  "fade-size": fade && fadeSize != null ? cssLength(fadeSize) : void 0,
40
51
  onmeasurechange: customEventHandler(onMeasureChange),
41
52
  oncontextchange: customEventHandler(onContextChange),
42
53
  class: className,
43
- style: lengthStyle(
44
- fade ? fadeSize : void 0,
45
- "--box-fade-size",
46
- lengthStyle(gap, "--box-gap", roundStyle(round, "--box-round", style))
47
- ),
54
+ style: boxStyle,
48
55
  ...rest,
49
56
  children
50
57
  }
@@ -1 +1 @@
1
- @layer anta.components{a-breadcrumbs{--breadcrumb-gap: 1px;--breadcrumb-separator-color: var(--text-5);--breadcrumb-separator-icon-size: 16px;--breadcrumb-separator-font-size: 15px;display:flex;align-items:center;gap:var(--breadcrumb-gap);width:max-content;min-width:100%;max-width:100%;overflow-x:auto}a-breadcrumbs[data-size=small]{--breadcrumb-separator-icon-size: 14px;--breadcrumb-separator-font-size: 13px}a-breadcrumbs[data-size=large]{--breadcrumb-separator-icon-size: 18px;--breadcrumb-separator-font-size: 17px}a-breadcrumbs[data-paddingless]{--breadcrumb-gap: .75ch}a-breadcrumbs[data-separator-icon]{--breadcrumb-gap: 0}a-breadcrumbs>*{flex:none}a-breadcrumb-separator{display:inline-flex;flex:none;align-items:center;justify-content:center;color:var(--breadcrumb-separator-color);font-family:var(--sans-serif);font-size:var(--breadcrumb-separator-font-size);line-height:1;user-select:none}a-breadcrumb-separator>a-icon{--icon-size: var(--breadcrumb-separator-icon-size)}}
1
+ @layer base,anta,components,utilities;@layer anta.reset,anta.components,anta.theme;@layer anta.components{a-breadcrumbs{--breadcrumb-gap: 1px;--breadcrumb-separator-color: var(--text-5);--breadcrumb-separator-icon-size: 16px;--breadcrumb-separator-font-size: 15px;display:flex;align-items:center;gap:var(--breadcrumb-gap);width:max-content;min-width:100%;max-width:100%}a-breadcrumbs[data-size=small]{--breadcrumb-separator-icon-size: 14px;--breadcrumb-separator-font-size: 13px}a-breadcrumbs[data-size=large]{--breadcrumb-separator-icon-size: 18px;--breadcrumb-separator-font-size: 17px}a-breadcrumbs[data-paddingless]{--breadcrumb-gap: .75ch}a-breadcrumbs[data-separator-icon]{--breadcrumb-gap: 0}a-breadcrumbs>*{flex:none}a-breadcrumb-separator{display:inline-flex;flex:none;align-items:center;justify-content:center;color:var(--breadcrumb-separator-color);font-family:var(--sans-serif);font-size:var(--breadcrumb-separator-font-size);line-height:1;user-select:none}a-breadcrumb-separator>a-icon{--icon-size: var(--breadcrumb-separator-icon-size)}}
@@ -1,5 +1,5 @@
1
1
  import { Fragment, jsx, jsxs } from "@antadesign/anta/jsx-runtime";
2
- import { toneStyle, roundStyle, roundAttr, wrapLabel } from "../anta_helpers";
2
+ import { neutralToneAttr, toneStyle, roundStyle, roundAttr, wrapLabel } from "../anta_helpers";
3
3
  const Button = ({
4
4
  priority,
5
5
  tone,
@@ -27,7 +27,7 @@ const Button = ({
27
27
  children,
28
28
  ...rest
29
29
  }) => {
30
- const toneAttr = tone || void 0;
30
+ const toneAttr = neutralToneAttr(tone);
31
31
  const unavailable = disabled || loading;
32
32
  const computedStyle = roundStyle(round, "--button-round", toneStyle(toneAttr, "--button-tone-source", style));
33
33
  const isIconOnly = icon != null && label == null && children == null && iconTrailing == null;
@@ -1,7 +1,7 @@
1
1
  import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
2
2
  import cn from "clsx";
3
3
  import { Temporal } from "temporal-polyfill";
4
- import { useId, useMemo, useState } from "../jsx-runtime";
4
+ import { useMemo, useState } from "../jsx-runtime";
5
5
  import { nativeStateChange } from "../anta_helpers";
6
6
  import { Button } from "./Button";
7
7
  import { Menu } from "./Menu";
@@ -50,7 +50,6 @@ const Calendar = ({
50
50
  }
51
51
  const [focusReq, setFocusReq] = useState(null);
52
52
  const [jumpOpen, setJumpOpen] = useState(false);
53
- const headingId = useId();
54
53
  const month = buildMonth({ anchor: effectiveCursor, locale: resolvedLocale, min: minD, max: maxD, selected, today });
55
54
  const cursorIso = effectiveCursor.toString();
56
55
  const [lastFocusSignal, setLastFocusSignal] = useState(focusSignal);
@@ -154,7 +153,6 @@ const Calendar = ({
154
153
  /* @__PURE__ */ jsx(
155
154
  Button,
156
155
  {
157
- id: headingId,
158
156
  "data-part": "heading",
159
157
  priority: "tertiary",
160
158
  size,
@@ -181,8 +179,7 @@ const Calendar = ({
181
179
  "a-calendar",
182
180
  {
183
181
  role: "group",
184
- "aria-labelledby": headingId,
185
- "aria-label": ariaLabel,
182
+ "aria-label": ariaLabel ?? month.heading,
186
183
  name,
187
184
  value: controlled ? value : void 0,
188
185
  defaultvalue: !controlled ? defaultValue : void 0,
@@ -212,6 +209,7 @@ const Calendar = ({
212
209
  disabled: disabled || d.disabled,
213
210
  tabIndex: d.iso === cursorIso ? 0 : -1,
214
211
  "aria-label": d.label,
212
+ "aria-hidden": d.outside ? "true" : void 0,
215
213
  "aria-current": d.today ? "date" : void 0,
216
214
  "data-part": "day-cell",
217
215
  "data-date": d.iso,
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
2
- import { toneStyle, roundStyle, roundAttr } from "../anta_helpers";
2
+ import { neutralToneAttr, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
3
3
  import { Title } from "./Title";
4
4
  import { Text } from "./Text";
5
5
  import { Icon } from "./Icon";
@@ -25,7 +25,7 @@ const Card = ({
25
25
  children,
26
26
  ...rest
27
27
  }) => {
28
- const toneAttr = tone || void 0;
28
+ const toneAttr = neutralToneAttr(tone);
29
29
  const computedStyle = roundStyle(
30
30
  round,
31
31
  "--card-round",
@@ -1,4 +1,4 @@
1
- import type { BaseProps } from "../general_types";
1
+ import type { BaseProps, ToneScope } from "../general_types";
2
2
  /** The wrapper-level checked value: a boolean for the binary axis, the string
3
3
  * `'indeterminate'` for the third state. Mirrors Radix's `Checkbox.Root`. */
4
4
  export type CheckboxValue = boolean | 'indeterminate';
@@ -27,8 +27,8 @@ export interface CheckboxProps extends BaseProps {
27
27
  * renders first. Required unless `children` or `aria-label` is provided
28
28
  * (a `role="checkbox"` takes its name from the author, not the markup). */
29
29
  label?: string;
30
- /** Secondary text rendered under the label — explanatory copy, like
31
- * Input's hint. Not part of the accessible name. */
30
+ /** Secondary text rendered under the label and exposed as the checkbox's
31
+ * accessible description. Not part of the accessible name. */
32
32
  hint?: React.ReactNode;
33
33
  /** Controlled checked state. When provided the checkbox is controlled — it
34
34
  * renders exactly this and never self-applies; `onStateChange` is a *request*
@@ -51,21 +51,20 @@ 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
- /** Color of the **mark** in every state — the checked-box fill *and* the
55
- * unselected box border. A named tone or any literal CSS color (`'#ff1493'`,
54
+ /** Color of the **mark**. In the default `all` scope this colors the checked-box
55
+ * fill and 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
57
  * automatically; a custom color keeps its hue + chroma and pins lightness to the
58
- * fill curve. Use `toneSelected` instead to tone only the checked mark and leave
58
+ * fill curve. Set `toneScope="selected"` to tone only the checked mark and leave
59
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 colored onto the **checked mark only** — the empty box stays
64
- * neutral grey until it's checked. Prefer this over `tone` when a resting tinted
65
- * border would read as a validation state. Same value set as `tone`; if both are
66
- * set, `tone` governs the off-state border and `toneSelected` the checked fill.
67
- * @defaultValue 'neutral' */
68
- toneSelected?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
63
+ /** Apply `tone` to every state, or only while checked so the empty box stays
64
+ * neutral. `selected` is useful when a tinted resting border would read as a
65
+ * validation state.
66
+ * @defaultValue 'all' */
67
+ toneScope?: ToneScope;
69
68
  /** Size variant. small=14px, medium=16px, large=18px box.
70
69
  * @defaultValue 'medium' */
71
70
  size?: 'small' | 'medium' | 'large';
@@ -98,5 +97,5 @@ export interface CheckboxProps extends BaseProps {
98
97
  * <Checkbox defaultChecked label="Remember me" hint="On this device" />
99
98
  * ```
100
99
  */
101
- export declare const Checkbox: ({ checked, defaultChecked, disabled, tone, toneSelected, size, round, onStateChange, onChange, onValueChange, label, hint, className, style, children, tabIndex, ...rest }: CheckboxProps) => any;
100
+ export declare const Checkbox: ({ checked, defaultChecked, disabled, tone, toneScope, size, round, onStateChange, onChange, onValueChange, label, hint, className, style, children, tabIndex, ...rest }: CheckboxProps) => any;
102
101
  export {};
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
2
- import { nativeStateChange, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
2
+ import { nativeStateChange, neutralToneAttr, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
3
3
  const valueToState = (v) => v === "indeterminate" ? "indeterminate" : v ? "checked" : "unchecked";
4
4
  const stateToValue = (s) => s === "indeterminate" ? "indeterminate" : s === "checked";
5
5
  const checkboxAttrsOf = (el) => ({
@@ -13,7 +13,7 @@ const Checkbox = ({
13
13
  defaultChecked,
14
14
  disabled,
15
15
  tone,
16
- toneSelected,
16
+ toneScope,
17
17
  size,
18
18
  round,
19
19
  onStateChange,
@@ -30,15 +30,7 @@ const Checkbox = ({
30
30
  const computedStyle = roundStyle(
31
31
  round,
32
32
  "--checkbox-round",
33
- toneStyle(
34
- toneSelected,
35
- "--checkbox-tone-source",
36
- toneStyle(
37
- tone,
38
- "--checkbox-off-tone-source",
39
- toneSelected == null ? toneStyle(tone, "--checkbox-tone-source", style) : style
40
- )
41
- )
33
+ toneStyle(tone, "--checkbox-tone-source", toneStyle(tone, "--checkbox-off-tone-source", style))
42
34
  );
43
35
  const explicitAriaLabel = rest["aria-label"];
44
36
  const ariaLabel = (typeof explicitAriaLabel === "string" ? explicitAriaLabel : void 0) ?? label ?? (typeof children === "string" ? children : void 0);
@@ -67,8 +59,8 @@ const Checkbox = ({
67
59
  state: stateAttr,
68
60
  "default-state": defaultStateAttr,
69
61
  disabled: disabled ? "" : void 0,
70
- tone: tone && tone !== "neutral" ? tone : void 0,
71
- "tone-selected": toneSelected || void 0,
62
+ tone: neutralToneAttr(tone),
63
+ "tone-scope": toneScope && toneScope !== "all" ? toneScope : void 0,
72
64
  size: size && size !== "medium" ? size : void 0,
73
65
  round: roundAttr(round),
74
66
  tabIndex: disabled ? -1 : tabIndex ?? 0,
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
2
- import { nativeStateChange, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
2
+ import { nativeStateChange, neutralToneAttr, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
3
3
  const Expander = ({
4
4
  title,
5
5
  level,
@@ -26,7 +26,7 @@ const Expander = ({
26
26
  state: controlled ? open ? "open" : "closed" : void 0,
27
27
  "default-state": !controlled && defaultOpen ? "open" : void 0,
28
28
  level: level != null ? String(level) : void 0,
29
- tone: tone && tone !== "neutral" ? tone : void 0,
29
+ tone: neutralToneAttr(tone),
30
30
  priority: priority && priority !== "secondary" ? priority : void 0,
31
31
  outdent: outdent ? "" : void 0,
32
32
  round: roundAttr(round),
@@ -102,6 +102,10 @@ export interface InputProps extends BaseProps, DOMEventHandlers {
102
102
  disabled?: boolean;
103
103
  /** Make the field read-only. */
104
104
  readOnly?: boolean;
105
+ /** Render the field surface with a native button as its focus target. This is
106
+ * available for Input-styled popup triggers; the value becomes
107
+ * the button text and the placeholder is shown while it is empty. */
108
+ button?: boolean;
105
109
  /** Mark the field required (drives native validity). */
106
110
  required?: boolean;
107
111
  /** Dim the `leading` / `trailing` adornments at rest; they brighten to full
@@ -153,7 +157,9 @@ export interface InputProps extends BaseProps, DOMEventHandlers {
153
157
  /** Fires when the field loses focus. */
154
158
  onBlur?: (e: any) => void;
155
159
  /** ARIA `role` for the field — e.g. `combobox` when the input drives a
156
- * suggestion `listbox` (see `InputAutocomplete`). Left unset by default. */
160
+ * suggestion `listbox` (see `InputAutocomplete`). The custom element
161
+ * delegates it, together with standard `aria-*` props, to the focused native
162
+ * shadow control. Left unset by default. */
157
163
  role?: string;
158
164
  }
159
165
  /**
@@ -173,4 +179,4 @@ export interface InputProps extends BaseProps, DOMEventHandlers {
173
179
  * <Input label="Email" type="email" placeholder="you@example.com" clearable />
174
180
  * ```
175
181
  */
176
- export declare const Input: ({ label, hint, status, statusIcon, tone, size, round, value, defaultValue, multiline, rows, maxRows, clearable, leading, trailing, type, autoComplete, inputMode, autoFocus, name, placeholder, truncate, disabled, readOnly, required, dimActions, spellCheck, maxLength, minLength, pattern, min, max, step, onInput, onChange, onValueChange, onClearClick, onClearInput, children, className, style, ...rest }: InputProps) => any;
182
+ export declare const Input: ({ label, hint, status, statusIcon, tone, size, round, value, defaultValue, multiline, rows, maxRows, clearable, leading, trailing, type, autoComplete, inputMode, autoFocus, name, placeholder, truncate, disabled, readOnly, button, required, dimActions, spellCheck, maxLength, minLength, pattern, min, max, step, role, onInput, onChange, onValueChange, onClearClick, onClearInput, children, className, style, ...rest }: InputProps) => any;
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
2
- import { nativeStateChange, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
2
+ import { nativeStateChange, neutralToneAttr, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
3
3
  import { Button } from "./Button";
4
4
  import { Icon } from "./Icon";
5
5
  const presence = (on) => on ? "" : void 0;
@@ -55,6 +55,7 @@ const Input = ({
55
55
  truncate = true,
56
56
  disabled,
57
57
  readOnly,
58
+ button,
58
59
  required,
59
60
  dimActions,
60
61
  spellCheck,
@@ -64,6 +65,7 @@ const Input = ({
64
65
  min,
65
66
  max,
66
67
  step,
68
+ role,
67
69
  onInput,
68
70
  onChange,
69
71
  onValueChange,
@@ -91,13 +93,14 @@ const Input = ({
91
93
  rows: rows != null ? String(rows) : void 0,
92
94
  maxrows: maxRows != null ? String(maxRows) : void 0,
93
95
  status: statusTone,
94
- tone: tone || void 0,
96
+ tone: neutralToneAttr(tone),
95
97
  type: !multiline && rows == null ? nativeType : void 0,
96
98
  name,
97
99
  placeholder,
98
100
  truncate: presence(truncate),
99
101
  disabled: presence(disabled),
100
102
  readonly: presence(readOnly),
103
+ button: presence(button),
101
104
  required: presence(required),
102
105
  "dim-actions": presence(dimActions),
103
106
  autocomplete: autoComplete ?? (!multiline && rows == null && type ? AUTOCOMPLETE_BY_TYPE[type] : void 0),
@@ -111,6 +114,7 @@ const Input = ({
111
114
  max,
112
115
  step,
113
116
  "aria-invalid": status === "critical" ? "true" : void 0,
117
+ role: role ?? (isSearch ? "searchbox" : void 0),
114
118
  oninput: onInput || onValueChange ? (e) => {
115
119
  onInput?.(e);
116
120
  onValueChange?.(e, attrsOf(e));
@@ -1,6 +1,6 @@
1
1
  import { Fragment, jsx, jsxs } from "@antadesign/anta/jsx-runtime";
2
- import { useState, useMemo, useId } from "../jsx-runtime";
3
- import { nativeStateChange, optionPresentationAttrs } from "../anta_helpers";
2
+ import { useState, useMemo } from "../jsx-runtime";
3
+ import { 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";
@@ -15,12 +15,10 @@ const InputAutocomplete = (props) => {
15
15
  filter = true,
16
16
  ...rest
17
17
  } = props;
18
- const rid = useId();
19
18
  const controlled = value !== void 0;
20
19
  const [internal, setInternal] = useState(defaultValue ?? "");
21
20
  const text = controlled ? value : internal;
22
21
  const [open, setOpen] = useState(false);
23
- const [activeId, setActiveId] = useState(null);
24
22
  const options = useMemo(() => suggestions.map(normalizeOpt), [suggestions]);
25
23
  const custom = typeof filter === "function";
26
24
  const queryRe = filter !== false && !custom ? matchQueryRegex(text) : null;
@@ -44,10 +42,8 @@ const InputAutocomplete = (props) => {
44
42
  "data-menu-search": "",
45
43
  role: "combobox",
46
44
  "aria-haspopup": "listbox",
47
- "aria-controls": `${rid}-list`,
48
45
  "aria-expanded": menuOpen ? "true" : "false",
49
46
  "aria-autocomplete": "list",
50
- "aria-activedescendant": menuOpen && activeId ? activeId : void 0,
51
47
  onFocus: () => setOpen(true),
52
48
  onInput: (e) => {
53
49
  setText(e.currentTarget.value);
@@ -61,23 +57,18 @@ const InputAutocomplete = (props) => {
61
57
  /* @__PURE__ */ jsx(
62
58
  Menu,
63
59
  {
64
- id: `${rid}-list`,
65
60
  role: "listbox",
66
61
  open: menuOpen,
67
62
  onStateChange: (_e, { next }) => {
68
63
  setOpen(next);
69
- if (!next) setActiveId(null);
70
64
  },
71
- onactivedescendant: (e) => setActiveId(nativeStateChange(e).detail?.id ?? null),
72
65
  children: visible.map((opt, i) => {
73
66
  const { className: optionClassName, style: optionStyle, ...optionAttrs } = optionPresentationAttrs(opt, true);
74
67
  return /* @__PURE__ */ jsx(
75
68
  MenuItem,
76
69
  {
77
70
  ...optionAttrs,
78
- id: `${rid}-o${i}`,
79
71
  role: "option",
80
- "aria-selected": activeId === `${rid}-o${i}` ? "true" : "false",
81
72
  icon: opt.icon,
82
73
  label: highlight(opt.label ?? opt.value, queryRe),
83
74
  hint: opt.hint ? highlight(opt.hint, queryRe) : opt.hint,
@@ -89,7 +80,7 @@ const InputAutocomplete = (props) => {
89
80
  className: optionClassName,
90
81
  style: optionStyle
91
82
  },
92
- `${rid}-${opt.value}-${i}`
83
+ `${opt.value}-${i}`
93
84
  );
94
85
  })
95
86
  }
@@ -1 +1 @@
1
- @layer anta.components{a-input-date-time-container{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:6px;padding-top:8px;border-top:1px solid var(--border-3)}}
1
+ @layer base,anta,components,utilities;@layer anta.reset,anta.components,anta.theme;@layer anta.components{a-input-date-time-container{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:6px;padding-top:8px;border-top:1px solid var(--border-3)}}
@@ -156,6 +156,8 @@ const InputDate = ({
156
156
  /* @__PURE__ */ jsx(
157
157
  Menu,
158
158
  {
159
+ role: "dialog",
160
+ "aria-label": time ? "Choose date and time" : "Choose date",
159
161
  open,
160
162
  placement: placement ?? "bottom-start",
161
163
  offset,
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
2
- import { nativeStateChange, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
2
+ import { nativeStateChange, neutralToneAttr, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
3
3
  import { Button } from "./Button";
4
4
  import { Icon } from "./Icon";
5
5
  const presence = (on) => on ? "" : void 0;
@@ -65,7 +65,7 @@ const InputTime = ({
65
65
  min,
66
66
  max,
67
67
  status: statusTone,
68
- tone: tone || void 0,
68
+ tone: neutralToneAttr(tone),
69
69
  name,
70
70
  disabled: presence(disabled),
71
71
  required: presence(required),
@@ -1,4 +1,5 @@
1
1
  import { jsx } from "@antadesign/anta/jsx-runtime";
2
+ import { neutralToneAttr } from "../anta_helpers";
2
3
  const Loader = ({ tone, value, max = 100, size, speed, label, className, style, ...rest }) => {
3
4
  const determinate = typeof value === "number" && Number.isFinite(value);
4
5
  const safeMax = Number.isFinite(max) && max > 0 ? max : 100;
@@ -20,7 +21,7 @@ const Loader = ({ tone, value, max = 100, size, speed, label, className, style,
20
21
  return /* @__PURE__ */ jsx(
21
22
  "a-loader",
22
23
  {
23
- tone,
24
+ tone: neutralToneAttr(tone),
24
25
  ...determinate ? { value: clampedValue } : {},
25
26
  class: className,
26
27
  style: computedStyle,
@@ -61,10 +61,10 @@ export interface MenuProps extends BaseProps {
61
61
  }) => void;
62
62
  /** Combobox-mode cursor report (raw element event). Fires when the active
63
63
  * option changes as arrow keys move the cursor while focus stays in a
64
- * `[data-menu-search]` filter field; `detail.id` is the active option's `id`
65
- * (`null` when none). The reactive layer that renders the field reflects this
66
- * onto its `aria-activedescendant` — the element can't write that light-DOM
67
- * attribute itself. Passed straight through to the element. */
64
+ * `[data-menu-search]` filter field; `detail.id` is an authored option `id`,
65
+ * or `null`. Built-in Anta Inputs receive the active option through a direct
66
+ * ARIA element relationship; this remains available to custom fields and
67
+ * observers. Passed straight through to the element. */
68
68
  onactivedescendant?: (e: CustomEvent<{
69
69
  id: string | null;
70
70
  }>) => void;
@@ -39,7 +39,7 @@ const Menu = ({
39
39
  round: roundAttr(round),
40
40
  "stop-propagation": stopPropagation === void 0 || stopPropagation === false ? void 0 : stopPropagation === true ? "" : Array.isArray(stopPropagation) ? stopPropagation.join(" ") : stopPropagation,
41
41
  role,
42
- "aria-orientation": "vertical",
42
+ "aria-orientation": role === "menu" || role === "listbox" ? "vertical" : void 0,
43
43
  class: className,
44
44
  style: lengthStyle(inset, "--menu-padding", roundStyle(round, "--menu-round", style)),
45
45
  ...rest,
@@ -1,4 +1,4 @@
1
- import type { BaseProps } from '../general_types';
1
+ import type { BaseProps, ToneScope } from '../general_types';
2
2
  import type { IconShape } from '../elements/a-icon.shapes';
3
3
  /** Props shared by every menu item, link or not. */
4
4
  export interface MenuItemCommonProps extends BaseProps {
@@ -39,12 +39,11 @@ export interface MenuItemCommonProps extends BaseProps {
39
39
  * gray.
40
40
  * @defaultValue neutral */
41
41
  tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
42
- /** Like `tone`, but applied only while the row is `selected` — an unselected row
43
- * stays neutral. The whole selected row (label, icon, tint, and the `checkbox` /
44
- * `radio` indicator) takes the tone. Same value set as `tone`; on a selected row
45
- * `toneSelected` wins over `tone` when both are set.
46
- * @defaultValue neutral */
47
- toneSelected?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
42
+ /** Apply `tone` to every row state, or only while the row is selected. In
43
+ * `selected` scope, an unselected row and its checkbox/radio indicator stay
44
+ * neutral.
45
+ * @defaultValue 'all' */
46
+ toneScope?: ToneScope;
48
47
  /** An opaque value identifying this item, handed back in `onSelect`'s detail
49
48
  * so a shared handler can tell which row was chosen without a per-item
50
49
  * closure. */
@@ -139,4 +138,4 @@ export type MenuItemProps = MenuItemCommonProps & (MenuItemLinkMode | MenuItemAc
139
138
  * </MenuItem>
140
139
  * ```
141
140
  */
142
- export declare const MenuItem: ({ icon, label, hint, kbd, iconTrailing, disabled, selected, selectionIndicator, indeterminate, indicator, tone, toneSelected, submenu, value, onSelect, href, target, rel, download, ping, role: roleOverride, className, style, children, ...rest }: MenuItemProps) => any;
141
+ export declare const MenuItem: ({ icon, label, hint, kbd, iconTrailing, disabled, selected, selectionIndicator, indeterminate, indicator, tone, toneScope, submenu, value, onSelect, href, target, rel, download, ping, role: roleOverride, className, style, children, ...rest }: MenuItemProps) => any;
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
2
- import { toneStyle } from "../anta_helpers";
2
+ import { neutralToneAttr, toneStyle } from "../anta_helpers";
3
3
  const SHORTCUT_KEYS = {
4
4
  "\u2318": "Meta",
5
5
  cmd: "Meta",
@@ -77,7 +77,7 @@ const MenuItem = ({
77
77
  indeterminate,
78
78
  indicator,
79
79
  tone,
80
- toneSelected,
80
+ toneScope,
81
81
  submenu,
82
82
  value,
83
83
  onSelect,
@@ -97,8 +97,8 @@ const MenuItem = ({
97
97
  const role = selectionIndicator === "checkbox" ? "menuitemcheckbox" : selectionIndicator === "radio" || selectionIndicator === "check" ? "menuitemradio" : "menuitem";
98
98
  const ariaChecked = !checkable ? void 0 : selectionIndicator === "checkbox" && indeterminate ? "mixed" : selected ? "true" : "false";
99
99
  const keepTint = selected && (selectionIndicator === void 0 || selectionIndicator === "check");
100
- const effectiveTone = selected && toneSelected || tone;
101
- const toneAttr = effectiveTone && effectiveTone !== "neutral" ? effectiveTone : void 0;
100
+ const effectiveTone = toneScope === "selected" && !selected ? void 0 : tone;
101
+ const toneAttr = neutralToneAttr(effectiveTone);
102
102
  const declaredShortcuts = rest["aria-keyshortcuts"];
103
103
  const keyShortcuts = kbd ? shortcutLabel(kbd) : void 0;
104
104
  const kbdNode = kbd ? /* @__PURE__ */ jsx("kbd", { "aria-hidden": declaredShortcuts ?? keyShortcuts ? "true" : void 0, children: kbd }) : null;
@@ -0,0 +1,17 @@
1
+ import type { BaseProps, DOMEventHandlers } from '../general_types';
2
+ export interface PanelProps extends BaseProps, DOMEventHandlers {
3
+ /** Fill the browser viewport and contain keyboard focus within the panel.
4
+ * When supplied, the application owns the state. */
5
+ maximized?: boolean;
6
+ /** Initial viewport maximization for an uncontrolled panel, read once on connect. */
7
+ defaultMaximized?: boolean;
8
+ /** Requested maximization change. Update `maximized` to accept a controlled
9
+ * request, or prevent the event to veto an uncontrolled request. */
10
+ onStateChange?: (event: CustomEvent, detail: {
11
+ next: boolean;
12
+ prev: boolean;
13
+ }) => void;
14
+ }
15
+ /** A scroll container that fills its parent and can maximize to the viewport.
16
+ * Percentage height requires a parent with a defined height. */
17
+ export declare const Panel: ({ maximized, defaultMaximized, onStateChange, className, children, ...rest }: PanelProps) => any;