@antadesign/anta 0.3.1 → 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.
Files changed (42) hide show
  1. package/dist/anta_helpers.d.ts +10 -0
  2. package/dist/anta_helpers.js +13 -1
  3. package/dist/components/Button.js +8 -17
  4. package/dist/components/Checkbox.d.ts +16 -15
  5. package/dist/components/Checkbox.js +10 -6
  6. package/dist/components/Input.d.ts +4 -4
  7. package/dist/components/Input.js +5 -5
  8. package/dist/components/RadioGroup.d.ts +15 -15
  9. package/dist/components/RadioGroup.js +8 -8
  10. package/dist/components/Tab.d.ts +34 -0
  11. package/dist/components/Tab.js +4 -0
  12. package/dist/components/TabPanel.d.ts +22 -0
  13. package/dist/components/TabPanel.js +4 -0
  14. package/dist/components/Tabs.d.ts +112 -0
  15. package/dist/components/Tabs.js +174 -0
  16. package/dist/components/Tabs.module.css +1 -0
  17. package/dist/components/Tooltip.d.ts +10 -1
  18. package/dist/components/Tooltip.js +4 -0
  19. package/dist/elements/a-button.css +1 -1
  20. package/dist/elements/a-checkbox.css +1 -1
  21. package/dist/elements/a-expander.js +6 -1
  22. package/dist/elements/a-input.js +1 -1
  23. package/dist/elements/a-radio.css +1 -1
  24. package/dist/elements/a-tab.css +1 -0
  25. package/dist/elements/a-tab.d.ts +14 -0
  26. package/dist/elements/a-tab.js +46 -0
  27. package/dist/elements/a-tabpanel.css +1 -0
  28. package/dist/elements/a-tabs.css +1 -0
  29. package/dist/elements/a-tabs.d.ts +31 -0
  30. package/dist/elements/a-tabs.js +157 -0
  31. package/dist/elements/a-text.css +1 -1
  32. package/dist/elements/a-title.css +1 -1
  33. package/dist/elements/a-tooltip.d.ts +18 -0
  34. package/dist/elements/a-tooltip.js +45 -0
  35. package/dist/elements/index.d.ts +3 -0
  36. package/dist/elements/index.js +7 -0
  37. package/dist/general_types.d.ts +146 -20
  38. package/dist/index.d.ts +6 -0
  39. package/dist/index.js +6 -0
  40. package/dist/jsx-runtime.d.ts +5 -1
  41. package/dist/tokens.css +1 -1
  42. package/package.json +1 -1
@@ -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
+ };
@@ -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);
@@ -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';
@@ -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
  };
@@ -321,6 +321,14 @@ export interface ATooltipAttributes extends BaseAttributes {
321
321
  /** Make the bubble hoverable/clickable (pointer events on, stays open while
322
322
  * hovered). Always pinned. Presence-based (`''` on, omit off). */
323
323
  interactive?: boolean | '';
324
+ /** Only show when the measured target is actually truncated/clipped (its text
325
+ * overflows). UI-thread layout read, re-measured per show. Defaults to the
326
+ * nearest Anta ellipsizing label part (`a-tab-label` / `a-button-label`) in the
327
+ * anchor, then the anchor itself. Presence-based (`''` on, omit off). */
328
+ 'truncated-only'?: boolean | '';
329
+ /** CSS selector (resolved within the anchor) for the element whose overflow a
330
+ * `truncated-only` tooltip measures. */
331
+ 'truncated-selector'?: string;
324
332
  /** HTML `id`. */
325
333
  id?: string;
326
334
  }
@@ -335,16 +343,17 @@ export interface ATooltipAttributes extends BaseAttributes {
335
343
  * `@antadesign/anta`.
336
344
  */
337
345
  export interface ACheckboxAttributes extends BaseAttributes {
338
- /** Colour variant, or any literal CSS color for a one-off custom tone.
339
- * Named tones track light/dark mode automatically via the theme-aware role
340
- * tokens. `'neutral'` is the default (same as omitting it). */
346
+ /** Mark colour (checked fill + unselected box border), or any literal CSS color
347
+ * for a one-off custom tone. Named tones track light/dark mode automatically via
348
+ * the theme-aware role tokens. `'neutral'` is the default (same as omitting it).
349
+ * The label + hint stay neutral — use `tone-text` for those. */
341
350
  tone?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
351
+ /** Text colour (label + hint), independent of `tone`. A named tone or any literal
352
+ * CSS color; named tones track light/dark via the `--text-*` role tokens. Omit
353
+ * (or `'neutral'`) to leave the text neutral. */
354
+ 'tone-text'?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
342
355
  /** Size variant. `small` = 14px, `medium` (default) = 16px, `large` = 18px box. */
343
356
  size?: 'small' | 'medium' | 'large';
344
- /** Visual priority. `primary` (default) fills the checked box with the tone
345
- * colour and draws a white checkmark; `secondary` keeps the box unfilled and
346
- * draws the border + checkmark in the tone colour (an outlined look). */
347
- priority?: 'primary' | 'secondary';
348
357
  /** Controlled state — the element reflects changes to this attribute. Use this
349
358
  * (driven from your store) for a controlled checkbox; use `default-state` for
350
359
  * an uncontrolled one. */
@@ -565,16 +574,17 @@ export interface AButtonAttributes extends BaseAttributes {
565
574
  export interface ARadioAttributes extends BaseAttributes {
566
575
  /** This option's identity / submitted value. */
567
576
  value?: string;
568
- /** Colour variant, or any literal CSS color for a one-off custom tone.
569
- * Named tones track light/dark mode automatically via the theme-aware role
570
- * tokens. `'neutral'` is the default (same as omitting it). */
577
+ /** Mark colour (selected ring fill + dot, unselected ring border), or any literal
578
+ * CSS color for a one-off custom tone. Named tones track light/dark mode via the
579
+ * theme-aware role tokens. `'neutral'` is the default. The label + hint stay
580
+ * neutral — use `tone-text` for those. */
571
581
  tone?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
582
+ /** Text colour (label + hint), independent of `tone`. A named tone or any literal
583
+ * CSS color; named tones track light/dark via the `--text-*` role tokens. Omit
584
+ * (or `'neutral'`) to leave the text neutral. */
585
+ 'tone-text'?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
572
586
  /** Size variant. small=14px, medium=16px, large=18px control. */
573
587
  size?: 'small' | 'medium' | 'large';
574
- /** Visual priority. `primary` (default) fills the selected ring with the tone
575
- * colour and draws a white dot; `secondary` keeps the ring unfilled and draws
576
- * the border + dot in the tone colour (an outlined look). */
577
- priority?: 'primary' | 'secondary';
578
588
  /** Disabled state. Presence-based (`''` on, omit off). */
579
589
  disabled?: boolean | '';
580
590
  /** Selected state — connect-time seed for the standalone render path (no
@@ -614,16 +624,16 @@ export interface ARadioGroupAttributes extends BaseAttributes {
614
624
  'default-state'?: string;
615
625
  /** Form field name — the group submits `name=value`. */
616
626
  name?: string;
617
- /** Tone cascaded to children that don't set their own, or any literal CSS
627
+ /** Mark tone cascaded to children that don't set their own, or any literal CSS
618
628
  * color for a one-off custom tone. Inherits through CSS so every child
619
- * `<a-radio>` picks up the same fill curve. */
629
+ * `<a-radio>` picks up the same fill curve. The option text stays neutral —
630
+ * use `tone-text`. */
620
631
  tone?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
632
+ /** Text tone cascaded to children's label + hint, independent of `tone`. A named
633
+ * tone or any literal CSS color. Omit (or `'neutral'`) to leave the text neutral. */
634
+ 'tone-text'?: 'brand' | 'neutral' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
621
635
  /** Size cascaded to children that don't set their own. */
622
636
  size?: 'small' | 'medium' | 'large';
623
- /** Visual priority cascaded to children that don't set their own. `primary`
624
- * (default) fills the selected ring with the tone colour; `secondary` keeps it
625
- * unfilled and draws the border + dot in the tone colour (an outlined look). */
626
- priority?: 'primary' | 'secondary';
627
637
  /** Validation/feedback tone for the group hint — same set as `<a-input>`'s
628
638
  * `status`. Recolours `<a-radio-group-hint>`; omit for the neutral default. */
629
639
  status?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical';
@@ -656,3 +666,119 @@ export interface ARadioGroupAttributes extends BaseAttributes {
656
666
  'aria-label'?: string;
657
667
  'aria-labelledby'?: string;
658
668
  }
669
+ /**
670
+ * Attributes for the `<a-tab>` custom element — one tab in a tablist. Presentational,
671
+ * the sibling of `<a-radio>`: the parent `<a-tabs>` owns selection, keyboard, and
672
+ * scrolling. The selected look comes from the element's `:state(selected)` (set by the
673
+ * tablist via the `selected` property), not a host attribute. There is no `Tab` web
674
+ * component to render directly — `Tabs` renders these from its `<Tab>` children, and
675
+ * hand-authors write `<a-tab>` directly inside an `<a-tabs>`. Wrap the visible label in
676
+ * `<a-tab-label>` (as `Tabs` does) so it carries the optical baseline nudge, truncates
677
+ * with an ellipsis when constrained, and keeps a sibling `<a-icon>` centered — exactly
678
+ * like `<a-button-label>`.
679
+ */
680
+ export interface ATabAttributes extends BaseAttributes {
681
+ /** This tab's identity / the value reported when it's selected. */
682
+ value?: string;
683
+ /** Per-tab tone override (same vocabulary as `<a-tabs tone>`): colours this tab's
684
+ * label + icons and, when selected, its indicator. Named tones tone the sliding
685
+ * indicator too; a custom literal colour tones the indicator only in `noslide`.
686
+ * Custom tones also set `--tabs-tone-source` on the tab (via the wrapper's style). */
687
+ tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
688
+ /** Selected state — connect-time seed for the standalone render path (no tablist).
689
+ * In an `<a-tabs>`, the tablist drives `:state(selected)` directly and this
690
+ * attribute is ignored. Presence-based (`''` on, omit off). */
691
+ selected?: boolean | '';
692
+ /** Disabled state. Presence-based (`''` on, omit off). */
693
+ disabled?: boolean | '';
694
+ /** ARIA — `role="tab"` is set by the consumer (`Tabs` on each tab, or a hand-author),
695
+ * and `aria-controls` points at the paired panel. `aria-selected` is published by
696
+ * the element through `ElementInternals` (off the DOM), driven by the `selected`
697
+ * property the tablist sets — not a DOM attribute. `tabindex` (inherited from
698
+ * `BaseAttributes`) is set by `Tabs` — every enabled tab is its own tab stop
699
+ * (`tabindex="0"`) — not by the element. */
700
+ role?: 'tab';
701
+ 'aria-controls'?: string;
702
+ 'aria-disabled'?: 'true' | 'false';
703
+ }
704
+ /**
705
+ * Attributes for the `<a-tabs>` custom element — the tablist + single-select
706
+ * coordinator. No shadow DOM: `<a-tab>` children are plain light-DOM, laid out by
707
+ * `a-tabs.css`, so the strip is restylable with ordinary CSS and usable hand-assembled.
708
+ * Unlike `<a-radio-group>` it is NOT form-associated (a tablist submits nothing), and
709
+ * the panels live outside it (siblings the `Tabs` wrapper shows/hides). The element
710
+ * coordinates **off-DOM only** — selection via each tab's `selected` property, focus via
711
+ * `internals.ariaActiveDescendantElement`, scroll via `scrollIntoView`. Roving
712
+ * `tabindex` (the JSX path) is rendered by the `Tabs` wrapper, not the element. For the
713
+ * typed JSX wrapper use `Tabs` from `@antadesign/anta`.
714
+ */
715
+ export interface ATabsAttributes extends BaseAttributes {
716
+ /** Controlled selected value (the active tab's `value`). Present → controlled: the
717
+ * element reflects changes to this attribute and a pick only dispatches
718
+ * `statechange`. Absent → uncontrolled (seed with `default-state`). */
719
+ state?: string;
720
+ /** Uncontrolled initial selected value — read once on connect. */
721
+ 'default-state'?: string;
722
+ /** Visual priority. `primary` (default) is the raised pill on a recessed track; `secondary`
723
+ * keeps that sizing but drops the track (selected = subtle active background fill, no
724
+ * border); `tertiary` is a bottom-underline under the selected tab only (no track, no rest
725
+ * line). `tone` tints secondary + tertiary; primary stays neutral. */
726
+ priority?: 'primary' | 'secondary' | 'tertiary';
727
+ /** Tone applied to the selected indicator/label, or any literal CSS color for a
728
+ * one-off custom tone (derived in oklch). `'neutral'` is the default. */
729
+ tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
730
+ /** Size variant. small=24px, medium (default)=28px, large=32px tall — matching Button's
731
+ * scale (the label leading runs a touch tighter, offset by 1px more block padding per side). */
732
+ size?: 'small' | 'medium' | 'large';
733
+ /** Layout + arrow-key axis. `'horizontal'` (default) ellipsizes labels when tabs
734
+ * overflow (scrolling is opt-in via CSS); `'vertical'` stacks them. */
735
+ orientation?: 'horizontal' | 'vertical';
736
+ /** Disable the sliding indicator. By default the selected-tab indicator is a single
737
+ * rectangle that animates between tabs via CSS anchor positioning; with `noslide` the
738
+ * highlight is painted on each tab and snaps with no movement (also the automatic
739
+ * fallback where anchor positioning isn't supported). Presence-based (`''` on, omit off). */
740
+ noslide?: boolean | '';
741
+ /** Disable the whole strip. Presence-based (`''` on, omit off). */
742
+ disabled?: boolean | '';
743
+ /** Fires whenever the active tab changes. `detail` carries `{ next, prev }` (values;
744
+ * `null` = none). Cancelable: a synchronous `preventDefault()` vetoes the pick in
745
+ * uncontrolled mode. All-lowercase to bind across both renderers (like
746
+ * `<a-radio-group>`). */
747
+ onstatechange?: (e: CustomEvent<{
748
+ next: string | null;
749
+ prev: string | null;
750
+ }>) => void;
751
+ /** Native `change`, fired *after* a selection applies (post-apply counterpart to
752
+ * `onstatechange`). Lowercase so both renderers bind the native event. */
753
+ onchange?: (e: Event) => void;
754
+ /** Strip focus enter / leave — wired from the bubbling `focusin` / `focusout` (focus
755
+ * lands on a tab, not the tablist). The `Tabs` wrapper maps its `onFocus`/`onBlur`. */
756
+ onfocusin?: (e: FocusEvent) => void;
757
+ onfocusout?: (e: FocusEvent) => void;
758
+ /** ARIA — set by the `Tabs` wrapper (the element never touches these). */
759
+ role?: 'tablist';
760
+ 'aria-orientation'?: 'horizontal' | 'vertical';
761
+ 'aria-disabled'?: 'true' | 'false';
762
+ 'aria-label'?: string;
763
+ }
764
+ /**
765
+ * Attributes for the `<a-tabpanel>` styled tag.
766
+ *
767
+ * `<a-tabpanel>` has no JS — it's a CSS-only styled element. The `Tabs` wrapper renders
768
+ * it, pairs it to its tab via id, and toggles visibility declaratively: `hidden`
769
+ * (display:none) or `data-hide="visibility"` (keeps the layout box), plus `inert` while
770
+ * hidden. Low-level attributes; for the typed JSX wrapper use `TabPanel` (inside `Tabs`)
771
+ * from `@antadesign/anta`.
772
+ */
773
+ export interface ATabpanelAttributes extends BaseAttributes {
774
+ /** Hidden via `display:none`. Presence-based (`''` on, omit off). */
775
+ hidden?: boolean | '';
776
+ /** Hidden via `visibility:hidden` (keeps the layout box). The `Tabs` wrapper sets
777
+ * this for `mounting="visibility"`. */
778
+ 'data-hide'?: 'visibility';
779
+ /** Removes the hidden panel from focus + the a11y tree. Presence-based. */
780
+ inert?: boolean | '';
781
+ /** ARIA — set by the `Tabs` wrapper. */
782
+ role?: 'tabpanel';
783
+ 'aria-labelledby'?: string;
784
+ }
package/dist/index.d.ts CHANGED
@@ -47,6 +47,12 @@ export { Input } from './components/Input';
47
47
  export type { InputProps, InputChangeAttrs } from './components/Input';
48
48
  export { RadioGroup } from './components/RadioGroup';
49
49
  export type { RadioGroupProps, RadioOption } from './components/RadioGroup';
50
+ export { Tabs } from './components/Tabs';
51
+ export type { TabsProps, TabsMounting, TabsChangeAttrs } from './components/Tabs';
52
+ export { Tab } from './components/Tab';
53
+ export type { TabProps } from './components/Tab';
54
+ export { TabPanel } from './components/TabPanel';
55
+ export type { TabPanelProps } from './components/TabPanel';
50
56
  export type { BaseProps, BaseAttributes } from './general_types';
51
57
  export { configure } from './jsx-runtime';
52
58
  export type { AntaIntrinsicElements } from './jsx-runtime';
package/dist/index.js CHANGED
@@ -14,6 +14,9 @@ import { MenuGroup } from "./components/MenuGroup";
14
14
  import { Expander } from "./components/Expander";
15
15
  import { Input } from "./components/Input";
16
16
  import { RadioGroup } from "./components/RadioGroup";
17
+ import { Tabs } from "./components/Tabs";
18
+ import { Tab } from "./components/Tab";
19
+ import { TabPanel } from "./components/TabPanel";
17
20
  import { configure } from "./jsx-runtime";
18
21
  export {
19
22
  Button,
@@ -29,6 +32,9 @@ export {
29
32
  MenuSeparator,
30
33
  Progress,
31
34
  RadioGroup,
35
+ Tab,
36
+ TabPanel,
37
+ Tabs,
32
38
  Tag,
33
39
  Text,
34
40
  Title,
@@ -37,7 +37,7 @@ export declare function useId(): string;
37
37
  export declare function jsx(type: ComponentType, props: Record<string, unknown> | null, key?: string | number): unknown;
38
38
  export declare function jsxs(type: ComponentType, props: Record<string, unknown> | null, key?: string | number): unknown;
39
39
  export { _Fragment as Fragment };
40
- import type { AProgressAttributes, ATextAttributes, ATitleAttributes, ATagAttributes, AExpanderAttributes, AIconAttributes, AButtonAttributes, ACheckboxAttributes, ATooltipAttributes, AInputAttributes, ARadioAttributes, ARadioGroupAttributes, AMenuAttributes, AMenuItemAttributes, AMenuGroupAttributes, BaseAttributes } from './general_types';
40
+ import type { AProgressAttributes, ATextAttributes, ATitleAttributes, ATagAttributes, AExpanderAttributes, AIconAttributes, AButtonAttributes, ACheckboxAttributes, ATooltipAttributes, AInputAttributes, ARadioAttributes, ARadioGroupAttributes, AMenuAttributes, AMenuItemAttributes, AMenuGroupAttributes, ATabsAttributes, ATabAttributes, ATabpanelAttributes, BaseAttributes } from './general_types';
41
41
  export declare namespace JSX {
42
42
  interface IntrinsicElements extends React.JSX.IntrinsicElements, AntaIntrinsicElements {
43
43
  }
@@ -77,4 +77,8 @@ export interface AntaIntrinsicElements {
77
77
  'a-menu-separator': BaseAttributes;
78
78
  'a-menu-group': AMenuGroupAttributes;
79
79
  'a-menu-group-label': BaseAttributes;
80
+ 'a-tabs': ATabsAttributes;
81
+ 'a-tab': ATabAttributes;
82
+ 'a-tab-label': BaseAttributes;
83
+ 'a-tabpanel': ATabpanelAttributes;
80
84
  }
package/dist/tokens.css CHANGED
@@ -1 +1 @@
1
- @layer base,anta,components,utilities;:root,.light{--sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;--monospace: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", monospace;font-size:15px;font-weight:400;font-feature-settings:"ss02" on,"ss05" on;--bg-1: #ffffff;--bg-2: #fbfafb;--bg-3: #f6f4f6;--bg-4: #f1eff1;--bg-5: #ece9ec;--bg-2-brand: #fcfcfe;--bg-3-brand: #f7f6fd;--bg-4-brand: #efeefc;--bg-5-brand: #e9e5fa;--bg-2-success: #f7fcf9;--bg-3-success: #ecf9f0;--bg-4-success: #e2f5e8;--bg-5-success: #d9f2e0;--bg-2-critical: #fefbfb;--bg-3-critical: #fdf2f2;--bg-4-critical: #fcebeb;--bg-5-critical: #fae5e5;--bg-2-warning: #fefbf6;--bg-3-warning: #fcf4e8;--bg-4-warning: #fbeeda;--bg-5-warning: #f9e7cd;--bg-2-info: #fbfcfe;--bg-3-info: #f2f7fd;--bg-4-info: #e9f3fb;--bg-5-info: #e1eefa;--text-1: #050306;--text-2: #302b31;--text-3: #635b65;--text-4: #878089;--text-5: #9f99a1;--text-1-brand: #2e1e7b;--text-2-brand: #483493;--text-3-brand: #483493cc;--text-4-brand: #48349399;--text-5-brand: #48349366;--text-1-success: #004618;--text-2-success: #1f5c31;--text-3-success: #1f5c31cc;--text-4-success: #1f5c3199;--text-5-success: #1f5c3166;--text-1-critical: #8f1014;--text-2-critical: #a01c1c;--text-3-critical: #a01c1ccc;--text-4-critical: #a01c1c99;--text-5-critical: #a01c1c66;--text-1-warning: #7f410b;--text-2-warning: #995200;--text-3-warning: #995200cc;--text-4-warning: #99520099;--text-5-warning: #99520066;--text-1-info: #003969;--text-2-info: #175082;--text-3-info: #175082cc;--text-4-info: #175082b2;--text-5-info: #17508280;--border-1: #938d96;--border-2: #c1b9c1;--border-3: #d4ced4;--border-4: #e0dce0;--border-5: #ece9ec;--border-1-brand: #9081df;--border-2-brand: #bcb1f1;--border-3-brand: #d2cbf6;--border-4-brand: #ddd8f8;--border-5-brand: #e9e5fa;--border-1-success: #44c169;--border-2-success: #88d7a0;--border-3-success: #b3e5c2;--border-4-success: #c6ecd1;--border-5-success: #d9f2e0;--border-1-critical: #e56c6c;--border-2-critical: #efa4a4;--border-3-critical: #f4c2c2;--border-4-critical: #f7d4d4;--border-5-critical: #fae5e5;--border-1-warning: #d88118;--border-2-warning: #edb25a;--border-3-warning: #f3cc91;--border-4-warning: #f6dbb1;--border-5-warning: #f9e7cd;--border-1-info: #56a1e1;--border-2-info: #93c5ec;--border-3-info: #bad6f3;--border-4-info: #cfe3f7;--border-5-info: #e1eefa;--link-color: #1466d4;--link-color-hover: #2674e6;--focus-ring: oklch(.55 .2 284.15)}.dark{font-weight:400;--bg-1: #000000;--bg-2: #0e0d0f;--bg-3: #121014;--bg-4: #161316;--bg-5: #1a171b;--bg-2-brand: #08060e;--bg-3-brand: #0f0c1d;--bg-4-brand: #130f24;--bg-5-brand: #16132b;--bg-2-success: #030b06;--bg-3-success: #051209;--bg-4-success: #06160b;--bg-5-success: #081b0e;--bg-2-critical: #120303;--bg-3-critical: #210606;--bg-4-critical: #260808;--bg-5-critical: #2e0a0b;--bg-2-warning: #110a03;--bg-3-warning: #1c1105;--bg-4-warning: #231406;--bg-5-warning: #2b1a08;--bg-2-info: #020a12;--bg-3-info: #05131f;--bg-4-info: #071725;--bg-5-info: #0c2337;--text-1: #ece9ec;--text-2: #c1b9c1;--text-3: #9f99a1;--text-4: #776e77;--text-5: #635b65;--text-1-brand: #c5baff;--text-2-brand: #ada0ee;--text-3-brand: #ada0eecc;--text-4-brand: #ada0ee99;--text-5-brand: #ada0ee66;--text-1-success: #9ddeb1;--text-2-success: #74cd8e;--text-3-success: #74cd8ecc;--text-4-success: #74cd8e99;--text-5-success: #74cd8e66;--text-1-critical: #ffabac;--text-2-critical: #e78e90;--text-3-critical: #e78e90cc;--text-4-critical: #e78e9099;--text-5-critical: #e78e9066;--text-1-warning: #f0bf75;--text-2-warning: #e1a452;--text-3-warning: #e1a452cc;--text-4-warning: #e1a45299;--text-5-warning: #e1a45266;--text-1-info: #9ed2ff;--text-2-info: #7db6e8;--text-3-info: #7db6e8cc;--text-4-info: #7db6e899;--text-5-info: #7db6e866;--border-1: hsl(288deg 5.21% 42%);--border-2: hsl(282deg 7.04% 28%);--border-3: hsl(277.5deg 6.56% 20%);--border-4: hsl(290deg 6.52% 13%);--border-5: hsl(285deg 7.14% 10%);--border-1-brand: hsl(250.08deg 59.8% 58%);--border-2-brand: hsl(250deg 50% 42%);--border-3-brand: hsl(252.63deg 47.74% 30%);--border-4-brand: hsl(249.8deg 39.84% 19%);--border-5-brand: hsl(249deg 39.22% 14%);--border-1-success: hsl(138.18deg 49.75% 29%);--border-2-success: hsl(138.26deg 50.36% 20%);--border-3-success: hsl(137.7deg 49.59% 16%);--border-4-success: hsl(138.46deg 52% 10%);--border-5-success: hsl(138.86deg 53.85% 7.5%);--border-1-critical: hsl(0deg 56% 46%);--border-2-critical: hsl(.42deg 63% 30%);--border-3-critical: hsl(0deg 62.21% 23%);--border-4-critical: hsl(359.13deg 59% 15%);--border-5-critical: hsl(359.06deg 63% 11%);--border-1-warning: hsl(32.13deg 80.31% 34%);--border-2-warning: hsl(27.93deg 84.06% 24%);--border-3-warning: hsl(30deg 79.66% 17%);--border-4-warning: hsl(28.75deg 63.16% 12%);--border-5-warning: hsl(28.64deg 66.67% 9%);--border-1-info: hsl(207.82deg 70.2% 40%);--border-2-info: hsl(207.77deg 69.94% 29%);--border-3-info: hsl(208.04deg 69.93% 21%);--border-4-info: hsl(208.52deg 62.89% 14%);--border-5-info: hsl(207.78deg 65.85% 10.5%);--link-color: #7baee9;--link-color-hover: #90bdee;--focus-ring: #a897fc}
1
+ @layer base,anta,components,utilities;:root,.light{--sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;--monospace: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", monospace;font-size:15px;font-weight:400;font-feature-settings:"ss02" on,"ss05" on,"tnum" on;--bg-1: #ffffff;--bg-2: #fbfafb;--bg-3: #f6f4f6;--bg-4: #f1eff1;--bg-5: #ece9ec;--bg-2-brand: #fcfcfe;--bg-3-brand: #f7f6fd;--bg-4-brand: #efeefc;--bg-5-brand: #e9e5fa;--bg-2-success: #f7fcf9;--bg-3-success: #ecf9f0;--bg-4-success: #e2f5e8;--bg-5-success: #d9f2e0;--bg-2-critical: #fefbfb;--bg-3-critical: #fdf2f2;--bg-4-critical: #fcebeb;--bg-5-critical: #fae5e5;--bg-2-warning: #fefbf6;--bg-3-warning: #fcf4e8;--bg-4-warning: #fbeeda;--bg-5-warning: #f9e7cd;--bg-2-info: #fbfcfe;--bg-3-info: #f2f7fd;--bg-4-info: #e9f3fb;--bg-5-info: #e1eefa;--text-1: #050306;--text-2: #302b31;--text-3: #635b65;--text-4: #878089;--text-5: #9f99a1;--text-1-brand: #2e1e7b;--text-2-brand: #483493;--text-3-brand: #483493cc;--text-4-brand: #48349399;--text-5-brand: #48349366;--text-1-success: #004618;--text-2-success: #1f5c31;--text-3-success: #1f5c31cc;--text-4-success: #1f5c3199;--text-5-success: #1f5c3166;--text-1-critical: #8f1014;--text-2-critical: #a01c1c;--text-3-critical: #a01c1ccc;--text-4-critical: #a01c1c99;--text-5-critical: #a01c1c66;--text-1-warning: #7f410b;--text-2-warning: #995200;--text-3-warning: #995200cc;--text-4-warning: #99520099;--text-5-warning: #99520066;--text-1-info: #003969;--text-2-info: #175082;--text-3-info: #175082cc;--text-4-info: #175082b2;--text-5-info: #17508280;--border-1: #938d96;--border-2: #c1b9c1;--border-3: #d4ced4;--border-4: #e0dce0;--border-5: #ece9ec;--border-1-brand: #9081df;--border-2-brand: #bcb1f1;--border-3-brand: #d2cbf6;--border-4-brand: #ddd8f8;--border-5-brand: #e9e5fa;--border-1-success: #44c169;--border-2-success: #88d7a0;--border-3-success: #b3e5c2;--border-4-success: #c6ecd1;--border-5-success: #d9f2e0;--border-1-critical: #e56c6c;--border-2-critical: #efa4a4;--border-3-critical: #f4c2c2;--border-4-critical: #f7d4d4;--border-5-critical: #fae5e5;--border-1-warning: #d88118;--border-2-warning: #edb25a;--border-3-warning: #f3cc91;--border-4-warning: #f6dbb1;--border-5-warning: #f9e7cd;--border-1-info: #56a1e1;--border-2-info: #93c5ec;--border-3-info: #bad6f3;--border-4-info: #cfe3f7;--border-5-info: #e1eefa;--link-color: #1466d4;--link-color-hover: #2674e6;--focus-ring: oklch(.55 .2 284.15)}.dark{font-weight:400;--bg-1: #000000;--bg-2: #0e0d0f;--bg-3: #121014;--bg-4: #161316;--bg-5: #1a171b;--bg-2-brand: #08060e;--bg-3-brand: #0f0c1d;--bg-4-brand: #130f24;--bg-5-brand: #16132b;--bg-2-success: #030b06;--bg-3-success: #051209;--bg-4-success: #06160b;--bg-5-success: #081b0e;--bg-2-critical: #120303;--bg-3-critical: #210606;--bg-4-critical: #260808;--bg-5-critical: #2e0a0b;--bg-2-warning: #110a03;--bg-3-warning: #1c1105;--bg-4-warning: #231406;--bg-5-warning: #2b1a08;--bg-2-info: #020a12;--bg-3-info: #05131f;--bg-4-info: #071725;--bg-5-info: #0c2337;--text-1: #ece9ec;--text-2: #c1b9c1;--text-3: #9f99a1;--text-4: #776e77;--text-5: #635b65;--text-1-brand: #c5baff;--text-2-brand: #ada0ee;--text-3-brand: #ada0eecc;--text-4-brand: #ada0ee99;--text-5-brand: #ada0ee66;--text-1-success: #9ddeb1;--text-2-success: #74cd8e;--text-3-success: #74cd8ecc;--text-4-success: #74cd8e99;--text-5-success: #74cd8e66;--text-1-critical: #ffabac;--text-2-critical: #e78e90;--text-3-critical: #e78e90cc;--text-4-critical: #e78e9099;--text-5-critical: #e78e9066;--text-1-warning: #f0bf75;--text-2-warning: #e1a452;--text-3-warning: #e1a452cc;--text-4-warning: #e1a45299;--text-5-warning: #e1a45266;--text-1-info: #9ed2ff;--text-2-info: #7db6e8;--text-3-info: #7db6e8cc;--text-4-info: #7db6e899;--text-5-info: #7db6e866;--border-1: hsl(288deg 5.21% 42%);--border-2: hsl(282deg 7.04% 28%);--border-3: hsl(277.5deg 6.56% 20%);--border-4: hsl(290deg 6.52% 13%);--border-5: hsl(285deg 7.14% 10%);--border-1-brand: hsl(250.08deg 59.8% 58%);--border-2-brand: hsl(250deg 50% 42%);--border-3-brand: hsl(252.63deg 47.74% 30%);--border-4-brand: hsl(249.8deg 39.84% 19%);--border-5-brand: hsl(249deg 39.22% 14%);--border-1-success: hsl(138.18deg 49.75% 29%);--border-2-success: hsl(138.26deg 50.36% 20%);--border-3-success: hsl(137.7deg 49.59% 16%);--border-4-success: hsl(138.46deg 52% 10%);--border-5-success: hsl(138.86deg 53.85% 7.5%);--border-1-critical: hsl(0deg 56% 46%);--border-2-critical: hsl(.42deg 63% 30%);--border-3-critical: hsl(0deg 62.21% 23%);--border-4-critical: hsl(359.13deg 59% 15%);--border-5-critical: hsl(359.06deg 63% 11%);--border-1-warning: hsl(32.13deg 80.31% 34%);--border-2-warning: hsl(27.93deg 84.06% 24%);--border-3-warning: hsl(30deg 79.66% 17%);--border-4-warning: hsl(28.75deg 63.16% 12%);--border-5-warning: hsl(28.64deg 66.67% 9%);--border-1-info: hsl(207.82deg 70.2% 40%);--border-2-info: hsl(207.77deg 69.94% 29%);--border-3-info: hsl(208.04deg 69.93% 21%);--border-4-info: hsl(208.52deg 62.89% 14%);--border-5-info: hsl(207.78deg 65.85% 10.5%);--link-color: #7baee9;--link-color-hover: #90bdee;--focus-ring: #a897fc}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antadesign/anta",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",