@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
@@ -0,0 +1,41 @@
1
+ import { isFocusable, tabbable } from "tabbable";
2
+ const options = { getShadowRoot: true };
3
+ function activeFocus(doc) {
4
+ let active = doc.activeElement;
5
+ while (active?.shadowRoot?.activeElement) active = active.shadowRoot.activeElement;
6
+ return active;
7
+ }
8
+ function focusParent(node) {
9
+ if (node.nodeType === 1 && node.assignedSlot) return node.assignedSlot;
10
+ const parent = node.parentNode;
11
+ return parent?.nodeType === 11 && "host" in parent ? parent.host : parent;
12
+ }
13
+ function containsFocus(scope, node) {
14
+ while (node) {
15
+ if (node === scope) return true;
16
+ node = focusParent(node);
17
+ }
18
+ return false;
19
+ }
20
+ function canFocus(node) {
21
+ return !!node && "focus" in node && isFocusable(node, options);
22
+ }
23
+ function tabStops(scope) {
24
+ return tabbable(scope, options);
25
+ }
26
+ function cycleFocus(nodes, current, backward, fallback) {
27
+ const index = nodes.indexOf(current);
28
+ const next = index < 0 ? backward ? nodes.length - 1 : 0 : (index + (backward ? -1 : 1) + nodes.length) % nodes.length;
29
+ const target = nodes[next] ?? fallback;
30
+ if (!target) return false;
31
+ target.focus();
32
+ return true;
33
+ }
34
+ export {
35
+ activeFocus,
36
+ canFocus,
37
+ containsFocus,
38
+ cycleFocus,
39
+ focusParent,
40
+ tabStops
41
+ };
@@ -19,6 +19,7 @@ export { ALoaderElement, register_a_loader } from './a-loader';
19
19
  export { ATextElement, register_a_text } from './a-text';
20
20
  export { ABoxElement, register_a_box } from './a-box';
21
21
  export { ACaptureElement, register_a_capture } from './a-capture';
22
+ export { APanelElement, register_a_panel } from './a-panel';
22
23
  export { AIconElement, register_a_icon } from './a-icon';
23
24
  export { AButtonElement, register_a_button } from './a-button';
24
25
  export { ACopyElement, register_a_copy } from './a-copy';
@@ -4,6 +4,7 @@ import { ALoaderElement, register_a_loader } from "./a-loader";
4
4
  import { ATextElement, register_a_text } from "./a-text";
5
5
  import { ABoxElement, register_a_box } from "./a-box";
6
6
  import { ACaptureElement, register_a_capture } from "./a-capture";
7
+ import { APanelElement, register_a_panel } from "./a-panel";
7
8
  import { AIconElement, register_a_icon } from "./a-icon";
8
9
  import { AButtonElement, register_a_button } from "./a-button";
9
10
  import { ACopyElement, register_a_copy } from "./a-copy";
@@ -51,6 +52,7 @@ export {
51
52
  AMenuGroupElement,
52
53
  AMenuItemElement,
53
54
  AMenuSeparatorElement,
55
+ APanelElement,
54
56
  AProgressElement,
55
57
  ARadioElement,
56
58
  ARadioGroupElement,
@@ -82,6 +84,7 @@ export {
82
84
  register_a_menu_group,
83
85
  register_a_menu_item,
84
86
  register_a_menu_separator,
87
+ register_a_panel,
85
88
  register_a_progress,
86
89
  register_a_radio,
87
90
  register_a_radio_group,
@@ -0,0 +1,10 @@
1
+ export { activeFocus } from './focus';
2
+ /** One active Panel scope per document; later scopes suspend earlier ones. */
3
+ export declare class PanelFocusScope {
4
+ #private;
5
+ constructor(surface: HTMLSlotElement);
6
+ activate(previous: Element | null): void;
7
+ focusInside(preferred?: Element | null): void;
8
+ /** Remove listeners before hiding the popover, then restore focus after layout. */
9
+ deactivate(): () => void;
10
+ }
@@ -0,0 +1,86 @@
1
+ import { activeFocus, canFocus, containsFocus, cycleFocus, tabStops } from "./focus";
2
+ import { activeFocus as activeFocus2 } from "./focus";
3
+ const scopes = /* @__PURE__ */ new WeakMap();
4
+ class PanelFocusScope {
5
+ #stack;
6
+ #doc;
7
+ #surface;
8
+ #previous = null;
9
+ #lastInside = null;
10
+ #active = false;
11
+ #redirecting = false;
12
+ constructor(surface) {
13
+ this.#surface = surface;
14
+ this.#doc = surface.ownerDocument;
15
+ this.#stack = scopes.get(this.#doc) ?? [];
16
+ scopes.set(this.#doc, this.#stack);
17
+ }
18
+ get #ownsFocus() {
19
+ return this.#stack.at(-1) === this && this.#surface.matches(":popover-open");
20
+ }
21
+ activate(previous) {
22
+ if (this.#active) return;
23
+ this.#active = true;
24
+ this.#previous = previous;
25
+ this.#lastInside = containsFocus(this.#surface, previous) ? previous : null;
26
+ this.#stack.push(this);
27
+ this.#doc.addEventListener("focusin", this.#onFocus, true);
28
+ this.#doc.addEventListener("keydown", this.#onKeyDown);
29
+ }
30
+ focusInside(preferred = this.#lastInside) {
31
+ if (!this.#ownsFocus) return;
32
+ const target = containsFocus(this.#surface, preferred) && canFocus(preferred) ? preferred : tabStops(this.#surface)[0] ?? this.#surface;
33
+ target.focus({ preventScroll: true });
34
+ }
35
+ /** Remove listeners before hiding the popover, then restore focus after layout. */
36
+ deactivate() {
37
+ if (!this.#active) return () => {
38
+ };
39
+ const current = activeFocus(this.#doc);
40
+ const restore = this.#stack.at(-1) === this && containsFocus(this.#surface, current);
41
+ const previous = this.#previous;
42
+ const target = previous && !containsFocus(this.#surface, previous) ? previous : current;
43
+ this.#active = false;
44
+ const index = this.#stack.indexOf(this);
45
+ if (index >= 0) this.#stack.splice(index, 1);
46
+ this.#doc.removeEventListener("focusin", this.#onFocus, true);
47
+ this.#doc.removeEventListener("keydown", this.#onKeyDown);
48
+ this.#previous = this.#lastInside = null;
49
+ return () => {
50
+ if (!restore) return;
51
+ if (canFocus(target)) target.focus({ preventScroll: true });
52
+ else if (canFocus(current)) current.focus({ preventScroll: true });
53
+ else if (canFocus(previous)) previous.focus({ preventScroll: true });
54
+ else this.#stack.at(-1)?.focusInside();
55
+ };
56
+ }
57
+ #inModal(path) {
58
+ for (const node of path) {
59
+ if (node === this.#surface) return false;
60
+ if (node instanceof Element && node.matches(":modal")) return true;
61
+ }
62
+ return false;
63
+ }
64
+ #onFocus = (event) => {
65
+ if (!this.#ownsFocus || this.#redirecting) return;
66
+ const path = event.composedPath();
67
+ if (this.#inModal(path)) return;
68
+ if (path.includes(this.#surface)) {
69
+ this.#lastInside = activeFocus(this.#doc);
70
+ return;
71
+ }
72
+ this.#redirecting = true;
73
+ this.focusInside();
74
+ this.#redirecting = false;
75
+ };
76
+ #onKeyDown = (event) => {
77
+ if (!this.#ownsFocus || event.defaultPrevented || event.key !== "Tab" || event.altKey || event.ctrlKey || event.metaKey) return;
78
+ if (this.#inModal(event.composedPath())) return;
79
+ event.preventDefault();
80
+ cycleFocus(tabStops(this.#surface), activeFocus(this.#doc), event.shiftKey, this.#surface);
81
+ };
82
+ }
83
+ export {
84
+ PanelFocusScope,
85
+ activeFocus2 as activeFocus
86
+ };
@@ -0,0 +1,10 @@
1
+ /** Standard semantic attributes that a shadow-hosted control may consume from
2
+ * its custom-element host. Keeping the public spelling standard lets raw HTML,
3
+ * React, Preact, and custom JSX runtimes use the same API. */
4
+ export declare const SHADOW_ARIA_ATTRIBUTES: readonly ["role", "aria-activedescendant", "aria-atomic", "aria-autocomplete", "aria-braillelabel", "aria-brailleroledescription", "aria-busy", "aria-checked", "aria-colcount", "aria-colindex", "aria-colspan", "aria-controls", "aria-current", "aria-description", "aria-describedby", "aria-details", "aria-disabled", "aria-dropeffect", "aria-errormessage", "aria-expanded", "aria-flowto", "aria-grabbed", "aria-haspopup", "aria-hidden", "aria-invalid", "aria-keyshortcuts", "aria-label", "aria-labelledby", "aria-level", "aria-live", "aria-modal", "aria-multiline", "aria-multiselectable", "aria-orientation", "aria-owns", "aria-placeholder", "aria-posinset", "aria-pressed", "aria-readonly", "aria-relevant", "aria-required", "aria-roledescription", "aria-rowcount", "aria-rowindex", "aria-rowspan", "aria-selected", "aria-setsize", "aria-sort", "aria-valuemax", "aria-valuemin", "aria-valuenow", "aria-valuetext"];
5
+ export type ShadowAriaAttribute = (typeof SHADOW_ARIA_ATTRIBUTES)[number];
6
+ export declare const SHADOW_ARIA_ATTRIBUTE_SET: Set<string>;
7
+ export declare function ariaAttributeProperty(name: ShadowAriaAttribute): string;
8
+ /** Apply one consumed host attribute to a shadow control. ID-reference ARIA
9
+ * uses element reflection so a shadow control can reference the host's tree. */
10
+ export declare function applyShadowAria(host: Element, target: Element, name: ShadowAriaAttribute, value: string | null): void;
@@ -0,0 +1,155 @@
1
+ const SHADOW_ARIA_ATTRIBUTES = [
2
+ "role",
3
+ "aria-activedescendant",
4
+ "aria-atomic",
5
+ "aria-autocomplete",
6
+ "aria-braillelabel",
7
+ "aria-brailleroledescription",
8
+ "aria-busy",
9
+ "aria-checked",
10
+ "aria-colcount",
11
+ "aria-colindex",
12
+ "aria-colspan",
13
+ "aria-controls",
14
+ "aria-current",
15
+ "aria-description",
16
+ "aria-describedby",
17
+ "aria-details",
18
+ "aria-disabled",
19
+ "aria-dropeffect",
20
+ "aria-errormessage",
21
+ "aria-expanded",
22
+ "aria-flowto",
23
+ "aria-grabbed",
24
+ "aria-haspopup",
25
+ "aria-hidden",
26
+ "aria-invalid",
27
+ "aria-keyshortcuts",
28
+ "aria-label",
29
+ "aria-labelledby",
30
+ "aria-level",
31
+ "aria-live",
32
+ "aria-modal",
33
+ "aria-multiline",
34
+ "aria-multiselectable",
35
+ "aria-orientation",
36
+ "aria-owns",
37
+ "aria-placeholder",
38
+ "aria-posinset",
39
+ "aria-pressed",
40
+ "aria-readonly",
41
+ "aria-relevant",
42
+ "aria-required",
43
+ "aria-roledescription",
44
+ "aria-rowcount",
45
+ "aria-rowindex",
46
+ "aria-rowspan",
47
+ "aria-selected",
48
+ "aria-setsize",
49
+ "aria-sort",
50
+ "aria-valuemax",
51
+ "aria-valuemin",
52
+ "aria-valuenow",
53
+ "aria-valuetext"
54
+ ];
55
+ const SHADOW_ARIA_ATTRIBUTE_SET = new Set(SHADOW_ARIA_ATTRIBUTES);
56
+ const SHADOW_ARIA_PROPERTIES = {
57
+ role: "role",
58
+ "aria-activedescendant": "ariaActiveDescendant",
59
+ "aria-atomic": "ariaAtomic",
60
+ "aria-autocomplete": "ariaAutoComplete",
61
+ "aria-braillelabel": "ariaBrailleLabel",
62
+ "aria-brailleroledescription": "ariaBrailleRoleDescription",
63
+ "aria-busy": "ariaBusy",
64
+ "aria-checked": "ariaChecked",
65
+ "aria-colcount": "ariaColCount",
66
+ "aria-colindex": "ariaColIndex",
67
+ "aria-colspan": "ariaColSpan",
68
+ "aria-controls": "ariaControls",
69
+ "aria-current": "ariaCurrent",
70
+ "aria-description": "ariaDescription",
71
+ "aria-describedby": "ariaDescribedBy",
72
+ "aria-details": "ariaDetails",
73
+ "aria-disabled": "ariaDisabled",
74
+ "aria-dropeffect": "ariaDropEffect",
75
+ "aria-errormessage": "ariaErrorMessage",
76
+ "aria-expanded": "ariaExpanded",
77
+ "aria-flowto": "ariaFlowTo",
78
+ "aria-grabbed": "ariaGrabbed",
79
+ "aria-haspopup": "ariaHasPopup",
80
+ "aria-hidden": "ariaHidden",
81
+ "aria-invalid": "ariaInvalid",
82
+ "aria-keyshortcuts": "ariaKeyShortcuts",
83
+ "aria-label": "ariaLabel",
84
+ "aria-labelledby": "ariaLabelledBy",
85
+ "aria-level": "ariaLevel",
86
+ "aria-live": "ariaLive",
87
+ "aria-modal": "ariaModal",
88
+ "aria-multiline": "ariaMultiLine",
89
+ "aria-multiselectable": "ariaMultiSelectable",
90
+ "aria-orientation": "ariaOrientation",
91
+ "aria-owns": "ariaOwns",
92
+ "aria-placeholder": "ariaPlaceholder",
93
+ "aria-posinset": "ariaPosInSet",
94
+ "aria-pressed": "ariaPressed",
95
+ "aria-readonly": "ariaReadOnly",
96
+ "aria-relevant": "ariaRelevant",
97
+ "aria-required": "ariaRequired",
98
+ "aria-roledescription": "ariaRoleDescription",
99
+ "aria-rowcount": "ariaRowCount",
100
+ "aria-rowindex": "ariaRowIndex",
101
+ "aria-rowspan": "ariaRowSpan",
102
+ "aria-selected": "ariaSelected",
103
+ "aria-setsize": "ariaSetSize",
104
+ "aria-sort": "ariaSort",
105
+ "aria-valuemax": "ariaValueMax",
106
+ "aria-valuemin": "ariaValueMin",
107
+ "aria-valuenow": "ariaValueNow",
108
+ "aria-valuetext": "ariaValueText"
109
+ };
110
+ function ariaAttributeProperty(name) {
111
+ return SHADOW_ARIA_PROPERTIES[name];
112
+ }
113
+ const ELEMENT_REFERENCE_PROPERTIES = {
114
+ "aria-activedescendant": "ariaActiveDescendantElement",
115
+ "aria-controls": "ariaControlsElements",
116
+ "aria-describedby": "ariaDescribedByElements",
117
+ "aria-details": "ariaDetailsElements",
118
+ "aria-errormessage": "ariaErrorMessageElements",
119
+ "aria-flowto": "ariaFlowToElements",
120
+ "aria-labelledby": "ariaLabelledByElements",
121
+ "aria-owns": "ariaOwnsElements"
122
+ };
123
+ function referencedElements(host, value) {
124
+ const root = host.getRootNode();
125
+ if (!("getElementById" in root)) return [];
126
+ return value.trim().split(/\s+/).filter(Boolean).map((id) => root.getElementById(id)).filter((element) => element != null);
127
+ }
128
+ function applyShadowAria(host, target, name, value) {
129
+ const property = ELEMENT_REFERENCE_PROPERTIES[name];
130
+ if (!property) {
131
+ if (value == null) target.removeAttribute(name);
132
+ else target.setAttribute(name, value);
133
+ return;
134
+ }
135
+ const reflected = target;
136
+ const elements = value == null ? [] : referencedElements(host, value);
137
+ try {
138
+ if (!(property in reflected)) throw new Error("ARIA element reflection is unavailable");
139
+ if (name === "aria-activedescendant") {
140
+ reflected.ariaActiveDescendantElement = elements[0] ?? null;
141
+ } else {
142
+ ;
143
+ reflected[property] = elements;
144
+ }
145
+ } catch {
146
+ if (value == null) target.removeAttribute(name);
147
+ else target.setAttribute(name, value);
148
+ }
149
+ }
150
+ export {
151
+ SHADOW_ARIA_ATTRIBUTES,
152
+ SHADOW_ARIA_ATTRIBUTE_SET,
153
+ applyShadowAria,
154
+ ariaAttributeProperty
155
+ };
@@ -29,6 +29,9 @@ export interface BaseProps {
29
29
  /** Any `aria-*` attribute is forwarded to the rendered element. */
30
30
  [key: `aria-${string}`]: unknown;
31
31
  }
32
+ /** Where a stateful component applies its tone. `all` colors both resting and
33
+ * selected chrome; `selected` keeps resting chrome neutral. */
34
+ export type ToneScope = 'all' | 'selected';
32
35
  /** Safe presentation attributes for a data-rendered option. They land on the
33
36
  * option's rendered row, rather than on the enclosing control. Menu-based
34
37
  * components reserve `data-menu-*` for their own selection and focus behavior. */
@@ -269,6 +272,22 @@ export interface ATextAttributes extends BaseAttributes {
269
272
  /** ARIA disclosure state, mirrors the JSX wrapper's `expanded` flag. */
270
273
  'aria-expanded'?: boolean | 'true' | 'false';
271
274
  }
275
+ /** Panel presentation state. Normal panels remain visible in their parent layout. */
276
+ export type PanelState = 'normal' | 'maximized';
277
+ /** Attributes for the persistent viewport-capable container. */
278
+ export interface APanelAttributes extends BaseAttributes {
279
+ state?: PanelState;
280
+ 'default-state'?: PanelState;
281
+ onstatechange?: (event: CustomEvent<{
282
+ next: PanelState;
283
+ prev: PanelState;
284
+ }> | {
285
+ nativeEvent: CustomEvent<{
286
+ next: PanelState;
287
+ prev: PanelState;
288
+ }>;
289
+ }) => void;
290
+ }
272
291
  /** Attributes for the opt-in light-DOM capture surface. */
273
292
  export interface ACaptureAttributes extends BaseAttributes {
274
293
  /** Space-separated accepted wheel directions. Bare means all; `none` preserves settling while declining input. */
@@ -315,20 +334,28 @@ export interface ABoxAttributes extends BaseAttributes {
315
334
  * typed `attr()` read it from `--box-gap` in the host's inline style
316
335
  * instead, which is what the JSX wrapper always sets. */
317
336
  gap?: boolean | '' | number | string;
337
+ /** CSS padding shorthand (`padding="8px 16px"`). Without typed `attr()`
338
+ * support, set `--box-padding` as well. The JSX wrapper supplies it. */
339
+ padding?: boolean | '' | number | string;
340
+ /** CSS margin shorthand (`margin="0 auto"`). Without typed `attr()`
341
+ * support, set `--box-margin` as well. The JSX wrapper supplies it. */
342
+ margin?: boolean | '' | number | string;
318
343
  /** Masks every edge that currently hides clipped content. */
319
344
  fade?: boolean | '';
320
- /** What the box watches. `size` reports geometry and overflow through
321
- * `measurechange` and the CSS states; `context` reports the rendering
322
- * environment through `contextchange`; `all`, or a bare `observe`, does both.
323
- * A box without it (and without `fade`) runs no observers, so a listener
324
- * alone reports nothing. The JSX wrapper sets it from `observe` and from the
325
- * handlers you pass. */
326
- observe?: 'size' | 'context' | 'all' | '';
345
+ /** Space-separated selections: `width`, `height`, `size`, `context`,
346
+ * `overflow`, `edges`, `scroll`, or `all`, in any order. `size` selects
347
+ * width and height; `edges` selects edge transitions. A bare
348
+ * attribute means `all`. Omission runs no observers unless `fade` is set;
349
+ * a native event listener alone does not enable observation. */
350
+ observe?: string;
351
+ /** Minimum interval between measurement events in milliseconds. Omit or
352
+ * pass `0` for frame-based reporting. Invalid or negative values use `0`. */
353
+ throttle?: number | string;
327
354
  /** Depth of that mask, as a length value (`fade-size="2rem"`). Engines
328
355
  * without typed `attr()` read it from `--box-fade-size` in the host's
329
356
  * inline style instead, which is what the JSX wrapper always sets. */
330
357
  'fade-size'?: number | string;
331
- /** Native event fired when geometry or overflow changes. */
358
+ /** Native event fired when a selected measurement field changes. */
332
359
  onmeasurechange?: (event: CustomEvent<BoxMeasurementChange> | {
333
360
  nativeEvent: CustomEvent<BoxMeasurementChange>;
334
361
  }) => void;
@@ -517,7 +544,7 @@ export interface ATooltipAttributes extends BaseAttributes {
517
544
  /** Show delay in milliseconds. Never use `0` — use ~`50`. Defaults to 300. */
518
545
  delay?: number | string;
519
546
  /** Preferred side; auto-flips when there's no room. Defaults to `'bottom'`. */
520
- placement?: 'top' | 'bottom';
547
+ placement?: 'top' | 'bottom' | 'left';
521
548
  /** Follow the cursor instead of pinning under the anchor (pinned is the
522
549
  * default). Presence-based (`''` on, omit off). */
523
550
  follow?: boolean | '';
@@ -549,15 +576,13 @@ export interface ATooltipAttributes extends BaseAttributes {
549
576
  * `@antadesign/anta`.
550
577
  */
551
578
  export interface ACheckboxAttributes extends BaseAttributes {
552
- /** Mark color in every state — checked fill *and* unselected box border — or any
553
- * literal CSS color for a one-off custom tone. Named tones track light/dark mode
554
- * automatically. `'neutral'` is the default (same as omitting it). The label + hint
579
+ /** Mark color, or any literal CSS color for a one-off custom tone. Named tones
580
+ * track light/dark mode automatically. Its scope is controlled by `tone-scope`. `'neutral'` is the
581
+ * default (same as omitting it). The label + hint
555
582
  * stay neutral — recolor them in plain CSS via the `--text-N-{tone}` tokens. */
556
583
  tone?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
557
- /** Like `tone`, but colored onto the checked mark only — the empty box stays
558
- * neutral grey. Same value set as `tone`; if both are set, `tone` governs the
559
- * off-state border and `tone-selected` the checked fill. */
560
- 'tone-selected'?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
584
+ /** Apply `tone` to every state (`all`, the default) or only while checked. */
585
+ 'tone-scope'?: ToneScope;
561
586
  /** Size variant. `small` = 14px, `medium` (default) = 16px, `large` = 18px box. */
562
587
  size?: 'small' | 'medium' | 'large';
563
588
  /** Controlled state — the element reflects changes to this attribute. Use this
@@ -603,10 +628,10 @@ export interface ACheckboxAttributes extends BaseAttributes {
603
628
  * wrapper supplies both.
604
629
  */
605
630
  export interface ASwitchAttributes extends BaseAttributes {
606
- /** Track and thumb color. A tinted tone also colors the unchecked chrome. */
631
+ /** Track and thumb color. Its scope is controlled by `tone-scope`. */
607
632
  tone?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
608
- /** Checked-track-only color. The unchecked track and thumb stay neutral. */
609
- 'tone-selected'?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
633
+ /** Apply `tone` to every state (`all`, the default) or only while checked. */
634
+ 'tone-scope'?: ToneScope;
610
635
  /** Size variant. `small` = 26×16px, `medium` (default) = 30×18px, `large` = 34×20px. */
611
636
  size?: 'small' | 'medium' | 'large';
612
637
  /** Fully round the thumb and track, or pass a custom track radius via a length
@@ -646,6 +671,9 @@ export interface ASwitchAttributes extends BaseAttributes {
646
671
  * for styling, and `:state(filled)` / `:state(invalid)` as CSS hooks.
647
672
  */
648
673
  export interface AInputAttributes extends BaseAttributes {
674
+ /** Standard ARIA attributes describe the native input/textarea in the shadow
675
+ * tree and are delegated there when the element upgrades. */
676
+ [key: `aria-${string}`]: unknown;
649
677
  /** Controlled value (string). Reflected to the shadow control only when it
650
678
  * differs, so the caret survives re-renders. */
651
679
  value?: string;
@@ -668,6 +696,8 @@ export interface AInputAttributes extends BaseAttributes {
668
696
  disabled?: boolean | '';
669
697
  /** Read-only state. Presence-based. */
670
698
  readonly?: boolean | '';
699
+ /** Render a native button inside the field surface. Presence-based. */
700
+ button?: boolean | '';
671
701
  /** Required — drives native validity. Presence-based. */
672
702
  required?: boolean | '';
673
703
  /** Dim the leading/trailing adornments at rest (0.6); they brighten to full
@@ -766,6 +796,9 @@ export interface ASliderAttributes extends BaseAttributes {
766
796
  /** Attributes for the `<a-input-time>` custom element — a segmented wall-clock
767
797
  * time field (hour / minute / AM-PM native text-input sections in one box). */
768
798
  export interface AInputTimeAttributes extends BaseAttributes {
799
+ /** Standard naming/description ARIA describes the complete segmented field;
800
+ * invalid/error state is delegated to its focusable segments. */
801
+ [key: `aria-${string}`]: unknown;
769
802
  /** Controlled value — 24-hour `"HH:mm"`, `''` when incomplete. */
770
803
  value?: string;
771
804
  /** Focus this field when its containing `a-dialog` opens. Presence-based. */
@@ -911,11 +944,9 @@ export interface AMenuAttributes extends BaseAttributes {
911
944
  next: 'open' | 'closed';
912
945
  prev: 'open' | 'closed';
913
946
  }>) => void;
914
- /** Combobox-mode cursor report — fired when the active option changes (arrow
915
- * keys, or the list re-filtering), with `detail.id` the active option's `id`
916
- * (`null` when none). The element owns the keyboard cursor but must NOT write
917
- * `aria-activedescendant` on the (light-DOM) filter field itself; the reactive
918
- * layer that owns the field (e.g. `Select`) listens here and reflects it.
947
+ /** Combobox-mode cursor report for custom fields and observers. Fires when
948
+ * the active option changes, with `detail.id` containing an authored option
949
+ * ID or `null`. Built-in Anta Inputs receive a direct ARIA element relation.
919
950
  * All-lowercase so React/Preact bind it to the CustomEvent. */
920
951
  onactivedescendant?: (e: CustomEvent<{
921
952
  id: string | null;
@@ -1066,15 +1097,13 @@ export interface ACopyAttributes extends BaseAttributes {
1066
1097
  export interface ARadioAttributes extends BaseAttributes {
1067
1098
  /** This option's identity / submitted value. */
1068
1099
  value?: string;
1069
- /** Mark color in every state — selected ring fill + dot *and* unselected ring
1070
- * border — or any literal CSS color for a one-off custom tone. Named tones track
1071
- * light/dark mode. `'neutral'` is the default. The label + hint stay neutral —
1100
+ /** Mark color, or any literal CSS color for a one-off custom tone. Named tones track
1101
+ * light/dark mode; `tone-scope` controls whether unselected chrome is tinted.
1102
+ * `'neutral'` is the default. The label + hint stay neutral —
1072
1103
  * recolor them in plain CSS via the `--text-N-{tone}` tokens. */
1073
1104
  tone?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
1074
- /** Like `tone`, but colored onto the selected mark only — an unselected ring stays
1075
- * neutral grey. Same value set as `tone`; if both are set, `tone` governs the
1076
- * off-state border and `tone-selected` the selected fill. */
1077
- 'tone-selected'?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
1105
+ /** Apply `tone` to every state (`all`, the default) or only while selected. */
1106
+ 'tone-scope'?: ToneScope;
1078
1107
  /** Size variant. small=14px, medium=16px, large=18px control. */
1079
1108
  size?: 'small' | 'medium' | 'large';
1080
1109
  /** Disabled state. Presence-based (`''` on, omit off). */
@@ -1117,13 +1146,13 @@ export interface ARadioGroupAttributes extends BaseAttributes {
1117
1146
  /** Form field name — the group submits `name=value`. */
1118
1147
  name?: string;
1119
1148
  /** Mark tone cascaded to children that don't set their own, or any literal CSS
1120
- * color for a one-off custom tone. Colors every child's ring fill + dot *and*
1121
- * unselected border. The option text stays neutral — recolor it in plain CSS via
1122
- * the `--text-N-{tone}` tokens. */
1149
+ * color for a one-off custom tone. In `all` scope it colors every child's ring
1150
+ * fill, dot, and unselected border. The option text stays neutral — recolor it
1151
+ * in plain CSS via the `--text-N-{tone}` tokens. */
1123
1152
  tone?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
1124
- /** Like `tone`, but colored onto the selected option only — every unselected ring
1125
- * stays neutral grey. Cascaded to children that don't set their own. */
1126
- 'tone-selected'?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
1153
+ /** Apply the cascaded `tone` to every state (`all`, the default) or only to the
1154
+ * selected option. A child's explicit scope overrides the group. */
1155
+ 'tone-scope'?: ToneScope;
1127
1156
  /** Size cascaded to children that don't set their own. */
1128
1157
  size?: 'small' | 'medium' | 'large';
1129
1158
  /** Validation/feedback tone for the group hint — same set as `<a-input>`'s
@@ -1266,11 +1295,10 @@ export interface ATabsAttributes extends BaseAttributes {
1266
1295
  /**
1267
1296
  * Attributes for the `<a-tabpanel>` styled tag.
1268
1297
  *
1269
- * `<a-tabpanel>` has no JS — it's a CSS-only styled element. The `Tabs` wrapper renders
1270
- * it, pairs it to its tab via id, and toggles visibility declaratively: `hidden`
1271
- * (display:none) or `data-hide="visibility"` (keeps the layout box), plus `inert` while
1272
- * hidden. Low-level attributes; for the typed JSX wrapper use `TabPanel` (inside `Tabs`)
1273
- * from `@antadesign/anta`.
1298
+ * `<a-tabpanel>` finds its sibling `<a-tabs>`, exposes its active state through
1299
+ * `ElementInternals`, and points its accessible label at the matching tab. Low-level
1300
+ * attributes; for the typed JSX wrapper use `TabPanel` (inside `Tabs`) from
1301
+ * `@antadesign/anta`.
1274
1302
  */
1275
1303
  export interface ATabpanelAttributes extends BaseAttributes {
1276
1304
  /** Pairs the panel with the tab of the same value. The element reads its
@@ -65,6 +65,9 @@ export async function generate({ input, output = '.', name = 'a-icon.shapes', in
65
65
  const cssLines = [
66
66
  '/* Auto-generated by @antadesign/anta. Do not edit by hand. */',
67
67
  '',
68
+ '@layer base, anta, components, utilities;',
69
+ '@layer anta.reset, anta.components, anta.theme;',
70
+ '',
68
71
  '@layer anta.components {',
69
72
  '',
70
73
  ]
package/dist/index.d.ts CHANGED
@@ -30,8 +30,11 @@ export { Box } from './components/Box';
30
30
  export type { BoxProps } from './components/Box';
31
31
  export { Capture } from './components/Capture';
32
32
  export type { CaptureProps } from './components/Capture';
33
+ export { Panel } from './components/Panel';
34
+ export type { PanelProps } from './components/Panel';
35
+ export type { PanelState } from './general_types';
33
36
  export type { CaptureInputCancelReason, CaptureInputDirection, CaptureInputDirections, CaptureInputGeometry, CaptureInputModifier, CapturePan, CapturePanInertia, CapturePanInput, CapturePointerActivationReason, CapturePointerCapture, CapturePointerInput, CapturePointerStart, CapturePointerType, CaptureWheelActivation, CaptureWheelActivationReason, CaptureWheelInput, CaptureWheelSettle, SerializedMouseEvent, SerializedPointerEvent, SerializedWheelEvent, } from './capture-types';
34
- export type { BoxChange, BoxContext, BoxContextChange, BoxDisplay, BoxFont, BoxInset, BoxMeasurement, BoxMeasurementChange, BoxMode, BoxOS, BoxBrowser, BoxPointer, } from './box-types';
37
+ export type { BoxChange, BoxContext, BoxContextChange, BoxDisplay, BoxFont, BoxInset, BoxMeasurement, BoxMeasurementChange, BoxObservation, BoxMode, BoxOS, BoxBrowser, BoxPointer, } from './box-types';
35
38
  export { Title } from './components/Title';
36
39
  export type { TitleProps } from './components/Title';
37
40
  export { Tag } from './components/Tag';
@@ -98,7 +101,7 @@ export { Banner } from './components/Banner';
98
101
  export type { BannerProps } from './components/Banner';
99
102
  export { Toaster, createToaster } from './components/Toaster';
100
103
  export type { ToasterProps, ToasterManager, ToastOptions, ToastPlacement, ToastContent, ToastRender, } from './components/Toaster';
101
- export type { BaseProps, BaseAttributes } from './general_types';
104
+ export type { BaseProps, BaseAttributes, ToneScope } from './general_types';
102
105
  export { configure } from './jsx-runtime';
103
106
  export type { AntaIntrinsicElements } from './jsx-runtime';
104
107
  /**
package/dist/index.js CHANGED
@@ -17,6 +17,7 @@ import { Loader } from "./components/Loader";
17
17
  import { Text } from "./components/Text";
18
18
  import { Box } from "./components/Box";
19
19
  import { Capture } from "./components/Capture";
20
+ import { Panel } from "./components/Panel";
20
21
  import { Title } from "./components/Title";
21
22
  import { Tag } from "./components/Tag";
22
23
  import { Icon } from "./components/Icon";
@@ -93,6 +94,7 @@ export {
93
94
  MenuItem,
94
95
  MenuItemCopy,
95
96
  MenuSeparator,
97
+ Panel,
96
98
  Progress,
97
99
  RadioGroup,
98
100
  Select,
@@ -44,7 +44,7 @@ export declare function useSyncExternalStore<T>(subscribe: (onChange: () => void
44
44
  export declare function jsx(type: ComponentType, props: Record<string, unknown> | null, key?: string | number): unknown;
45
45
  export declare function jsxs(type: ComponentType, props: Record<string, unknown> | null, key?: string | number): unknown;
46
46
  export { _Fragment as Fragment };
47
- import type { AAvatarAttributes, AProgressAttributes, ALoaderAttributes, ATextAttributes, ABoxAttributes, ACaptureAttributes, ATitleAttributes, ATagAttributes, AExpanderAttributes, AIconAttributes, AButtonAttributes, ACopyAttributes, ACheckboxAttributes, ASwitchAttributes, ATooltipAttributes, AInputAttributes, ASliderAttributes, AInputTimeAttributes, ACalendarAttributes, ARadioAttributes, ARadioGroupAttributes, AMenuAttributes, AMenuItemAttributes, AMenuGroupAttributes, ATabsAttributes, ATabAttributes, ATabpanelAttributes, ADialogAttributes, ACardAttributes, ABannerAttributes, AToasterAttributes, AToastAttributes, BaseAttributes } from './general_types';
47
+ import type { AAvatarAttributes, AProgressAttributes, ALoaderAttributes, ATextAttributes, ABoxAttributes, ACaptureAttributes, APanelAttributes, ATitleAttributes, ATagAttributes, AExpanderAttributes, AIconAttributes, AButtonAttributes, ACopyAttributes, ACheckboxAttributes, ASwitchAttributes, ATooltipAttributes, AInputAttributes, ASliderAttributes, AInputTimeAttributes, ACalendarAttributes, ARadioAttributes, ARadioGroupAttributes, AMenuAttributes, AMenuItemAttributes, AMenuGroupAttributes, ATabsAttributes, ATabAttributes, ATabpanelAttributes, ADialogAttributes, ACardAttributes, ABannerAttributes, AToasterAttributes, AToastAttributes, BaseAttributes } from './general_types';
48
48
  export declare namespace JSX {
49
49
  interface IntrinsicElements extends React.JSX.IntrinsicElements, AntaIntrinsicElements {
50
50
  }
@@ -62,6 +62,7 @@ export interface AntaIntrinsicElements {
62
62
  'a-text': ATextAttributes;
63
63
  'a-box': ABoxAttributes;
64
64
  'a-capture': ACaptureAttributes;
65
+ 'a-panel': APanelAttributes;
65
66
  'a-title': ATitleAttributes;
66
67
  'a-tag': ATagAttributes;
67
68
  'a-tag-label': BaseAttributes;
@@ -101,6 +102,14 @@ export interface AntaIntrinsicElements {
101
102
  'a-menu-separator': BaseAttributes;
102
103
  'a-menu-header': BaseAttributes;
103
104
  'a-menu-footer': BaseAttributes;
105
+ 'a-select-field': BaseAttributes & {
106
+ size?: string;
107
+ status?: string;
108
+ disabled?: boolean | '';
109
+ };
110
+ 'a-select-label': BaseAttributes;
111
+ 'a-select-hint': BaseAttributes;
112
+ 'a-select-leading': BaseAttributes;
104
113
  'a-select-header': BaseAttributes;
105
114
  'a-select-footer': BaseAttributes;
106
115
  'a-select-chevron': BaseAttributes & {