@antadesign/anta 0.3.28 → 0.3.30
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.
- package/NOTICES.md +32 -1
- package/dist/anta_helpers.d.ts +21 -0
- package/dist/anta_helpers.js +24 -0
- package/dist/box-observation.d.ts +8 -0
- package/dist/box-observation.js +41 -0
- package/dist/box-types.d.ts +2 -0
- package/dist/bundle.css +1 -1
- package/dist/bundle.js +66 -29
- package/dist/components/Box.d.ts +28 -12
- package/dist/components/Box.js +18 -11
- package/dist/components/Breadcrumbs.css +1 -1
- package/dist/components/Breadcrumbs.d.ts +1 -1
- package/dist/components/Button.d.ts +3 -3
- package/dist/components/ButtonCopy.d.ts +1 -1
- package/dist/components/Calendar.js +3 -5
- package/dist/components/Checkbox.d.ts +2 -2
- package/dist/components/Input.d.ts +8 -2
- package/dist/components/Input.js +4 -0
- package/dist/components/InputAutocomplete.js +3 -12
- package/dist/components/InputDate.css +1 -1
- package/dist/components/InputDate.js +2 -0
- package/dist/components/Menu.d.ts +4 -4
- package/dist/components/Menu.js +1 -1
- package/dist/components/Panel.d.ts +17 -0
- package/dist/components/Panel.js +22 -0
- package/dist/components/RadioGroup.d.ts +2 -1
- package/dist/components/Select.d.ts +14 -14
- package/dist/components/Select.js +47 -35
- package/dist/components/SelectFaceted.d.ts +17 -6
- package/dist/components/SelectFaceted.js +61 -41
- package/dist/components/Steps.css +1 -1
- package/dist/components/Switch.d.ts +3 -3
- package/dist/components/TabPanel.d.ts +3 -8
- package/dist/components/TabPanel.js +2 -1
- package/dist/components/Tabs.d.ts +2 -2
- package/dist/components/Tabs.js +2 -1
- package/dist/components/Tooltip.d.ts +1 -1
- package/dist/components/Tooltip.js +1 -1
- package/dist/components/select-parts.css +1 -1
- package/dist/elements/a-avatar.css +1 -1
- package/dist/elements/a-banner.css +1 -1
- package/dist/elements/a-box.css +1 -1
- package/dist/elements/a-box.d.ts +6 -6
- package/dist/elements/a-box.js +76 -23
- package/dist/elements/a-button.css +1 -1
- package/dist/elements/a-button.d.ts +9 -1
- package/dist/elements/a-button.js +64 -1
- package/dist/elements/a-calendar.css +1 -1
- package/dist/elements/a-capture.css +1 -1
- package/dist/elements/a-card.css +1 -1
- package/dist/elements/a-checkbox.css +1 -1
- package/dist/elements/a-checkbox.d.ts +3 -0
- package/dist/elements/a-checkbox.js +17 -1
- package/dist/elements/a-copy.css +1 -1
- package/dist/elements/a-dialog.css +1 -1
- package/dist/elements/a-expander.css +1 -1
- package/dist/elements/a-icon.css +1 -1
- package/dist/elements/a-icon.shapes.css +1 -1
- package/dist/elements/a-icon.shapes.d.ts +1 -1
- package/dist/elements/a-input-time.css +1 -1
- package/dist/elements/a-input-time.d.ts +8 -0
- package/dist/elements/a-input-time.js +115 -8
- package/dist/elements/a-input.css +1 -1
- package/dist/elements/a-input.d.ts +27 -1
- package/dist/elements/a-input.js +176 -35
- package/dist/elements/a-loader.css +1 -1
- package/dist/elements/a-menu-group.css +1 -1
- package/dist/elements/a-menu-item.css +1 -1
- package/dist/elements/a-menu-item.js +1 -0
- package/dist/elements/a-menu-separator.css +1 -1
- package/dist/elements/a-menu.css +1 -1
- package/dist/elements/a-menu.d.ts +8 -13
- package/dist/elements/a-menu.js +146 -45
- package/dist/elements/a-panel.css +1 -0
- package/dist/elements/a-panel.d.ts +16 -0
- package/dist/elements/a-panel.js +153 -0
- package/dist/elements/a-progress.css +1 -1
- package/dist/elements/a-radio-group.css +1 -1
- package/dist/elements/a-radio.css +1 -1
- package/dist/elements/a-radio.d.ts +4 -0
- package/dist/elements/a-radio.js +18 -0
- package/dist/elements/a-slider.css +1 -1
- package/dist/elements/a-slider.d.ts +1 -0
- package/dist/elements/a-slider.js +3 -3
- package/dist/elements/a-switch.css +1 -1
- package/dist/elements/a-switch.d.ts +3 -0
- package/dist/elements/a-switch.js +17 -1
- package/dist/elements/a-tab.css +1 -1
- package/dist/elements/a-tabpanel.css +1 -1
- package/dist/elements/a-tabs.css +1 -1
- package/dist/elements/a-tag.css +1 -1
- package/dist/elements/a-text.css +1 -1
- package/dist/elements/a-title.css +1 -1
- package/dist/elements/a-toast.css +1 -1
- package/dist/elements/a-toaster.css +1 -1
- package/dist/elements/a-tooltip.css +1 -1
- package/dist/elements/a-tooltip.js +30 -7
- package/dist/elements/focus.d.ts +9 -0
- package/dist/elements/focus.js +41 -0
- package/dist/elements/index.d.ts +1 -0
- package/dist/elements/index.js +3 -0
- package/dist/elements/panel-focus.d.ts +10 -0
- package/dist/elements/panel-focus.js +86 -0
- package/dist/elements/shadow-aria.d.ts +10 -0
- package/dist/elements/shadow-aria.js +155 -0
- package/dist/general_types.d.ts +48 -19
- package/dist/generate-icons.mjs +3 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.js +2 -0
- package/dist/jsx-runtime.d.ts +20 -1
- package/dist/jsx-runtime.js +12 -0
- package/dist/reset.css +1 -1
- package/dist/theme-antithesis.css +1 -1
- package/dist/theme-antune.css +1 -1
- package/dist/toaster.d.ts +1 -1
- package/dist/tokens.css +1 -1
- package/docs/accessibility.md +4 -2
- package/docs/changelog.md +89 -4
- package/docs/colors.md +6 -6
- package/docs/components/box.md +98 -34
- package/docs/components/breadcrumbs.md +33 -0
- package/docs/components/button.md +2 -2
- package/docs/components/capture.md +8 -8
- package/docs/components/checkbox.md +9 -4
- package/docs/components/input-autocomplete.md +6 -0
- package/docs/components/input-date.md +8 -2
- package/docs/components/input.md +99 -40
- package/docs/components/menu.md +3 -3
- package/docs/components/panel.md +189 -0
- package/docs/components/radio.md +4 -2
- package/docs/components/select-faceted.md +57 -2
- package/docs/components/select.md +63 -51
- package/docs/components/steps.md +4 -4
- package/docs/components/switch.md +12 -6
- package/docs/components/tabs.md +21 -8
- package/docs/components/tooltip.md +6 -4
- package/docs/index.md +2 -0
- package/docs/install-config.md +5 -4
- package/docs/normalization.md +3 -1
- package/docs/packages/plot.md +3771 -0
- package/docs/theming.md +1 -1
- package/package.json +16 -9
package/dist/elements/a-input.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import { HTMLElementBase } from "../anta_helpers";
|
|
1
|
+
import { HTMLElementBase, SYNC_POPUP_ARIA } from "../anta_helpers";
|
|
2
|
+
import {
|
|
3
|
+
applyShadowAria,
|
|
4
|
+
ariaAttributeProperty,
|
|
5
|
+
SHADOW_ARIA_ATTRIBUTES,
|
|
6
|
+
SHADOW_ARIA_ATTRIBUTE_SET
|
|
7
|
+
} from "./shadow-aria";
|
|
2
8
|
import "./a-input.css";
|
|
3
9
|
const FORWARDED = [
|
|
4
10
|
"placeholder",
|
|
@@ -14,12 +20,7 @@ const FORWARDED = [
|
|
|
14
20
|
"required",
|
|
15
21
|
"min",
|
|
16
22
|
"max",
|
|
17
|
-
"step"
|
|
18
|
-
// `aria-label` on the host names the internal control (the actual textbox);
|
|
19
|
-
// without forwarding it, a bare `<a-input aria-label>` leaves the control
|
|
20
|
-
// unnamed. `applyLabelAria` already defers to a host `aria-label` over the
|
|
21
|
-
// label-slot text, so the two don't fight.
|
|
22
|
-
"aria-label"
|
|
23
|
+
"step"
|
|
23
24
|
];
|
|
24
25
|
const BOOL_FORWARDED = /* @__PURE__ */ new Set(["readonly", "required"]);
|
|
25
26
|
let focusFromKeyboard = false;
|
|
@@ -83,7 +84,7 @@ const SHADOW_STYLE = `
|
|
|
83
84
|
@media (hover: hover) and (pointer: fine) {
|
|
84
85
|
:host(:not(:disabled)) .field:hover { --_bw: 1px; }
|
|
85
86
|
}
|
|
86
|
-
:host(:not([readonly])) .field:has(input:focus, textarea:focus),
|
|
87
|
+
:host(:not([readonly])) .field:has(input:focus, textarea:focus, button:focus-visible),
|
|
87
88
|
:host([readonly]:state(kb-focus)) .field {
|
|
88
89
|
--_bw: 1px;
|
|
89
90
|
outline: 1px solid var(--focus-ring);
|
|
@@ -91,7 +92,7 @@ const SHADOW_STYLE = `
|
|
|
91
92
|
}
|
|
92
93
|
@media (forced-colors: active) { .field { border: 1px solid ButtonBorder; } }
|
|
93
94
|
|
|
94
|
-
input, textarea {
|
|
95
|
+
input, textarea, button {
|
|
95
96
|
flex: 1 1 auto;
|
|
96
97
|
min-width: 0;
|
|
97
98
|
width: 100%;
|
|
@@ -118,11 +119,13 @@ const SHADOW_STYLE = `
|
|
|
118
119
|
padding-block: var(--_pad-block);
|
|
119
120
|
overflow-y: auto;
|
|
120
121
|
}
|
|
122
|
+
button { text-align: start; white-space: nowrap; overflow: hidden; cursor: pointer; }
|
|
123
|
+
button.placeholder { color: var(--input-placeholder); }
|
|
121
124
|
:host([maxrows]:not([rows])) textarea {
|
|
122
125
|
max-height: calc(var(--_lh) * var(--_maxrows) + var(--_pad-block) * 2);
|
|
123
126
|
}
|
|
124
127
|
input::placeholder, textarea::placeholder { color: var(--input-placeholder); opacity: 1; }
|
|
125
|
-
input:disabled, textarea:disabled { cursor: not-allowed; }
|
|
128
|
+
input:disabled, textarea:disabled, button:disabled { cursor: not-allowed; }
|
|
126
129
|
:host([readonly]:not([disabled])) .field,
|
|
127
130
|
:host([readonly]:not([disabled])) input,
|
|
128
131
|
:host([readonly]:not([disabled])) textarea { cursor: pointer; }
|
|
@@ -181,13 +184,17 @@ const SHADOW_STYLE = `
|
|
|
181
184
|
line-height: calc(var(--_lh) - 2px);
|
|
182
185
|
}
|
|
183
186
|
`;
|
|
187
|
+
const READ_DELEGATED_ARIA = /* @__PURE__ */ Symbol("readDelegatedAria");
|
|
188
|
+
const WRITE_DELEGATED_ARIA = /* @__PURE__ */ Symbol("writeDelegatedAria");
|
|
184
189
|
class AInputElement extends HTMLElementBase {
|
|
185
190
|
static formAssociated = true;
|
|
186
191
|
static observedAttributes = [
|
|
187
192
|
...FORWARDED,
|
|
193
|
+
...SHADOW_ARIA_ATTRIBUTES,
|
|
188
194
|
"value",
|
|
189
195
|
"defaultvalue",
|
|
190
196
|
"multiline",
|
|
197
|
+
"button",
|
|
191
198
|
"rows",
|
|
192
199
|
"maxrows",
|
|
193
200
|
"status",
|
|
@@ -209,6 +216,18 @@ class AInputElement extends HTMLElementBase {
|
|
|
209
216
|
// Set by formDisabledCallback when an ancestor <fieldset disabled> / disabled
|
|
210
217
|
// form turns the field off (the host can't carry a [disabled] attribute itself).
|
|
211
218
|
formDisabled = false;
|
|
219
|
+
// Standard role/aria attributes are consumed from the neutral host and
|
|
220
|
+
// applied to the native shadow control. The values live off-DOM so the host
|
|
221
|
+
// does not become a second control in the accessibility tree.
|
|
222
|
+
delegatedAria = /* @__PURE__ */ new Map();
|
|
223
|
+
consumingAria = /* @__PURE__ */ new Set();
|
|
224
|
+
ariaApplyQueued = false;
|
|
225
|
+
// Direct element relationships supplied by an adjacent a-menu. These avoid
|
|
226
|
+
// renderer-local IDs and apply only when the consumer has not authored the
|
|
227
|
+
// corresponding ARIA relationship explicitly.
|
|
228
|
+
popupAriaSource;
|
|
229
|
+
popupControls = null;
|
|
230
|
+
popupActiveDescendant = null;
|
|
212
231
|
constructor() {
|
|
213
232
|
super();
|
|
214
233
|
try {
|
|
@@ -261,14 +280,6 @@ class AInputElement extends HTMLElementBase {
|
|
|
261
280
|
}
|
|
262
281
|
connectedCallback() {
|
|
263
282
|
trackFocusModality(this.doc);
|
|
264
|
-
const type = this.getAttribute("type")?.toLowerCase();
|
|
265
|
-
if (this.internals && type !== "number" && type !== "search") {
|
|
266
|
-
this.internals.role = "textbox";
|
|
267
|
-
} else if (this.internals && type === "number") {
|
|
268
|
-
this.internals.role = "spinbutton";
|
|
269
|
-
} else if (this.internals && type === "search") {
|
|
270
|
-
this.internals.role = "searchbox";
|
|
271
|
-
}
|
|
272
283
|
if (Object.prototype.hasOwnProperty.call(this, "value")) {
|
|
273
284
|
const v = this.value;
|
|
274
285
|
delete this.value;
|
|
@@ -277,13 +288,34 @@ class AInputElement extends HTMLElementBase {
|
|
|
277
288
|
if (!this.control) this.buildControl();
|
|
278
289
|
this.ready = true;
|
|
279
290
|
}
|
|
291
|
+
[SYNC_POPUP_ARIA](relations) {
|
|
292
|
+
if (relations.clear) {
|
|
293
|
+
if (this.popupAriaSource !== relations.source) return;
|
|
294
|
+
this.popupAriaSource = void 0;
|
|
295
|
+
this.popupControls = null;
|
|
296
|
+
this.popupActiveDescendant = null;
|
|
297
|
+
} else {
|
|
298
|
+
this.popupAriaSource = relations.source;
|
|
299
|
+
if ("controls" in relations) this.popupControls = relations.controls ?? null;
|
|
300
|
+
if ("activeDescendant" in relations)
|
|
301
|
+
this.popupActiveDescendant = relations.activeDescendant ?? null;
|
|
302
|
+
}
|
|
303
|
+
this.applyPopupAria();
|
|
304
|
+
}
|
|
280
305
|
attributeChangedCallback(name, _old, value) {
|
|
306
|
+
if (SHADOW_ARIA_ATTRIBUTE_SET.has(name)) {
|
|
307
|
+
if (this.consumingAria.has(name)) return;
|
|
308
|
+
this.consumeAria(name, value);
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
281
311
|
if (!this.ready && name !== "value" && name !== "defaultvalue") return;
|
|
282
|
-
if (name === "multiline" || name === "rows" || name === "maxrows") {
|
|
312
|
+
if (name === "multiline" || name === "button" || name === "rows" || name === "maxrows") {
|
|
283
313
|
if (!this.control) return;
|
|
284
314
|
const needTextarea = this.hasAttribute("multiline") || this.hasAttribute("rows");
|
|
285
315
|
const isTextarea = this.control instanceof HTMLTextAreaElement;
|
|
286
|
-
|
|
316
|
+
const needButton = !needTextarea && this.hasAttribute("button");
|
|
317
|
+
const isButton = this.control instanceof HTMLButtonElement;
|
|
318
|
+
if (needTextarea !== isTextarea || needButton !== isButton) this.buildControl(this.value);
|
|
287
319
|
else if (this.control instanceof HTMLTextAreaElement) this.configureTextarea(this.control);
|
|
288
320
|
return;
|
|
289
321
|
}
|
|
@@ -303,22 +335,88 @@ class AInputElement extends HTMLElementBase {
|
|
|
303
335
|
if (name === "defaultvalue") return;
|
|
304
336
|
if (this.control) {
|
|
305
337
|
this.forward(name, value);
|
|
338
|
+
this.syncButtonPresentation();
|
|
306
339
|
this.updateValidity();
|
|
307
340
|
}
|
|
308
341
|
}
|
|
342
|
+
/** Standard ARIA is the raw custom-element API, but its semantic target is the
|
|
343
|
+
* native shadow field. Consume it synchronously so the host never remains a
|
|
344
|
+
* duplicate control after upgrade. */
|
|
345
|
+
consumeAria(name, value) {
|
|
346
|
+
if (value == null) this.delegatedAria.delete(name);
|
|
347
|
+
else this.delegatedAria.set(name, value);
|
|
348
|
+
if (this.hasAttribute(name)) {
|
|
349
|
+
this.consumingAria.add(name);
|
|
350
|
+
super.removeAttribute(name);
|
|
351
|
+
this.consumingAria.delete(name);
|
|
352
|
+
}
|
|
353
|
+
this.applyDelegatedAria(name);
|
|
354
|
+
this.queueDelegatedAria();
|
|
355
|
+
}
|
|
356
|
+
/** React/Preact may remove a prop after Anta has already consumed its host
|
|
357
|
+
* attribute. Catch that no-op DOM removal so the shadow control still updates. */
|
|
358
|
+
removeAttribute(name) {
|
|
359
|
+
if (SHADOW_ARIA_ATTRIBUTE_SET.has(name) && !this.consumingAria.has(name) && !this.hasAttribute(name)) {
|
|
360
|
+
const ariaName = name;
|
|
361
|
+
if (this.delegatedAria.delete(ariaName)) {
|
|
362
|
+
this.applyDelegatedAria(ariaName);
|
|
363
|
+
this.queueDelegatedAria();
|
|
364
|
+
}
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
super.removeAttribute(name);
|
|
368
|
+
}
|
|
369
|
+
toggleAttribute(name, force) {
|
|
370
|
+
if (SHADOW_ARIA_ATTRIBUTE_SET.has(name)) {
|
|
371
|
+
const ariaName = name;
|
|
372
|
+
const next = force ?? !this.delegatedAria.has(ariaName);
|
|
373
|
+
this.consumeAria(ariaName, next ? "" : null);
|
|
374
|
+
return next;
|
|
375
|
+
}
|
|
376
|
+
return super.toggleAttribute(name, force);
|
|
377
|
+
}
|
|
378
|
+
[READ_DELEGATED_ARIA](name) {
|
|
379
|
+
return this.delegatedAria.get(name) ?? null;
|
|
380
|
+
}
|
|
381
|
+
[WRITE_DELEGATED_ARIA](name, value) {
|
|
382
|
+
this.consumeAria(name, value == null ? null : String(value));
|
|
383
|
+
}
|
|
384
|
+
applyDelegatedAria(name) {
|
|
385
|
+
const control = this.control;
|
|
386
|
+
if (!control) return;
|
|
387
|
+
applyShadowAria(this, control, name, this.delegatedAria.get(name) ?? null);
|
|
388
|
+
if (name === "aria-label" || name === "aria-labelledby") this.applyLabelAria();
|
|
389
|
+
if (name === "aria-description" || name === "aria-describedby") this.applyDescriptionAria();
|
|
390
|
+
if (name === "aria-invalid" && !this.delegatedAria.has(name)) this.syncStatus();
|
|
391
|
+
if (name === "aria-controls" || name === "aria-activedescendant") this.applyPopupAria();
|
|
392
|
+
}
|
|
393
|
+
queueDelegatedAria() {
|
|
394
|
+
if (this.ariaApplyQueued) return;
|
|
395
|
+
this.ariaApplyQueued = true;
|
|
396
|
+
queueMicrotask(() => {
|
|
397
|
+
this.ariaApplyQueued = false;
|
|
398
|
+
const control = this.control;
|
|
399
|
+
if (!control) return;
|
|
400
|
+
for (const [name, value] of this.delegatedAria) applyShadowAria(this, control, name, value);
|
|
401
|
+
});
|
|
402
|
+
}
|
|
309
403
|
/** (Re)build the shadow control from the current attributes. */
|
|
310
404
|
buildControl(initial) {
|
|
311
405
|
const prev = this.control;
|
|
312
406
|
const refocus = prev != null && this.shadowRoot?.activeElement === prev;
|
|
313
407
|
let selStart = null;
|
|
314
408
|
let selEnd = null;
|
|
315
|
-
if (prev)
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
409
|
+
if (prev instanceof HTMLInputElement || prev instanceof HTMLTextAreaElement) {
|
|
410
|
+
try {
|
|
411
|
+
selStart = prev.selectionStart;
|
|
412
|
+
selEnd = prev.selectionEnd;
|
|
413
|
+
} catch {
|
|
414
|
+
}
|
|
319
415
|
}
|
|
320
416
|
const multiline = this.hasAttribute("multiline") || this.hasAttribute("rows");
|
|
321
|
-
const
|
|
417
|
+
const button = !multiline && this.hasAttribute("button");
|
|
418
|
+
const next = document.createElement(button ? "button" : multiline ? "textarea" : "input");
|
|
419
|
+
if (next instanceof HTMLButtonElement) next.type = "button";
|
|
322
420
|
next.setAttribute("part", "input");
|
|
323
421
|
if (this.control) this.control.replaceWith(next);
|
|
324
422
|
else this.leadingSlot.after(next);
|
|
@@ -329,23 +427,29 @@ class AInputElement extends HTMLElementBase {
|
|
|
329
427
|
}
|
|
330
428
|
this.syncDisabled();
|
|
331
429
|
this.syncStatus();
|
|
430
|
+
for (const [name, value2] of this.delegatedAria) applyShadowAria(this, next, name, value2);
|
|
431
|
+
this.queueDelegatedAria();
|
|
332
432
|
this.applyLabelAria();
|
|
333
433
|
this.applyDescriptionAria();
|
|
434
|
+
this.applyPopupAria();
|
|
334
435
|
if (multiline) this.configureTextarea(next);
|
|
335
436
|
const value = initial ?? this.pendingValue ?? this.getAttribute("value") ?? this.getAttribute("defaultvalue") ?? "";
|
|
336
437
|
next.value = value;
|
|
438
|
+
this.syncButtonPresentation();
|
|
337
439
|
next.addEventListener("input", this.onInput);
|
|
338
440
|
next.addEventListener("change", this.onChange);
|
|
339
441
|
next.addEventListener("focus", this.onFocus);
|
|
340
442
|
next.addEventListener("blur", this.onBlur);
|
|
341
443
|
if (refocus) {
|
|
342
444
|
next.focus();
|
|
343
|
-
if (selStart != null)
|
|
344
|
-
|
|
345
|
-
|
|
445
|
+
if (selStart != null && (next instanceof HTMLInputElement || next instanceof HTMLTextAreaElement)) {
|
|
446
|
+
try {
|
|
447
|
+
next.setSelectionRange(selStart, selEnd ?? selStart);
|
|
448
|
+
} catch {
|
|
449
|
+
}
|
|
346
450
|
}
|
|
347
451
|
}
|
|
348
|
-
this.
|
|
452
|
+
this.syncFormValue(value);
|
|
349
453
|
this.updateValidity();
|
|
350
454
|
this.updateFilled();
|
|
351
455
|
this.syncAutoHeight();
|
|
@@ -385,6 +489,7 @@ class AInputElement extends HTMLElementBase {
|
|
|
385
489
|
forward(name, value) {
|
|
386
490
|
const c = this.control;
|
|
387
491
|
if (!c) return;
|
|
492
|
+
if (c instanceof HTMLButtonElement) return;
|
|
388
493
|
if (c instanceof HTMLTextAreaElement && name === "type") return;
|
|
389
494
|
if (BOOL_FORWARDED.has(name)) c.toggleAttribute(name, value != null);
|
|
390
495
|
else if (value == null) c.removeAttribute(name);
|
|
@@ -393,6 +498,16 @@ class AInputElement extends HTMLElementBase {
|
|
|
393
498
|
syncDisabled() {
|
|
394
499
|
if (this.control) this.control.disabled = this.hasAttribute("disabled") || this.formDisabled;
|
|
395
500
|
}
|
|
501
|
+
syncButtonPresentation() {
|
|
502
|
+
const button = this.control;
|
|
503
|
+
if (!(button instanceof HTMLButtonElement)) return;
|
|
504
|
+
const value = button.value;
|
|
505
|
+
button.textContent = value || this.getAttribute("placeholder") || "";
|
|
506
|
+
button.classList.toggle("placeholder", !value);
|
|
507
|
+
}
|
|
508
|
+
syncFormValue(value) {
|
|
509
|
+
this.internals?.setFormValue(this.control instanceof HTMLButtonElement ? null : value);
|
|
510
|
+
}
|
|
396
511
|
/** Reflect `status` into the control's `aria-invalid` and the `:state(invalid)`
|
|
397
512
|
* custom state. Called on `status` change AND from buildControl — so a field
|
|
398
513
|
* that mounts already `status="critical"` gets `:state(invalid)` on the FIRST
|
|
@@ -400,7 +515,8 @@ class AInputElement extends HTMLElementBase {
|
|
|
400
515
|
* `ready` is false and the early-return skips it). */
|
|
401
516
|
syncStatus() {
|
|
402
517
|
const critical = this.getAttribute("status") === "critical";
|
|
403
|
-
this.
|
|
518
|
+
const explicit = this.delegatedAria.get("aria-invalid");
|
|
519
|
+
this.control?.setAttribute("aria-invalid", explicit ?? (critical ? "true" : "false"));
|
|
404
520
|
try {
|
|
405
521
|
critical ? this.internals?.states?.add("invalid") : this.internals?.states?.delete("invalid");
|
|
406
522
|
} catch {
|
|
@@ -408,7 +524,7 @@ class AInputElement extends HTMLElementBase {
|
|
|
408
524
|
}
|
|
409
525
|
onInput = (event) => {
|
|
410
526
|
const v = this.control?.value ?? "";
|
|
411
|
-
this.
|
|
527
|
+
this.syncFormValue(v);
|
|
412
528
|
this.updateValidity();
|
|
413
529
|
this.updateFilled();
|
|
414
530
|
this.syncAutoHeight();
|
|
@@ -441,7 +557,7 @@ class AInputElement extends HTMLElementBase {
|
|
|
441
557
|
applyLabelAria() {
|
|
442
558
|
const c = this.control;
|
|
443
559
|
if (!c) return;
|
|
444
|
-
if (this.
|
|
560
|
+
if (this.delegatedAria.has("aria-label") || this.delegatedAria.has("aria-labelledby")) return;
|
|
445
561
|
const text = this.labelSlot.assignedNodes().map((n) => n.textContent ?? "").join(" ").trim();
|
|
446
562
|
if (text) c.setAttribute("aria-label", text);
|
|
447
563
|
else c.removeAttribute("aria-label");
|
|
@@ -452,11 +568,22 @@ class AInputElement extends HTMLElementBase {
|
|
|
452
568
|
applyDescriptionAria() {
|
|
453
569
|
const c = this.control;
|
|
454
570
|
if (!c) return;
|
|
455
|
-
if (this.
|
|
571
|
+
if (this.delegatedAria.has("aria-description") || this.delegatedAria.has("aria-describedby")) return;
|
|
456
572
|
const text = this.hintSlot.assignedNodes().map((n) => n.textContent ?? "").join(" ").trim();
|
|
457
573
|
if (text) c.setAttribute("aria-description", text);
|
|
458
574
|
else c.removeAttribute("aria-description");
|
|
459
575
|
}
|
|
576
|
+
applyPopupAria() {
|
|
577
|
+
const control = this.control;
|
|
578
|
+
if (!control) return;
|
|
579
|
+
try {
|
|
580
|
+
if (!this.delegatedAria.has("aria-controls") && "ariaControlsElements" in control)
|
|
581
|
+
control.ariaControlsElements = this.popupControls ? [this.popupControls] : null;
|
|
582
|
+
if (!this.delegatedAria.has("aria-activedescendant") && "ariaActiveDescendantElement" in control)
|
|
583
|
+
control.ariaActiveDescendantElement = this.popupActiveDescendant;
|
|
584
|
+
} catch {
|
|
585
|
+
}
|
|
586
|
+
}
|
|
460
587
|
updateFilled() {
|
|
461
588
|
if (this.value) this.internals?.states?.add("filled");
|
|
462
589
|
else this.internals?.states?.delete("filled");
|
|
@@ -479,7 +606,8 @@ class AInputElement extends HTMLElementBase {
|
|
|
479
606
|
set value(v) {
|
|
480
607
|
this.pendingValue = v;
|
|
481
608
|
if (this.control && this.control.value !== v) this.control.value = v;
|
|
482
|
-
this.
|
|
609
|
+
this.syncButtonPresentation();
|
|
610
|
+
this.syncFormValue(v);
|
|
483
611
|
this.updateValidity();
|
|
484
612
|
this.updateFilled();
|
|
485
613
|
this.syncAutoHeight();
|
|
@@ -495,7 +623,8 @@ class AInputElement extends HTMLElementBase {
|
|
|
495
623
|
clear() {
|
|
496
624
|
if (!this.control) return;
|
|
497
625
|
this.control.value = "";
|
|
498
|
-
this.
|
|
626
|
+
this.syncButtonPresentation();
|
|
627
|
+
this.syncFormValue("");
|
|
499
628
|
this.updateValidity();
|
|
500
629
|
this.updateFilled();
|
|
501
630
|
this.syncAutoHeight();
|
|
@@ -543,6 +672,18 @@ class AInputElement extends HTMLElementBase {
|
|
|
543
672
|
this.value = state ?? "";
|
|
544
673
|
}
|
|
545
674
|
}
|
|
675
|
+
for (const name of SHADOW_ARIA_ATTRIBUTES) {
|
|
676
|
+
Object.defineProperty(AInputElement.prototype, ariaAttributeProperty(name), {
|
|
677
|
+
configurable: true,
|
|
678
|
+
enumerable: true,
|
|
679
|
+
get() {
|
|
680
|
+
return this[READ_DELEGATED_ARIA](name);
|
|
681
|
+
},
|
|
682
|
+
set(value) {
|
|
683
|
+
this[WRITE_DELEGATED_ARIA](name, value);
|
|
684
|
+
}
|
|
685
|
+
});
|
|
686
|
+
}
|
|
546
687
|
function register_a_input() {
|
|
547
688
|
if (typeof customElements === "undefined") return;
|
|
548
689
|
if (!customElements.get("a-input")) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer anta.components{a-loader{color:var(--text-3)}@media not (forced-colors:active){a-loader[tone=brand]{color:var(--text-2-brand)}a-loader[tone=info]{color:var(--text-2-info)}a-loader[tone=success]{color:var(--text-2-success)}a-loader[tone=warning]{color:var(--text-2-warning)}a-loader[tone=critical]{color:var(--text-2-critical)}}:where(a-loader,a-icon[shape=loader]){display:inline-block;inline-size:var(--loader-size, var(--icon-size, 16px));block-size:var(--loader-size, var(--icon-size, 16px));flex:none;vertical-align:middle;border-radius:50%;animation:loader-spin var(--loader-speed, .75s) linear infinite;animation-delay:-9999s}a-loader{background:conic-gradient(from 0deg,color-mix(in oklch,currentColor 6%,transparent),color-mix(in oklch,currentColor 70%,transparent))}a-icon[shape=loader]{-webkit-mask-image:conic-gradient(from 0deg,color-mix(in oklch,#000 6%,transparent),color-mix(in oklch,#000 70%,transparent));mask-image:conic-gradient(from 0deg,color-mix(in oklch,#000 6%,transparent),color-mix(in oklch,#000 75%,transparent))}a-loader[value]{background:conic-gradient(from 0deg,color-mix(in oklch,currentColor 60%,transparent) 0,color-mix(in oklch,currentColor 75%,transparent) var(--loader-value, 0%),color-mix(in oklch,currentColor 6%,transparent) var(--loader-value, 0%) 100%);animation:none}@keyframes loader-spin{to{transform:rotate(1turn)}}@media(forced-colors:active){a-loader{forced-color-adjust:none;color:CanvasText}}}
|
|
1
|
+
@layer base,anta,components,utilities;@layer anta.reset,anta.components,anta.theme;@layer anta.components{a-loader{color:var(--text-3)}@media not (forced-colors:active){a-loader[tone=brand]{color:var(--text-2-brand)}a-loader[tone=info]{color:var(--text-2-info)}a-loader[tone=success]{color:var(--text-2-success)}a-loader[tone=warning]{color:var(--text-2-warning)}a-loader[tone=critical]{color:var(--text-2-critical)}}:where(a-loader,a-icon[shape=loader]){display:inline-block;inline-size:var(--loader-size, var(--icon-size, 16px));block-size:var(--loader-size, var(--icon-size, 16px));flex:none;vertical-align:middle;border-radius:50%;animation:loader-spin var(--loader-speed, .75s) linear infinite;animation-delay:-9999s}a-loader{background:conic-gradient(from 0deg,color-mix(in oklch,currentColor 6%,transparent),color-mix(in oklch,currentColor 70%,transparent))}a-icon[shape=loader]{-webkit-mask-image:conic-gradient(from 0deg,color-mix(in oklch,#000 6%,transparent),color-mix(in oklch,#000 70%,transparent));mask-image:conic-gradient(from 0deg,color-mix(in oklch,#000 6%,transparent),color-mix(in oklch,#000 75%,transparent))}a-loader[value]{background:conic-gradient(from 0deg,color-mix(in oklch,currentColor 60%,transparent) 0,color-mix(in oklch,currentColor 75%,transparent) var(--loader-value, 0%),color-mix(in oklch,currentColor 6%,transparent) var(--loader-value, 0%) 100%);animation:none}@keyframes loader-spin{to{transform:rotate(1turn)}}@media(forced-colors:active){a-loader{forced-color-adjust:none;color:CanvasText}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer anta.components{a-menu-group:not(:defined){display:none}a-menu-group{display:flex;flex-direction:column;gap:1px}a-menu-group-label{display:block;padding:6px 8px 2px;color:var(--text-5);font-size:.75em;font-weight:600;letter-spacing:.
|
|
1
|
+
@layer base,anta,components,utilities;@layer anta.reset,anta.components,anta.theme;@layer anta.components{a-menu-group:not(:defined){display:none}a-menu-group{display:flex;flex-direction:column;gap:1px}a-menu-group-label{display:block;padding:6px 8px 2px;color:var(--text-5);font-size:.75em;font-weight:600;letter-spacing:.03em;text-transform:uppercase;user-select:none}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer anta.components{a-menu-item:not(:defined){display:none}a[data-anta-menu-item]{text-decoration:none}a-menu-item,a[data-anta-menu-item]{--menu-item-color: var(--text-2);--menu-item-icon-color: var(--text-3);--menu-item-hint-color: var(--text-3);--menu-item-hover-bg: light-dark( color-mix(in oklch, currentColor 5%, transparent), color-mix(in oklch, currentColor 10%, transparent) );--menu-item-active-bg: light-dark( color-mix(in oklch, currentColor 8%, transparent), color-mix(in oklch, currentColor 14%, transparent) );--menu-item-selected-bg: var(--menu-item-active-bg);--menu-item-timing-in: 60ms ease-in-out;--menu-item-timing-out: .28s ease-out;--menu-item-padding-x: 8px;--menu-item-padding-y: 6px;display:flex;flex-shrink:0;align-items:center;gap:.6ch;box-sizing:border-box;width:100%;min-height:28px;padding-block:var(--menu-item-padding-y);padding-inline:var(--menu-item-padding-x);border-radius:var(--radius-sm, 4px);color:var(--menu-item-color);background:transparent;transition:background-color var(--menu-item-timing-out);font:inherit;font-variation-settings:inherit;font-size:14px;line-height:16px;text-align:left;white-space:nowrap;cursor:pointer;user-select:none;outline:none}a-menu[round] a-menu-item,a-menu[round] a[data-anta-menu-item]{border-radius:999px}a-menu-item:hover,a-menu-item:focus-visible,a[data-anta-menu-item]:hover,a[data-anta-menu-item]:focus-visible,a-menu-item:has(>a-menu:state(open)),a-menu-item:state(active){background:var(--menu-item-hover-bg);transition:background-color var(--menu-item-timing-in)}a-menu-item:active,a[data-anta-menu-item]:active{background:var(--menu-item-active-bg);transition:none}a-menu-item[selected],a[data-anta-menu-item][aria-current=true]{background:var(--menu-item-selected-bg)}a-menu-item:focus-visible,a[data-anta-menu-item]:focus-visible{outline:1px solid var(--focus-ring);outline-offset:1px}a-menu-item>a-menu-item-label,a-menu-item>a-menu-item-text,a[data-anta-menu-item]>a-menu-item-label,a[data-anta-menu-item]>a-menu-item-text{flex:1 1 auto;min-width:0}a-menu-item>a-menu-item-text,a[data-anta-menu-item]>a-menu-item-text{display:flex;flex-direction:column}a-menu-item:has(>a-menu-item-text),a[data-anta-menu-item]:has(>a-menu-item-text){align-items:flex-start}a-menu-item-label{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis}a-menu-item-hint{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;margin-block-start:1px;color:var(--menu-item-hint-color);font-size:12px;line-height:15px}a-menu-item>a-icon,a[data-anta-menu-item]>a-icon{flex:none;--icon-size: 16px;color:var(--menu-item-icon-color)}a-menu-item>a-checkbox,a-menu-item>a-radio{flex:none;--checkbox-gap: 0;--radio-gap: 0;pointer-events:none}a-menu-item>a-checkbox:before,a-menu-item>a-checkbox:after,a-menu-item>a-radio:before{margin-block-start:0}a-menu-item>a-radio:after{margin-block-start:calc((var(--radio-control-size) - (var(--radio-dot-size) - var(--_radio-dot-adjust))) / 2)}a-menu-item:has(>:is(a-icon,a-checkbox,a-radio,[data-indicator]):first-child:not(:only-child)),a[data-anta-menu-item]:has(>:is(a-icon,[data-indicator]):first-child:not(:only-child)){padding-inline-start:var(--menu-item-padding-y)}a-menu-item:not([submenu]):has(>a-icon:last-child:not(:only-child)),a[data-anta-menu-item]:has(>a-icon:last-child:not(:only-child)){padding-inline-end:max(0px,var(--menu-item-padding-x) - 2px)}a-menu-item>kbd,a[data-anta-menu-item]>kbd{flex:none;margin-left:auto;padding-left:12px;color:var(--text-5);font:inherit;font-variation-settings:inherit;font-size:1em;letter-spacing:.1ch;white-space:nowrap}a-menu-item[submenu]>a-icon:last-of-type{margin-left:auto}a-menu-item[submenu]>a-icon:last-of-type,a-menu-item>a-icon:last-child:not(:only-child),a[data-anta-menu-item]>a-icon:last-child:not(:only-child){position:relative;inset-inline-end:-2px}a-menu-item[tone=brand],a-menu-item[tone=info],a-menu-item[tone=success],a-menu-item[tone=warning],a-menu-item[tone=critical],a[data-anta-menu-item][tone=brand],a[data-anta-menu-item][tone=info],a[data-anta-menu-item][tone=success],a[data-anta-menu-item][tone=warning],a[data-anta-menu-item][tone=critical]{--menu-item-icon-color: var(--menu-item-color)}a-menu-item[tone=brand],a[data-anta-menu-item][tone=brand]{--menu-item-color: var(--text-2-brand);--menu-item-hint-color: var(--text-3-brand)}a-menu-item[tone=info],a[data-anta-menu-item][tone=info]{--menu-item-color: var(--text-2-info);--menu-item-hint-color: var(--text-3-info)}a-menu-item[tone=success],a[data-anta-menu-item][tone=success]{--menu-item-color: var(--text-2-success);--menu-item-hint-color: var(--text-3-success)}a-menu-item[tone=warning],a[data-anta-menu-item][tone=warning]{--menu-item-color: var(--text-2-warning);--menu-item-hint-color: var(--text-3-warning)}a-menu-item[tone=critical],a[data-anta-menu-item][tone=critical]{--menu-item-color: var(--text-2-critical);--menu-item-hint-color: var(--text-3-critical)}a-menu-item[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]),a[data-anta-menu-item][tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]){--menu-item-tone-source: var(--text-2);--menu-item-color: light-dark( oklch(from var(--menu-item-tone-source) .45 c h), oklch(from var(--menu-item-tone-source) .78 c h) );--menu-item-icon-color: var(--menu-item-color);--menu-item-hint-color: light-dark( oklch(from var(--menu-item-tone-source) .45 c h / .8), oklch(from var(--menu-item-tone-source) .78 c h / .8) );@supports (color: attr(probe type(<color>),red)){--menu-item-tone-source: attr(tone type(<color>), var(--text-2))}}a-menu-item[disabled],a[data-anta-menu-item][aria-disabled=true]{--menu-item-color: var(--text-5);--menu-item-icon-color: var(--text-5);--menu-item-hint-color: var(--text-5);cursor:default;pointer-events:none}}
|
|
1
|
+
@layer base,anta,components,utilities;@layer anta.reset,anta.components,anta.theme;@layer anta.components{a-menu-item:not(:defined){display:none}a[data-anta-menu-item]{text-decoration:none}a-menu-item,a[data-anta-menu-item]{--menu-item-color: var(--text-2);--menu-item-icon-color: var(--text-3);--menu-item-hint-color: var(--text-3);--menu-item-hover-bg: light-dark( color-mix(in oklch, currentColor 5%, transparent), color-mix(in oklch, currentColor 10%, transparent) );--menu-item-active-bg: light-dark( color-mix(in oklch, currentColor 8%, transparent), color-mix(in oklch, currentColor 14%, transparent) );--menu-item-selected-bg: var(--menu-item-active-bg);--menu-item-timing-in: 60ms ease-in-out;--menu-item-timing-out: .28s ease-out;--menu-item-padding-x: 8px;--menu-item-padding-y: 6px;display:flex;flex-shrink:0;align-items:center;gap:.6ch;box-sizing:border-box;width:100%;min-height:28px;padding-block:var(--menu-item-padding-y);padding-inline:var(--menu-item-padding-x);border-radius:var(--radius-sm, 4px);color:var(--menu-item-color);background:transparent;transition:background-color var(--menu-item-timing-out);font:inherit;font-variation-settings:inherit;font-size:14px;line-height:16px;text-align:left;white-space:nowrap;cursor:pointer;user-select:none;outline:none}a-menu[round] a-menu-item,a-menu[round] a[data-anta-menu-item]{border-radius:999px}a-menu-item:hover,a-menu-item:focus-visible,a[data-anta-menu-item]:hover,a[data-anta-menu-item]:focus-visible,a-menu-item:has(>a-menu:state(open)),a-menu-item:state(active){background:var(--menu-item-hover-bg);transition:background-color var(--menu-item-timing-in)}a-menu-item:active,a[data-anta-menu-item]:active{background:var(--menu-item-active-bg);transition:none}a-menu-item[selected],a[data-anta-menu-item][aria-current=true]{background:var(--menu-item-selected-bg)}a-menu-item:focus-visible,a[data-anta-menu-item]:focus-visible{outline:1px solid var(--focus-ring);outline-offset:1px}a-menu-item>a-menu-item-label,a-menu-item>a-menu-item-text,a[data-anta-menu-item]>a-menu-item-label,a[data-anta-menu-item]>a-menu-item-text{flex:1 1 auto;min-width:0}a-menu-item>a-menu-item-text,a[data-anta-menu-item]>a-menu-item-text{display:flex;flex-direction:column}a-menu-item:has(>a-menu-item-text),a[data-anta-menu-item]:has(>a-menu-item-text){align-items:flex-start}a-menu-item-label{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis}a-menu-item-hint{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;margin-block-start:1px;color:var(--menu-item-hint-color);font-size:12px;line-height:15px}a-menu-item>a-icon,a[data-anta-menu-item]>a-icon{flex:none;--icon-size: 16px;color:var(--menu-item-icon-color)}a-menu-item>a-checkbox,a-menu-item>a-radio{flex:none;--checkbox-gap: 0;--radio-gap: 0;pointer-events:none}a-menu-item>a-checkbox:before,a-menu-item>a-checkbox:after,a-menu-item>a-radio:before{margin-block-start:0}a-menu-item>a-radio:after{margin-block-start:calc((var(--radio-control-size) - (var(--radio-dot-size) - var(--_radio-dot-adjust))) / 2)}a-menu-item:has(>:is(a-icon,a-checkbox,a-radio,[data-indicator]):first-child:not(:only-child)),a[data-anta-menu-item]:has(>:is(a-icon,[data-indicator]):first-child:not(:only-child)){padding-inline-start:var(--menu-item-padding-y)}a-menu-item:not([submenu]):has(>a-icon:last-child:not(:only-child)),a[data-anta-menu-item]:has(>a-icon:last-child:not(:only-child)){padding-inline-end:max(0px,var(--menu-item-padding-x) - 2px)}a-menu-item>kbd,a[data-anta-menu-item]>kbd{flex:none;margin-left:auto;padding-left:12px;color:var(--text-5);font:inherit;font-variation-settings:inherit;font-size:1em;letter-spacing:.1ch;white-space:nowrap}a-menu-item[submenu]>a-icon:last-of-type{margin-left:auto}a-menu-item[submenu]>a-icon:last-of-type,a-menu-item>a-icon:last-child:not(:only-child),a[data-anta-menu-item]>a-icon:last-child:not(:only-child){position:relative;inset-inline-end:-2px}a-menu-item[tone=brand],a-menu-item[tone=info],a-menu-item[tone=success],a-menu-item[tone=warning],a-menu-item[tone=critical],a[data-anta-menu-item][tone=brand],a[data-anta-menu-item][tone=info],a[data-anta-menu-item][tone=success],a[data-anta-menu-item][tone=warning],a[data-anta-menu-item][tone=critical]{--menu-item-icon-color: var(--menu-item-color)}a-menu-item[tone=brand],a[data-anta-menu-item][tone=brand]{--menu-item-color: var(--text-2-brand);--menu-item-hint-color: var(--text-3-brand)}a-menu-item[tone=info],a[data-anta-menu-item][tone=info]{--menu-item-color: var(--text-2-info);--menu-item-hint-color: var(--text-3-info)}a-menu-item[tone=success],a[data-anta-menu-item][tone=success]{--menu-item-color: var(--text-2-success);--menu-item-hint-color: var(--text-3-success)}a-menu-item[tone=warning],a[data-anta-menu-item][tone=warning]{--menu-item-color: var(--text-2-warning);--menu-item-hint-color: var(--text-3-warning)}a-menu-item[tone=critical],a[data-anta-menu-item][tone=critical]{--menu-item-color: var(--text-2-critical);--menu-item-hint-color: var(--text-3-critical)}a-menu-item[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]),a[data-anta-menu-item][tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]){--menu-item-tone-source: var(--text-2);--menu-item-color: light-dark( oklch(from var(--menu-item-tone-source) .45 c h), oklch(from var(--menu-item-tone-source) .78 c h) );--menu-item-icon-color: var(--menu-item-color);--menu-item-hint-color: light-dark( oklch(from var(--menu-item-tone-source) .45 c h / .8), oklch(from var(--menu-item-tone-source) .78 c h / .8) );@supports (color: attr(probe type(<color>),red)){--menu-item-tone-source: attr(tone type(<color>), var(--text-2))}}a-menu-item[disabled],a[data-anta-menu-item][aria-disabled=true]{--menu-item-color: var(--text-5);--menu-item-icon-color: var(--text-5);--menu-item-hint-color: var(--text-5);cursor:default;pointer-events:none}}
|
|
@@ -15,6 +15,7 @@ class AMenuItemElement extends HTMLElementBase {
|
|
|
15
15
|
if (!this.internals) return;
|
|
16
16
|
if (on) this.internals?.states?.add("active");
|
|
17
17
|
else this.internals?.states?.delete("active");
|
|
18
|
+
this.internals.ariaSelected = this.getAttribute("role") === "option" ? on ? "true" : "false" : null;
|
|
18
19
|
}
|
|
19
20
|
get active() {
|
|
20
21
|
return this.internals?.states?.has("active") ?? false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer anta.components{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
|
+
@layer base,anta,components,utilities;@layer anta.reset,anta.components,anta.theme;@layer anta.components{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}}
|
package/dist/elements/a-menu.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer anta.components{a-menu:not(:defined){display:none}a-menu{--menu-bg: light-dark( color-mix(in oklch, var(--bg-1) 90%, transparent), color-mix(in oklch, var(--bg-1) 78%, 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);--menu-width-duration: .16s}@media(prefers-reduced-motion:reduce){a-menu{--menu-width-duration: 0}}a-menu[round]{--menu-radius: 20px;@supports (border-radius: attr(probe type(<length>),1px)){--menu-radius: attr(round type(<length>), 20px)}}.dark a-menu{--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 base,anta,components,utilities;@layer anta.reset,anta.components,anta.theme;@layer anta.components{a-menu:not(:defined){display:none}a-menu{--menu-bg: light-dark( color-mix(in oklch, var(--bg-1) 90%, transparent), color-mix(in oklch, var(--bg-1) 78%, 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);--menu-width-duration: .16s}@media(prefers-reduced-motion:reduce){a-menu{--menu-width-duration: 0}}a-menu[round]{--menu-radius: 20px;@supports (border-radius: attr(probe type(<length>),1px)){--menu-radius: attr(round type(<length>), 20px)}}.dark a-menu{--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)}}
|
|
@@ -42,6 +42,7 @@ export declare class AMenuElement extends HTMLElementBase {
|
|
|
42
42
|
private typeTimer?;
|
|
43
43
|
private activeItem;
|
|
44
44
|
private comboObserver?;
|
|
45
|
+
private accessibilityObserver?;
|
|
45
46
|
private _flippedTop;
|
|
46
47
|
private _flippedSide;
|
|
47
48
|
constructor();
|
|
@@ -73,9 +74,7 @@ export declare class AMenuElement extends HTMLElementBase {
|
|
|
73
74
|
* `.focus()` on one silently fails). `getClientRects` is the fallback where
|
|
74
75
|
* `checkVisibility` isn't available. */
|
|
75
76
|
private isVisible;
|
|
76
|
-
/**
|
|
77
|
-
* End / type-ahead navigation). Same visibility / disabled / ownership
|
|
78
|
-
* filter — just narrowed to `a-menu-item`. */
|
|
77
|
+
/** Custom menu rows that support the combobox cursor and selection state. */
|
|
79
78
|
private focusableItems;
|
|
80
79
|
/** The rows the arrow keys / Home / End / initial-focus step between:
|
|
81
80
|
* `focusableItems()` PLUS native-anchor link items (`<a data-anta-menu-item>`),
|
|
@@ -83,10 +82,7 @@ export declare class AMenuElement extends HTMLElementBase {
|
|
|
83
82
|
* custom-element-only because the combobox cursor (`setActive`) and selection
|
|
84
83
|
* seating are `a-menu-item` affordances a plain link doesn't carry. */
|
|
85
84
|
private navigableItems;
|
|
86
|
-
/**
|
|
87
|
-
* like inputs / sliders / buttons), in DOM order, visible and enabled —
|
|
88
|
-
* used to trap Tab within the open menu. Submenu contents are excluded
|
|
89
|
-
* (their nearest `a-menu` is the submenu). */
|
|
85
|
+
/** Tab stops in rendered order, excluding controls owned by nested menus. */
|
|
90
86
|
private focusables;
|
|
91
87
|
/** On open, seat initial focus like a native `<select>` / macOS menu: a menu
|
|
92
88
|
* carrying a current value opens *at* that value, not at the top. Brings the
|
|
@@ -107,10 +103,9 @@ export declare class AMenuElement extends HTMLElementBase {
|
|
|
107
103
|
* `.scroll` mask reads; runs on scroll and after every (re)position.
|
|
108
104
|
* Shadow-internal only. */
|
|
109
105
|
private updateScrollFade;
|
|
110
|
-
/** Move the combobox cursor. Sets the item's `active`
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
* `aria-activedescendant` on the light-DOM field. `null` clears the cursor. */
|
|
106
|
+
/** Move the combobox cursor. Sets the item's `active` property for its
|
|
107
|
+
* off-DOM highlight/selected state, associates it directly with an Anta
|
|
108
|
+
* Input, and reports it for raw/custom observers. `null` clears the cursor. */
|
|
114
109
|
private setActive;
|
|
115
110
|
/** Re-seat the cursor on the first option — but only once the filter has input.
|
|
116
111
|
* An empty filter (e.g. right after opening) shows NO active row, so the first
|
|
@@ -168,8 +163,8 @@ export declare class AMenuElement extends HTMLElementBase {
|
|
|
168
163
|
* mutates deep in its subtree, not this menu's direct children, so it won't
|
|
169
164
|
* spuriously reset the cursor. */
|
|
170
165
|
private startComboObserver;
|
|
171
|
-
/** Apply CLOSE
|
|
172
|
-
*
|
|
166
|
+
/** Apply CLOSE without notifying this menu's owner. Notify nested menus so
|
|
167
|
+
* their controlled state follows the closing parent. */
|
|
173
168
|
private hide;
|
|
174
169
|
/** Shadow-only show: open the popover and position it. `instant` positions
|
|
175
170
|
* synchronously (no rAF), so a menu opening over an already-visible one is
|