@antadesign/anta 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/dist/anta_helpers.d.ts +101 -0
  2. package/dist/anta_helpers.js +77 -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 +80 -0
  8. package/dist/components/Calendar.js +220 -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 +87 -0
  16. package/dist/components/InputDate.js +278 -0
  17. package/dist/components/InputDate.module.css +1 -0
  18. package/dist/components/Menu.d.ts +5 -1
  19. package/dist/components/Menu.js +6 -2
  20. package/dist/components/MenuItem.d.ts +48 -7
  21. package/dist/components/MenuItem.js +71 -7
  22. package/dist/components/MenuSeparator.d.ts +13 -2
  23. package/dist/components/MenuSeparator.js +12 -2
  24. package/dist/components/Progress.d.ts +4 -1
  25. package/dist/components/Progress.js +4 -3
  26. package/dist/components/RadioGroup.d.ts +12 -10
  27. package/dist/components/RadioGroup.js +5 -5
  28. package/dist/components/Select.d.ts +255 -0
  29. package/dist/components/Select.js +290 -0
  30. package/dist/components/Select.module.css +1 -0
  31. package/dist/components/Tab.d.ts +3 -0
  32. package/dist/components/Tab.js +2 -1
  33. package/dist/components/TabPanel.js +2 -1
  34. package/dist/components/Tabs.d.ts +18 -1
  35. package/dist/components/Tabs.js +8 -6
  36. package/dist/components/Tag.d.ts +10 -9
  37. package/dist/components/Tag.js +2 -2
  38. package/dist/components/Text.d.ts +6 -5
  39. package/dist/components/Title.d.ts +4 -2
  40. package/dist/components/Tooltip.d.ts +4 -1
  41. package/dist/components/Tooltip.js +5 -0
  42. package/dist/elements/a-button.css +1 -1
  43. package/dist/elements/a-calendar.css +1 -0
  44. package/dist/elements/a-calendar.d.ts +76 -0
  45. package/dist/elements/a-calendar.js +190 -0
  46. package/dist/elements/a-checkbox.css +1 -1
  47. package/dist/elements/a-checkbox.d.ts +1 -2
  48. package/dist/elements/a-checkbox.js +5 -5
  49. package/dist/elements/a-expander.css +1 -1
  50. package/dist/elements/a-expander.d.ts +16 -5
  51. package/dist/elements/a-expander.js +59 -8
  52. package/dist/elements/a-icon.shapes.css +1 -1
  53. package/dist/elements/a-icon.shapes.d.ts +6 -1
  54. package/dist/elements/a-icon.shapes.js +9 -0
  55. package/dist/elements/a-input.css +1 -1
  56. package/dist/elements/a-input.d.ts +6 -0
  57. package/dist/elements/a-input.js +27 -8
  58. package/dist/elements/a-menu-group.css +1 -1
  59. package/dist/elements/a-menu-item.css +1 -1
  60. package/dist/elements/a-menu-item.d.ts +14 -4
  61. package/dist/elements/a-menu-item.js +17 -0
  62. package/dist/elements/a-menu-separator.css +1 -1
  63. package/dist/elements/a-menu.css +1 -1
  64. package/dist/elements/a-menu.d.ts +51 -8
  65. package/dist/elements/a-menu.js +285 -42
  66. package/dist/elements/a-progress.css +1 -1
  67. package/dist/elements/a-radio-group.d.ts +1 -3
  68. package/dist/elements/a-radio-group.js +13 -13
  69. package/dist/elements/a-radio.css +1 -1
  70. package/dist/elements/a-radio.d.ts +3 -11
  71. package/dist/elements/a-radio.js +3 -34
  72. package/dist/elements/a-tab.css +1 -1
  73. package/dist/elements/a-tab.d.ts +3 -11
  74. package/dist/elements/a-tab.js +3 -34
  75. package/dist/elements/a-tabs.css +1 -1
  76. package/dist/elements/a-tabs.d.ts +1 -4
  77. package/dist/elements/a-tabs.js +14 -14
  78. package/dist/elements/a-tag.css +1 -1
  79. package/dist/elements/a-text.d.ts +14 -13
  80. package/dist/elements/a-text.js +53 -23
  81. package/dist/elements/a-tooltip.css +1 -1
  82. package/dist/elements/a-tooltip.d.ts +1 -11
  83. package/dist/elements/a-tooltip.js +20 -19
  84. package/dist/elements/index.d.ts +1 -0
  85. package/dist/elements/index.js +3 -0
  86. package/dist/general_types.d.ts +127 -31
  87. package/dist/index.d.ts +9 -1
  88. package/dist/index.js +37 -1
  89. package/dist/jsx-runtime.d.ts +16 -7
  90. package/dist/jsx-runtime.js +6 -0
  91. package/dist/reset.css +1 -1
  92. package/package.json +4 -2
@@ -0,0 +1 @@
1
+ @layer anta{.anta-calendar{--calendar-cell-width: 32px;--calendar-cell-height: 28px;display:inline-flex;flex-direction:column;gap:6px}.anta-calendar [data-part=header]{display:flex;align-items:center;gap:0}.anta-calendar [data-part=heading]{flex:1 1 auto;justify-content:center;white-space:nowrap}.anta-calendar .year-dot{flex:none;inline-size:6px;block-size:6px;border-radius:999px;background:currentColor}.anta-calendar[data-size=small]{--calendar-cell-width: 28px;--calendar-cell-height: 24px}.anta-calendar[data-size=large]{--calendar-cell-width: 36px;--calendar-cell-height: 32px}.anta-calendar[data-size=small] [data-part=weekday]{font-size:13px;line-height:16px}.anta-calendar[data-size=large] [data-part=weekday]{font-size:17px;line-height:24px}a-calendar{display:inline-grid;grid-template-columns:repeat(7,var(--calendar-cell-width, 32px));gap:1px;font-family:var(--sans-serif)}a-calendar [data-part=weekday]{display:flex;align-items:center;justify-content:center;height:24px;font-size:15px;line-height:20px;font-weight:400;color:var(--text-4);user-select:none}a-calendar [data-part=weekday][data-weekend]{color:var(--text-5)}a-calendar a-button[data-part=day-cell]{padding-inline:0;min-width:var(--calendar-cell-width, 32px);min-height:var(--calendar-cell-height, 28px);justify-content:center}a-calendar a-button[data-part=day-cell] a-button-label{padding-bottom:0}a-calendar a-button[data-part=day-cell]:focus-visible{outline-offset:0}a-calendar a-button[data-part=day-cell][data-today]:not([selected]){font-weight:600}a-calendar a-button[data-part=day-cell][data-outside]:not([selected]){opacity:.5}}
@@ -0,0 +1,76 @@
1
+ import { HTMLElementBase } from '../anta_helpers';
2
+ import './a-calendar.css';
3
+ /**
4
+ * `<a-calendar>` — a **light-DOM, form-associated** month grid, and the
5
+ * **interaction authority** for it. It is the grid itself (`a-calendar.css` gives
6
+ * it a flat 7-column CSS grid), owns the form value, and **dispatches the
7
+ * selection and navigation events** — so it works for a vanilla consumer, not
8
+ * only through the JSX wrapper.
9
+ *
10
+ * It does **not** build or mutate its own contents — that would break the
11
+ * no-UI-thread-DOM-mutation rule (app DOM may render off a worker). Whoever
12
+ * renders into it (the `Calendar` JSX wrapper, or a vanilla consumer using the
13
+ * exported `buildMonth` engine) fills it with `<a-button>` day cells + weekday
14
+ * headers and *re-renders* on the element's events. The element confines itself
15
+ * to off-DOM work (form value, `ElementInternals` state), event dispatch, and
16
+ * imperative focus of cells that already exist — the `<a-radio-group>` model.
17
+ *
18
+ * ## Events (all bubble; lowercase so React + Preact bind them)
19
+ *
20
+ * - `statechange` — cancelable, fired BEFORE a pick applies. `detail` is
21
+ * `{ next, prev, reason }`: ISO-string dates (or `null`), `reason` ∈
22
+ * `'user' | 'reset' | 'restore'`. `preventDefault()` vetoes a `'user'` pick in
23
+ * uncontrolled mode.
24
+ * - `change` — fired AFTER a selection applies (uncontrolled), and on
25
+ * reset/restore.
26
+ * - `navigate` — `detail: { date }` (ISO). Fired on keyboard navigation (and
27
+ * when the target month isn't rendered) so the renderer can move the roving tab
28
+ * stop and flip the displayed month.
29
+ *
30
+ * ## Controlled vs uncontrolled (like `<a-radio-group>`)
31
+ *
32
+ * Presence of the **`value`** attribute = controlled: a pick only *requests* a
33
+ * change (fires `statechange`); the consumer answers by updating `value`. With
34
+ * **`defaultvalue`** instead, the element owns selection — a pick self-applies
35
+ * (form value + `change`) unless vetoed.
36
+ *
37
+ * ## Selection & keyboard
38
+ *
39
+ * Day cells are `<a-button>`s, so a click (and Enter/Space, which `<a-button>`
40
+ * turns into a click) bubbles here; the element delegates off `data-part="day-cell"`.
41
+ * Arrow / Home / End / PageUp / PageDown move focus among rendered cells directly,
42
+ * and emit `navigate` for month changes. `data-focus` (`"<iso>#<nonce>"`, set by
43
+ * the renderer) focuses a cell after a re-render lands a new month.
44
+ */
45
+ export declare class ACalendarElement extends HTMLElementBase {
46
+ #private;
47
+ static formAssociated: boolean;
48
+ static observedAttributes: string[];
49
+ private internals?;
50
+ /** Selection in uncontrolled mode (controlled reads the `value` attribute). */
51
+ private selectedIso;
52
+ constructor();
53
+ connectedCallback(): void;
54
+ attributeChangedCallback(name: string, _old: string | null, value: string | null): void;
55
+ private currentIso;
56
+ private applyFormValue;
57
+ private onClick;
58
+ /** Request selecting `iso`: fire cancelable `statechange`; in uncontrolled mode,
59
+ * if not vetoed, apply the form value and fire `change`. The renderer mirrors
60
+ * the new selection visually off `statechange`. */
61
+ private requestSelect;
62
+ private onKeydown;
63
+ /** Focus the day cell whose `data-date` matches the signal's ISO. Deferred to a
64
+ * microtask so a just-rendered new month has committed. Signal: `"<iso>#<nonce>"`. */
65
+ private focusCell;
66
+ private emitState;
67
+ /** The selected date as an ISO string (`''` when empty). */
68
+ get value(): string;
69
+ set value(v: string);
70
+ /** Form field name — mirrors the `name` attribute, like native `<input>.name`. */
71
+ get name(): string;
72
+ set name(v: string);
73
+ formResetCallback(): void;
74
+ formStateRestoreCallback(state: string): void;
75
+ }
76
+ export declare function register_a_calendar(): void;
@@ -0,0 +1,190 @@
1
+ import { HTMLElementBase } from "../anta_helpers";
2
+ import { Temporal } from "temporal-polyfill";
3
+ import "./a-calendar.css";
4
+ class ACalendarElement extends HTMLElementBase {
5
+ static formAssociated = true;
6
+ static observedAttributes = ["value", "data-focus"];
7
+ internals;
8
+ /** Selection in uncontrolled mode (controlled reads the `value` attribute). */
9
+ selectedIso = null;
10
+ constructor() {
11
+ super();
12
+ try {
13
+ this.internals = this.attachInternals?.();
14
+ } catch (err) {
15
+ console.warn("a-calendar: ElementInternals unavailable \u2014 form association disabled.", err);
16
+ }
17
+ this.addEventListener("click", this.onClick);
18
+ this.addEventListener("keydown", this.onKeydown);
19
+ }
20
+ connectedCallback() {
21
+ if (Object.prototype.hasOwnProperty.call(this, "value")) {
22
+ const v = this.value;
23
+ delete this.value;
24
+ this.value = v;
25
+ }
26
+ this.selectedIso = this.getAttribute("value") || this.getAttribute("defaultvalue") || null;
27
+ this.applyFormValue(this.currentIso());
28
+ }
29
+ attributeChangedCallback(name, _old, value) {
30
+ if (name === "value") {
31
+ this.applyFormValue(value);
32
+ return;
33
+ }
34
+ if (name === "data-focus") {
35
+ this.focusCell(value);
36
+ }
37
+ }
38
+ /** Controlled when the `value` attribute is present (the renderer sets it only
39
+ * in controlled mode); otherwise the element owns selection. */
40
+ get #controlled() {
41
+ return this.hasAttribute("value");
42
+ }
43
+ currentIso() {
44
+ return this.#controlled ? this.getAttribute("value") || null : this.selectedIso;
45
+ }
46
+ applyFormValue(value) {
47
+ this.internals?.setFormValue(value || null);
48
+ try {
49
+ if (value) this.internals?.states.add("filled");
50
+ else this.internals?.states.delete("filled");
51
+ } catch {
52
+ }
53
+ }
54
+ // --- Selection ----------------------------------------------------------
55
+ onClick = (e) => {
56
+ if (this.hasAttribute("disabled")) return;
57
+ const cell = e.target?.closest('[data-part="day-cell"]');
58
+ if (!cell || cell.hasAttribute("disabled")) return;
59
+ const iso = cell.dataset.date;
60
+ if (iso) this.requestSelect(iso);
61
+ };
62
+ /** Request selecting `iso`: fire cancelable `statechange`; in uncontrolled mode,
63
+ * if not vetoed, apply the form value and fire `change`. The renderer mirrors
64
+ * the new selection visually off `statechange`. */
65
+ requestSelect(iso) {
66
+ const prev = this.currentIso();
67
+ if (iso === prev) return;
68
+ const proceed = this.dispatchEvent(
69
+ new CustomEvent("statechange", {
70
+ bubbles: false,
71
+ cancelable: true,
72
+ detail: { next: iso, prev, reason: "user" }
73
+ })
74
+ );
75
+ if (this.#controlled || !proceed) return;
76
+ this.selectedIso = iso;
77
+ this.applyFormValue(iso);
78
+ this.dispatchEvent(new Event("change", { bubbles: true }));
79
+ }
80
+ // --- Keyboard navigation ------------------------------------------------
81
+ get #dayCells() {
82
+ return Array.from(this.querySelectorAll('[data-part="day-cell"]'));
83
+ }
84
+ onKeydown = (e) => {
85
+ if (this.hasAttribute("disabled")) return;
86
+ const cells = this.#dayCells;
87
+ if (cells.length === 0) return;
88
+ const focused = e.target?.closest('[data-part="day-cell"]') ?? cells.find((c) => c.tabIndex === 0) ?? null;
89
+ if (!focused?.dataset.date) return;
90
+ let targetIso = null;
91
+ switch (e.key) {
92
+ case "Home":
93
+ case "End": {
94
+ const idx = cells.indexOf(focused);
95
+ if (idx < 0) return;
96
+ const rowStart = idx - idx % 7;
97
+ targetIso = cells[e.key === "Home" ? rowStart : rowStart + 6]?.dataset.date ?? null;
98
+ break;
99
+ }
100
+ default: {
101
+ const cur = Temporal.PlainDate.from(focused.dataset.date);
102
+ let next;
103
+ switch (e.key) {
104
+ case "ArrowLeft":
105
+ next = cur.subtract({ days: 1 });
106
+ break;
107
+ case "ArrowRight":
108
+ next = cur.add({ days: 1 });
109
+ break;
110
+ case "ArrowUp":
111
+ next = cur.subtract({ days: 7 });
112
+ break;
113
+ case "ArrowDown":
114
+ next = cur.add({ days: 7 });
115
+ break;
116
+ case "PageUp":
117
+ next = cur.add({ [e.shiftKey ? "years" : "months"]: -1 });
118
+ break;
119
+ case "PageDown":
120
+ next = cur.add({ [e.shiftKey ? "years" : "months"]: 1 });
121
+ break;
122
+ default:
123
+ return;
124
+ }
125
+ targetIso = next.toString();
126
+ }
127
+ }
128
+ if (!targetIso) return;
129
+ e.preventDefault();
130
+ const cell = cells.find((c) => c.dataset.date === targetIso);
131
+ if (cell && !cell.hasAttribute("disabled")) cell.focus();
132
+ this.dispatchEvent(new CustomEvent("navigate", { bubbles: true, detail: { date: targetIso } }));
133
+ };
134
+ // --- Focus signal -------------------------------------------------------
135
+ /** Focus the day cell whose `data-date` matches the signal's ISO. Deferred to a
136
+ * microtask so a just-rendered new month has committed. Signal: `"<iso>#<nonce>"`. */
137
+ focusCell(signal) {
138
+ if (!signal) return;
139
+ const iso = signal.split("#")[0];
140
+ queueMicrotask(() => {
141
+ this.querySelector(`[data-date="${iso}"]`)?.focus();
142
+ });
143
+ }
144
+ // --- Public value API + form callbacks ----------------------------------
145
+ emitState(next, prev, reason) {
146
+ this.dispatchEvent(
147
+ new CustomEvent("statechange", { bubbles: false, detail: { next, prev, reason } })
148
+ );
149
+ this.dispatchEvent(new Event("change", { bubbles: true }));
150
+ }
151
+ /** The selected date as an ISO string (`''` when empty). */
152
+ get value() {
153
+ return this.currentIso() ?? "";
154
+ }
155
+ set value(v) {
156
+ this.selectedIso = v || null;
157
+ this.applyFormValue(v || null);
158
+ }
159
+ /** Form field name — mirrors the `name` attribute, like native `<input>.name`. */
160
+ get name() {
161
+ return this.getAttribute("name") ?? "";
162
+ }
163
+ set name(v) {
164
+ this.setAttribute("name", v);
165
+ }
166
+ formResetCallback() {
167
+ const def = this.getAttribute("defaultvalue") || null;
168
+ const prev = this.currentIso();
169
+ this.selectedIso = def;
170
+ this.applyFormValue(def);
171
+ this.emitState(def, prev, "reset");
172
+ }
173
+ formStateRestoreCallback(state) {
174
+ const prev = this.currentIso();
175
+ this.selectedIso = state || null;
176
+ this.applyFormValue(state || null);
177
+ this.emitState(state || null, prev, "restore");
178
+ }
179
+ }
180
+ function register_a_calendar() {
181
+ if (typeof customElements === "undefined") return;
182
+ if (!customElements.get("a-calendar")) {
183
+ customElements.define("a-calendar", ACalendarElement);
184
+ }
185
+ }
186
+ register_a_calendar();
187
+ export {
188
+ ACalendarElement,
189
+ register_a_calendar
190
+ };
@@ -1 +1 @@
1
- @layer anta{a-checkbox{--checkbox-gap: 8px;--checkbox-bg: var(--bg-1);--checkbox-fill: #635b65;--checkbox-fill-hover: #534c57;--checkbox-fill-active: #49424c;--checkbox-border-neutral: #d4ced4;--checkbox-border: var(--checkbox-border-neutral);--checkbox-border-hover: #c1b9c1;--checkbox-border-active: #9f99a1;--checkbox-icon: #ffffff;--checkbox-icon-disabled: #c1b9c1;--checkbox-bg-disabled: color-mix(in oklch, #44374b 10%, transparent);--checkbox-border-disabled: color-mix(in oklch, #44374b 15%, transparent);--checkbox-mask-size: 12px;--checkbox-mask-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");--checkbox-mask-indeterminate: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E");--checkbox-label-color: var(--text-2);--checkbox-label-color-disabled: var(--text-4);--checkbox-hint-color: var(--text-4);--checkbox-label-fs: 15px;--checkbox-label-lh: 20px;--checkbox-hint-fs: 13px;--checkbox-hint-lh: 16px;display:inline-grid;grid-template-columns:auto 1fr;align-items:center;column-gap:var(--checkbox-gap);vertical-align:middle;cursor:pointer;user-select:none;-webkit-user-drag:none;outline:none;color:var(--checkbox-label-color);font-family:var(--sans-serif);font-size:var(--checkbox-label-fs);line-height:var(--checkbox-label-lh);font-feature-settings:"ss02","ss05","tnum";&:before{content:"";grid-column:1;grid-row:1 / -1;align-self:center;box-sizing:border-box;inline-size:16px;block-size:16px;border-radius:4px;background:var(--checkbox-bg);border:1.5px solid var(--checkbox-border);transition:background-color .15s ease-out,border-color .15s ease-out}&:after{content:"";grid-column:1;grid-row:1 / -1;align-self:center;inline-size:16px;block-size:16px;background-color:transparent;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-size:var(--checkbox-mask-size);mask-size:var(--checkbox-mask-size)}@media(hover:hover)and (pointer:fine){&:not(:disabled):hover:before{border-color:var(--checkbox-border-hover);transition:background-color 75ms ease-in,border-color 75ms ease-in}&:not(:disabled):hover:is(:state(checked),:state(indeterminate)):before{background:var(--checkbox-fill-hover);border-color:var(--checkbox-fill-hover)}}&:not(:disabled):active:before{border-color:var(--checkbox-border-active);transition:background-color 50ms linear,border-color 50ms linear}&:not(:disabled):active:is(:state(checked),:state(indeterminate)):before{background:var(--checkbox-fill-active);border-color:var(--checkbox-fill-active)}&:is(:state(checked),:state(indeterminate)){&:before{background:var(--checkbox-fill);border-color:var(--checkbox-fill)}&:after{background-color:var(--checkbox-icon)}}&:state(checked):after{-webkit-mask-image:var(--checkbox-mask-check);mask-image:var(--checkbox-mask-check)}&:state(indeterminate):after{-webkit-mask-image:var(--checkbox-mask-indeterminate);mask-image:var(--checkbox-mask-indeterminate)}&:focus-visible:before{outline:1px solid var(--focus-ring);outline-offset:1px}&:disabled{cursor:not-allowed;color:var(--checkbox-label-color-disabled);&:before{background:var(--checkbox-bg-disabled);border-color:var(--checkbox-border-disabled);transition:none}&:is(:state(checked),:state(indeterminate)):after{background-color:var(--checkbox-icon-disabled)}a-checkbox-hint{color:var(--checkbox-label-color-disabled)}}&[size=small]{--checkbox-gap: 6px;--checkbox-label-fs: 13px;--checkbox-label-lh: 16px;--checkbox-hint-fs: 12px;--checkbox-hint-lh: 14px;--checkbox-mask-size: 10px;&:before,&:after{inline-size:14px;block-size:14px}}&[size=large]{--checkbox-label-fs: 17px;--checkbox-label-lh: 24px;--checkbox-hint-fs: 15px;--checkbox-hint-lh: 19px;--checkbox-mask-size: 14px;&:before,&:after{inline-size:18px;block-size:18px}}}.dark a-checkbox{--checkbox-mask-size: 13px}.dark a-checkbox[size=small]{--checkbox-mask-size: 11px}.dark a-checkbox[size=large]{--checkbox-mask-size: 15px}a-checkbox-label,a-checkbox-hint{display:block;grid-column:2;min-width:0}a-checkbox-hint{color:var(--checkbox-hint-color);font-size:var(--checkbox-hint-fs);line-height:var(--checkbox-hint-lh);margin-block-start:2px}a-checkbox[tone=brand]{--checkbox-fill: #5f4bc3;--checkbox-fill-hover: #503cb4;--checkbox-fill-active: #483493}a-checkbox[tone=neutral]{--checkbox-fill: #635b65;--checkbox-fill-hover: #534c57;--checkbox-fill-active: #49424c}a-checkbox[tone=info]{--checkbox-fill: #1f6eb2;--checkbox-fill-hover: #1a5b93;--checkbox-fill-active: #175082}a-checkbox[tone=success]{--checkbox-fill: #2a7e43;--checkbox-fill-hover: #226737;--checkbox-fill-active: #1f5c31}a-checkbox[tone=warning]{--checkbox-fill: #c37416;--checkbox-fill-hover: #ae6613;--checkbox-fill-active: #995200}a-checkbox[tone=critical]{--checkbox-fill: #c9302c;--checkbox-fill-hover: #b02120;--checkbox-fill-active: #a01c1c}a-checkbox[tone-text=brand]{--checkbox-label-color: var(--text-2-brand);--checkbox-hint-color: var(--text-4-brand)}a-checkbox[tone-text=info]{--checkbox-label-color: var(--text-2-info);--checkbox-hint-color: var(--text-4-info)}a-checkbox[tone-text=success]{--checkbox-label-color: var(--text-2-success);--checkbox-hint-color: var(--text-4-success)}a-checkbox[tone-text=warning]{--checkbox-label-color: var(--text-2-warning);--checkbox-hint-color: var(--text-4-warning)}a-checkbox[tone-text=critical]{--checkbox-label-color: var(--text-2-critical);--checkbox-hint-color: var(--text-4-critical)}a-checkbox[tone]:not([tone=""],[tone=neutral]){--_checkbox-border-base: color-mix(in oklch, var(--checkbox-fill) 70%, var(--checkbox-border-neutral));--checkbox-border: oklch(from var(--_checkbox-border-base) calc(l + .17) c h);--checkbox-border-hover: oklch(from var(--_checkbox-border-base) calc(l + .1) c h);--checkbox-border-active: var(--_checkbox-border-base);.dark &{--checkbox-border: var(--_checkbox-border-base);--checkbox-border-hover: oklch(from var(--_checkbox-border-base) calc(l + .1) c h);--checkbox-border-active: oklch(from var(--_checkbox-border-base) calc(l + .17) c h)}}a-checkbox[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]){--checkbox-tone-source: attr(tone type(<color>), transparent);--_tone-l-rest: .5;--_tone-l-hover: .45;--_tone-l-active: .4;--checkbox-fill: oklch(from var(--checkbox-tone-source) var(--_tone-l-rest) c h);--checkbox-fill-hover: oklch(from var(--checkbox-tone-source) var(--_tone-l-hover) c h);--checkbox-fill-active: oklch(from var(--checkbox-tone-source) var(--_tone-l-active) c h);.dark &{--_tone-l-rest: .45;--_tone-l-hover: .5;--_tone-l-active: .57}}a-checkbox[tone-text]:not([tone-text=""],[tone-text=brand],[tone-text=neutral],[tone-text=info],[tone-text=success],[tone-text=warning],[tone-text=critical]){--checkbox-tone-text-source: attr(tone-text type(<color>), transparent);--checkbox-label-color: oklch(from var(--checkbox-tone-text-source) .5 c h);--checkbox-hint-color: oklch(from var(--checkbox-tone-text-source) .5 c h / .7);.dark &{--checkbox-label-color: oklch(from var(--checkbox-tone-text-source) .8 c h);--checkbox-hint-color: oklch(from var(--checkbox-tone-text-source) .8 c h / .7)}}.dark a-checkbox{--checkbox-border-neutral: #49424c;--checkbox-border-hover: #635b65;--checkbox-border-active: #776e77;--checkbox-fill: #534c57;--checkbox-fill-hover: #635b65;--checkbox-fill-active: #938d96;--checkbox-icon-disabled: #635b65;--checkbox-bg-disabled: color-mix(in oklch, #e4d1ef 10%, transparent);--checkbox-border-disabled: color-mix(in oklch, #e4d1ef 15%, transparent)}.dark a-checkbox[tone=brand]{--checkbox-fill: #503cb4;--checkbox-fill-hover: #5f4bc3;--checkbox-fill-active: #7460d7}.dark a-checkbox[tone=neutral]{--checkbox-fill: #534c57;--checkbox-fill-hover: #635b65;--checkbox-fill-active: #938d96}.dark a-checkbox[tone=info]{--checkbox-fill: #1a5b93;--checkbox-fill-hover: #1f6eb2;--checkbox-fill-active: #2686d9}.dark a-checkbox[tone=success]{--checkbox-fill: #226737;--checkbox-fill-hover: #2a7e43;--checkbox-fill-active: #329550}.dark a-checkbox[tone=warning]{--checkbox-fill: #7f410b;--checkbox-fill-hover: #995200;--checkbox-fill-active: #ae6613}.dark a-checkbox[tone=critical]{--checkbox-fill: #b02120;--checkbox-fill-hover: #c9302c;--checkbox-fill-active: #de4545}}
1
+ @layer anta{a-checkbox{--checkbox-gap: 8px;--checkbox-bg: var(--bg-1);--checkbox-fill: #635b65;--checkbox-fill-hover: #534c57;--checkbox-fill-active: #49424c;--checkbox-border-neutral: #d4ced4;--checkbox-border: var(--checkbox-border-neutral);--checkbox-border-hover: #c1b9c1;--checkbox-border-active: #9f99a1;--checkbox-icon: #ffffff;--checkbox-icon-disabled: #c1b9c1;--checkbox-bg-disabled: color-mix(in oklch, #44374b 10%, transparent);--checkbox-border-disabled: color-mix(in oklch, #44374b 15%, transparent);--checkbox-mask-size: 12px;--checkbox-mask-check: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");--checkbox-mask-indeterminate: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E");--checkbox-label-color: var(--text-2);--checkbox-label-color-disabled: var(--text-4);--checkbox-hint-color: var(--text-4);--checkbox-label-fs: 15px;--checkbox-label-lh: 20px;--checkbox-hint-fs: 13px;--checkbox-hint-lh: 16px;display:inline-grid;grid-template-columns:auto 1fr;align-items:center;column-gap:var(--checkbox-gap);vertical-align:middle;cursor:pointer;user-select:none;-webkit-user-drag:none;outline:none;color:var(--checkbox-label-color);font-family:var(--sans-serif);font-size:var(--checkbox-label-fs);line-height:var(--checkbox-label-lh);font-feature-settings:"ss02","ss05","tnum";&:before{content:"";grid-column:1;grid-row:1 / -1;align-self:center;box-sizing:border-box;inline-size:16px;block-size:16px;border-radius:4px;background:var(--checkbox-bg);border:1.5px solid var(--checkbox-border);transition:background-color .15s ease-out,border-color .15s ease-out}&[round]{--checkbox-round: attr(round type(<length>), 999px)}&[round]:before{border-radius:var(--checkbox-round, 999px)}&:after{content:"";grid-column:1;grid-row:1 / -1;align-self:center;inline-size:16px;block-size:16px;background-color:transparent;-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;-webkit-mask-position:center;mask-position:center;-webkit-mask-size:var(--checkbox-mask-size);mask-size:var(--checkbox-mask-size)}@media(hover:hover)and (pointer:fine){&:not(:disabled):hover:before{border-color:var(--checkbox-border-hover);transition:background-color 75ms ease-in,border-color 75ms ease-in}&:not(:disabled):hover:is(:state(checked),:state(indeterminate)):before{background:var(--checkbox-fill-hover);border-color:var(--checkbox-fill-hover)}}&:not(:disabled):active:before{border-color:var(--checkbox-border-active);transition:background-color 50ms linear,border-color 50ms linear}&:not(:disabled):active:is(:state(checked),:state(indeterminate)):before{background:var(--checkbox-fill-active);border-color:var(--checkbox-fill-active)}&:is(:state(checked),:state(indeterminate)){&:before{background:var(--checkbox-fill);border-color:var(--checkbox-fill)}&:after{background-color:var(--checkbox-icon)}}&:state(checked):after{-webkit-mask-image:var(--checkbox-mask-check);mask-image:var(--checkbox-mask-check)}&:state(indeterminate):after{-webkit-mask-image:var(--checkbox-mask-indeterminate);mask-image:var(--checkbox-mask-indeterminate)}&:focus-visible:before{outline:1px solid var(--focus-ring);outline-offset:1px}&:disabled{cursor:not-allowed;color:var(--checkbox-label-color-disabled);&:before{background:var(--checkbox-bg-disabled);border-color:var(--checkbox-border-disabled);transition:none}&:is(:state(checked),:state(indeterminate)):after{background-color:var(--checkbox-icon-disabled)}a-checkbox-hint{color:var(--checkbox-label-color-disabled)}}&[size=small]{--checkbox-gap: 6px;--checkbox-label-fs: 13px;--checkbox-label-lh: 16px;--checkbox-hint-fs: 12px;--checkbox-hint-lh: 14px;--checkbox-mask-size: 10px;&:before,&:after{inline-size:14px;block-size:14px}}&[size=large]{--checkbox-label-fs: 17px;--checkbox-label-lh: 24px;--checkbox-hint-fs: 15px;--checkbox-hint-lh: 19px;--checkbox-mask-size: 14px;&:before,&:after{inline-size:18px;block-size:18px}}}.dark a-checkbox{--checkbox-mask-size: 13px}.dark a-checkbox[size=small]{--checkbox-mask-size: 11px}.dark a-checkbox[size=large]{--checkbox-mask-size: 15px}a-checkbox-label,a-checkbox-hint{display:block;grid-column:2;min-width:0}a-checkbox-hint{color:var(--checkbox-hint-color);font-size:var(--checkbox-hint-fs);line-height:var(--checkbox-hint-lh);margin-block-start:2px}a-checkbox[tone=brand],a-checkbox[tone-selected=brand]{--checkbox-fill: #5f4bc3;--checkbox-fill-hover: #503cb4;--checkbox-fill-active: #483493}a-checkbox[tone=neutral],a-checkbox[tone-selected=neutral]{--checkbox-fill: #635b65;--checkbox-fill-hover: #534c57;--checkbox-fill-active: #49424c}a-checkbox[tone=info],a-checkbox[tone-selected=info]{--checkbox-fill: #1f6eb2;--checkbox-fill-hover: #1a5b93;--checkbox-fill-active: #175082}a-checkbox[tone=success],a-checkbox[tone-selected=success]{--checkbox-fill: #2a7e43;--checkbox-fill-hover: #226737;--checkbox-fill-active: #1f5c31}a-checkbox[tone=warning],a-checkbox[tone-selected=warning]{--checkbox-fill: #c37416;--checkbox-fill-hover: #ae6613;--checkbox-fill-active: #995200}a-checkbox[tone=critical],a-checkbox[tone-selected=critical]{--checkbox-fill: #c9302c;--checkbox-fill-hover: #b02120;--checkbox-fill-active: #a01c1c}a-checkbox[tone]:not([tone=""],[tone=neutral]){--_checkbox-border-base: color-mix(in oklch, var(--checkbox-fill) 70%, var(--checkbox-border-neutral));--checkbox-border: oklch(from var(--_checkbox-border-base) calc(l + .17) c h);--checkbox-border-hover: oklch(from var(--_checkbox-border-base) calc(l + .1) c h);--checkbox-border-active: var(--_checkbox-border-base);.dark &{--checkbox-border: var(--_checkbox-border-base);--checkbox-border-hover: oklch(from var(--_checkbox-border-base) calc(l + .1) c h);--checkbox-border-active: oklch(from var(--_checkbox-border-base) calc(l + .17) c h)}}a-checkbox[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]){--checkbox-tone-source: attr(tone type(<color>), transparent)}a-checkbox[tone-selected]:not([tone-selected=""],[tone-selected=brand],[tone-selected=neutral],[tone-selected=info],[tone-selected=success],[tone-selected=warning],[tone-selected=critical]){--checkbox-tone-source: attr(tone-selected type(<color>), transparent)}a-checkbox[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]),a-checkbox[tone-selected]:not([tone-selected=""],[tone-selected=brand],[tone-selected=neutral],[tone-selected=info],[tone-selected=success],[tone-selected=warning],[tone-selected=critical]){--_tone-l-rest: .5;--_tone-l-hover: .45;--_tone-l-active: .4;--checkbox-fill: oklch(from var(--checkbox-tone-source) var(--_tone-l-rest) c h);--checkbox-fill-hover: oklch(from var(--checkbox-tone-source) var(--_tone-l-hover) c h);--checkbox-fill-active: oklch(from var(--checkbox-tone-source) var(--_tone-l-active) c h);.dark &{--_tone-l-rest: .45;--_tone-l-hover: .5;--_tone-l-active: .57}}.dark a-checkbox{--checkbox-border-neutral: #49424c;--checkbox-border-hover: #635b65;--checkbox-border-active: #776e77;--checkbox-fill: #534c57;--checkbox-fill-hover: #635b65;--checkbox-fill-active: #938d96;--checkbox-icon-disabled: #635b65;--checkbox-bg-disabled: color-mix(in oklch, #e4d1ef 10%, transparent);--checkbox-border-disabled: color-mix(in oklch, #e4d1ef 15%, transparent)}.dark a-checkbox[tone=brand],.dark a-checkbox[tone-selected=brand]{--checkbox-fill: #503cb4;--checkbox-fill-hover: #5f4bc3;--checkbox-fill-active: #7460d7}.dark a-checkbox[tone=neutral],.dark a-checkbox[tone-selected=neutral]{--checkbox-fill: #534c57;--checkbox-fill-hover: #635b65;--checkbox-fill-active: #938d96}.dark a-checkbox[tone=info],.dark a-checkbox[tone-selected=info]{--checkbox-fill: #1a5b93;--checkbox-fill-hover: #1f6eb2;--checkbox-fill-active: #2686d9}.dark a-checkbox[tone=success],.dark a-checkbox[tone-selected=success]{--checkbox-fill: #226737;--checkbox-fill-hover: #2a7e43;--checkbox-fill-active: #329550}.dark a-checkbox[tone=warning],.dark a-checkbox[tone-selected=warning]{--checkbox-fill: #7f410b;--checkbox-fill-hover: #995200;--checkbox-fill-active: #ae6613}.dark a-checkbox[tone=critical],.dark a-checkbox[tone-selected=critical]{--checkbox-fill: #b02120;--checkbox-fill-hover: #c9302c;--checkbox-fill-active: #de4545}}
@@ -24,6 +24,7 @@ import "./a-checkbox.css";
24
24
  * optimistic self-paint.
25
25
  */
26
26
  export declare class ACheckboxElement extends HTMLElementBase {
27
+ #private;
27
28
  static formAssociated: boolean;
28
29
  static observedAttributes: string[];
29
30
  private internals?;
@@ -39,8 +40,6 @@ export declare class ACheckboxElement extends HTMLElementBase {
39
40
  constructor();
40
41
  connectedCallback(): void;
41
42
  attributeChangedCallback(name: string): void;
42
- private get isDisabled();
43
- private get isControlled();
44
43
  private seed;
45
44
  private emitChange;
46
45
  private toggle;
@@ -50,15 +50,15 @@ class ACheckboxElement extends HTMLElementBase {
50
50
  if (changed && this.alive) this.emitChange();
51
51
  return;
52
52
  }
53
- if (name === "default-state" && !this.isControlled && !this.dirty) this.seed();
53
+ if (name === "default-state" && !this.#isControlled && !this.dirty) this.seed();
54
54
  this.paint();
55
55
  }
56
56
  // Matches the host `disabled` attribute and an ancestor `<fieldset disabled>`.
57
- get isDisabled() {
57
+ get #isDisabled() {
58
58
  return this.matches(":disabled");
59
59
  }
60
60
  // Controlled mode: the `state` attribute is present and owns the live value.
61
- get isControlled() {
61
+ get #isControlled() {
62
62
  return this.hasAttribute("state");
63
63
  }
64
64
  seed() {
@@ -74,7 +74,7 @@ class ACheckboxElement extends HTMLElementBase {
74
74
  this.dispatchEvent(new Event("change", { bubbles: true }));
75
75
  }
76
76
  toggle(_e) {
77
- if (this.isDisabled) return;
77
+ if (this.#isDisabled) return;
78
78
  const prev = this.currentState;
79
79
  const next = prev === "checked" ? "unchecked" : "checked";
80
80
  const ok = this.dispatchEvent(
@@ -85,7 +85,7 @@ class ACheckboxElement extends HTMLElementBase {
85
85
  detail: { next, prev }
86
86
  })
87
87
  );
88
- if (this.isControlled) return;
88
+ if (this.#isControlled) return;
89
89
  if (ok) {
90
90
  this.currentState = next;
91
91
  this.dirty = true;
@@ -1 +1 @@
1
- @layer anta{a-expander{--expander-text: var(--text-2);--expander-text-hover: var(--text-1);--expander-bg-secondary: var(--bg-2);--expander-border-secondary: var(--border-5);--expander-bg-primary: var(--bg-4);--expander-border-primary: var(--border-4);--expander-bg: var(--expander-bg-secondary);--expander-border: var(--expander-border-secondary);--expander-bg-hover-lift: .01;--expander-bg-hover: oklch(from var(--expander-bg) calc(l + var(--expander-bg-hover-lift)) c h);--expander-gutter: 24px;--_expander-chevron: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'%3e%3cpath stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m9 18 6-6-6-6'/%3e%3c/svg%3e");display:block;width:100%;box-sizing:border-box;border:1px solid var(--expander-border);border-radius:4px;color:var(--expander-text);background:var(--expander-bg);transition:background-color .1s ease}a-expander:not(:defined) a-expander-details{display:none}a-expander:not(:defined)[state=open] a-expander-details,a-expander:not(:defined)[default-state=open] a-expander-details{display:block}a-expander:not(:defined) a-expander-summary{position:relative;padding:6px 4px 6px var(--expander-gutter)}a-expander:not(:defined) a-expander-summary:before{content:"";position:absolute;left:calc(var(--expander-gutter) - 16px - 2px);top:50%;width:16px;height:16px;transform:translateY(-50%);background-color:currentColor;-webkit-mask:var(--_expander-chevron) center / contain no-repeat;mask:var(--_expander-chevron) center / contain no-repeat;opacity:.6}a-expander-summary{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-decoration-line:var(--_summary-underline, none);text-decoration-style:dotted;text-decoration-color:color-mix(in oklch,currentColor 75%,transparent);text-decoration-thickness:1px;text-underline-offset:3px;transition:color .15s ease}a-expander-details{display:block;padding:2px 4px 6px var(--expander-gutter);line-height:20px}a-expander[priority=primary]{--expander-bg: var(--expander-bg-primary);--expander-border: var(--expander-border-primary)}a-expander[priority=tertiary]{--expander-bg: transparent;--expander-border: transparent}a-expander:not([disabled]):not(:state(open)):hover{background:var(--expander-bg-hover)}a-expander:not([disabled]):not(:state(open)):active{background:var(--expander-bg)}a-expander[priority=tertiary][outdent]{--expander-gutter: 0px}a-expander[tone=brand]{--expander-text: var(--text-2-brand);--expander-text-hover: var(--text-1-brand);--expander-bg-secondary: var(--bg-2-brand);--expander-border-secondary: var(--border-5-brand);--expander-bg-primary: var(--bg-4-brand);--expander-border-primary: var(--border-4-brand)}a-expander[tone=info]{--expander-text: var(--text-2-info);--expander-text-hover: var(--text-1-info);--expander-bg-secondary: var(--bg-2-info);--expander-border-secondary: var(--border-5-info);--expander-bg-primary: var(--bg-4-info);--expander-border-primary: var(--border-4-info)}a-expander[tone=success]{--expander-text: var(--text-2-success);--expander-text-hover: var(--text-1-success);--expander-bg-secondary: var(--bg-2-success);--expander-border-secondary: var(--border-5-success);--expander-bg-primary: var(--bg-4-success);--expander-border-primary: var(--border-4-success)}a-expander[tone=warning]{--expander-text: var(--text-2-warning);--expander-text-hover: var(--text-1-warning);--expander-bg-secondary: var(--bg-2-warning);--expander-border-secondary: var(--border-5-warning);--expander-bg-primary: var(--bg-4-warning);--expander-border-primary: var(--border-4-warning)}a-expander[tone=critical]{--expander-text: var(--text-2-critical);--expander-text-hover: var(--text-1-critical);--expander-bg-secondary: var(--bg-2-critical);--expander-border-secondary: var(--border-5-critical);--expander-bg-primary: var(--bg-4-critical);--expander-border-primary: var(--border-4-critical)}a-expander[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--expander-tone-source: attr(tone type(<color>), currentColor);--expander-text: oklch(from var(--expander-tone-source) .41 .15 h);--expander-text-hover: oklch(from var(--expander-tone-source) .33 .15 h);--expander-bg-secondary: oklch(from var(--expander-tone-source) .99 .006 h);--expander-border-secondary: oklch(from var(--expander-tone-source) .93 .03 h);--expander-bg-primary: oklch(from var(--expander-tone-source) .955 .02 h);--expander-border-primary: oklch(from var(--expander-tone-source) .895 .045 h)}.dark a-expander[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--expander-text: oklch(from var(--expander-tone-source) .75 .11 h);--expander-text-hover: oklch(from var(--expander-tone-source) .82 .1 h);--expander-bg-secondary: oklch(from var(--expander-tone-source) .13 .02 h);--expander-border-secondary: oklch(from var(--expander-tone-source) .22 .05 h);--expander-bg-primary: oklch(from var(--expander-tone-source) .19 .04 h);--expander-border-primary: oklch(from var(--expander-tone-source) .26 .07 h)}a-expander[disabled],a-expander[disabled][tone]{--expander-text: #afa9b1}.dark a-expander[disabled],.dark a-expander[disabled][tone]{--expander-text: #635b65}}
1
+ @layer anta{a-expander{--expander-text: var(--text-2);--expander-text-hover: var(--text-1);--expander-bg-secondary: var(--bg-2);--expander-border-secondary: var(--border-5);--expander-bg-primary: var(--bg-4);--expander-border-primary: var(--border-4);--expander-bg: var(--expander-bg-secondary);--expander-border: var(--expander-border-secondary);--expander-bg-hover-lift: .01;--expander-bg-hover: oklch(from var(--expander-bg) calc(l + var(--expander-bg-hover-lift)) c h);--expander-gutter: 24px;--_expander-chevron: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24'%3e%3cpath stroke='currentColor' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m9 18 6-6-6-6'/%3e%3c/svg%3e");display:block;width:100%;box-sizing:border-box;border:1px solid var(--expander-border);border-radius:4px;color:var(--expander-text);background:var(--expander-bg);transition:background-color .1s ease}a-expander[round]{--expander-round: attr(round type(<length>));border-radius:var(--expander-round, var(--_expander-round-radius, 999px))}a-expander:not(:defined) a-expander-details{display:none}a-expander:not(:defined)[state=open] a-expander-details,a-expander:not(:defined)[default-state=open] a-expander-details{display:block}a-expander:not(:defined) a-expander-summary{position:relative;padding:6px 4px 6px var(--expander-gutter)}a-expander:not(:defined) a-expander-summary:before{content:"";position:absolute;left:calc(var(--expander-gutter) - 16px - 2px);top:50%;width:16px;height:16px;transform:translateY(-50%);background-color:currentColor;-webkit-mask:var(--_expander-chevron) center / contain no-repeat;mask:var(--_expander-chevron) center / contain no-repeat;opacity:.6}a-expander-summary{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-decoration-line:var(--_summary-underline, none);text-decoration-style:dotted;text-decoration-color:color-mix(in oklch,currentColor 75%,transparent);text-decoration-thickness:1px;text-underline-offset:3px;transition:color .15s ease}a-expander-details{display:block;padding:2px 4px 6px var(--expander-gutter);line-height:20px}a-expander[priority=primary]{--expander-bg: var(--expander-bg-primary);--expander-border: var(--expander-border-primary)}a-expander[priority=tertiary]{--expander-bg: transparent;--expander-border: transparent}a-expander:not([disabled]):not(:state(open)):hover{background:var(--expander-bg-hover)}a-expander:not([disabled]):not(:state(open)):active{background:var(--expander-bg)}a-expander[priority=tertiary][outdent]{--expander-gutter: 0px}a-expander[tone=brand]{--expander-text: var(--text-2-brand);--expander-text-hover: var(--text-1-brand);--expander-bg-secondary: var(--bg-2-brand);--expander-border-secondary: var(--border-5-brand);--expander-bg-primary: var(--bg-4-brand);--expander-border-primary: var(--border-4-brand)}a-expander[tone=info]{--expander-text: var(--text-2-info);--expander-text-hover: var(--text-1-info);--expander-bg-secondary: var(--bg-2-info);--expander-border-secondary: var(--border-5-info);--expander-bg-primary: var(--bg-4-info);--expander-border-primary: var(--border-4-info)}a-expander[tone=success]{--expander-text: var(--text-2-success);--expander-text-hover: var(--text-1-success);--expander-bg-secondary: var(--bg-2-success);--expander-border-secondary: var(--border-5-success);--expander-bg-primary: var(--bg-4-success);--expander-border-primary: var(--border-4-success)}a-expander[tone=warning]{--expander-text: var(--text-2-warning);--expander-text-hover: var(--text-1-warning);--expander-bg-secondary: var(--bg-2-warning);--expander-border-secondary: var(--border-5-warning);--expander-bg-primary: var(--bg-4-warning);--expander-border-primary: var(--border-4-warning)}a-expander[tone=critical]{--expander-text: var(--text-2-critical);--expander-text-hover: var(--text-1-critical);--expander-bg-secondary: var(--bg-2-critical);--expander-border-secondary: var(--border-5-critical);--expander-bg-primary: var(--bg-4-critical);--expander-border-primary: var(--border-4-critical)}a-expander[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--expander-tone-source: attr(tone type(<color>), currentColor);--expander-text: oklch(from var(--expander-tone-source) .41 .15 h);--expander-text-hover: oklch(from var(--expander-tone-source) .33 .15 h);--expander-bg-secondary: oklch(from var(--expander-tone-source) .99 .006 h);--expander-border-secondary: oklch(from var(--expander-tone-source) .93 .03 h);--expander-bg-primary: oklch(from var(--expander-tone-source) .955 .02 h);--expander-border-primary: oklch(from var(--expander-tone-source) .895 .045 h)}.dark a-expander[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--expander-text: oklch(from var(--expander-tone-source) .75 .11 h);--expander-text-hover: oklch(from var(--expander-tone-source) .82 .1 h);--expander-bg-secondary: oklch(from var(--expander-tone-source) .13 .02 h);--expander-border-secondary: oklch(from var(--expander-tone-source) .22 .05 h);--expander-bg-primary: oklch(from var(--expander-tone-source) .19 .04 h);--expander-border-primary: oklch(from var(--expander-tone-source) .26 .07 h)}a-expander[disabled],a-expander[disabled][tone]{--expander-text: #afa9b1}.dark a-expander[disabled],.dark a-expander[disabled][tone]{--expander-text: #635b65}}
@@ -1,17 +1,28 @@
1
1
  import { HTMLElementBase } from '../anta_helpers';
2
2
  import './a-expander.css';
3
3
  export declare class AExpanderElement extends HTMLElementBase {
4
+ #private;
4
5
  static observedAttributes: string[];
5
6
  private summary;
6
7
  private region;
8
+ private header;
9
+ private roundStyle;
10
+ private roundObserver?;
7
11
  private internals?;
8
12
  constructor();
9
- /** Controlled mode: the `state` attribute is present and owns the state. */
10
- private get controlled();
11
- /** The currently *applied* state (read from the shadow, the source of truth
12
- * for what's painted). */
13
- private get current();
13
+ /** Publish HALF the folded (header + host borders) height as
14
+ * `--_expander-round-radius` on `:host`, for `a-expander[round]` to consume.
15
+ * Reads layout only; writes only the shadow sheet no host mutation. */
16
+ /** A `round` attribute carrying a length (`round="12px"`) is a fixed radius —
17
+ * the CSS uses it directly and the measured pill is unused, so skip measuring.
18
+ * (The wrapper's `round={12}` path sets an inline var + a bare `round=""`, so
19
+ * it isn't caught here; the measurement runs but its var is simply overridden.) */
20
+ private hasFixedRound;
21
+ private measureRoundRadius;
22
+ private startRoundObserver;
23
+ private stopRoundObserver;
14
24
  connectedCallback(): void;
25
+ disconnectedCallback(): void;
15
26
  attributeChangedCallback(name: string): void;
16
27
  private syncDisabled;
17
28
  /** Apply state to the shadow internals (idempotent; reads the host, writes
@@ -141,9 +141,18 @@ const SHADOW_STYLE = `
141
141
  `;
142
142
  const parseState = (v) => v === "open" ? "open" : "closed";
143
143
  class AExpanderElement extends HTMLElementBase {
144
- static observedAttributes = ["state", "disabled"];
144
+ static observedAttributes = ["state", "disabled", "round"];
145
145
  summary;
146
146
  region;
147
+ header;
148
+ // A dedicated shadow <style> the element rewrites to publish the measured
149
+ // `round` radius as a `:host` custom property (see `measureRoundRadius`). Kept
150
+ // separate from the static SHADOW_STYLE so updating it is a cheap textContent
151
+ // swap on one small sheet, and it's shadow-internal (no host mutation).
152
+ roundStyle;
153
+ // Observes the header (folded) box so the `round` radius tracks its height —
154
+ // including custom header content. Guarded for engines without ResizeObserver.
155
+ roundObserver;
147
156
  // ElementInternals exposes the open/closed state as a custom state
148
157
  // (`:state(open)`) for consumer styling — e.g. rotating a chevron that lives
149
158
  // in `actions`, or matching an open header to a design. It's NOT a host
@@ -167,6 +176,7 @@ class AExpanderElement extends HTMLElementBase {
167
176
  this.summary.addEventListener("click", this.onSummaryClick);
168
177
  const header = document.createElement("div");
169
178
  header.className = "header";
179
+ this.header = header;
170
180
  const actionsSlot = document.createElement("slot");
171
181
  actionsSlot.name = "actions";
172
182
  actionsSlot.setAttribute("part", "actions");
@@ -179,24 +189,65 @@ class AExpanderElement extends HTMLElementBase {
179
189
  const content = document.createElement("slot");
180
190
  content.setAttribute("part", "content");
181
191
  this.region.append(content);
182
- shadow.append(style, header, this.region);
192
+ this.roundStyle = document.createElement("style");
193
+ if (typeof ResizeObserver !== "undefined") {
194
+ this.roundObserver = new ResizeObserver(() => this.measureRoundRadius());
195
+ }
196
+ shadow.append(style, this.roundStyle, header, this.region);
197
+ }
198
+ /** Publish HALF the folded (header + host borders) height as
199
+ * `--_expander-round-radius` on `:host`, for `a-expander[round]` to consume.
200
+ * Reads layout only; writes only the shadow sheet — no host mutation. */
201
+ /** A `round` attribute carrying a length (`round="12px"`) is a fixed radius —
202
+ * the CSS uses it directly and the measured pill is unused, so skip measuring.
203
+ * (The wrapper's `round={12}` path sets an inline var + a bare `round=""`, so
204
+ * it isn't caught here; the measurement runs but its var is simply overridden.) */
205
+ hasFixedRound() {
206
+ const v = this.getAttribute("round");
207
+ return v != null && v.trim() !== "";
208
+ }
209
+ measureRoundRadius() {
210
+ if (!this.hasAttribute("round") || this.hasFixedRound()) return;
211
+ const h = this.header.getBoundingClientRect().height;
212
+ if (h <= 0) return;
213
+ const cs = getComputedStyle(this);
214
+ const borders = (parseFloat(cs.borderTopWidth) || 0) + (parseFloat(cs.borderBottomWidth) || 0);
215
+ const radius = (h + borders) / 2;
216
+ this.roundStyle.textContent = `:host{--_expander-round-radius:${radius}px}`;
217
+ }
218
+ startRoundObserver() {
219
+ if (!this.roundObserver || this.hasFixedRound()) return;
220
+ this.roundObserver.observe(this.header);
221
+ this.measureRoundRadius();
222
+ }
223
+ stopRoundObserver() {
224
+ this.roundObserver?.disconnect();
225
+ this.roundStyle.textContent = "";
183
226
  }
184
227
  /** Controlled mode: the `state` attribute is present and owns the state. */
185
- get controlled() {
228
+ get #controlled() {
186
229
  return this.hasAttribute("state");
187
230
  }
188
231
  /** The currently *applied* state (read from the shadow, the source of truth
189
232
  * for what's painted). */
190
- get current() {
233
+ get #current() {
191
234
  return this.summary.getAttribute("aria-expanded") === "true" ? "open" : "closed";
192
235
  }
193
236
  connectedCallback() {
194
237
  this.syncDisabled();
195
- this.applyState(parseState(this.getAttribute(this.controlled ? "state" : "default-state")));
238
+ this.applyState(parseState(this.getAttribute(this.#controlled ? "state" : "default-state")));
239
+ if (this.hasAttribute("round")) this.startRoundObserver();
240
+ }
241
+ disconnectedCallback() {
242
+ this.roundObserver?.disconnect();
196
243
  }
197
244
  attributeChangedCallback(name) {
198
245
  if (name === "disabled") this.syncDisabled();
199
- else if (name === "state" && this.controlled) this.applyState(parseState(this.getAttribute("state")));
246
+ else if (name === "state" && this.#controlled) this.applyState(parseState(this.getAttribute("state")));
247
+ else if (name === "round") {
248
+ if (this.hasAttribute("round")) this.startRoundObserver();
249
+ else this.stopRoundObserver();
250
+ }
200
251
  }
201
252
  syncDisabled() {
202
253
  this.summary.disabled = this.hasAttribute("disabled");
@@ -220,12 +271,12 @@ class AExpanderElement extends HTMLElementBase {
220
271
  * Controlled: never self-apply; the consumer answers via the `state`
221
272
  * attribute. See STATEFUL-COMPONENTS.md. */
222
273
  onSummaryClick = () => {
223
- const prev = this.current;
274
+ const prev = this.#current;
224
275
  const next = prev === "open" ? "closed" : "open";
225
276
  const ok = this.dispatchEvent(
226
277
  new CustomEvent("statechange", { cancelable: true, detail: { next, prev } })
227
278
  );
228
- if (this.controlled) return;
279
+ if (this.#controlled) return;
229
280
  if (ok) this.applyState(next);
230
281
  };
231
282
  }