@antadesign/anta 0.3.5 → 0.3.7
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/dist/anta_helpers.d.ts +10 -0
- package/dist/anta_helpers.js +8 -0
- package/dist/components/Card.d.ts +86 -0
- package/dist/components/Card.js +72 -0
- package/dist/components/Dialog.d.ts +92 -0
- package/dist/components/Dialog.js +71 -0
- package/dist/components/Input.d.ts +3 -0
- package/dist/components/InputAutocomplete.d.ts +69 -0
- package/dist/components/InputAutocomplete.js +95 -0
- package/dist/components/InputDate.js +1 -2
- package/dist/components/Menu.d.ts +4 -1
- package/dist/components/Menu.js +2 -1
- package/dist/components/MenuItem.d.ts +9 -1
- package/dist/components/MenuItem.js +2 -1
- package/dist/components/Select.d.ts +5 -2
- package/dist/components/Select.js +11 -34
- package/dist/components/SelectFaceted.d.ts +7 -1
- package/dist/components/SelectFaceted.js +12 -11
- package/dist/components/select-options.d.ts +14 -0
- package/dist/components/select-options.js +31 -0
- package/dist/elements/a-card.css +211 -0
- package/dist/elements/a-card.d.ts +10 -0
- package/dist/elements/a-card.js +213 -0
- package/dist/elements/a-checkbox.css +1 -1
- package/dist/elements/a-dialog.css +1 -0
- package/dist/elements/a-dialog.d.ts +26 -0
- package/dist/elements/a-dialog.js +386 -0
- package/dist/elements/a-expander.js +2 -2
- package/dist/elements/a-input-time.js +2 -1
- package/dist/elements/a-input.d.ts +2 -0
- package/dist/elements/a-input.js +34 -1
- package/dist/elements/a-menu.d.ts +5 -2
- package/dist/elements/a-menu.js +52 -15
- package/dist/elements/a-radio.css +1 -1
- package/dist/elements/a-tooltip.d.ts +17 -0
- package/dist/elements/a-tooltip.js +28 -0
- package/dist/elements/index.d.ts +1 -0
- package/dist/elements/index.js +3 -0
- package/dist/general_types.d.ts +45 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/jsx-runtime.d.ts +2 -1
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HTMLElementBase } from "../anta_helpers";
|
|
1
|
+
import { HTMLElementBase, parseOpenState } from "../anta_helpers";
|
|
2
2
|
import "./a-expander.css";
|
|
3
3
|
const ANIM_MS = 200;
|
|
4
4
|
const SUMMARY_TYPE_SCALE = {
|
|
@@ -139,7 +139,7 @@ const SHADOW_STYLE = `
|
|
|
139
139
|
transition-behavior: allow-discrete;
|
|
140
140
|
}
|
|
141
141
|
`;
|
|
142
|
-
const parseState =
|
|
142
|
+
const parseState = parseOpenState;
|
|
143
143
|
class AExpanderElement extends HTMLElementBase {
|
|
144
144
|
static observedAttributes = ["state", "disabled", "round"];
|
|
145
145
|
summary;
|
|
@@ -94,6 +94,7 @@ const SHADOW_STYLE = `
|
|
|
94
94
|
padding-inline: 1px;
|
|
95
95
|
border-radius: 2px;
|
|
96
96
|
text-align: center;
|
|
97
|
+
white-space: nowrap;
|
|
97
98
|
outline: none;
|
|
98
99
|
cursor: default;
|
|
99
100
|
font-variant-numeric: tabular-nums;
|
|
@@ -102,7 +103,7 @@ const SHADOW_STYLE = `
|
|
|
102
103
|
.seg[inputmode="numeric"] {
|
|
103
104
|
/* Fixed to two tabular digits so the box never reflows: neither the narrower
|
|
104
105
|
placeholder dashes nor a mid-entry single digit changes the field width. */
|
|
105
|
-
width: calc(2ch +
|
|
106
|
+
width: calc(2ch + 4px);
|
|
106
107
|
}
|
|
107
108
|
.seg:focus {
|
|
108
109
|
background: var(--input-time-seg-focus-bg);
|
package/dist/elements/a-input.js
CHANGED
|
@@ -22,6 +22,18 @@ const FORWARDED = [
|
|
|
22
22
|
"aria-label"
|
|
23
23
|
];
|
|
24
24
|
const BOOL_FORWARDED = /* @__PURE__ */ new Set(["readonly", "required"]);
|
|
25
|
+
let focusFromKeyboard = false;
|
|
26
|
+
const modalityDocs = /* @__PURE__ */ new WeakSet();
|
|
27
|
+
function trackFocusModality(doc) {
|
|
28
|
+
if (modalityDocs.has(doc)) return;
|
|
29
|
+
modalityDocs.add(doc);
|
|
30
|
+
doc.addEventListener("keydown", () => {
|
|
31
|
+
focusFromKeyboard = true;
|
|
32
|
+
}, true);
|
|
33
|
+
doc.addEventListener("pointerdown", () => {
|
|
34
|
+
focusFromKeyboard = false;
|
|
35
|
+
}, true);
|
|
36
|
+
}
|
|
25
37
|
const CLEAR_TRIGGER = "clearrequest";
|
|
26
38
|
const CLEAR_CLICK_EVENT = "clearclick";
|
|
27
39
|
const CLEAR_INPUT_EVENT = "clearinput";
|
|
@@ -72,7 +84,8 @@ const SHADOW_STYLE = `
|
|
|
72
84
|
@media (hover: hover) and (pointer: fine) {
|
|
73
85
|
:host(:not(:disabled)) .field:hover { --_bc: var(--input-border-hover); }
|
|
74
86
|
}
|
|
75
|
-
.field:has(input:focus, textarea:focus)
|
|
87
|
+
:host(:not([readonly])) .field:has(input:focus, textarea:focus),
|
|
88
|
+
:host([readonly]:state(kb-focus)) .field {
|
|
76
89
|
--_bc: var(--input-border-hover);
|
|
77
90
|
outline: 1px solid var(--focus-ring);
|
|
78
91
|
outline-offset: 1px;
|
|
@@ -269,6 +282,7 @@ class AInputElement extends HTMLElementBase {
|
|
|
269
282
|
return this.field.getBoundingClientRect();
|
|
270
283
|
}
|
|
271
284
|
connectedCallback() {
|
|
285
|
+
trackFocusModality(this.doc);
|
|
272
286
|
if (Object.prototype.hasOwnProperty.call(this, "value")) {
|
|
273
287
|
const v = this.value;
|
|
274
288
|
delete this.value;
|
|
@@ -336,6 +350,8 @@ class AInputElement extends HTMLElementBase {
|
|
|
336
350
|
next.value = value;
|
|
337
351
|
next.addEventListener("input", this.onInput);
|
|
338
352
|
next.addEventListener("change", this.onChange);
|
|
353
|
+
next.addEventListener("focus", this.onFocus);
|
|
354
|
+
next.addEventListener("blur", this.onBlur);
|
|
339
355
|
if (refocus) {
|
|
340
356
|
next.focus();
|
|
341
357
|
if (selStart != null) try {
|
|
@@ -415,6 +431,23 @@ class AInputElement extends HTMLElementBase {
|
|
|
415
431
|
onChange = () => {
|
|
416
432
|
this.dispatchEvent(new Event("change", { bubbles: true }));
|
|
417
433
|
};
|
|
434
|
+
// Stamp the off-DOM `:state(kb-focus)` when this focus arrived via the keyboard
|
|
435
|
+
// (see `trackFocusModality`), so the read-only field's ring can draw for keyboard
|
|
436
|
+
// focus but not a mouse click — the one distinction Chromium's `:focus-visible`
|
|
437
|
+
// won't make for an <input>. Editable fields ignore the state (ring on `:focus`).
|
|
438
|
+
onFocus = () => {
|
|
439
|
+
try {
|
|
440
|
+
if (focusFromKeyboard) this.internals?.states.add("kb-focus");
|
|
441
|
+
else this.internals?.states.delete("kb-focus");
|
|
442
|
+
} catch {
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
onBlur = () => {
|
|
446
|
+
try {
|
|
447
|
+
this.internals?.states.delete("kb-focus");
|
|
448
|
+
} catch {
|
|
449
|
+
}
|
|
450
|
+
};
|
|
418
451
|
onLabelSlotChange = () => {
|
|
419
452
|
this.labelBox.classList.toggle("has-label", this.labelSlot.assignedNodes().length > 0);
|
|
420
453
|
this.applyLabelAria();
|
|
@@ -110,8 +110,11 @@ export declare class AMenuElement extends HTMLElementBase {
|
|
|
110
110
|
* the seat target — the cursor lands on the first real option — but they stay
|
|
111
111
|
* arrow-reachable. */
|
|
112
112
|
private resetActive;
|
|
113
|
-
/** Combobox arrow /
|
|
114
|
-
* key (so `handleKey` stops).
|
|
113
|
+
/** Combobox arrow / PageUp / PageDown / Enter handling; returns true if it
|
|
114
|
+
* consumed the key (so `handleKey` stops). Home / End are deliberately NOT
|
|
115
|
+
* handled: focus is in a text field, so they must reach it for caret movement
|
|
116
|
+
* (line start/end); PageUp / PageDown jump the option list to first / last
|
|
117
|
+
* instead. Any other key falls through to the input (typing). */
|
|
115
118
|
private handleComboKey;
|
|
116
119
|
/** Public imperative API. Routes through the same intent path as the
|
|
117
120
|
* triggers, so it emits `statechange` and respects controlled mode. */
|
package/dist/elements/a-menu.js
CHANGED
|
@@ -7,6 +7,8 @@ const SUBMENU_OPEN_DELAY = 130;
|
|
|
7
7
|
const SUBMENU_CLOSE_DELAY = 130;
|
|
8
8
|
const TYPEAHEAD_RESET = 500;
|
|
9
9
|
const ANCHOR_VISIBLE_RATIO = 0.5;
|
|
10
|
+
const SELF_ACTIVATING = 'a-button, button, a[href], input[type="button"], input[type="submit"], input[type="reset"], [role="button"]';
|
|
11
|
+
const EDITABLE_FIELD = "input:not([readonly]), textarea:not([readonly]), a-input:not([readonly]), a-input-time:not([readonly])";
|
|
10
12
|
const openStack = [];
|
|
11
13
|
let docBound = false;
|
|
12
14
|
let boundDoc = null;
|
|
@@ -451,11 +453,22 @@ class AMenuElement extends HTMLElementBase {
|
|
|
451
453
|
el.style.setProperty("--fade-bottom", bottom ? "14px" : "0px");
|
|
452
454
|
}
|
|
453
455
|
/* ------------------------------ combobox mode ------------------------------ */
|
|
454
|
-
/**
|
|
456
|
+
/** Combobox-anchor mode: the trigger anchor ITSELF is the filter field (it
|
|
457
|
+
* carries `[data-menu-search]`), as in `InputAutocomplete` where an editable
|
|
458
|
+
* `<a-input>` is the always-visible field the menu hangs under. null for the
|
|
459
|
+
* normal case — `Select`/`SelectFaceted` slot the field as a child, so their
|
|
460
|
+
* anchor never carries the marker and this stays inert for them. */
|
|
461
|
+
get #comboAnchor() {
|
|
462
|
+
const a = this.triggerAnchor;
|
|
463
|
+
return a?.matches("[data-menu-search]") ? a : null;
|
|
464
|
+
}
|
|
465
|
+
/** The filter field of THIS menu, or null. A slotted child (never a submenu's)
|
|
466
|
+
* wins; else the anchor when it's the field (combobox-anchor mode). Its
|
|
455
467
|
* presence switches the menu to the combobox keyboard. */
|
|
456
468
|
get #searchField() {
|
|
457
469
|
const el = this.querySelector("[data-menu-search]");
|
|
458
|
-
|
|
470
|
+
if (el && el.closest("a-menu") === this) return el;
|
|
471
|
+
return this.#comboAnchor;
|
|
459
472
|
}
|
|
460
473
|
/** Move the combobox cursor. Sets the item's `active` **property** (off-DOM
|
|
461
474
|
* `:state(active)`, no attribute churn) for the highlight, and REPORTS the
|
|
@@ -481,11 +494,15 @@ class AMenuElement extends HTMLElementBase {
|
|
|
481
494
|
resetActive() {
|
|
482
495
|
const q = this.#searchField?.value;
|
|
483
496
|
if (!q || !q.trim()) return this.setActive(null);
|
|
497
|
+
if (this.#comboAnchor) return this.setActive(null);
|
|
484
498
|
const items = this.focusableItems();
|
|
485
499
|
this.setActive(items.find((it) => !it.hasAttribute("data-menu-skip-active")) ?? items[0] ?? null);
|
|
486
500
|
}
|
|
487
|
-
/** Combobox arrow /
|
|
488
|
-
* key (so `handleKey` stops).
|
|
501
|
+
/** Combobox arrow / PageUp / PageDown / Enter handling; returns true if it
|
|
502
|
+
* consumed the key (so `handleKey` stops). Home / End are deliberately NOT
|
|
503
|
+
* handled: focus is in a text field, so they must reach it for caret movement
|
|
504
|
+
* (line start/end); PageUp / PageDown jump the option list to first / last
|
|
505
|
+
* instead. Any other key falls through to the input (typing). */
|
|
489
506
|
handleComboKey(e) {
|
|
490
507
|
const items = this.focusableItems();
|
|
491
508
|
const idx = this.activeItem ? items.indexOf(this.activeItem) : -1;
|
|
@@ -498,11 +515,11 @@ class AMenuElement extends HTMLElementBase {
|
|
|
498
515
|
e.preventDefault();
|
|
499
516
|
this.setActive(items[idx <= 0 ? items.length - 1 : idx - 1] ?? null);
|
|
500
517
|
return true;
|
|
501
|
-
case "
|
|
518
|
+
case "PageUp":
|
|
502
519
|
e.preventDefault();
|
|
503
520
|
this.setActive(items[0] ?? null);
|
|
504
521
|
return true;
|
|
505
|
-
case "
|
|
522
|
+
case "PageDown":
|
|
506
523
|
e.preventDefault();
|
|
507
524
|
this.setActive(items[items.length - 1] ?? null);
|
|
508
525
|
return true;
|
|
@@ -848,6 +865,10 @@ class AMenuElement extends HTMLElementBase {
|
|
|
848
865
|
return;
|
|
849
866
|
}
|
|
850
867
|
if (e.key === "Tab") {
|
|
868
|
+
if (this.#comboAnchor) {
|
|
869
|
+
this.requestClose(e);
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
851
872
|
const f = this.focusables();
|
|
852
873
|
if (!f.length) return;
|
|
853
874
|
e.preventDefault();
|
|
@@ -928,6 +949,12 @@ class AMenuElement extends HTMLElementBase {
|
|
|
928
949
|
return ((label ?? it).textContent ?? "").trim().toLowerCase();
|
|
929
950
|
}
|
|
930
951
|
/* ====================== trigger listener wiring ====================== */
|
|
952
|
+
/** Pointer coord for a keyboard-opened `coord` menu: the trigger's own rect
|
|
953
|
+
* (a DOM read, not a mutation) instead of the 0,0 a keyboard event reports. */
|
|
954
|
+
#anchorCoord(anchor) {
|
|
955
|
+
const r = anchorRect(anchor);
|
|
956
|
+
return [r.left, r.bottom];
|
|
957
|
+
}
|
|
931
958
|
setupListeners() {
|
|
932
959
|
if (this.listening) return;
|
|
933
960
|
const anchor = this.triggerAnchor;
|
|
@@ -969,24 +996,34 @@ class AMenuElement extends HTMLElementBase {
|
|
|
969
996
|
anchor.removeEventListener("contextmenu", onContext);
|
|
970
997
|
this.listening = false;
|
|
971
998
|
};
|
|
999
|
+
} else if (this.#comboAnchor) {
|
|
1000
|
+
this.teardown = () => {
|
|
1001
|
+
this.listening = false;
|
|
1002
|
+
};
|
|
1003
|
+
this.listening = true;
|
|
1004
|
+
return;
|
|
972
1005
|
} else {
|
|
973
1006
|
const onClick = (e) => {
|
|
974
1007
|
const viaKeyboard = e.detail === 0;
|
|
975
|
-
|
|
976
|
-
if (this.#isCoord) {
|
|
977
|
-
if (viaKeyboard) {
|
|
978
|
-
const r = anchorRect(anchor);
|
|
979
|
-
coord = [r.left, r.bottom];
|
|
980
|
-
} else {
|
|
981
|
-
coord = [e.clientX, e.clientY];
|
|
982
|
-
}
|
|
983
|
-
}
|
|
1008
|
+
const coord = this.#isCoord ? viaKeyboard ? this.#anchorCoord(anchor) : [e.clientX, e.clientY] : void 0;
|
|
984
1009
|
if (this._shown) this.requestClose(e);
|
|
985
1010
|
else this.requestOpen({ coord, viaKeyboard, originEvent: e });
|
|
986
1011
|
};
|
|
1012
|
+
const onKey = (e) => {
|
|
1013
|
+
if (this._shown) return;
|
|
1014
|
+
if (anchor.matches(SELF_ACTIVATING) || anchor.hasAttribute("disabled")) return;
|
|
1015
|
+
const editable = anchor.matches(EDITABLE_FIELD);
|
|
1016
|
+
const opens = e.key === "ArrowDown" || e.key === "ArrowUp" || !editable && (e.key === "Enter" || e.key === " ");
|
|
1017
|
+
if (!opens) return;
|
|
1018
|
+
e.preventDefault();
|
|
1019
|
+
const coord = this.#isCoord ? this.#anchorCoord(anchor) : void 0;
|
|
1020
|
+
this.requestOpen({ coord, viaKeyboard: true, originEvent: e });
|
|
1021
|
+
};
|
|
987
1022
|
anchor.addEventListener("click", onClick);
|
|
1023
|
+
anchor.addEventListener("keydown", onKey);
|
|
988
1024
|
this.teardown = () => {
|
|
989
1025
|
anchor.removeEventListener("click", onClick);
|
|
1026
|
+
anchor.removeEventListener("keydown", onKey);
|
|
990
1027
|
this.listening = false;
|
|
991
1028
|
};
|
|
992
1029
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer anta{a-radio{--radio-control-size: 16px;--radio-border-width: 1.5px;--radio-dot-size: 6px;--_radio-dot-adjust: 0px;--radio-gap: 8px;--radio-bg: var(--bg-1);--radio-fill: #878089;--radio-fill-hover: #776e77;--radio-fill-active: #635b65;--radio-border-neutral: #d4ced4;--radio-border: var(--radio-border-neutral);--radio-border-hover: #c1b9c1;--radio-border-active: #9f99a1;--radio-dot: #f1eff1;--radio-dot-disabled: #c1b9c1;--radio-bg-disabled: color-mix(in oklch, #44374b 10%, transparent);--radio-border-disabled: color-mix(in oklch, #44374b 10%, transparent);--radio-label-color: var(--text-2);--radio-label-color-disabled: var(--text-4);--radio-hint-color: var(--text-3);--radio-label-fs: 15px;--radio-label-lh: 20px;--radio-hint-fs: 14px;--radio-hint-lh: 17px;display:inline-grid;grid-template-columns:auto 1fr;align-items:start;column-gap:var(--radio-gap);cursor:pointer;user-select:none;-webkit-user-drag:none;vertical-align:middle;outline:none;color:var(--radio-label-color);font-family:var(--sans-serif);font-size:var(--radio-label-fs);line-height:var(--radio-label-lh);font-feature-settings:"ss02","ss05","tnum";&:before{content:"";grid-column:1;grid-row:1 / -1;align-self:start;margin-block-start:calc((var(--radio-label-lh) - var(--radio-control-size)) / 2);box-sizing:border-box;inline-size:var(--radio-control-size);block-size:var(--radio-control-size);border-radius:50%;background:var(--radio-bg);border:var(--radio-border-width) solid var(--radio-border);transition:background-color .15s ease-out,border-color .15s ease-out}&:after{content:"";grid-column:1;grid-row:1 / -1;align-self:start;justify-self:center;margin-block-start:calc((var(--radio-label-lh) - (var(--radio-dot-size) - var(--_radio-dot-adjust))) / 2);inline-size:calc(var(--radio-dot-size) - var(--_radio-dot-adjust));block-size:calc(var(--radio-dot-size) - var(--_radio-dot-adjust));border-radius:50%;background:var(--radio-dot);transform:scale(0);transition:transform .12s ease-out;pointer-events:none}@media(hover:hover)and (pointer:fine){&:not([disabled]):hover:before{border-color:var(--radio-border-hover);transition:background-color 75ms ease-in,border-color 75ms ease-in}&:not([disabled]):hover:state(selected):before{background:var(--radio-fill-hover);border-color:var(--radio-fill-hover)}}&:not([disabled]):active:before{border-color:var(--radio-border-active);transition:background-color 50ms linear,border-color 50ms linear}&:not([disabled]):active:state(selected):before{background:var(--radio-fill-active);border-color:var(--radio-fill-active)}&:state(selected){&:before{background:var(--radio-fill);border-color:var(--radio-fill)}&:after{transform:scale(1)}}&:focus-visible:before{outline:1px solid var(--focus-ring);outline-offset:1px}&[disabled]{cursor:not-allowed;color:var(--radio-label-color-disabled);&:before{background:var(--radio-bg-disabled);border-color:var(--radio-border-disabled);transition:none}&:state(selected):after{background:var(--radio-dot-disabled)}a-radio-hint{color:var(--radio-label-color-disabled)}}&[size=small]{--radio-control-size: 14px;--radio-dot-size: 5px;--radio-gap: 6px;--radio-label-fs: 13px;--radio-label-lh: 16px;--radio-hint-fs: 12px;--radio-hint-lh: 14px}&[size=large]{--radio-control-size: 18px;--radio-dot-size: 7px;--radio-label-fs: 17px;--radio-label-lh: 22px;--radio-hint-fs: 16px;--radio-hint-lh: 21px}}a-radio-label,a-radio-hint{display:block;grid-column:2;min-width:0}a-radio-hint{color:var(--radio-hint-color);font-size:var(--radio-hint-fs);line-height:var(--radio-hint-lh);margin-block-start:2px}a-radio-group:focus-visible a-radio:state(selected):before{outline:1px solid var(--focus-ring);outline-offset:1px}a-radio[tone=brand],a-radio[tone-selected=brand],a-radio-group[tone=brand] a-radio:not([tone]),a-radio-group[tone-selected=brand] a-radio:not([tone-selected]){--radio-fill: #5f4bc3;--radio-fill-hover: #503cb4;--radio-fill-active: #483493}a-radio[tone=neutral],a-radio[tone-selected=neutral],a-radio-group[tone=neutral] a-radio:not([tone]),a-radio-group[tone-selected=neutral] a-radio:not([tone-selected]){--radio-fill: #878089;--radio-fill-hover: #776e77;--radio-fill-active: #635b65}a-radio[tone=info],a-radio[tone-selected=info],a-radio-group[tone=info] a-radio:not([tone]),a-radio-group[tone-selected=info] a-radio:not([tone-selected]){--radio-fill: #1f6eb2;--radio-fill-hover: #1a5b93;--radio-fill-active: #175082}a-radio[tone=success],a-radio[tone-selected=success],a-radio-group[tone=success] a-radio:not([tone]),a-radio-group[tone-selected=success] a-radio:not([tone-selected]){--radio-fill: #2a7e43;--radio-fill-hover: #226737;--radio-fill-active: #1f5c31}a-radio[tone=warning],a-radio[tone-selected=warning],a-radio-group[tone=warning] a-radio:not([tone]),a-radio-group[tone-selected=warning] a-radio:not([tone-selected]){--radio-fill: #c37416;--radio-fill-hover: #ae6613;--radio-fill-active: #995200}a-radio[tone=critical],a-radio[tone-selected=critical],a-radio-group[tone=critical] a-radio:not([tone]),a-radio-group[tone-selected=critical] a-radio:not([tone-selected]){--radio-fill: #c9302c;--radio-fill-hover: #b02120;--radio-fill-active: #a01c1c}a-radio[tone=brand],a-radio-group[tone=brand] a-radio:not([tone]){--radio-bg: #fcfcfe;--radio-border: #bcb1f1;--radio-border-hover: #9e8eeb;--radio-border-active: #9081df}a-radio[tone=info],a-radio-group[tone=info] a-radio:not([tone]){--radio-bg: #fbfcfe;--radio-border: #93c5ec;--radio-border-hover: #69ace5;--radio-border-active: #56a1e1}a-radio[tone=success],a-radio-group[tone=success] a-radio:not([tone]){--radio-bg: #f7fcf9;--radio-border: #88d7a0;--radio-border-hover: #5bc87b;--radio-border-active: #44c169}a-radio[tone=warning],a-radio-group[tone=warning] a-radio:not([tone]){--radio-bg: #fefbf6;--radio-border: #edb25a;--radio-border-hover: #e09127;--radio-border-active: #d88118}a-radio[tone=critical],a-radio-group[tone=critical] a-radio:not([tone]){--radio-bg: #fefbfb;--radio-border: #efa4a4;--radio-border-hover: #e87f7f;--radio-border-active: #e56c6c}a-radio[tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]),a-radio-group[tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]) a-radio:not([tone]){--radio-bg: oklch(from var(--radio-tone-source) .99 calc(c*.03) h);--_radio-border-base: color-mix(in oklch, var(--radio-fill) 70%, var(--radio-border-neutral));--radio-border: oklch(from var(--_radio-border-base) calc(l + .17) c h);--radio-border-hover: oklch(from var(--_radio-border-base) calc(l + .1) c h);--radio-border-active: var(--_radio-border-base);.dark &{--radio-bg: oklch(from var(--radio-tone-source) .15 calc(c*.18) h);--radio-border: var(--_radio-border-base);--radio-border-hover: oklch(from var(--_radio-border-base) calc(l + .1) c h);--radio-border-active: oklch(from var(--_radio-border-base) calc(l + .17) c h)}}a-radio[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]){--radio-tone-source: attr(tone type(<color>), transparent)}a-radio[tone-selected]:not([tone-selected=""],[tone-selected=brand],[tone-selected=neutral],[tone-selected=info],[tone-selected=success],[tone-selected=warning],[tone-selected=critical]){--radio-tone-source: attr(tone-selected type(<color>), transparent)}a-radio[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]),a-radio[tone-selected]:not([tone-selected=""],[tone-selected=brand],[tone-selected=neutral],[tone-selected=info],[tone-selected=success],[tone-selected=warning],[tone-selected=critical]),a-radio-group[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]) a-radio:not([tone]),a-radio-group[tone-selected]:not([tone-selected=""],[tone-selected=brand],[tone-selected=neutral],[tone-selected=info],[tone-selected=success],[tone-selected=warning],[tone-selected=critical]) a-radio:not([tone-selected]){--_tone-l-rest: .5;--_tone-l-hover: .45;--_tone-l-active: .4;--radio-fill: oklch(from var(--radio-tone-source) var(--_tone-l-rest) c h);--radio-fill-hover: oklch(from var(--radio-tone-source) var(--_tone-l-hover) c h);--radio-fill-active: oklch(from var(--radio-tone-source) var(--_tone-l-active) c h);.dark &{--_tone-l-rest: .45;--_tone-l-hover: .5;--_tone-l-active: .57}}.dark a-radio{--_radio-dot-adjust: 1px;&:after{box-shadow:0 0 1px 1px color-mix(in oklch,black 40%,transparent)}--radio-border-neutral: #49424c;--radio-border-hover: #635b65;--radio-border-active: #776e77;--radio-fill: #49424c;--radio-fill-hover: #534c57;--radio-fill-active: #635b65;--radio-dot: #d4ced4;--radio-dot-disabled: #534c57;--radio-bg-disabled: color-mix(in oklch, #e4d1ef 10%, transparent);--radio-border-disabled: color-mix(in oklch, #e4d1ef 10%, transparent)}.dark a-radio[tone=brand],.dark a-radio[tone-selected=brand],.dark a-radio-group[tone=brand] a-radio:not([tone]),.dark a-radio-group[tone-selected=brand] a-radio:not([tone-selected]){--radio-fill: #503cb4;--radio-fill-hover: #5f4bc3;--radio-fill-active: #7460d7}.dark a-radio[tone=neutral],.dark a-radio[tone-selected=neutral],.dark a-radio-group[tone=neutral] a-radio:not([tone]),.dark a-radio-group[tone-selected=neutral] a-radio:not([tone-selected]){--radio-fill: #49424c;--radio-fill-hover: #534c57;--radio-fill-active: #635b65}.dark a-radio[tone=info],.dark a-radio[tone-selected=info],.dark a-radio-group[tone=info] a-radio:not([tone]),.dark a-radio-group[tone-selected=info] a-radio:not([tone-selected]){--radio-fill: #1a5b93;--radio-fill-hover: #1f6eb2;--radio-fill-active: #2686d9}.dark a-radio[tone=success],.dark a-radio[tone-selected=success],.dark a-radio-group[tone=success] a-radio:not([tone]),.dark a-radio-group[tone-selected=success] a-radio:not([tone-selected]){--radio-fill: #226737;--radio-fill-hover: #2a7e43;--radio-fill-active: #329550}.dark a-radio[tone=warning],.dark a-radio[tone-selected=warning],.dark a-radio-group[tone=warning] a-radio:not([tone]),.dark a-radio-group[tone-selected=warning] a-radio:not([tone-selected]){--radio-fill: #7f410b;--radio-fill-hover: #995200;--radio-fill-active: #ae6613}.dark a-radio[tone=critical],.dark a-radio[tone-selected=critical],.dark a-radio-group[tone=critical] a-radio:not([tone]),.dark a-radio-group[tone-selected=critical] a-radio:not([tone-selected]){--radio-fill: #b02120;--radio-fill-hover: #c9302c;--radio-fill-active: #de4545}.dark a-radio[tone=brand],.dark a-radio-group[tone=brand] a-radio:not([tone]){--radio-bg: #0b0916;--radio-border: #483493;--radio-border-hover: #5f4bc3;--radio-border-active: #7460d7}.dark a-radio[tone=info],.dark a-radio-group[tone=info] a-radio:not([tone]){--radio-bg: #040d18;--radio-border: #175082;--radio-border-hover: #1f6eb2;--radio-border-active: #2686d9}.dark a-radio[tone=success],.dark a-radio-group[tone=success] a-radio:not([tone]){--radio-bg: #041008;--radio-border: #1f5c31;--radio-border-hover: #2a7e43;--radio-border-active: #329550}.dark a-radio[tone=warning],.dark a-radio-group[tone=warning] a-radio:not([tone]){--radio-bg: #120a03;--radio-border: #6a3b0c;--radio-border-hover: #995200;--radio-border-active: #ae6613}.dark a-radio[tone=critical],.dark a-radio-group[tone=critical] a-radio:not([tone]){--radio-bg: #190405;--radio-border: #a01c1c;--radio-border-hover: #c9302c;--radio-border-active: #de4545}}
|
|
1
|
+
@layer anta{a-radio{--radio-control-size: 16px;--radio-border-width: 1.5px;--radio-dot-size: 6px;--_radio-dot-adjust: 0px;--radio-gap: 8px;--radio-bg: var(--bg-1);--radio-fill: #878089;--radio-fill-hover: #776e77;--radio-fill-active: #635b65;--radio-border-neutral: #d4ced4;--radio-border: var(--radio-border-neutral);--radio-border-hover: #c1b9c1;--radio-border-active: #9f99a1;--radio-dot: #f6f4f6;--radio-dot-disabled: #c1b9c1;--radio-bg-disabled: color-mix(in oklch, #44374b 10%, transparent);--radio-border-disabled: color-mix(in oklch, #44374b 10%, transparent);--radio-label-color: var(--text-2);--radio-label-color-disabled: var(--text-4);--radio-hint-color: var(--text-3);--radio-label-fs: 15px;--radio-label-lh: 20px;--radio-hint-fs: 14px;--radio-hint-lh: 17px;display:inline-grid;grid-template-columns:auto 1fr;align-items:start;column-gap:var(--radio-gap);cursor:pointer;user-select:none;-webkit-user-drag:none;vertical-align:middle;outline:none;color:var(--radio-label-color);font-family:var(--sans-serif);font-size:var(--radio-label-fs);line-height:var(--radio-label-lh);font-feature-settings:"ss02","ss05","tnum";&:before{content:"";grid-column:1;grid-row:1 / -1;align-self:start;margin-block-start:calc((var(--radio-label-lh) - var(--radio-control-size)) / 2);box-sizing:border-box;inline-size:var(--radio-control-size);block-size:var(--radio-control-size);border-radius:50%;background:var(--radio-bg);border:var(--radio-border-width) solid var(--radio-border);transition:background-color .15s ease-out,border-color .15s ease-out}&:after{content:"";grid-column:1;grid-row:1 / -1;align-self:start;justify-self:center;margin-block-start:calc((var(--radio-label-lh) - (var(--radio-dot-size) - var(--_radio-dot-adjust))) / 2);inline-size:calc(var(--radio-dot-size) - var(--_radio-dot-adjust));block-size:calc(var(--radio-dot-size) - var(--_radio-dot-adjust));border-radius:50%;background:var(--radio-dot);transform:scale(0);transition:transform .12s ease-out;pointer-events:none}@media(hover:hover)and (pointer:fine){&:not([disabled]):hover:before{border-color:var(--radio-border-hover);transition:background-color 75ms ease-in,border-color 75ms ease-in}&:not([disabled]):hover:state(selected):before{background:var(--radio-fill-hover);border-color:var(--radio-fill-hover)}}&:not([disabled]):active:before{border-color:var(--radio-border-active);transition:background-color 50ms linear,border-color 50ms linear}&:not([disabled]):active:state(selected):before{background:var(--radio-fill-active);border-color:var(--radio-fill-active)}&:state(selected){&:before{background:var(--radio-fill);border-color:var(--radio-fill)}&:after{transform:scale(1)}}&:focus-visible:before{outline:1px solid var(--focus-ring);outline-offset:1px}&[disabled]{cursor:not-allowed;color:var(--radio-label-color-disabled);&:before{background:var(--radio-bg-disabled);border-color:var(--radio-border-disabled);transition:none}&:state(selected):after{background:var(--radio-dot-disabled)}a-radio-hint{color:var(--radio-label-color-disabled)}}&[size=small]{--radio-control-size: 14px;--radio-dot-size: 5px;--radio-gap: 6px;--radio-label-fs: 13px;--radio-label-lh: 16px;--radio-hint-fs: 12px;--radio-hint-lh: 14px}&[size=large]{--radio-control-size: 18px;--radio-dot-size: 7px;--radio-label-fs: 17px;--radio-label-lh: 22px;--radio-hint-fs: 16px;--radio-hint-lh: 21px}}a-radio-label,a-radio-hint{display:block;grid-column:2;min-width:0}a-radio-hint{color:var(--radio-hint-color);font-size:var(--radio-hint-fs);line-height:var(--radio-hint-lh);margin-block-start:2px}a-radio-group:focus-visible a-radio:state(selected):before{outline:1px solid var(--focus-ring);outline-offset:1px}a-radio[tone=brand],a-radio[tone-selected=brand],a-radio-group[tone=brand] a-radio:not([tone]),a-radio-group[tone-selected=brand] a-radio:not([tone-selected]){--radio-fill: #5f4bc3;--radio-fill-hover: #503cb4;--radio-fill-active: #483493}a-radio[tone=neutral],a-radio[tone-selected=neutral],a-radio-group[tone=neutral] a-radio:not([tone]),a-radio-group[tone-selected=neutral] a-radio:not([tone-selected]){--radio-fill: #878089;--radio-fill-hover: #776e77;--radio-fill-active: #635b65}a-radio[tone=info],a-radio[tone-selected=info],a-radio-group[tone=info] a-radio:not([tone]),a-radio-group[tone-selected=info] a-radio:not([tone-selected]){--radio-fill: #1f6eb2;--radio-fill-hover: #1a5b93;--radio-fill-active: #175082}a-radio[tone=success],a-radio[tone-selected=success],a-radio-group[tone=success] a-radio:not([tone]),a-radio-group[tone-selected=success] a-radio:not([tone-selected]){--radio-fill: #2a7e43;--radio-fill-hover: #226737;--radio-fill-active: #1f5c31}a-radio[tone=warning],a-radio[tone-selected=warning],a-radio-group[tone=warning] a-radio:not([tone]),a-radio-group[tone-selected=warning] a-radio:not([tone-selected]){--radio-fill: #c37416;--radio-fill-hover: #ae6613;--radio-fill-active: #995200}a-radio[tone=critical],a-radio[tone-selected=critical],a-radio-group[tone=critical] a-radio:not([tone]),a-radio-group[tone-selected=critical] a-radio:not([tone-selected]){--radio-fill: #c9302c;--radio-fill-hover: #b02120;--radio-fill-active: #a01c1c}a-radio[tone=brand],a-radio-group[tone=brand] a-radio:not([tone]){--radio-bg: #fcfcfe;--radio-border: #bcb1f1;--radio-border-hover: #9e8eeb;--radio-border-active: #9081df}a-radio[tone=info],a-radio-group[tone=info] a-radio:not([tone]){--radio-bg: #fbfcfe;--radio-border: #93c5ec;--radio-border-hover: #69ace5;--radio-border-active: #56a1e1}a-radio[tone=success],a-radio-group[tone=success] a-radio:not([tone]){--radio-bg: #f7fcf9;--radio-border: #88d7a0;--radio-border-hover: #5bc87b;--radio-border-active: #44c169}a-radio[tone=warning],a-radio-group[tone=warning] a-radio:not([tone]){--radio-bg: #fefbf6;--radio-border: #edb25a;--radio-border-hover: #e09127;--radio-border-active: #d88118}a-radio[tone=critical],a-radio-group[tone=critical] a-radio:not([tone]){--radio-bg: #fefbfb;--radio-border: #efa4a4;--radio-border-hover: #e87f7f;--radio-border-active: #e56c6c}a-radio[tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]),a-radio-group[tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]) a-radio:not([tone]){--radio-bg: oklch(from var(--radio-tone-source) .99 calc(c*.03) h);--_radio-border-base: color-mix(in oklch, var(--radio-fill) 70%, var(--radio-border-neutral));--radio-border: oklch(from var(--_radio-border-base) calc(l + .17) c h);--radio-border-hover: oklch(from var(--_radio-border-base) calc(l + .1) c h);--radio-border-active: var(--_radio-border-base);.dark &{--radio-bg: oklch(from var(--radio-tone-source) .15 calc(c*.18) h);--radio-border: var(--_radio-border-base);--radio-border-hover: oklch(from var(--_radio-border-base) calc(l + .1) c h);--radio-border-active: oklch(from var(--_radio-border-base) calc(l + .17) c h)}}a-radio[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]){--radio-tone-source: attr(tone type(<color>), transparent)}a-radio[tone-selected]:not([tone-selected=""],[tone-selected=brand],[tone-selected=neutral],[tone-selected=info],[tone-selected=success],[tone-selected=warning],[tone-selected=critical]){--radio-tone-source: attr(tone-selected type(<color>), transparent)}a-radio[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]),a-radio[tone-selected]:not([tone-selected=""],[tone-selected=brand],[tone-selected=neutral],[tone-selected=info],[tone-selected=success],[tone-selected=warning],[tone-selected=critical]),a-radio-group[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]) a-radio:not([tone]),a-radio-group[tone-selected]:not([tone-selected=""],[tone-selected=brand],[tone-selected=neutral],[tone-selected=info],[tone-selected=success],[tone-selected=warning],[tone-selected=critical]) a-radio:not([tone-selected]){--_tone-l-rest: .5;--_tone-l-hover: .45;--_tone-l-active: .4;--radio-fill: oklch(from var(--radio-tone-source) var(--_tone-l-rest) c h);--radio-fill-hover: oklch(from var(--radio-tone-source) var(--_tone-l-hover) c h);--radio-fill-active: oklch(from var(--radio-tone-source) var(--_tone-l-active) c h);.dark &{--_tone-l-rest: .45;--_tone-l-hover: .5;--_tone-l-active: .57}}.dark a-radio{--_radio-dot-adjust: 1px;&:after{box-shadow:0 0 1px 1px color-mix(in oklch,black 40%,transparent)}--radio-border-neutral: #49424c;--radio-border-hover: #635b65;--radio-border-active: #776e77;--radio-fill: #49424c;--radio-fill-hover: #534c57;--radio-fill-active: #635b65;--radio-dot: #ece9ec;--radio-dot-disabled: #534c57;--radio-bg-disabled: color-mix(in oklch, #e4d1ef 10%, transparent);--radio-border-disabled: color-mix(in oklch, #e4d1ef 10%, transparent)}.dark a-radio[tone=brand],.dark a-radio[tone-selected=brand],.dark a-radio-group[tone=brand] a-radio:not([tone]),.dark a-radio-group[tone-selected=brand] a-radio:not([tone-selected]){--radio-fill: #503cb4;--radio-fill-hover: #5f4bc3;--radio-fill-active: #7460d7}.dark a-radio[tone=neutral],.dark a-radio[tone-selected=neutral],.dark a-radio-group[tone=neutral] a-radio:not([tone]),.dark a-radio-group[tone-selected=neutral] a-radio:not([tone-selected]){--radio-fill: #49424c;--radio-fill-hover: #534c57;--radio-fill-active: #635b65}.dark a-radio[tone=info],.dark a-radio[tone-selected=info],.dark a-radio-group[tone=info] a-radio:not([tone]),.dark a-radio-group[tone-selected=info] a-radio:not([tone-selected]){--radio-fill: #1a5b93;--radio-fill-hover: #1f6eb2;--radio-fill-active: #2686d9}.dark a-radio[tone=success],.dark a-radio[tone-selected=success],.dark a-radio-group[tone=success] a-radio:not([tone]),.dark a-radio-group[tone-selected=success] a-radio:not([tone-selected]){--radio-fill: #226737;--radio-fill-hover: #2a7e43;--radio-fill-active: #329550}.dark a-radio[tone=warning],.dark a-radio[tone-selected=warning],.dark a-radio-group[tone=warning] a-radio:not([tone]),.dark a-radio-group[tone-selected=warning] a-radio:not([tone-selected]){--radio-fill: #7f410b;--radio-fill-hover: #995200;--radio-fill-active: #ae6613}.dark a-radio[tone=critical],.dark a-radio[tone-selected=critical],.dark a-radio-group[tone=critical] a-radio:not([tone]),.dark a-radio-group[tone-selected=critical] a-radio:not([tone-selected]){--radio-fill: #b02120;--radio-fill-hover: #c9302c;--radio-fill-active: #de4545}.dark a-radio[tone=brand],.dark a-radio-group[tone=brand] a-radio:not([tone]){--radio-bg: #0b0916;--radio-border: #483493;--radio-border-hover: #5f4bc3;--radio-border-active: #7460d7}.dark a-radio[tone=info],.dark a-radio-group[tone=info] a-radio:not([tone]){--radio-bg: #040d18;--radio-border: #175082;--radio-border-hover: #1f6eb2;--radio-border-active: #2686d9}.dark a-radio[tone=success],.dark a-radio-group[tone=success] a-radio:not([tone]){--radio-bg: #041008;--radio-border: #1f5c31;--radio-border-hover: #2a7e43;--radio-border-active: #329550}.dark a-radio[tone=warning],.dark a-radio-group[tone=warning] a-radio:not([tone]){--radio-bg: #120a03;--radio-border: #6a3b0c;--radio-border-hover: #995200;--radio-border-active: #ae6613}.dark a-radio[tone=critical],.dark a-radio-group[tone=critical] a-radio:not([tone]){--radio-bg: #190405;--radio-border: #a01c1c;--radio-border-hover: #c9302c;--radio-border-active: #de4545}}
|
|
@@ -52,6 +52,9 @@ export declare class ATooltipElement extends HTMLElementBase {
|
|
|
52
52
|
private fading;
|
|
53
53
|
private fadeTimer?;
|
|
54
54
|
private docMoveBound;
|
|
55
|
+
/** Active only while shown: re-runs the empty gate when the slotted content
|
|
56
|
+
* changes under a live bubble. See observeContent(). */
|
|
57
|
+
private contentObserver?;
|
|
55
58
|
constructor();
|
|
56
59
|
connectedCallback(): void;
|
|
57
60
|
disconnectedCallback(): void;
|
|
@@ -76,6 +79,20 @@ export declare class ATooltipElement extends HTMLElementBase {
|
|
|
76
79
|
* (so formatting whitespace / an empty conditional doesn't open a blank bubble).
|
|
77
80
|
* Re-checked on every show(), so a tooltip populated later self-corrects. */
|
|
78
81
|
private isEmpty;
|
|
82
|
+
/** While shown, watch the slotted content so a bubble whose content is
|
|
83
|
+
* cleared out from under it — a reactive re-render dropping the text /
|
|
84
|
+
* children under one persistent anchor — self-hides. The mirror of
|
|
85
|
+
* isEmpty()'s "populated later self-corrects": the show-time gate can't fire
|
|
86
|
+
* again on its own once open, so this drives the reverse.
|
|
87
|
+
*
|
|
88
|
+
* A MutationObserver, not `slotchange`, because reactive renderers update
|
|
89
|
+
* text in place — React sets an existing text node's nodeValue rather than
|
|
90
|
+
* replacing the node — which changes no assigned-node set and so fires no
|
|
91
|
+
* `slotchange`; childList + characterData + subtree catches both that and
|
|
92
|
+
* node removal. Observing our own light-DOM children is a READ (like the
|
|
93
|
+
* truncation measurements), so it stays within the no-host-mutation rule.
|
|
94
|
+
* Runs only while shown — attached here, disconnected by hide() / cleanup(). */
|
|
95
|
+
private observeContent;
|
|
79
96
|
private positionFrame?;
|
|
80
97
|
private pendingPosition?;
|
|
81
98
|
private schedulePosition;
|
|
@@ -85,6 +85,9 @@ class ATooltipElement extends HTMLElementBase {
|
|
|
85
85
|
fading = false;
|
|
86
86
|
fadeTimer;
|
|
87
87
|
docMoveBound = false;
|
|
88
|
+
/** Active only while shown: re-runs the empty gate when the slotted content
|
|
89
|
+
* changes under a live bubble. See observeContent(). */
|
|
90
|
+
contentObserver;
|
|
88
91
|
constructor() {
|
|
89
92
|
super();
|
|
90
93
|
const shadow = this.attachShadow({ mode: "open" });
|
|
@@ -259,6 +262,28 @@ class ATooltipElement extends HTMLElementBase {
|
|
|
259
262
|
isEmpty() {
|
|
260
263
|
return this.children.length === 0 && (this.textContent ?? "").trim() === "";
|
|
261
264
|
}
|
|
265
|
+
/** While shown, watch the slotted content so a bubble whose content is
|
|
266
|
+
* cleared out from under it — a reactive re-render dropping the text /
|
|
267
|
+
* children under one persistent anchor — self-hides. The mirror of
|
|
268
|
+
* isEmpty()'s "populated later self-corrects": the show-time gate can't fire
|
|
269
|
+
* again on its own once open, so this drives the reverse.
|
|
270
|
+
*
|
|
271
|
+
* A MutationObserver, not `slotchange`, because reactive renderers update
|
|
272
|
+
* text in place — React sets an existing text node's nodeValue rather than
|
|
273
|
+
* replacing the node — which changes no assigned-node set and so fires no
|
|
274
|
+
* `slotchange`; childList + characterData + subtree catches both that and
|
|
275
|
+
* node removal. Observing our own light-DOM children is a READ (like the
|
|
276
|
+
* truncation measurements), so it stays within the no-host-mutation rule.
|
|
277
|
+
* Runs only while shown — attached here, disconnected by hide() / cleanup(). */
|
|
278
|
+
observeContent() {
|
|
279
|
+
if (typeof MutationObserver === "undefined") return;
|
|
280
|
+
if (!this.contentObserver) {
|
|
281
|
+
this.contentObserver = new MutationObserver(() => {
|
|
282
|
+
if (this.shown && this.isEmpty()) this.hide();
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
this.contentObserver.observe(this, { childList: true, characterData: true, subtree: true });
|
|
286
|
+
}
|
|
262
287
|
// --- positioning (sets only the shadow container's own transform) ---
|
|
263
288
|
// Single pending position frame: a burst of mousemoves within one frame
|
|
264
289
|
// coalesces to ONE layout read + transform write, using the LATEST geometry
|
|
@@ -353,6 +378,7 @@ class ATooltipElement extends HTMLElementBase {
|
|
|
353
378
|
this.doc.addEventListener("mousemove", this.onDocMove);
|
|
354
379
|
this.docMoveBound = true;
|
|
355
380
|
}
|
|
381
|
+
this.observeContent();
|
|
356
382
|
}
|
|
357
383
|
this.position(e);
|
|
358
384
|
};
|
|
@@ -361,6 +387,7 @@ class ATooltipElement extends HTMLElementBase {
|
|
|
361
387
|
if (!this.shown) return;
|
|
362
388
|
this.shown = false;
|
|
363
389
|
this.touchOpen = false;
|
|
390
|
+
this.contentObserver?.disconnect();
|
|
364
391
|
this.container.hidePopover();
|
|
365
392
|
this.fading = true;
|
|
366
393
|
if (this.fadeTimer !== void 0) clearTimeout(this.fadeTimer);
|
|
@@ -391,6 +418,7 @@ class ATooltipElement extends HTMLElementBase {
|
|
|
391
418
|
* calls it. */
|
|
392
419
|
cleanup() {
|
|
393
420
|
this.cancelHide();
|
|
421
|
+
this.contentObserver?.disconnect();
|
|
394
422
|
if (this.shown) {
|
|
395
423
|
this.shown = false;
|
|
396
424
|
this.touchOpen = false;
|
package/dist/elements/index.d.ts
CHANGED
|
@@ -32,5 +32,6 @@ export { AMenuGroupElement, register_a_menu_group } from './a-menu-group';
|
|
|
32
32
|
export { ATabElement, register_a_tab } from './a-tab';
|
|
33
33
|
export { ATabsElement, register_a_tabs } from './a-tabs';
|
|
34
34
|
export { ATabPanelElement, register_a_tabpanel } from './a-tabpanel';
|
|
35
|
+
export { ADialogElement, register_a_dialog } from './a-dialog';
|
|
35
36
|
import './a-title.css';
|
|
36
37
|
import './a-tag.css';
|
package/dist/elements/index.js
CHANGED
|
@@ -17,12 +17,14 @@ import { AMenuGroupElement, register_a_menu_group } from "./a-menu-group";
|
|
|
17
17
|
import { ATabElement, register_a_tab } from "./a-tab";
|
|
18
18
|
import { ATabsElement, register_a_tabs } from "./a-tabs";
|
|
19
19
|
import { ATabPanelElement, register_a_tabpanel } from "./a-tabpanel";
|
|
20
|
+
import { ADialogElement, register_a_dialog } from "./a-dialog";
|
|
20
21
|
import "./a-title.css";
|
|
21
22
|
import "./a-tag.css";
|
|
22
23
|
export {
|
|
23
24
|
AButtonElement,
|
|
24
25
|
ACalendarElement,
|
|
25
26
|
ACheckboxElement,
|
|
27
|
+
ADialogElement,
|
|
26
28
|
AExpanderElement,
|
|
27
29
|
AIconElement,
|
|
28
30
|
AInputElement,
|
|
@@ -42,6 +44,7 @@ export {
|
|
|
42
44
|
register_a_button,
|
|
43
45
|
register_a_calendar,
|
|
44
46
|
register_a_checkbox,
|
|
47
|
+
register_a_dialog,
|
|
45
48
|
register_a_expander,
|
|
46
49
|
register_a_icon,
|
|
47
50
|
register_a_input,
|
package/dist/general_types.d.ts
CHANGED
|
@@ -291,6 +291,51 @@ export interface AExpanderAttributes extends BaseAttributes {
|
|
|
291
291
|
prev: 'open' | 'closed';
|
|
292
292
|
}>) => void;
|
|
293
293
|
}
|
|
294
|
+
/**
|
|
295
|
+
* Attributes for the `<a-dialog>` custom element — a modal dialog / edge drawer
|
|
296
|
+
* built on a native `<dialog>` in shadow DOM (top layer, focus trap, backdrop,
|
|
297
|
+
* Esc from the platform). Slots (light-DOM children): `header`, `footer`,
|
|
298
|
+
* `close` (the close button), and the default slot for the body. The element
|
|
299
|
+
* exposes `::part(dialog | header | body | footer | close)`. Low-level
|
|
300
|
+
* attributes; for the typed JSX wrapper use `Dialog` from `@antadesign/anta`.
|
|
301
|
+
*/
|
|
302
|
+
export interface ADialogAttributes extends BaseAttributes {
|
|
303
|
+
/** Controlled open state (`'open'` / `'closed'`). Present → controlled: the
|
|
304
|
+
* attribute is the source of truth, user dismiss only dispatches the
|
|
305
|
+
* cancelable `statechange` event, and the consumer answers by updating it.
|
|
306
|
+
* Absent → uncontrolled (use `default-state`). See STATEFUL-COMPONENTS.md. */
|
|
307
|
+
state?: 'open' | 'closed';
|
|
308
|
+
/** Initial open state for the uncontrolled mode (`'open'` / `'closed'`); read
|
|
309
|
+
* once when the element connects. */
|
|
310
|
+
'default-state'?: 'open' | 'closed';
|
|
311
|
+
/** Placement. `center` (default, omit) is a centered modal; `left` / `right` /
|
|
312
|
+
* `top` / `bottom` turn it into an edge drawer; `fullscreen` fills the whole
|
|
313
|
+
* viewport (no edge gap, no radius). */
|
|
314
|
+
position?: 'center' | 'left' | 'right' | 'top' | 'bottom' | 'fullscreen';
|
|
315
|
+
/** Corner radius. A side keyword (`top` / `right` / `bottom` / `left`) rounds
|
|
316
|
+
* only that edge's two corners at `--dialog-radius`; a length (`round="20px"`)
|
|
317
|
+
* or full `border-radius` shorthand rounds all corners at that value; bare
|
|
318
|
+
* `round` rounds all corners at `--dialog-radius`. Omit for the position
|
|
319
|
+
* default (center rounded, drawers / fullscreen square). */
|
|
320
|
+
round?: boolean | number | 'top' | 'right' | 'bottom' | 'left' | (string & {});
|
|
321
|
+
/** Disable light dismiss — Esc + backdrop click no longer close the dialog (it
|
|
322
|
+
* closes only via the close button or programmatically). For alert / confirm
|
|
323
|
+
* dialogs. Presence-based (`''` on, omit off). */
|
|
324
|
+
persistent?: boolean | '';
|
|
325
|
+
/** Uncontrolled trigger name. Any element with `data-dialog-open="{name}"`
|
|
326
|
+
* opens this dialog and `data-dialog-close="{name}"` closes it, via a document
|
|
327
|
+
* click listener. Ignored in controlled mode. */
|
|
328
|
+
name?: string;
|
|
329
|
+
/** Fires before the open state changes — the element dispatches a `cancelable`
|
|
330
|
+
* `statechange` `CustomEvent` whose `detail` is `{ next, prev }` in the
|
|
331
|
+
* `'open'|'closed'` vocabulary. Uncontrolled, `preventDefault()` vetoes the
|
|
332
|
+
* transition. All-lowercase so both renderers bind it (React 19 keeps the case
|
|
333
|
+
* after `on`; Preact lowercases). */
|
|
334
|
+
onstatechange?: (e: CustomEvent<{
|
|
335
|
+
next: 'open' | 'closed';
|
|
336
|
+
prev: 'open' | 'closed';
|
|
337
|
+
}>) => void;
|
|
338
|
+
}
|
|
294
339
|
/**
|
|
295
340
|
* Attributes for the `<a-icon>` custom element. `shape` is typed as
|
|
296
341
|
* `IconShape` (`keyof IconShapes`); the `IconShapes` interface is
|
package/dist/index.d.ts
CHANGED
|
@@ -51,6 +51,8 @@ export { InputDate } from './components/InputDate';
|
|
|
51
51
|
export type { InputDateProps, InputDateChangeAttrs } from './components/InputDate';
|
|
52
52
|
export { InputTime } from './components/InputTime';
|
|
53
53
|
export type { InputTimeProps, InputTimeChangeAttrs } from './components/InputTime';
|
|
54
|
+
export { InputAutocomplete } from './components/InputAutocomplete';
|
|
55
|
+
export type { InputAutocompleteProps } from './components/InputAutocomplete';
|
|
54
56
|
export { buildMonth, getWeekdays, firstDayOfWeek, clampDate, isOutOfRange, parseISODate, parseDateInput, formatDateInput, dateFormatPattern, parseTimeInput, parseDateTimeInput, formatDateTimeInput, dateTimeFormatPattern, usesHour12, } from './calendar-core';
|
|
55
57
|
export type { CalendarDay, CalendarWeekday, CalendarMonth, BuildMonthOptions, ParseDateOptions, } from './calendar-core';
|
|
56
58
|
export { RadioGroup } from './components/RadioGroup';
|
|
@@ -63,6 +65,8 @@ export { Tabs } from './components/Tabs';
|
|
|
63
65
|
export type { TabsProps, TabOption, TabsChangeAttrs } from './components/Tabs';
|
|
64
66
|
export { TabPanel } from './components/TabPanel';
|
|
65
67
|
export type { TabPanelProps } from './components/TabPanel';
|
|
68
|
+
export { Dialog } from './components/Dialog';
|
|
69
|
+
export type { DialogProps } from './components/Dialog';
|
|
66
70
|
export type { BaseProps, BaseAttributes } from './general_types';
|
|
67
71
|
export { configure } from './jsx-runtime';
|
|
68
72
|
export type { AntaIntrinsicElements } from './jsx-runtime';
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import { Input } from "./components/Input";
|
|
|
16
16
|
import { Calendar } from "./components/Calendar";
|
|
17
17
|
import { InputDate } from "./components/InputDate";
|
|
18
18
|
import { InputTime } from "./components/InputTime";
|
|
19
|
+
import { InputAutocomplete } from "./components/InputAutocomplete";
|
|
19
20
|
import {
|
|
20
21
|
buildMonth,
|
|
21
22
|
getWeekdays,
|
|
@@ -37,16 +38,19 @@ import { Select, optionsWithSelection } from "./components/Select";
|
|
|
37
38
|
import { SelectFaceted } from "./components/SelectFaceted";
|
|
38
39
|
import { Tabs } from "./components/Tabs";
|
|
39
40
|
import { TabPanel } from "./components/TabPanel";
|
|
41
|
+
import { Dialog } from "./components/Dialog";
|
|
40
42
|
import { configure } from "./jsx-runtime";
|
|
41
43
|
export {
|
|
42
44
|
Button,
|
|
43
45
|
Calendar,
|
|
44
46
|
Checkbox,
|
|
47
|
+
Dialog,
|
|
45
48
|
Expander,
|
|
46
49
|
ICON_SHAPES,
|
|
47
50
|
ICON_SYNONYMS,
|
|
48
51
|
Icon,
|
|
49
52
|
Input,
|
|
53
|
+
InputAutocomplete,
|
|
50
54
|
InputDate,
|
|
51
55
|
InputTime,
|
|
52
56
|
Menu,
|
package/dist/jsx-runtime.d.ts
CHANGED
|
@@ -41,7 +41,7 @@ export declare function useMemo<T>(factory: () => T, deps: unknown[]): T;
|
|
|
41
41
|
export declare function jsx(type: ComponentType, props: Record<string, unknown> | null, key?: string | number): unknown;
|
|
42
42
|
export declare function jsxs(type: ComponentType, props: Record<string, unknown> | null, key?: string | number): unknown;
|
|
43
43
|
export { _Fragment as Fragment };
|
|
44
|
-
import type { AProgressAttributes, ATextAttributes, ATitleAttributes, ATagAttributes, AExpanderAttributes, AIconAttributes, AButtonAttributes, ACheckboxAttributes, ATooltipAttributes, AInputAttributes, AInputTimeAttributes, ACalendarAttributes, ARadioAttributes, ARadioGroupAttributes, AMenuAttributes, AMenuItemAttributes, AMenuGroupAttributes, ATabsAttributes, ATabAttributes, ATabpanelAttributes, BaseAttributes } from './general_types';
|
|
44
|
+
import type { AProgressAttributes, ATextAttributes, ATitleAttributes, ATagAttributes, AExpanderAttributes, AIconAttributes, AButtonAttributes, ACheckboxAttributes, ATooltipAttributes, AInputAttributes, AInputTimeAttributes, ACalendarAttributes, ARadioAttributes, ARadioGroupAttributes, AMenuAttributes, AMenuItemAttributes, AMenuGroupAttributes, ATabsAttributes, ATabAttributes, ATabpanelAttributes, ADialogAttributes, BaseAttributes } from './general_types';
|
|
45
45
|
export declare namespace JSX {
|
|
46
46
|
interface IntrinsicElements extends React.JSX.IntrinsicElements, AntaIntrinsicElements {
|
|
47
47
|
}
|
|
@@ -91,4 +91,5 @@ export interface AntaIntrinsicElements {
|
|
|
91
91
|
'a-tab': ATabAttributes;
|
|
92
92
|
'a-tab-label': BaseAttributes;
|
|
93
93
|
'a-tabpanel': ATabpanelAttributes;
|
|
94
|
+
'a-dialog': ADialogAttributes;
|
|
94
95
|
}
|