@antadesign/anta 0.3.2 → 0.3.4

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 (96) hide show
  1. package/dist/anta_helpers.d.ts +97 -0
  2. package/dist/anta_helpers.js +70 -0
  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 +5 -2
  7. package/dist/components/Calendar.d.ts +85 -0
  8. package/dist/components/Calendar.js +226 -0
  9. package/dist/components/Checkbox.d.ts +16 -11
  10. package/dist/components/Checkbox.js +13 -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 +13 -5
  14. package/dist/components/Input.js +14 -6
  15. package/dist/components/InputDate.d.ts +89 -0
  16. package/dist/components/InputDate.js +273 -0
  17. package/dist/components/InputDate.module.css +1 -0
  18. package/dist/components/Menu.d.ts +14 -1
  19. package/dist/components/Menu.js +6 -2
  20. package/dist/components/MenuItem.d.ts +48 -7
  21. package/dist/components/MenuItem.js +72 -14
  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 +12 -10
  27. package/dist/components/RadioGroup.js +5 -5
  28. package/dist/components/Select.d.ts +319 -0
  29. package/dist/components/Select.js +341 -0
  30. package/dist/components/Select.module.css +1 -0
  31. package/dist/components/Tab.d.ts +3 -0
  32. package/dist/components/Tab.js +2 -1
  33. package/dist/components/TabPanel.d.ts +21 -13
  34. package/dist/components/TabPanel.js +13 -1
  35. package/dist/components/Tabs.d.ts +75 -40
  36. package/dist/components/Tabs.js +20 -88
  37. package/dist/components/Tag.d.ts +10 -9
  38. package/dist/components/Tag.js +2 -2
  39. package/dist/components/Text.d.ts +6 -5
  40. package/dist/components/Title.d.ts +4 -2
  41. package/dist/components/Tooltip.d.ts +4 -1
  42. package/dist/components/Tooltip.js +5 -0
  43. package/dist/elements/a-button.css +1 -1
  44. package/dist/elements/a-calendar.css +1 -0
  45. package/dist/elements/a-calendar.d.ts +76 -0
  46. package/dist/elements/a-calendar.js +190 -0
  47. package/dist/elements/a-checkbox.css +1 -1
  48. package/dist/elements/a-checkbox.d.ts +1 -2
  49. package/dist/elements/a-checkbox.js +5 -5
  50. package/dist/elements/a-expander.css +1 -1
  51. package/dist/elements/a-expander.d.ts +16 -5
  52. package/dist/elements/a-expander.js +59 -8
  53. package/dist/elements/a-icon.shapes.css +1 -1
  54. package/dist/elements/a-icon.shapes.d.ts +6 -1
  55. package/dist/elements/a-icon.shapes.js +9 -0
  56. package/dist/elements/a-input.css +1 -1
  57. package/dist/elements/a-input.d.ts +6 -0
  58. package/dist/elements/a-input.js +28 -8
  59. package/dist/elements/a-menu-group.css +1 -1
  60. package/dist/elements/a-menu-item.css +1 -1
  61. package/dist/elements/a-menu-item.d.ts +22 -10
  62. package/dist/elements/a-menu-item.js +17 -0
  63. package/dist/elements/a-menu-separator.css +1 -1
  64. package/dist/elements/a-menu.css +1 -1
  65. package/dist/elements/a-menu.d.ts +61 -20
  66. package/dist/elements/a-menu.js +337 -58
  67. package/dist/elements/a-progress.css +1 -1
  68. package/dist/elements/a-radio-group.d.ts +1 -3
  69. package/dist/elements/a-radio-group.js +13 -13
  70. package/dist/elements/a-radio.css +1 -1
  71. package/dist/elements/a-radio.d.ts +3 -11
  72. package/dist/elements/a-radio.js +3 -34
  73. package/dist/elements/a-tab.css +1 -1
  74. package/dist/elements/a-tab.d.ts +3 -11
  75. package/dist/elements/a-tab.js +3 -34
  76. package/dist/elements/a-tabpanel.css +1 -1
  77. package/dist/elements/a-tabpanel.d.ts +17 -0
  78. package/dist/elements/a-tabpanel.js +66 -0
  79. package/dist/elements/a-tabs.css +1 -1
  80. package/dist/elements/a-tabs.d.ts +1 -4
  81. package/dist/elements/a-tabs.js +14 -14
  82. package/dist/elements/a-tag.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-tooltip.css +1 -1
  86. package/dist/elements/a-tooltip.d.ts +1 -11
  87. package/dist/elements/a-tooltip.js +20 -19
  88. package/dist/elements/index.d.ts +2 -1
  89. package/dist/elements/index.js +6 -1
  90. package/dist/general_types.d.ts +158 -42
  91. package/dist/index.d.ts +10 -4
  92. package/dist/index.js +38 -3
  93. package/dist/jsx-runtime.d.ts +16 -7
  94. package/dist/jsx-runtime.js +6 -0
  95. package/dist/reset.css +1 -1
  96. package/package.json +4 -2
@@ -16,12 +16,14 @@ declare global {
16
16
  * Enter / Space on a focused item synthesizes a click (the single
17
17
  * activation path that flows through the menu's click delegation).
18
18
  *
19
- * Static ARIA (`role="menuitem"`, `tabindex`, `aria-haspopup` and the
20
- * `aria-expanded="false"` baseline on submenu parents) is added by the
21
- * `MenuItem` JSX wrapper, never here the element must stay re-renderable
22
- * from any reactive engine without churning host attributes. The one dynamic
23
- * bit, live `aria-expanded` on a submenu parent, is reflected by the nested
24
- * `a-menu` element, which owns that state (see `reflectExpanded` there).
19
+ * ARIA (`role="menuitem"`, `tabindex`, `aria-haspopup` on submenu parents) is
20
+ * added by the `MenuItem` JSX wrapper, never here the element must stay
21
+ * re-renderable from any reactive engine, and a web component must not mutate
22
+ * light DOM (it would desync the worker-thread reactive model that owns the
23
+ * light tree). So submenu open state is NOT written to the parent's attributes
24
+ * (no `aria-expanded`): the nested `a-menu` carries its own off-DOM
25
+ * `:state(open)`, and the parent styles its open branch purely in CSS
26
+ * (`a-menu-item:has(> a-menu:state(open))`, see `reflectOpen` there).
25
27
  *
26
28
  * Styling notes (`a-menu-item.css` ships comment-free):
27
29
  * - `a-menu-item:not(:defined)` is hidden against the pre-upgrade flash
@@ -36,12 +38,22 @@ declare global {
36
38
  * surface's 4px padding; pairs with the hover background so keyboard focus
37
39
  * reads as tint + ring.
38
40
  * - Optical side padding (same idea as a-button): a non-only icon at an edge
39
- * is trimmed ~2px on that side. Submenu items keep symmetric padding —
40
- * the nested `<a-menu>` is the actual last child, so the trim rule doesn't
41
- * fire and the chevron / a trailing icon is instead nudged toward the
42
- * edge with relative positioning (visual only, no reflow).
41
+ * is trimmed ~2px on that side. Submenu items keep symmetric padding — the
42
+ * end-trim is scoped `:not([submenu])` and the chevron / a trailing icon is
43
+ * instead nudged toward the edge with relative positioning (visual only, no
44
+ * reflow). The trim's `:not([submenu])` guard is why children (which include a
45
+ * submenu's nested `<a-menu>`) can render before the chevron without the
46
+ * chevron-as-last-child re-triggering the trim.
43
47
  */
44
48
  export declare class AMenuItemElement extends HTMLElementBase {
49
+ private internals?;
50
+ constructor();
51
+ /** The active (combobox) cursor. `a-menu` sets this **property** (never an
52
+ * attribute — no DOM mutation, same rule as `a-radio.selected`) as ArrowUp/Down
53
+ * move the cursor while focus stays in the filter input; the item mirrors it to
54
+ * `:state(active)` for CSS. Off-DOM, so a reactive re-render never churns it. */
55
+ set active(on: boolean);
56
+ get active(): boolean;
45
57
  connectedCallback(): void;
46
58
  }
47
59
  export declare function register_a_menu_item(): void;
@@ -1,6 +1,23 @@
1
1
  import { HTMLElementBase } from "../anta_helpers";
2
2
  import "./a-menu-item.css";
3
3
  class AMenuItemElement extends HTMLElementBase {
4
+ internals;
5
+ constructor() {
6
+ super();
7
+ this.internals = this.attachInternals?.();
8
+ }
9
+ /** The active (combobox) cursor. `a-menu` sets this **property** (never an
10
+ * attribute — no DOM mutation, same rule as `a-radio.selected`) as ArrowUp/Down
11
+ * move the cursor while focus stays in the filter input; the item mirrors it to
12
+ * `:state(active)` for CSS. Off-DOM, so a reactive re-render never churns it. */
13
+ set active(on) {
14
+ if (!this.internals) return;
15
+ if (on) this.internals.states.add("active");
16
+ else this.internals.states.delete("active");
17
+ }
18
+ get active() {
19
+ return this.internals?.states.has("active") ?? false;
20
+ }
4
21
  connectedCallback() {
5
22
  const doc = this.doc;
6
23
  if (!doc.hasKeyListenerForAMenuItem) {
@@ -1 +1 @@
1
- @layer anta{a-menu-separator:not(:defined){display:none}a-menu-separator{display:block;flex-shrink:0;height:1px;margin:2px 4px;background:var(--border-5)}}
1
+ @layer anta{a-menu-separator:not(:defined){display:none}a-menu-separator{--menu-separator-label-size: 13px;display:block;flex-shrink:0;height:1px;margin:2px 4px;background:var(--border-5)}a-menu-separator:not(:empty){height:auto;margin:0;padding:6px 8px;background:none;color:var(--text-3);font-size:var(--menu-separator-label-size);line-height:1.3;user-select:none}}
@@ -1 +1 @@
1
- @layer anta{a-menu:not(:defined){display:none}a-menu{--menu-bg: color-mix(in oklch, var(--bg-1) 90%, transparent);--menu-radius: var(--radius-md, 8px);--menu-border: 1px solid var(--border-3);--menu-shadow: 0 2px 6px color-mix(in oklch, var(--text-1) 8%, transparent), 0 8px 24px color-mix(in oklch, var(--text-1) 10%, transparent);--menu-padding: 4px;--menu-min-width: 88px;--menu-backdrop-filter: blur(20px)}.dark a-menu{--menu-bg: color-mix(in oklch, var(--bg-1) 78%, transparent);--menu-shadow: 0 2px 8px color-mix(in oklch, black 50%, transparent), 0 12px 32px color-mix(in oklch, black 40%, transparent), inset 0 0 0 1px color-mix(in oklch, white 8%, transparent)}}
1
+ @layer anta{a-menu:not(:defined){display:none}a-menu{--menu-bg: color-mix(in oklch, var(--bg-1) 90%, transparent);--menu-radius: var(--radius-md, 8px);--menu-border: 1px solid var(--border-3);--menu-shadow: 0 2px 6px color-mix(in oklch, var(--text-1) 8%, transparent), 0 8px 24px color-mix(in oklch, var(--text-1) 10%, transparent);--menu-padding: 4px;--menu-min-width: 88px;--menu-backdrop-filter: blur(20px)}a-menu[round]{--menu-radius: attr(round type(<length>), 20px)}.dark a-menu{--menu-bg: color-mix(in oklch, var(--bg-1) 78%, transparent);--menu-shadow: 0 2px 8px color-mix(in oklch, black 50%, transparent), 0 12px 32px color-mix(in oklch, black 40%, transparent), inset 0 0 0 1px color-mix(in oklch, white 8%, transparent)}}
@@ -22,9 +22,12 @@ type MenuState = 'open' | 'closed';
22
22
  * slotted light DOM (see `a-menu-item.css`), directly styleable.
23
23
  */
24
24
  export declare class AMenuElement extends HTMLElementBase {
25
+ #private;
25
26
  static observedAttributes: string[];
26
27
  /** Shadow-internal popover surface — the only thing we ever mutate. */
27
28
  surface: HTMLDivElement;
29
+ /** The scrolling body inside the surface (holds the items). */
30
+ private scrollEl;
28
31
  listening: boolean;
29
32
  private _shown;
30
33
  private teardown?;
@@ -32,10 +35,14 @@ export declare class AMenuElement extends HTMLElementBase {
32
35
  * but stays visible until the consumer flips `state`. The flag lets the
33
36
  * `closeAll` backstop skip a duplicate emit. Cleared on every show. */
34
37
  _dismissNotified: boolean;
38
+ private internals?;
35
39
  private openTimer?;
36
40
  private closeTimer?;
37
41
  private typeBuffer;
38
42
  private typeTimer?;
43
+ private activeItem;
44
+ private comboObserver?;
45
+ private _flippedTop;
39
46
  constructor();
40
47
  connectedCallback(): void;
41
48
  disconnectedCallback(): void;
@@ -48,16 +55,13 @@ export declare class AMenuElement extends HTMLElementBase {
48
55
  /** A submenu is an `<a-menu>` nested inside an `<a-menu-item>` — derived from
49
56
  * structure, no `submenu` attribute needed (the parent item is the anchor). */
50
57
  get isSubmenu(): boolean;
51
- private get isContext();
52
- private get isCoord();
53
- private get isHover();
54
- private get offset();
55
- private get placement();
56
58
  /** Root menu: the previous element sibling is the trigger. Submenu: the
57
59
  * enclosing menu item. One deterministic rule per case — no ambiguity. */
58
60
  get triggerAnchor(): HTMLElement | null;
59
- /** For a submenu: the menu that contains its anchor item. */
60
- private get ownerMenu();
61
+ /** Return focus to the trigger. Focuses the first focusable in the anchor; if
62
+ * there is none (a mis-authored trigger — e.g. `renderTrigger` returning a
63
+ * fragment or a non-focusable node), warns instead of silently focusing air. */
64
+ private focusTrigger;
61
65
  get isOpen(): boolean;
62
66
  /** Skip elements that can't actually take focus — `display:none` (incl. a
63
67
  * closed submenu's contents), `visibility:hidden`, `content-visibility`
@@ -74,7 +78,41 @@ export declare class AMenuElement extends HTMLElementBase {
74
78
  * used to trap Tab within the open menu. Submenu contents are excluded
75
79
  * (their nearest `a-menu` is the submenu). */
76
80
  private focusables;
77
- private focusFirstItem;
81
+ /** On open, seat initial focus like a native `<select>` / macOS menu: a menu
82
+ * carrying a current value opens *at* that value, not at the top. Brings the
83
+ * first selected row into view and, when opened via keyboard, focuses it;
84
+ * with no selected row it focuses the first item (keyboard) and does nothing
85
+ * otherwise. "Selected" = a `selected` row (tint) or `aria-checked` /
86
+ * `aria-selected="true"` (checkable rows) — the first such visible item of
87
+ * THIS menu, so a leaf buried in a closed submenu (not visible) is skipped and
88
+ * a multi-select lands on its topmost checked row. */
89
+ private seatInitialFocus;
90
+ /** Scroll THIS menu's body so `item` sits inside the visible scroll viewport,
91
+ * touching only the internal `.scroll` container — never the document, whose
92
+ * scroll would trip the anchor-scrolled-out dismiss. No-op for a menu short
93
+ * enough not to scroll. */
94
+ private scrollItemIntoView;
95
+ /** Fade the scrolling body's content into the top / bottom edges — but only on the
96
+ * side that actually has more to scroll, so a short (non-scrolling) menu and the
97
+ * true top / bottom stay crisp. Drives the `--fade-*` / `--gap-top` vars the
98
+ * `.scroll` mask reads; runs on scroll and after every (re)position.
99
+ * Shadow-internal only. */
100
+ private updateScrollFade;
101
+ /** Move the combobox cursor. Sets the item's `active` **property** (off-DOM
102
+ * `:state(active)`, no attribute churn) for the highlight, and REPORTS the
103
+ * active id via the `activedescendant` event so the reactive layer can set
104
+ * `aria-activedescendant` on the light-DOM field. `null` clears the cursor. */
105
+ private setActive;
106
+ /** Re-seat the cursor on the first option — but only once the filter has input.
107
+ * An empty filter (e.g. right after opening) shows NO active row, so the first
108
+ * ArrowDown is what steps onto the list; typing then keeps the top match active.
109
+ * Rows marked `data-menu-skip-active` (e.g. a Select-all action) are skipped as
110
+ * the seat target — the cursor lands on the first real option — but they stay
111
+ * arrow-reachable. */
112
+ private resetActive;
113
+ /** Combobox arrow / Home / End / Enter handling; returns true if it consumed the
114
+ * key (so `handleKey` stops). Any other key falls through to the input (typing). */
115
+ private handleComboKey;
78
116
  /** Public imperative API. Routes through the same intent path as the
79
117
  * triggers, so it emits `statechange` and respects controlled mode. */
80
118
  open(opts?: {
@@ -109,6 +147,12 @@ export declare class AMenuElement extends HTMLElementBase {
109
147
  /** Apply OPEN to the DOM (no event) — used by uncontrolled intent and by the
110
148
  * controlled `state` sync. */
111
149
  private show;
150
+ /** While a filter field is open, the visible option list changes as the user
151
+ * types (the consumer re-renders the matches); re-seat the cursor on the first
152
+ * match. `childList` only — an item toggling its own `selected` (multi-select)
153
+ * mutates deep in its subtree, not this menu's direct children, so it won't
154
+ * spuriously reset the cursor. */
155
+ private startComboObserver;
112
156
  /** Watch the root trigger and dismiss the system once it scrolls out of the
113
157
  * spot it held at open (see trackPosition). Deferred a frame so the trigger's
114
158
  * post-open layout has settled before the rect is snapshotted; guarded in case
@@ -132,18 +176,15 @@ export declare class AMenuElement extends HTMLElementBase {
132
176
  private hideAnchorTooltip;
133
177
  /** Shadow-only hide. */
134
178
  _doHide(): void;
135
- /** Mirror the open state onto a SUBMENU parent's `aria-expanded`. This is the
136
- * one sanctioned light-DOM ARIA mutation (like `el.focus()`): the anchor is
137
- * an `<a-menu-item>` the `MenuItem` wrapper renders WITH a resting
138
- * `aria-expanded="false"` baseline, so a reactive re-render resets it to a
139
- * valid value and the next open/close re-syncs.
140
- *
141
- * A ROOT menu's trigger is a consumer-owned sibling we don't render and have
142
- * no baseline forwriting to it would mutate foreign DOM (and couldn't
143
- * self-heal), so we leave its `aria-expanded` to the consumer. The menu is
144
- * still announced and Esc-dismissable; consumers add `aria-haspopup="menu"`
145
- * to their trigger themselves. (`context` menus aren't triggers either.) */
146
- private reflectExpanded;
179
+ /** Expose the menu's OWN open state as an off-DOM custom state (`:state(open)`),
180
+ * never a light-DOM attribute. A web component must not mutate light DOM — it
181
+ * desyncs the worker-thread reactive model, which owns the light tree. A
182
+ * submenu parent lights its open branch purely in CSS via
183
+ * `a-menu-item:has(> a-menu:state(open))`; the state is element-owned (like
184
+ * `a-menu-item`'s `:state(active)`) and, being off-DOM, survives a reactive
185
+ * re-render without the element ever writing an attribute. Set on every menu
186
+ * (harmless on rootsno `a-menu-item` parent matches the selector). */
187
+ private reflectOpen;
147
188
  private position;
148
189
  /**
149
190
  * Fully declarative close contract — decided synchronously from the DOM, so