@antadesign/anta 0.3.0 → 0.3.2
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 +13 -1
- package/dist/components/Button.js +8 -17
- package/dist/components/Checkbox.d.ts +16 -15
- package/dist/components/Checkbox.js +10 -6
- package/dist/components/Input.d.ts +4 -4
- package/dist/components/Input.js +5 -5
- package/dist/components/Menu.d.ts +7 -4
- package/dist/components/Menu.js +2 -2
- package/dist/components/MenuItem.d.ts +18 -7
- package/dist/components/MenuItem.js +11 -2
- package/dist/components/RadioGroup.d.ts +15 -15
- package/dist/components/RadioGroup.js +8 -8
- package/dist/components/Tab.d.ts +34 -0
- package/dist/components/Tab.js +4 -0
- package/dist/components/TabPanel.d.ts +22 -0
- package/dist/components/TabPanel.js +4 -0
- package/dist/components/Tabs.d.ts +112 -0
- package/dist/components/Tabs.js +174 -0
- package/dist/components/Tabs.module.css +1 -0
- package/dist/components/Tooltip.d.ts +10 -1
- package/dist/components/Tooltip.js +4 -0
- package/dist/elements/a-button.css +1 -1
- package/dist/elements/a-checkbox.css +1 -1
- package/dist/elements/a-expander.js +6 -1
- package/dist/elements/a-icon.shapes.css +1 -1
- package/dist/elements/a-icon.shapes.d.ts +2 -1
- package/dist/elements/a-icon.shapes.js +1 -0
- package/dist/elements/a-input.js +1 -1
- package/dist/elements/a-menu.d.ts +12 -0
- package/dist/elements/a-menu.js +70 -21
- package/dist/elements/a-radio.css +1 -1
- package/dist/elements/a-tab.css +1 -0
- package/dist/elements/a-tab.d.ts +14 -0
- package/dist/elements/a-tab.js +46 -0
- package/dist/elements/a-tabpanel.css +1 -0
- package/dist/elements/a-tabs.css +1 -0
- package/dist/elements/a-tabs.d.ts +31 -0
- package/dist/elements/a-tabs.js +157 -0
- package/dist/elements/a-text.css +1 -1
- package/dist/elements/a-title.css +1 -1
- package/dist/elements/a-tooltip.d.ts +18 -0
- package/dist/elements/a-tooltip.js +45 -0
- package/dist/elements/index.d.ts +3 -0
- package/dist/elements/index.js +7 -0
- package/dist/general_types.d.ts +150 -23
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -0
- package/dist/jsx-runtime.d.ts +5 -1
- package/dist/tokens.css +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer anta{a-tab{user-select:none;display:inline-flex;align-items:center;justify-content:center;gap:.5ch;flex-shrink:1;min-width:0;cursor:pointer;color:var(--tab-fg, var(--text-3));background-color:var(--tab-bg, transparent);border:none;border-radius:var(--tab-radius);box-shadow:0 0 0 0 transparent;font-size:var(--_fs);font-family:var(--sans-serif);font-weight:450;font-variation-settings:"wdth" 88,"slnt" 0,"ital" 0;font-feature-settings:"ss02","ss05","tnum";line-height:var(--_lh);letter-spacing:.05ch;white-space:nowrap;text-wrap:nowrap;padding-block:var(--tab-padding-y);padding-inline:var(--tab-padding-x);transition:background-color var(--tab-timing),box-shadow var(--tab-timing);>a-tab-label{display:inline-block;min-width:0;overflow:hidden;text-overflow:ellipsis;text-wrap:nowrap;white-space:nowrap;line-height:calc(var(--_lh) - 2px);padding-bottom:var(--_pb);&:has(>*){display:inline-flex;gap:.25ch}}>*{pointer-events:none}&:has(>a-icon:first-child):has(>a-tab-label){padding-inline-start:max(0px,var(--tab-padding-x) - 2px)}&:has(>a-icon:last-child):has(>a-tab-label){padding-inline-end:max(0px,var(--tab-padding-x) - 2px)}}a-tab:focus-visible{outline:1px solid var(--focus-ring);outline-offset:-1px}a-tab[disabled]{pointer-events:none;cursor:not-allowed;opacity:.45}}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HTMLElementBase } from "../anta_helpers";
|
|
2
|
+
import "./a-tab.css";
|
|
3
|
+
export declare class ATabElement extends HTMLElementBase {
|
|
4
|
+
static observedAttributes: string[];
|
|
5
|
+
private internals?;
|
|
6
|
+
constructor();
|
|
7
|
+
connectedCallback(): void;
|
|
8
|
+
attributeChangedCallback(name: string): void;
|
|
9
|
+
get selected(): boolean;
|
|
10
|
+
set selected(on: boolean);
|
|
11
|
+
get value(): string;
|
|
12
|
+
private applyState;
|
|
13
|
+
}
|
|
14
|
+
export declare function register_a_tab(): void;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { HTMLElementBase } from "../anta_helpers";
|
|
2
|
+
import "./a-tab.css";
|
|
3
|
+
class ATabElement extends HTMLElementBase {
|
|
4
|
+
static observedAttributes = ["selected"];
|
|
5
|
+
internals;
|
|
6
|
+
constructor() {
|
|
7
|
+
super();
|
|
8
|
+
this.internals = this.attachInternals?.();
|
|
9
|
+
}
|
|
10
|
+
connectedCallback() {
|
|
11
|
+
if (this.hasAttribute("selected")) this.applyState(true);
|
|
12
|
+
}
|
|
13
|
+
attributeChangedCallback(name) {
|
|
14
|
+
if (name === "selected") this.applyState(this.hasAttribute("selected"));
|
|
15
|
+
}
|
|
16
|
+
get selected() {
|
|
17
|
+
return this.internals?.states.has("selected") ?? false;
|
|
18
|
+
}
|
|
19
|
+
set selected(on) {
|
|
20
|
+
this.applyState(!!on);
|
|
21
|
+
}
|
|
22
|
+
get value() {
|
|
23
|
+
return this.getAttribute("value") ?? "";
|
|
24
|
+
}
|
|
25
|
+
// `selected` is the single source: it drives the visual `:state(selected)` and
|
|
26
|
+
// publishes `aria-selected` through ElementInternals (the accessibility tree,
|
|
27
|
+
// not a DOM attribute). <a-tabs> only sets `t.selected`; the tab owns how it
|
|
28
|
+
// reflects that. role="tab" comes from the wrapper, which gives ariaSelected
|
|
29
|
+
// something to attach to.
|
|
30
|
+
applyState(on) {
|
|
31
|
+
if (!this.internals) return;
|
|
32
|
+
if (on) this.internals.states.add("selected");
|
|
33
|
+
else this.internals.states.delete("selected");
|
|
34
|
+
this.internals.ariaSelected = on ? "true" : "false";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function register_a_tab() {
|
|
38
|
+
if (typeof customElements === "undefined") return;
|
|
39
|
+
if (!customElements.get("a-tab"))
|
|
40
|
+
customElements.define("a-tab", ATabElement);
|
|
41
|
+
}
|
|
42
|
+
register_a_tab();
|
|
43
|
+
export {
|
|
44
|
+
ATabElement,
|
|
45
|
+
register_a_tab
|
|
46
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer anta{a-tabpanel{display:block}a-tabpanel[hidden]{display:none}a-tabpanel[data-hide=visibility]{visibility:hidden}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer anta{a-tabs{--_fs: 15px;--_lh: 20px;--_pb: 1px;--tab-padding-x: 9px;--tab-padding-y: calc((10px - var(--_pb)) / 2);--tab-radius: 4px;--tabs-gap: 3px;--tab-timing: .15s ease-out;--tabs-tone-source: #635b65;--tab-fg-rest: var(--text-3);--tab-fg-hover: var(--text-1);--tab-selected-text: var(--text-1);--tab-text-2: var(--text-2);--tabs-track-bg: color-mix(in oklch, #44374b 6%, transparent);--tabs-track-border: var(--border-4);--tab-pill-bg: var(--bg-1);--tab-pill-shadow: 0 0 3px 0 var(--border-3);--tab-secondary-bg: color-mix(in oklch, #44374b 3%, transparent);--tab-secondary-border: var(--border-3);--tab-secondary-shadow: 0 0 0px 1px var(--tab-secondary-border);display:flex;flex-direction:row;align-items:stretch;gap:var(--tabs-gap);width:fit-content;align-self:flex-start;min-width:0;max-width:100%;overflow:hidden;scroll-behavior:smooth}a-tabs[size=small]{--_fs: 13px;--_lh: 16px;--_pb: .5px;--tab-padding-x: 7px}a-tabs[size=large]{--_fs: 17px;--_lh: 24px;--_pb: 1.5px;--tab-padding-x: 13px}a-tabs a-tab a-icon{--icon-size: 16px}a-tabs[size=small] a-tab a-icon{--icon-size: 14px}a-tabs[size=large] a-tab a-icon{--icon-size: 18px}a-tabs[tone=brand],a-tab[tone=brand]{--tabs-tone-source: #5f4bc3;--tab-selected-text: var(--text-1-brand);--tab-text-2: var(--text-2-brand);--tab-rest-tone: var(--text-3-brand);--tabs-track-border: var(--border-4-brand);--tab-secondary-border: var(--border-3-brand)}a-tabs[tone=info],a-tab[tone=info]{--tabs-tone-source: #1f6eb2;--tab-selected-text: var(--text-1-info);--tab-text-2: var(--text-2-info);--tab-rest-tone: var(--text-3-info);--tabs-track-border: var(--border-4-info);--tab-secondary-border: var(--border-3-info)}a-tabs[tone=success],a-tab[tone=success]{--tabs-tone-source: #2a7e43;--tab-selected-text: var(--text-1-success);--tab-text-2: var(--text-2-success);--tab-rest-tone: var(--text-3-success);--tabs-track-border: var(--border-4-success);--tab-secondary-border: var(--border-3-success)}a-tabs[tone=warning],a-tab[tone=warning]{--tabs-tone-source: #c37416;--tab-selected-text: var(--text-1-warning);--tab-text-2: var(--text-2-warning);--tab-rest-tone: var(--text-3-warning);--tabs-track-border: var(--border-4-warning);--tab-secondary-border: var(--border-3-warning)}a-tabs[tone=critical],a-tab[tone=critical]{--tabs-tone-source: #c9302c;--tab-selected-text: var(--text-1-critical);--tab-text-2: var(--text-2-critical);--tab-rest-tone: var(--text-3-critical);--tabs-track-border: var(--border-4-critical);--tab-secondary-border: var(--border-3-critical)}a-tabs[tone]:not([tone=""],[tone=neutral]),a-tab[tone]:not([tone=""],[tone=neutral]){--tabs-track-bg: oklch(from var(--tabs-tone-source) .55 .14 h / .08);--tab-secondary-bg: oklch(from var(--tabs-tone-source) .55 .14 h / .03);--tab-pill-shadow: 0 0 3px 0 oklch(from var(--tabs-tone-source) .62 .12 h / .5)}a-tabs:has(>a-tab[tone=brand]:state(selected)){--tabs-tone-source: #5f4bc3;--tab-selected-text: var(--text-1-brand);--tab-secondary-border: var(--border-3-brand)}a-tabs:has(>a-tab[tone=info]:state(selected)){--tabs-tone-source: #1f6eb2;--tab-selected-text: var(--text-1-info);--tab-secondary-border: var(--border-3-info)}a-tabs:has(>a-tab[tone=success]:state(selected)){--tabs-tone-source: #2a7e43;--tab-selected-text: var(--text-1-success);--tab-secondary-border: var(--border-3-success)}a-tabs:has(>a-tab[tone=warning]:state(selected)){--tabs-tone-source: #c37416;--tab-selected-text: var(--text-1-warning);--tab-secondary-border: var(--border-3-warning)}a-tabs:has(>a-tab[tone=critical]:state(selected)){--tabs-tone-source: #c9302c;--tab-selected-text: var(--text-1-critical);--tab-secondary-border: var(--border-3-critical)}a-tabs:has(>a-tab[tone]:state(selected):not([tone=""],[tone=neutral])){--tab-pill-shadow: 0 0 3px 0 oklch(from var(--tabs-tone-source) .62 .12 h / .5);--tab-secondary-bg: oklch(from var(--tabs-tone-source) .55 .14 h / .03)}a-tabs[tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]),a-tab[tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--tabs-tone-source: attr(tone type(<color>), #635b65);--tab-selected-text: oklch(from var(--tabs-tone-source) .38 .13 h);--tab-text-2: oklch(from var(--tabs-tone-source) .45 .13 h);--tab-rest-tone: oklch(from var(--tabs-tone-source) .45 .13 h);--tabs-track-border: oklch(from var(--tabs-tone-source) .9 .047 h);--tab-secondary-border: oklch(from var(--tabs-tone-source) .87 .065 h)}a-tabs a-tab{--tab-fg: var(--tab-fg-rest);--tab-bg: transparent}a-tabs:not([orientation=vertical]) a-tab{flex:1 1 0;max-width:max-content}@media(hover:hover)and (pointer:fine){a-tabs a-tab:hover{--tab-fg: var(--tab-fg-hover)}}a-tabs:not([priority=secondary],[priority=tertiary]){background:var(--tabs-track-bg);border:.5px solid var(--tabs-track-border);border-radius:6px;padding:1.5px}a-tabs:not([priority=secondary],[priority=tertiary]) a-tab:state(selected){--tab-fg: var(--tab-selected-text);--tab-bg: var(--tab-pill-bg);box-shadow:var(--tab-pill-shadow)}a-tabs[tone]:not([tone=""],[tone=neutral]),a-tab[tone]:not([tone=""],[tone=neutral]){--tab-fg-rest: var(--tab-rest-tone);--tab-fg-hover: var(--tab-selected-text)}a-tabs[priority=secondary]{border:.5px solid transparent;padding:1.5px}@media(hover:hover)and (pointer:fine){a-tabs[priority=secondary] a-tab:hover{--tab-fg: var(--tab-selected-text)}}a-tabs[priority=secondary] a-tab:state(selected){--tab-fg: var(--tab-selected-text);--tab-bg: var(--tab-secondary-bg);box-shadow:var(--tab-secondary-shadow)}a-tabs[priority=tertiary]{padding-inline:2px}a-tabs[priority=tertiary] a-tab{--tab-underline-size: 1px;--tab-underline-color: transparent;position:relative;border-radius:0}a-tabs[priority=tertiary]:not([orientation=vertical]) a-tab{padding-block:calc(var(--tab-padding-y) + 2px)}a-tabs[priority=tertiary] a-tab:after{content:"";position:absolute;inset:0;box-sizing:border-box;pointer-events:none;border-bottom:var(--tab-underline-size) solid var(--tab-underline-color);transition:border-width var(--tab-timing),border-color var(--tab-timing)}a-tabs[orientation=vertical][priority=tertiary] a-tab:after{border-bottom:0;border-inline-end:var(--tab-underline-size) solid var(--tab-underline-color)}@media(hover:hover)and (pointer:fine){a-tabs[priority=tertiary] a-tab:hover{--tab-fg: var(--tab-text-2)}}a-tabs[priority=tertiary] a-tab:state(selected){--tab-fg: var(--tab-selected-text);--tab-underline-size: 1px;--tab-underline-color: var(--tab-selected-text)}a-tabs[orientation=vertical]{flex-direction:column;align-items:stretch;max-width:none;overflow-x:hidden;overflow-y:auto;flex-shrink:0}a-tabs[orientation=vertical] a-tab{justify-content:flex-start;flex-shrink:0}@supports (anchor-scope: all){a-tabs:not([noslide]){position:relative;anchor-scope:all}a-tabs:not([noslide]) a-tab{position:relative;z-index:1}a-tabs:not([noslide]) a-tab:state(selected){anchor-name:--tabs-active}a-tabs:not([noslide]):before{content:"";position:absolute;z-index:0;box-sizing:border-box;position-anchor:--tabs-active;top:anchor(top);right:anchor(right);bottom:anchor(bottom);left:anchor(left);transition:top var(--tab-timing),right var(--tab-timing),bottom var(--tab-timing),left var(--tab-timing)}a-tabs:not([noslide]):not(:has(a-tab:state(selected))):before{display:none}@media(prefers-reduced-motion:reduce){a-tabs:not([noslide]):before{transition:none}}a-tabs:not([noslide]) a-tab:state(selected){--tab-bg: transparent;box-shadow:none}a-tabs:not([noslide],[priority=secondary],[priority=tertiary]):before{background:var(--tab-pill-bg);border-radius:var(--tab-radius);box-shadow:var(--tab-pill-shadow)}a-tabs:not([noslide])[priority=secondary]:before{background:var(--tab-secondary-bg);border-radius:var(--tab-radius);box-shadow:var(--tab-secondary-shadow)}a-tabs:not([noslide])[priority=tertiary] a-tab:state(selected){--tab-underline-size: 1px;--tab-underline-color: transparent}a-tabs:not([noslide])[priority=tertiary]:before{z-index:2;border-bottom:1px solid var(--tab-selected-text)}a-tabs[orientation=vertical]:not([noslide])[priority=tertiary]:before{border-bottom:0;border-inline-end:1px solid var(--tab-selected-text)}}.dark a-tabs{--tabs-track-bg: color-mix(in oklch, #e4d1ef 10%, transparent);--tab-secondary-bg: color-mix(in oklch, #e4d1ef 6%, transparent)}.dark a-tabs[tone]:not([tone=""],[tone=neutral]),.dark a-tab[tone]:not([tone=""],[tone=neutral]){--tabs-track-bg: oklch(from var(--tabs-tone-source) .8 .12 h / .12);--tab-secondary-bg: oklch(from var(--tabs-tone-source) .8 .12 h / .06);--tab-pill-shadow: 0 0 3px 0 oklch(from var(--tabs-tone-source) .8 .1 h / .45)}.dark a-tabs:has(>a-tab[tone]:state(selected):not([tone=""],[tone=neutral])){--tab-secondary-bg: oklch(from var(--tabs-tone-source) .8 .12 h / .06);--tab-pill-shadow: 0 0 3px 0 oklch(from var(--tabs-tone-source) .8 .1 h / .45)}.dark a-tabs[tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]),.dark a-tab[tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--tab-selected-text: oklch(from var(--tabs-tone-source) .83 .1 h);--tab-text-2: oklch(from var(--tabs-tone-source) .76 .11 h);--tab-rest-tone: oklch(from var(--tabs-tone-source) .76 .11 h);--tabs-track-border: oklch(from var(--tabs-tone-source) .25 .057 h);--tab-secondary-border: oklch(from var(--tabs-tone-source) .33 .087 h)}}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { HTMLElementBase } from "../anta_helpers";
|
|
2
|
+
import "./a-tabs.css";
|
|
3
|
+
export declare class ATabsElement extends HTMLElementBase {
|
|
4
|
+
static observedAttributes: string[];
|
|
5
|
+
private internals?;
|
|
6
|
+
private uncontrolledValue;
|
|
7
|
+
private seeded;
|
|
8
|
+
private observer?;
|
|
9
|
+
private lastSelected;
|
|
10
|
+
private alive;
|
|
11
|
+
/** The selected tab's value, or `null` when nothing is selected. */
|
|
12
|
+
get value(): string | null;
|
|
13
|
+
constructor();
|
|
14
|
+
connectedCallback(): void;
|
|
15
|
+
disconnectedCallback(): void;
|
|
16
|
+
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
17
|
+
formDisabledCallback(disabled: boolean): void;
|
|
18
|
+
private get currentValue();
|
|
19
|
+
private get isDisabled();
|
|
20
|
+
private get isVertical();
|
|
21
|
+
private get tabs();
|
|
22
|
+
private sync;
|
|
23
|
+
private requestSelect;
|
|
24
|
+
private emitChange;
|
|
25
|
+
/** Dispatch the shared cancelable `statechange`. `next`/`prev` are values
|
|
26
|
+
* (`null` when nothing is selected). Returns false if a listener vetoed. */
|
|
27
|
+
private emitStateChange;
|
|
28
|
+
private onClick;
|
|
29
|
+
private onKeyDown;
|
|
30
|
+
}
|
|
31
|
+
export declare function register_a_tabs(): void;
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { HTMLElementBase } from "../anta_helpers";
|
|
2
|
+
import "./a-tabs.css";
|
|
3
|
+
class ATabsElement extends HTMLElementBase {
|
|
4
|
+
static observedAttributes = ["state", "disabled", "orientation"];
|
|
5
|
+
internals;
|
|
6
|
+
uncontrolledValue = null;
|
|
7
|
+
seeded = false;
|
|
8
|
+
observer;
|
|
9
|
+
// The tab last scrolled into view — so scroll-into-view fires only when the SELECTION
|
|
10
|
+
// changes, not on every sync() (orientation / disabled changes call sync() too).
|
|
11
|
+
lastSelected = null;
|
|
12
|
+
// True after the first connect — gates the native `change` event so it never fires
|
|
13
|
+
// for the initial seed, and gates scroll-into-view so mounting doesn't jump the page.
|
|
14
|
+
alive = false;
|
|
15
|
+
/** The selected tab's value, or `null` when nothing is selected. */
|
|
16
|
+
get value() {
|
|
17
|
+
return this.currentValue;
|
|
18
|
+
}
|
|
19
|
+
constructor() {
|
|
20
|
+
super();
|
|
21
|
+
this.internals = this.attachInternals?.();
|
|
22
|
+
}
|
|
23
|
+
connectedCallback() {
|
|
24
|
+
if (!this.seeded) {
|
|
25
|
+
this.uncontrolledValue = this.getAttribute("default-state");
|
|
26
|
+
this.seeded = true;
|
|
27
|
+
}
|
|
28
|
+
this.addEventListener("click", this.onClick);
|
|
29
|
+
this.addEventListener("keydown", this.onKeyDown);
|
|
30
|
+
this.observer ??= new this.view.MutationObserver((records) => {
|
|
31
|
+
const touchedTabs = records.some(
|
|
32
|
+
(rec) => [...rec.addedNodes, ...rec.removedNodes].some(
|
|
33
|
+
(n) => n.nodeName === "A-TAB" || n.querySelector?.("a-tab") != null
|
|
34
|
+
)
|
|
35
|
+
);
|
|
36
|
+
if (touchedTabs) this.sync();
|
|
37
|
+
});
|
|
38
|
+
this.observer.observe(this, { childList: true, subtree: true });
|
|
39
|
+
this.sync();
|
|
40
|
+
this.alive = true;
|
|
41
|
+
}
|
|
42
|
+
disconnectedCallback() {
|
|
43
|
+
this.observer?.disconnect();
|
|
44
|
+
}
|
|
45
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
46
|
+
this.sync();
|
|
47
|
+
if (name === "state" && this.alive && newValue !== oldValue) this.emitChange();
|
|
48
|
+
}
|
|
49
|
+
formDisabledCallback(disabled) {
|
|
50
|
+
if (disabled) this.internals?.states.add("disabled");
|
|
51
|
+
else this.internals?.states.delete("disabled");
|
|
52
|
+
this.sync();
|
|
53
|
+
}
|
|
54
|
+
// Controlled when `state` is present; otherwise the in-memory uncontrolled value.
|
|
55
|
+
get currentValue() {
|
|
56
|
+
return this.hasAttribute("state") ? this.getAttribute("state") : this.uncontrolledValue;
|
|
57
|
+
}
|
|
58
|
+
get isDisabled() {
|
|
59
|
+
return this.hasAttribute("disabled") || (this.internals?.states.has("disabled") ?? false);
|
|
60
|
+
}
|
|
61
|
+
get isVertical() {
|
|
62
|
+
return this.getAttribute("orientation") === "vertical";
|
|
63
|
+
}
|
|
64
|
+
get tabs() {
|
|
65
|
+
return Array.from(this.querySelectorAll("a-tab"));
|
|
66
|
+
}
|
|
67
|
+
sync = () => {
|
|
68
|
+
const value = this.currentValue;
|
|
69
|
+
const tabs = this.tabs;
|
|
70
|
+
const selectedEl = tabs.find((t) => t.value === value && value != null) ?? null;
|
|
71
|
+
for (const t of tabs) t.selected = t === selectedEl;
|
|
72
|
+
if (this.internals && "ariaActiveDescendantElement" in this.internals) {
|
|
73
|
+
this.internals.ariaActiveDescendantElement = selectedEl;
|
|
74
|
+
}
|
|
75
|
+
if (this.alive && selectedEl && selectedEl !== this.lastSelected) {
|
|
76
|
+
selectedEl.scrollIntoView({ block: "nearest", inline: "nearest" });
|
|
77
|
+
}
|
|
78
|
+
this.lastSelected = selectedEl;
|
|
79
|
+
};
|
|
80
|
+
// The shared state algorithm: fire the cancelable `statechange` *before* applying.
|
|
81
|
+
// Controlled never self-applies; uncontrolled applies unless vetoed.
|
|
82
|
+
requestSelect(next) {
|
|
83
|
+
const prev = this.currentValue;
|
|
84
|
+
if (next === prev) return;
|
|
85
|
+
const ok = this.emitStateChange(next, prev);
|
|
86
|
+
if (this.hasAttribute("state")) return;
|
|
87
|
+
if (ok) {
|
|
88
|
+
this.uncontrolledValue = next;
|
|
89
|
+
this.sync();
|
|
90
|
+
this.emitChange();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Native `change`, fired *after* a selection applies (user pick or a controlled
|
|
94
|
+
// `state` update) — the post-apply counterpart to the cancelable `statechange`.
|
|
95
|
+
emitChange() {
|
|
96
|
+
this.dispatchEvent(new Event("change", { bubbles: true }));
|
|
97
|
+
}
|
|
98
|
+
/** Dispatch the shared cancelable `statechange`. `next`/`prev` are values
|
|
99
|
+
* (`null` when nothing is selected). Returns false if a listener vetoed. */
|
|
100
|
+
emitStateChange(next, prev) {
|
|
101
|
+
return this.dispatchEvent(
|
|
102
|
+
new CustomEvent("statechange", {
|
|
103
|
+
cancelable: true,
|
|
104
|
+
bubbles: true,
|
|
105
|
+
composed: true,
|
|
106
|
+
detail: { next, prev }
|
|
107
|
+
})
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
onClick = (e) => {
|
|
111
|
+
if (this.isDisabled) return;
|
|
112
|
+
const tab = e.target?.closest("a-tab");
|
|
113
|
+
if (!tab || tab.hasAttribute("disabled")) return;
|
|
114
|
+
tab.focus();
|
|
115
|
+
this.requestSelect(tab.value);
|
|
116
|
+
};
|
|
117
|
+
onKeyDown = (e) => {
|
|
118
|
+
if (this.isDisabled) return;
|
|
119
|
+
const enabled = this.tabs.filter((t) => !t.hasAttribute("disabled"));
|
|
120
|
+
if (enabled.length === 0) return;
|
|
121
|
+
const focused = e.target?.closest("a-tab");
|
|
122
|
+
if (e.key === " " || e.key === "Enter") {
|
|
123
|
+
if (focused && enabled.includes(focused)) {
|
|
124
|
+
e.preventDefault();
|
|
125
|
+
this.requestSelect(focused.value);
|
|
126
|
+
}
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
if (e.key === "Home" || e.key === "End") {
|
|
130
|
+
e.preventDefault();
|
|
131
|
+
const target = e.key === "Home" ? enabled[0] : enabled[enabled.length - 1];
|
|
132
|
+
target.focus();
|
|
133
|
+
this.requestSelect(target.value);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
const forward = e.key === (this.isVertical ? "ArrowDown" : "ArrowRight");
|
|
137
|
+
const back = e.key === (this.isVertical ? "ArrowUp" : "ArrowLeft");
|
|
138
|
+
if (!forward && !back) return;
|
|
139
|
+
e.preventDefault();
|
|
140
|
+
let i = focused ? enabled.indexOf(focused) : -1;
|
|
141
|
+
if (i === -1) i = enabled.findIndex((t) => t.value === this.currentValue);
|
|
142
|
+
if (i === -1) i = 0;
|
|
143
|
+
const next = enabled[(i + (forward ? 1 : -1) + enabled.length) % enabled.length];
|
|
144
|
+
next.focus();
|
|
145
|
+
this.requestSelect(next.value);
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function register_a_tabs() {
|
|
149
|
+
if (typeof customElements === "undefined") return;
|
|
150
|
+
if (!customElements.get("a-tabs"))
|
|
151
|
+
customElements.define("a-tabs", ATabsElement);
|
|
152
|
+
}
|
|
153
|
+
register_a_tabs();
|
|
154
|
+
export {
|
|
155
|
+
ATabsElement,
|
|
156
|
+
register_a_tabs
|
|
157
|
+
};
|
package/dist/elements/a-text.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer anta{a-text{--text-color: var(--text-2);--text-link-color: var(--link-color);--text-link-hover: var(--link-color-hover);display:block;color:var(--text-color);font-size:15px;line-height:20px;text-wrap:pretty;font-feature-settings:"ss02","ss05"}a-text[size=small]{font-size:13px;line-height:16px}a-text[size=medium]{font-size:15px;line-height:20px}a-text[size=large]{font-size:17px;line-height:24px}a-text[inline]{display:inline-block}a-text[truncate]{min-width:0}a-text[priority=primary]{--text-color: var(--text-1)}a-text[priority=tertiary]{--text-color: var(--text-3);--text-link-color: currentColor;--text-link-hover: var(--text-2)}a-text[priority=quaternary]{--text-color: var(--text-4);--text-link-color: currentColor;--text-link-hover: var(--text-3)}a-text[priority=quinary]{--text-color: var(--text-5);--text-link-color: currentColor;--text-link-hover: var(--text-4)}a-text[tone=brand]{--text-color: var(--text-2-brand);--text-link-color: currentColor;--text-link-hover: var(--text-1-brand)}a-text[tone=brand][priority=primary]{--text-color: var(--text-1-brand)}a-text[tone=brand][priority=tertiary]{--text-color: var(--text-3-brand);--text-link-hover: var(--text-2-brand)}a-text[tone=brand][priority=quaternary]{--text-color: var(--text-4-brand);--text-link-hover: var(--text-3-brand)}a-text[tone=brand][priority=quinary]{--text-color: var(--text-5-brand);--text-link-hover: var(--text-4-brand)}a-text[tone=success]{--text-color: var(--text-2-success);--text-link-color: currentColor;--text-link-hover: var(--text-1-success)}a-text[tone=success][priority=primary]{--text-color: var(--text-1-success)}a-text[tone=success][priority=tertiary]{--text-color: var(--text-3-success);--text-link-hover: var(--text-2-success)}a-text[tone=success][priority=quaternary]{--text-color: var(--text-4-success);--text-link-hover: var(--text-3-success)}a-text[tone=success][priority=quinary]{--text-color: var(--text-5-success);--text-link-hover: var(--text-4-success)}a-text[tone=critical]{--text-color: var(--text-2-critical);--text-link-color: currentColor;--text-link-hover: var(--text-1-critical)}a-text[tone=critical][priority=primary]{--text-color: var(--text-1-critical)}a-text[tone=critical][priority=tertiary]{--text-color: var(--text-3-critical);--text-link-hover: var(--text-2-critical)}a-text[tone=critical][priority=quaternary]{--text-color: var(--text-4-critical);--text-link-hover: var(--text-3-critical)}a-text[tone=critical][priority=quinary]{--text-color: var(--text-5-critical);--text-link-hover: var(--text-4-critical)}a-text[tone=warning]{--text-color: var(--text-2-warning);--text-link-color: currentColor;--text-link-hover: var(--text-1-warning)}a-text[tone=warning][priority=primary]{--text-color: var(--text-1-warning)}a-text[tone=warning][priority=tertiary]{--text-color: var(--text-3-warning);--text-link-hover: var(--text-2-warning)}a-text[tone=warning][priority=quaternary]{--text-color: var(--text-4-warning);--text-link-hover: var(--text-3-warning)}a-text[tone=warning][priority=quinary]{--text-color: var(--text-5-warning);--text-link-hover: var(--text-4-warning)}a-text[tone=info]{--text-color: var(--text-2-info);--text-link-color: currentColor;--text-link-hover: var(--text-1-info)}a-text[tone=info][priority=primary]{--text-color: var(--text-1-info)}a-text[tone=info][priority=tertiary]{--text-color: var(--text-3-info);--text-link-hover: var(--text-2-info)}a-text[tone=info][priority=quaternary]{--text-color: var(--text-4-info);--text-link-hover: var(--text-3-info)}a-text[tone=info][priority=quinary]{--text-color: var(--text-5-info);--text-link-hover: var(--text-4-info)}a-text a,a-text a:link,a-text a:visited{color:var(--text-link-color)}@media(hover:hover)and (pointer:fine){a-text a:hover{color:var(--text-link-hover);text-decoration-color:var(--text-link-hover)}}}
|
|
1
|
+
@layer anta{a-text{--text-color: var(--text-2);--text-link-color: var(--link-color);--text-link-hover: var(--link-color-hover);display:block;color:var(--text-color);font-size:15px;line-height:20px;text-wrap:pretty;font-feature-settings:"ss02","ss05","tnum"}a-text[size=small]{font-size:13px;line-height:16px}a-text[size=medium]{font-size:15px;line-height:20px}a-text[size=large]{font-size:17px;line-height:24px}a-text[inline]{display:inline-block}a-text[truncate]{min-width:0}a-text[priority=primary]{--text-color: var(--text-1)}a-text[priority=tertiary]{--text-color: var(--text-3);--text-link-color: currentColor;--text-link-hover: var(--text-2)}a-text[priority=quaternary]{--text-color: var(--text-4);--text-link-color: currentColor;--text-link-hover: var(--text-3)}a-text[priority=quinary]{--text-color: var(--text-5);--text-link-color: currentColor;--text-link-hover: var(--text-4)}a-text[tone=brand]{--text-color: var(--text-2-brand);--text-link-color: currentColor;--text-link-hover: var(--text-1-brand)}a-text[tone=brand][priority=primary]{--text-color: var(--text-1-brand)}a-text[tone=brand][priority=tertiary]{--text-color: var(--text-3-brand);--text-link-hover: var(--text-2-brand)}a-text[tone=brand][priority=quaternary]{--text-color: var(--text-4-brand);--text-link-hover: var(--text-3-brand)}a-text[tone=brand][priority=quinary]{--text-color: var(--text-5-brand);--text-link-hover: var(--text-4-brand)}a-text[tone=success]{--text-color: var(--text-2-success);--text-link-color: currentColor;--text-link-hover: var(--text-1-success)}a-text[tone=success][priority=primary]{--text-color: var(--text-1-success)}a-text[tone=success][priority=tertiary]{--text-color: var(--text-3-success);--text-link-hover: var(--text-2-success)}a-text[tone=success][priority=quaternary]{--text-color: var(--text-4-success);--text-link-hover: var(--text-3-success)}a-text[tone=success][priority=quinary]{--text-color: var(--text-5-success);--text-link-hover: var(--text-4-success)}a-text[tone=critical]{--text-color: var(--text-2-critical);--text-link-color: currentColor;--text-link-hover: var(--text-1-critical)}a-text[tone=critical][priority=primary]{--text-color: var(--text-1-critical)}a-text[tone=critical][priority=tertiary]{--text-color: var(--text-3-critical);--text-link-hover: var(--text-2-critical)}a-text[tone=critical][priority=quaternary]{--text-color: var(--text-4-critical);--text-link-hover: var(--text-3-critical)}a-text[tone=critical][priority=quinary]{--text-color: var(--text-5-critical);--text-link-hover: var(--text-4-critical)}a-text[tone=warning]{--text-color: var(--text-2-warning);--text-link-color: currentColor;--text-link-hover: var(--text-1-warning)}a-text[tone=warning][priority=primary]{--text-color: var(--text-1-warning)}a-text[tone=warning][priority=tertiary]{--text-color: var(--text-3-warning);--text-link-hover: var(--text-2-warning)}a-text[tone=warning][priority=quaternary]{--text-color: var(--text-4-warning);--text-link-hover: var(--text-3-warning)}a-text[tone=warning][priority=quinary]{--text-color: var(--text-5-warning);--text-link-hover: var(--text-4-warning)}a-text[tone=info]{--text-color: var(--text-2-info);--text-link-color: currentColor;--text-link-hover: var(--text-1-info)}a-text[tone=info][priority=primary]{--text-color: var(--text-1-info)}a-text[tone=info][priority=tertiary]{--text-color: var(--text-3-info);--text-link-hover: var(--text-2-info)}a-text[tone=info][priority=quaternary]{--text-color: var(--text-4-info);--text-link-hover: var(--text-3-info)}a-text[tone=info][priority=quinary]{--text-color: var(--text-5-info);--text-link-hover: var(--text-4-info)}a-text a,a-text a:link,a-text a:visited{color:var(--text-link-color)}@media(hover:hover)and (pointer:fine){a-text a:hover{color:var(--text-link-hover);text-decoration-color:var(--text-link-hover)}}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer anta{a-title{display:block;color:var(--text-1);font-weight:584.62;letter-spacing:0;text-wrap:balance;font-feature-settings:"ss02","ss05"}a-title a-icon{transform:translateY(-.05em)}a-title[level="1"]{font-size:28px;line-height:32px;margin-block-start:0;margin-block-end:16px}a-title[level="2"]{font-size:24px;line-height:28px;margin-block-start:32px;margin-block-end:12px}a-title[level="3"]{font-size:20px;line-height:24px;margin-block-start:24px;margin-block-end:12px}a-title[level="4"]{font-size:17px;line-height:20px;margin-block-start:20px;margin-block-end:8px}a-title[level="5"]{font-size:15px;line-height:20px;margin-block-start:16px;margin-block-end:8px}a-title[level="6"]{font-size:13px;line-height:16px;margin-block-start:16px;margin-block-end:4px}a-title[priority=secondary]{color:var(--text-2)}a-title[priority=tertiary]{color:var(--text-3)}a-title[priority=quaternary]{color:var(--text-4)}a-title[priority=quinary]{color:var(--text-5)}a-title[tone=brand]{color:var(--text-1-brand)}a-title[tone=brand][priority=secondary]{color:var(--text-2-brand)}a-title[tone=brand][priority=tertiary]{color:var(--text-3-brand)}a-title[tone=brand][priority=quaternary]{color:var(--text-4-brand)}a-title[tone=brand][priority=quinary]{color:var(--text-5-brand)}a-title[tone=success]{color:var(--text-1-success)}a-title[tone=success][priority=secondary]{color:var(--text-2-success)}a-title[tone=success][priority=tertiary]{color:var(--text-3-success)}a-title[tone=success][priority=quaternary]{color:var(--text-4-success)}a-title[tone=success][priority=quinary]{color:var(--text-5-success)}a-title[tone=critical]{color:var(--text-1-critical)}a-title[tone=critical][priority=secondary]{color:var(--text-2-critical)}a-title[tone=critical][priority=tertiary]{color:var(--text-3-critical)}a-title[tone=critical][priority=quaternary]{color:var(--text-4-critical)}a-title[tone=critical][priority=quinary]{color:var(--text-5-critical)}a-title[tone=warning]{color:var(--text-1-warning)}a-title[tone=warning][priority=secondary]{color:var(--text-2-warning)}a-title[tone=warning][priority=tertiary]{color:var(--text-3-warning)}a-title[tone=warning][priority=quaternary]{color:var(--text-4-warning)}a-title[tone=warning][priority=quinary]{color:var(--text-5-warning)}a-title[tone=info]{color:var(--text-1-info)}a-title[tone=info][priority=secondary]{color:var(--text-2-info)}a-title[tone=info][priority=tertiary]{color:var(--text-3-info)}a-title[tone=info][priority=quaternary]{color:var(--text-4-info)}a-title[tone=info][priority=quinary]{color:var(--text-5-info)}}
|
|
1
|
+
@layer anta{a-title{display:block;color:var(--text-1);font-weight:584.62;letter-spacing:0;text-wrap:balance;font-feature-settings:"ss02","ss05","tnum"}a-title a-icon{transform:translateY(-.05em)}a-title[level="1"]{font-size:28px;line-height:32px;margin-block-start:0;margin-block-end:16px}a-title[level="2"]{font-size:24px;line-height:28px;margin-block-start:32px;margin-block-end:12px}a-title[level="3"]{font-size:20px;line-height:24px;margin-block-start:24px;margin-block-end:12px}a-title[level="4"]{font-size:17px;line-height:20px;margin-block-start:20px;margin-block-end:8px}a-title[level="5"]{font-size:15px;line-height:20px;margin-block-start:16px;margin-block-end:8px}a-title[level="6"]{font-size:13px;line-height:16px;margin-block-start:16px;margin-block-end:4px}a-title[priority=secondary]{color:var(--text-2)}a-title[priority=tertiary]{color:var(--text-3)}a-title[priority=quaternary]{color:var(--text-4)}a-title[priority=quinary]{color:var(--text-5)}a-title[tone=brand]{color:var(--text-1-brand)}a-title[tone=brand][priority=secondary]{color:var(--text-2-brand)}a-title[tone=brand][priority=tertiary]{color:var(--text-3-brand)}a-title[tone=brand][priority=quaternary]{color:var(--text-4-brand)}a-title[tone=brand][priority=quinary]{color:var(--text-5-brand)}a-title[tone=success]{color:var(--text-1-success)}a-title[tone=success][priority=secondary]{color:var(--text-2-success)}a-title[tone=success][priority=tertiary]{color:var(--text-3-success)}a-title[tone=success][priority=quaternary]{color:var(--text-4-success)}a-title[tone=success][priority=quinary]{color:var(--text-5-success)}a-title[tone=critical]{color:var(--text-1-critical)}a-title[tone=critical][priority=secondary]{color:var(--text-2-critical)}a-title[tone=critical][priority=tertiary]{color:var(--text-3-critical)}a-title[tone=critical][priority=quaternary]{color:var(--text-4-critical)}a-title[tone=critical][priority=quinary]{color:var(--text-5-critical)}a-title[tone=warning]{color:var(--text-1-warning)}a-title[tone=warning][priority=secondary]{color:var(--text-2-warning)}a-title[tone=warning][priority=tertiary]{color:var(--text-3-warning)}a-title[tone=warning][priority=quaternary]{color:var(--text-4-warning)}a-title[tone=warning][priority=quinary]{color:var(--text-5-warning)}a-title[tone=info]{color:var(--text-1-info)}a-title[tone=info][priority=secondary]{color:var(--text-2-info)}a-title[tone=info][priority=tertiary]{color:var(--text-3-info)}a-title[tone=info][priority=quaternary]{color:var(--text-4-info)}a-title[tone=info][priority=quinary]{color:var(--text-5-info)}}
|
|
@@ -68,6 +68,24 @@ export declare class ATooltipElement extends HTMLElementBase {
|
|
|
68
68
|
private get isPinned();
|
|
69
69
|
private get prefersTop();
|
|
70
70
|
private get delay();
|
|
71
|
+
/** When set, the tooltip only shows if its resolved target is actually
|
|
72
|
+
* truncated/clipped; a fitting label gets no tooltip. */
|
|
73
|
+
private get truncatedOnly();
|
|
74
|
+
/** The element whose overflow decides whether the tooltip shows: a
|
|
75
|
+
* `truncated-selector` resolved within the anchor wins; else the first of
|
|
76
|
+
* Anta's ellipsizing label parts inside the anchor; else the anchor itself
|
|
77
|
+
* (which may be the clipping box for a hand-authored target). */
|
|
78
|
+
private resolveTruncationTarget;
|
|
79
|
+
/** True when the resolved target overflows its box (horizontal ellipsis or
|
|
80
|
+
* vertical clamp). A 1px threshold absorbs sub-pixel rounding; a zero-size
|
|
81
|
+
* (hidden / detached) target counts as not truncated. Measured fresh on each
|
|
82
|
+
* show attempt, so late fonts / resizes self-correct with no observer. */
|
|
83
|
+
private isTargetTruncated;
|
|
84
|
+
/** True when there's nothing worth showing: no element children (so an
|
|
85
|
+
* icon/image-only bubble still counts as content) and no non-whitespace text
|
|
86
|
+
* (so formatting whitespace / an empty conditional doesn't open a blank bubble).
|
|
87
|
+
* Re-checked on every show(), so a tooltip populated later self-corrects. */
|
|
88
|
+
private isEmpty;
|
|
71
89
|
private positionFrame?;
|
|
72
90
|
private pendingPosition?;
|
|
73
91
|
private schedulePosition;
|
|
@@ -12,6 +12,7 @@ const PROX_NEAR = 10;
|
|
|
12
12
|
const PROX_FAR = 100;
|
|
13
13
|
const PROX_FADE_MS = 60;
|
|
14
14
|
const ENTER_TOUCH_DELAY = 500;
|
|
15
|
+
const TRUNCATING_PARTS = "a-tab-label, a-button-label";
|
|
15
16
|
const LEAVE_TOUCH_DELAY = 1500;
|
|
16
17
|
const TOUCH_SLOP = 10;
|
|
17
18
|
let currentOpen = null;
|
|
@@ -218,6 +219,46 @@ class ATooltipElement extends HTMLElementBase {
|
|
|
218
219
|
const n = parseInt(attr, 10);
|
|
219
220
|
return Number.isFinite(n) ? n : DEFAULT_DELAY;
|
|
220
221
|
}
|
|
222
|
+
// --- truncated-only gating (UI-thread layout READS — no mutation) ---
|
|
223
|
+
/** When set, the tooltip only shows if its resolved target is actually
|
|
224
|
+
* truncated/clipped; a fitting label gets no tooltip. */
|
|
225
|
+
get truncatedOnly() {
|
|
226
|
+
return this.hasAttribute("truncated-only");
|
|
227
|
+
}
|
|
228
|
+
/** The element whose overflow decides whether the tooltip shows: a
|
|
229
|
+
* `truncated-selector` resolved within the anchor wins; else the first of
|
|
230
|
+
* Anta's ellipsizing label parts inside the anchor; else the anchor itself
|
|
231
|
+
* (which may be the clipping box for a hand-authored target). */
|
|
232
|
+
resolveTruncationTarget() {
|
|
233
|
+
const anchor = this.anchor;
|
|
234
|
+
if (!anchor) return null;
|
|
235
|
+
const sel = this.getAttribute("truncated-selector");
|
|
236
|
+
if (sel) {
|
|
237
|
+
try {
|
|
238
|
+
const found = anchor.querySelector(sel);
|
|
239
|
+
if (found) return found;
|
|
240
|
+
} catch {
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return anchor.querySelector(TRUNCATING_PARTS) ?? anchor;
|
|
244
|
+
}
|
|
245
|
+
/** True when the resolved target overflows its box (horizontal ellipsis or
|
|
246
|
+
* vertical clamp). A 1px threshold absorbs sub-pixel rounding; a zero-size
|
|
247
|
+
* (hidden / detached) target counts as not truncated. Measured fresh on each
|
|
248
|
+
* show attempt, so late fonts / resizes self-correct with no observer. */
|
|
249
|
+
isTargetTruncated() {
|
|
250
|
+
const t = this.resolveTruncationTarget();
|
|
251
|
+
if (!t) return false;
|
|
252
|
+
if (t.clientWidth === 0 && t.clientHeight === 0) return false;
|
|
253
|
+
return t.scrollWidth - t.clientWidth > 1 || t.scrollHeight - t.clientHeight > 1;
|
|
254
|
+
}
|
|
255
|
+
/** True when there's nothing worth showing: no element children (so an
|
|
256
|
+
* icon/image-only bubble still counts as content) and no non-whitespace text
|
|
257
|
+
* (so formatting whitespace / an empty conditional doesn't open a blank bubble).
|
|
258
|
+
* Re-checked on every show(), so a tooltip populated later self-corrects. */
|
|
259
|
+
isEmpty() {
|
|
260
|
+
return this.children.length === 0 && (this.textContent ?? "").trim() === "";
|
|
261
|
+
}
|
|
221
262
|
// --- positioning (sets only the shadow container's own transform) ---
|
|
222
263
|
// Single pending position frame: a burst of mousemoves within one frame
|
|
223
264
|
// coalesces to ONE layout read + transform write, using the LATEST geometry
|
|
@@ -289,6 +330,8 @@ class ATooltipElement extends HTMLElementBase {
|
|
|
289
330
|
// --- show / hide ---
|
|
290
331
|
show = (e) => {
|
|
291
332
|
if (!this.anchor) return;
|
|
333
|
+
if (this.isEmpty()) return;
|
|
334
|
+
if (this.truncatedOnly && !this.isTargetTruncated()) return;
|
|
292
335
|
this.cancelHide();
|
|
293
336
|
if (currentOpen && currentOpen !== this && this.anchor.contains(currentOpen.anchor)) {
|
|
294
337
|
return;
|
|
@@ -400,6 +443,8 @@ class ATooltipElement extends HTMLElementBase {
|
|
|
400
443
|
/** Open now if another tooltip is hot (skip delay), else (re)arm the delayed
|
|
401
444
|
* show with the latest cursor event. */
|
|
402
445
|
trigger(e) {
|
|
446
|
+
if (this.isEmpty()) return;
|
|
447
|
+
if (this.truncatedOnly && !this.isTargetTruncated()) return;
|
|
403
448
|
if (isHot()) {
|
|
404
449
|
this.debouncedShow?.cancel();
|
|
405
450
|
this.show(e);
|
package/dist/elements/index.d.ts
CHANGED
|
@@ -27,5 +27,8 @@ export { AMenuElement, register_a_menu } from './a-menu';
|
|
|
27
27
|
export { AMenuItemElement, register_a_menu_item } from './a-menu-item';
|
|
28
28
|
export { AMenuSeparatorElement, register_a_menu_separator } from './a-menu-separator';
|
|
29
29
|
export { AMenuGroupElement, register_a_menu_group } from './a-menu-group';
|
|
30
|
+
export { ATabElement, register_a_tab } from './a-tab';
|
|
31
|
+
export { ATabsElement, register_a_tabs } from './a-tabs';
|
|
30
32
|
import './a-title.css';
|
|
31
33
|
import './a-tag.css';
|
|
34
|
+
import './a-tabpanel.css';
|
package/dist/elements/index.js
CHANGED
|
@@ -12,8 +12,11 @@ import { AMenuElement, register_a_menu } from "./a-menu";
|
|
|
12
12
|
import { AMenuItemElement, register_a_menu_item } from "./a-menu-item";
|
|
13
13
|
import { AMenuSeparatorElement, register_a_menu_separator } from "./a-menu-separator";
|
|
14
14
|
import { AMenuGroupElement, register_a_menu_group } from "./a-menu-group";
|
|
15
|
+
import { ATabElement, register_a_tab } from "./a-tab";
|
|
16
|
+
import { ATabsElement, register_a_tabs } from "./a-tabs";
|
|
15
17
|
import "./a-title.css";
|
|
16
18
|
import "./a-tag.css";
|
|
19
|
+
import "./a-tabpanel.css";
|
|
17
20
|
export {
|
|
18
21
|
AButtonElement,
|
|
19
22
|
ACheckboxElement,
|
|
@@ -27,6 +30,8 @@ export {
|
|
|
27
30
|
AProgressElement,
|
|
28
31
|
ARadioElement,
|
|
29
32
|
ARadioGroupElement,
|
|
33
|
+
ATabElement,
|
|
34
|
+
ATabsElement,
|
|
30
35
|
ATextElement,
|
|
31
36
|
ATooltipElement,
|
|
32
37
|
register_a_button,
|
|
@@ -41,6 +46,8 @@ export {
|
|
|
41
46
|
register_a_progress,
|
|
42
47
|
register_a_radio,
|
|
43
48
|
register_a_radio_group,
|
|
49
|
+
register_a_tab,
|
|
50
|
+
register_a_tabs,
|
|
44
51
|
register_a_text,
|
|
45
52
|
register_a_tooltip
|
|
46
53
|
};
|