@antadesign/anta 0.2.2 → 0.3.0
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/README.md +14 -0
- package/dist/anta_helpers.d.ts +39 -1
- package/dist/anta_helpers.js +30 -2
- package/dist/components/Button.d.ts +7 -4
- package/dist/components/Button.js +6 -11
- package/dist/components/Checkbox.d.ts +97 -0
- package/dist/components/Checkbox.js +77 -0
- package/dist/components/Expander.d.ts +74 -0
- package/dist/components/Expander.js +53 -0
- package/dist/components/Input.d.ts +159 -0
- package/dist/components/Input.js +150 -0
- package/dist/components/Menu.d.ts +70 -0
- package/dist/components/Menu.js +42 -0
- package/dist/components/MenuGroup.d.ts +24 -0
- package/dist/components/MenuGroup.js +19 -0
- package/dist/components/MenuItem.d.ts +50 -0
- package/dist/components/MenuItem.js +41 -0
- package/dist/components/MenuSeparator.d.ts +14 -0
- package/dist/components/MenuSeparator.js +7 -0
- package/dist/components/Progress.d.ts +12 -6
- package/dist/components/Progress.js +7 -4
- package/dist/components/Radio.d.ts +37 -0
- package/dist/components/Radio.js +33 -0
- package/dist/components/RadioGroup.d.ts +119 -0
- package/dist/components/RadioGroup.js +108 -0
- package/dist/components/Tag.d.ts +38 -5
- package/dist/components/Tag.js +9 -5
- package/dist/components/Text.d.ts +27 -12
- package/dist/components/Text.js +6 -3
- package/dist/components/Title.d.ts +10 -1
- package/dist/elements/a-button.css +1 -1
- package/dist/elements/a-button.d.ts +56 -0
- package/dist/elements/a-button.js +13 -11
- package/dist/elements/a-checkbox.css +1 -0
- package/dist/elements/a-checkbox.d.ts +52 -0
- package/dist/elements/a-checkbox.js +130 -0
- package/dist/elements/a-expander.css +1 -0
- package/dist/elements/a-expander.d.ts +28 -0
- package/dist/elements/a-expander.js +237 -0
- package/dist/elements/a-icon.d.ts +14 -0
- package/dist/elements/a-icon.shapes.css +1 -1
- package/dist/elements/a-icon.shapes.d.ts +9 -1
- package/dist/elements/a-icon.shapes.js +10 -1
- package/dist/elements/a-input.css +1 -0
- package/dist/elements/a-input.d.ts +68 -0
- package/dist/elements/a-input.js +511 -0
- package/dist/elements/a-menu-group.css +1 -0
- package/dist/elements/a-menu-group.d.ts +13 -0
- package/dist/elements/a-menu-group.js +15 -0
- package/dist/elements/a-menu-item.css +1 -0
- package/dist/elements/a-menu-item.d.ts +47 -0
- package/dist/elements/a-menu-item.js +30 -0
- package/dist/elements/a-menu-separator.css +1 -0
- package/dist/elements/a-menu-separator.d.ts +13 -0
- package/dist/elements/a-menu-separator.js +15 -0
- package/dist/elements/a-menu.css +1 -0
- package/dist/elements/a-menu.d.ts +171 -0
- package/dist/elements/a-menu.js +714 -0
- package/dist/elements/a-progress.css +1 -1
- package/dist/elements/a-progress.d.ts +12 -0
- package/dist/elements/a-progress.js +1 -0
- package/dist/elements/a-radio-group.css +1 -0
- package/dist/elements/a-radio-group.d.ts +33 -0
- package/dist/elements/a-radio-group.js +160 -0
- package/dist/elements/a-radio.css +1 -0
- package/dist/elements/a-radio.d.ts +14 -0
- package/dist/elements/a-radio.js +46 -0
- package/dist/elements/a-tag.css +1 -1
- package/dist/elements/a-text.css +1 -1
- package/dist/elements/a-text.d.ts +42 -3
- package/dist/elements/a-text.js +73 -33
- package/dist/elements/a-tooltip.d.ts +43 -11
- package/dist/elements/a-tooltip.js +46 -51
- package/dist/elements/index.d.ts +9 -0
- package/dist/elements/index.js +27 -0
- package/dist/general_types.d.ts +467 -15
- package/dist/index.d.ts +16 -0
- package/dist/index.js +16 -0
- package/dist/jsx-runtime.d.ts +42 -7
- package/dist/jsx-runtime.js +14 -2
- package/dist/tokens.css +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer anta{a-progress{--progress-bg: var(--bg-4);--progress-border-color: var(--border-4);--progress-indicator-bg: var(--bg-5);--progress-indicator-edge: linear-gradient( 90deg, var(--progress-indicator-bg) 0%, var(--progress-border-color) 100% );--progress-text-color: var(--text-2);--progress-hint-color: var(--text-3);display:block;container-type:inline-size;padding:4px 8px;min-height:8px;background:var(--progress-bg);border:0px solid var(--progress-border-color);border-radius:0}a-progress[tone=info]{--progress-bg: var(--bg-4-info);--progress-border-color: var(--border-4-info);--progress-indicator-bg: var(--bg-5-info);--progress-text-color: var(--text-2-info);--progress-hint-color: var(--text-3-info)}a-progress-label{display:flex;align-items:flex-start;gap:.5ch;font-variant-numeric:tabular-nums;font-feature-settings:"ss02","ss05";letter-spacing:.03em;font-size:13px;line-height:16px}a-progress-number{flex-shrink:0;color:var(--progress-text-color)}a-progress-text{flex:1 1 auto;min-width:0;color:var(--progress-text-color)}a-progress-hint{flex-shrink:0;margin-left:auto;color:var(--progress-hint-color)}}
|
|
1
|
+
@layer anta{a-progress{--progress-bg: var(--bg-4);--progress-border-color: var(--border-4);--progress-indicator-bg: var(--bg-5);--progress-indicator-edge: linear-gradient( 90deg, var(--progress-indicator-bg) 0%, var(--progress-border-color) 100% );--progress-text-color: var(--text-2);--progress-hint-color: var(--text-3);display:block;container-type:inline-size;padding:4px 8px;min-height:8px;background:var(--progress-bg);border:0px solid var(--progress-border-color);border-radius:0}a-progress[tone=brand]{--progress-bg: var(--bg-4-brand);--progress-border-color: var(--border-4-brand);--progress-indicator-bg: var(--bg-5-brand);--progress-text-color: var(--text-2-brand);--progress-hint-color: var(--text-3-brand)}a-progress[tone=info]{--progress-bg: var(--bg-4-info);--progress-border-color: var(--border-4-info);--progress-indicator-bg: var(--bg-5-info);--progress-text-color: var(--text-2-info);--progress-hint-color: var(--text-3-info)}a-progress[tone=success]{--progress-bg: var(--bg-4-success);--progress-border-color: var(--border-4-success);--progress-indicator-bg: var(--bg-5-success);--progress-text-color: var(--text-2-success);--progress-hint-color: var(--text-3-success)}a-progress[tone=warning]{--progress-bg: var(--bg-4-warning);--progress-border-color: var(--border-4-warning);--progress-indicator-bg: var(--bg-5-warning);--progress-text-color: var(--text-2-warning);--progress-hint-color: var(--text-3-warning)}a-progress[tone=critical]{--progress-bg: var(--bg-4-critical);--progress-border-color: var(--border-4-critical);--progress-indicator-bg: var(--bg-5-critical);--progress-text-color: var(--text-2-critical);--progress-hint-color: var(--text-3-critical)}a-progress[tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--progress-tone-source: attr(tone type(<color>), transparent);--progress-bg: oklch(from var(--progress-tone-source) .95 calc(c*.4) h);--progress-border-color: oklch(from var(--progress-tone-source) .85 calc(c*.6) h);--progress-indicator-bg: oklch(from var(--progress-tone-source) .6 c h);--progress-text-color: oklch(from var(--progress-tone-source) .45 c h);--progress-hint-color: oklch(from var(--progress-tone-source) .55 c h);.dark &{--progress-bg: oklch(from var(--progress-tone-source) .28 calc(c/2) h);--progress-border-color: oklch(from var(--progress-tone-source) .4 calc(c*.6) h);--progress-indicator-bg: oklch(from var(--progress-tone-source) .6 c h);--progress-text-color: oklch(from var(--progress-tone-source) .85 c h);--progress-hint-color: oklch(from var(--progress-tone-source) .75 c h)}}a-progress-label{display:flex;align-items:flex-start;gap:.5ch;font-variant-numeric:tabular-nums;font-feature-settings:"ss02","ss05";letter-spacing:.03em;font-size:13px;line-height:16px}a-progress-number{flex-shrink:0;color:var(--progress-text-color)}a-progress-text{flex:1 1 auto;min-width:0;color:var(--progress-text-color)}a-progress-hint{flex-shrink:0;margin-left:auto;color:var(--progress-hint-color)}}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { HTMLElementBase } from '../anta_helpers';
|
|
2
2
|
import './a-progress.css';
|
|
3
|
+
/**
|
|
4
|
+
* `<a-progress>` — progress bar element.
|
|
5
|
+
*
|
|
6
|
+
* Styling notes (`a-progress.css` ships comment-free):
|
|
7
|
+
* - `--progress-indicator-edge` is a right-edge fade from the indicator's
|
|
8
|
+
* own bg to the border color, both opaque; tone variants re-tint it
|
|
9
|
+
* automatically because both endpoint tokens are re-aliased per tone.
|
|
10
|
+
* - `border: 0px solid var(--progress-border-color)` is a per-component
|
|
11
|
+
* reset (same spirit as Tailwind preflight): style and color are declared
|
|
12
|
+
* at a known state so a consumer opts into a themed border by changing
|
|
13
|
+
* only `border-width`.
|
|
14
|
+
*/
|
|
3
15
|
export declare class AProgressElement extends HTMLElementBase {
|
|
4
16
|
static observedAttributes: string[];
|
|
5
17
|
indicator: HTMLDivElement;
|
|
@@ -39,6 +39,7 @@ class AProgressElement extends HTMLElementBase {
|
|
|
39
39
|
`;
|
|
40
40
|
this.indicator = document.createElement("div");
|
|
41
41
|
this.indicator.className = "indicator";
|
|
42
|
+
this.indicator.setAttribute("part", "indicator");
|
|
42
43
|
const slot = document.createElement("slot");
|
|
43
44
|
shadow.append(style, this.indicator, slot);
|
|
44
45
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer anta{a-radio-group{--radio-group-hint: var(--text-3);display:flex;flex-direction:column}a-radio-list{display:flex;flex-direction:column;gap:8px}a-radio-group[orientation=horizontal] a-radio-list{flex-direction:row;flex-wrap:wrap;gap:16px}a-radio-list:not(:first-child){margin-block-start:10px}a-radio-group-label{display:block;color:var(--text-3);font-family:var(--sans-serif);font-size:15px;line-height:20px;font-weight:500}a-radio-group-hint{display:block;color:var(--radio-group-hint);font-size:14px;line-height:17px;margin-block-start:2px}a-radio-group[status=critical]{--radio-group-hint: var(--text-2-critical)}a-radio-group[status=warning]{--radio-group-hint: var(--text-2-warning)}a-radio-group[status=success]{--radio-group-hint: var(--text-2-success)}a-radio-group[status=info]{--radio-group-hint: var(--text-2-info)}a-radio-group[status=brand]{--radio-group-hint: var(--text-2-brand)}a-radio-group[size=small] a-radio:not([size]){--radio-control-size: 14px;--radio-dot-size: 5px;--radio-gap: 6px;--radio-label-fs: 13px;--radio-label-lh: 16px;--radio-hint-fs: 12px;--radio-hint-lh: 14px}a-radio-group[size=large] a-radio:not([size]){--radio-control-size: 18px;--radio-dot-size: 7px;--radio-label-fs: 17px;--radio-label-lh: 24px;--radio-hint-fs: 16px;--radio-hint-lh: 21px}a-radio-group[disabled]{--radio-group-hint: var(--text-5)}a-radio-group[disabled] a-radio{cursor:not-allowed;pointer-events:none;color:var(--radio-label-color-disabled);--radio-hint-color: var(--radio-label-color-disabled);--radio-bg: var(--radio-bg-disabled);--radio-border: var(--radio-border-disabled);--radio-border-hover: var(--radio-border-disabled);--radio-border-active: var(--radio-border-disabled);--radio-fill: var(--radio-bg-disabled);--radio-fill-hover: var(--radio-bg-disabled);--radio-fill-active: var(--radio-bg-disabled);--radio-dot: var(--radio-dot-disabled)}}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { HTMLElementBase } from "../anta_helpers";
|
|
2
|
+
import "./a-radio-group.css";
|
|
3
|
+
export declare class ARadioGroupElement extends HTMLElementBase {
|
|
4
|
+
static formAssociated: boolean;
|
|
5
|
+
static observedAttributes: string[];
|
|
6
|
+
private internals?;
|
|
7
|
+
private uncontrolledValue;
|
|
8
|
+
private seeded;
|
|
9
|
+
private observer?;
|
|
10
|
+
private alive;
|
|
11
|
+
/** The selected option'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
|
+
formResetCallback(): void;
|
|
19
|
+
formStateRestoreCallback(state: string): void;
|
|
20
|
+
private get currentValue();
|
|
21
|
+
private get isDisabled();
|
|
22
|
+
private get radios();
|
|
23
|
+
private sync;
|
|
24
|
+
private requestSelect;
|
|
25
|
+
private emitChange;
|
|
26
|
+
/** Dispatch the shared `statechange` event. `reason` lets a controller tell a
|
|
27
|
+
* user pick (cancelable) apart from a form `reset` / bfcache `restore` (not).
|
|
28
|
+
* `next` is `null` when nothing is selected (no default / reset-to-none). */
|
|
29
|
+
private emitStateChange;
|
|
30
|
+
private onClick;
|
|
31
|
+
private onKeyDown;
|
|
32
|
+
}
|
|
33
|
+
export declare function register_a_radio_group(): void;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { HTMLElementBase } from "../anta_helpers";
|
|
2
|
+
import "./a-radio-group.css";
|
|
3
|
+
class ARadioGroupElement extends HTMLElementBase {
|
|
4
|
+
static formAssociated = true;
|
|
5
|
+
static observedAttributes = ["state", "disabled"];
|
|
6
|
+
internals;
|
|
7
|
+
uncontrolledValue = null;
|
|
8
|
+
seeded = false;
|
|
9
|
+
observer;
|
|
10
|
+
// True after the first connect — gates the native `change` event so it never
|
|
11
|
+
// fires for the initial seed (only for real, post-connect selection changes).
|
|
12
|
+
alive = false;
|
|
13
|
+
/** The selected option's value, or `null` when nothing is selected. */
|
|
14
|
+
get value() {
|
|
15
|
+
return this.currentValue;
|
|
16
|
+
}
|
|
17
|
+
constructor() {
|
|
18
|
+
super();
|
|
19
|
+
this.internals = this.attachInternals?.();
|
|
20
|
+
}
|
|
21
|
+
connectedCallback() {
|
|
22
|
+
if (!this.seeded) {
|
|
23
|
+
this.uncontrolledValue = this.getAttribute("default-state");
|
|
24
|
+
this.seeded = true;
|
|
25
|
+
}
|
|
26
|
+
this.addEventListener("click", this.onClick);
|
|
27
|
+
this.addEventListener("keydown", this.onKeyDown);
|
|
28
|
+
this.observer ??= new this.view.MutationObserver((records) => {
|
|
29
|
+
const touchedOptions = records.some(
|
|
30
|
+
(rec) => [...rec.addedNodes, ...rec.removedNodes].some(
|
|
31
|
+
(n) => n.nodeName === "A-RADIO" || n.querySelector?.("a-radio") != null
|
|
32
|
+
)
|
|
33
|
+
);
|
|
34
|
+
if (touchedOptions) this.sync();
|
|
35
|
+
});
|
|
36
|
+
this.observer.observe(this, { childList: true, subtree: true });
|
|
37
|
+
this.sync();
|
|
38
|
+
this.alive = true;
|
|
39
|
+
}
|
|
40
|
+
disconnectedCallback() {
|
|
41
|
+
this.observer?.disconnect();
|
|
42
|
+
}
|
|
43
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
44
|
+
this.sync();
|
|
45
|
+
if (name === "state" && this.alive && newValue !== oldValue) this.emitChange();
|
|
46
|
+
}
|
|
47
|
+
formDisabledCallback(disabled) {
|
|
48
|
+
if (disabled) this.internals?.states.add("disabled");
|
|
49
|
+
else this.internals?.states.delete("disabled");
|
|
50
|
+
this.sync();
|
|
51
|
+
}
|
|
52
|
+
formResetCallback() {
|
|
53
|
+
const next = this.getAttribute("default-state");
|
|
54
|
+
this.emitStateChange(next, this.currentValue, "reset", false);
|
|
55
|
+
this.uncontrolledValue = next;
|
|
56
|
+
this.sync();
|
|
57
|
+
}
|
|
58
|
+
formStateRestoreCallback(state) {
|
|
59
|
+
this.emitStateChange(state, this.currentValue, "restore", false);
|
|
60
|
+
this.uncontrolledValue = state;
|
|
61
|
+
this.sync();
|
|
62
|
+
}
|
|
63
|
+
// Controlled when `state` is present; otherwise the in-memory uncontrolled value.
|
|
64
|
+
get currentValue() {
|
|
65
|
+
return this.hasAttribute("state") ? this.getAttribute("state") : this.uncontrolledValue;
|
|
66
|
+
}
|
|
67
|
+
get isDisabled() {
|
|
68
|
+
return this.hasAttribute("disabled") || (this.internals?.states.has("disabled") ?? false);
|
|
69
|
+
}
|
|
70
|
+
get radios() {
|
|
71
|
+
return Array.from(this.querySelectorAll("a-radio"));
|
|
72
|
+
}
|
|
73
|
+
sync = () => {
|
|
74
|
+
const value = this.currentValue;
|
|
75
|
+
const radios = this.radios;
|
|
76
|
+
const selectedEl = radios.find((r) => r.value === value && value != null) ?? null;
|
|
77
|
+
const submitted = selectedEl ? selectedEl.value : null;
|
|
78
|
+
this.internals?.setFormValue(submitted, submitted);
|
|
79
|
+
for (const r of radios) r.selected = r === selectedEl;
|
|
80
|
+
if (this.internals && "ariaActiveDescendantElement" in this.internals) {
|
|
81
|
+
this.internals.ariaActiveDescendantElement = selectedEl;
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
// The shared state algorithm: fire the cancelable `statechange` *before*
|
|
85
|
+
// applying. Controlled never self-applies; uncontrolled applies unless vetoed.
|
|
86
|
+
requestSelect(next) {
|
|
87
|
+
const prev = this.currentValue;
|
|
88
|
+
if (next === prev) return;
|
|
89
|
+
const ok = this.emitStateChange(next, prev, "user", true);
|
|
90
|
+
if (this.hasAttribute("state")) return;
|
|
91
|
+
if (ok) {
|
|
92
|
+
this.uncontrolledValue = next;
|
|
93
|
+
this.sync();
|
|
94
|
+
this.emitChange();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Native `change`, fired *after* a selection applies (user pick or a controlled
|
|
98
|
+
// `state` update) — the post-apply counterpart to the cancelable, pre-apply
|
|
99
|
+
// `statechange`. Bubbles like a native radio group.
|
|
100
|
+
emitChange() {
|
|
101
|
+
this.dispatchEvent(new Event("change", { bubbles: true }));
|
|
102
|
+
}
|
|
103
|
+
/** Dispatch the shared `statechange` event. `reason` lets a controller tell a
|
|
104
|
+
* user pick (cancelable) apart from a form `reset` / bfcache `restore` (not).
|
|
105
|
+
* `next` is `null` when nothing is selected (no default / reset-to-none). */
|
|
106
|
+
emitStateChange(next, prev, reason, cancelable) {
|
|
107
|
+
return this.dispatchEvent(
|
|
108
|
+
new CustomEvent("statechange", {
|
|
109
|
+
cancelable,
|
|
110
|
+
bubbles: true,
|
|
111
|
+
composed: true,
|
|
112
|
+
detail: { next, prev, reason }
|
|
113
|
+
})
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
onClick = (e) => {
|
|
117
|
+
if (this.isDisabled) return;
|
|
118
|
+
const radio = e.target?.closest(
|
|
119
|
+
"a-radio"
|
|
120
|
+
);
|
|
121
|
+
if (!radio || radio.hasAttribute("disabled")) return;
|
|
122
|
+
radio.focus();
|
|
123
|
+
this.requestSelect(radio.value);
|
|
124
|
+
};
|
|
125
|
+
onKeyDown = (e) => {
|
|
126
|
+
if (this.isDisabled) return;
|
|
127
|
+
const enabled = this.radios.filter((r) => !r.hasAttribute("disabled"));
|
|
128
|
+
if (enabled.length === 0) return;
|
|
129
|
+
const focused = e.target?.closest(
|
|
130
|
+
"a-radio"
|
|
131
|
+
);
|
|
132
|
+
if (e.key === " " || e.key === "Enter") {
|
|
133
|
+
if (focused && enabled.includes(focused)) {
|
|
134
|
+
e.preventDefault();
|
|
135
|
+
this.requestSelect(focused.value);
|
|
136
|
+
}
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const forward = e.key === "ArrowDown" || e.key === "ArrowRight";
|
|
140
|
+
const back = e.key === "ArrowUp" || e.key === "ArrowLeft";
|
|
141
|
+
if (!forward && !back) return;
|
|
142
|
+
e.preventDefault();
|
|
143
|
+
let i = focused ? enabled.indexOf(focused) : -1;
|
|
144
|
+
if (i === -1) i = enabled.findIndex((r) => r.value === this.currentValue);
|
|
145
|
+
if (i === -1) i = 0;
|
|
146
|
+
const next = enabled[(i + (forward ? 1 : -1) + enabled.length) % enabled.length];
|
|
147
|
+
next.focus();
|
|
148
|
+
this.requestSelect(next.value);
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
function register_a_radio_group() {
|
|
152
|
+
if (typeof customElements === "undefined") return;
|
|
153
|
+
if (!customElements.get("a-radio-group"))
|
|
154
|
+
customElements.define("a-radio-group", ARadioGroupElement);
|
|
155
|
+
}
|
|
156
|
+
register_a_radio_group();
|
|
157
|
+
export {
|
|
158
|
+
ARadioGroupElement,
|
|
159
|
+
register_a_radio_group
|
|
160
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer anta{a-radio{--radio-control-size: 16px;--radio-border-width: 1.5px;--radio-dot-size: 6px;--_radio-dot-adjust: 0px;--radio-gap: 8px;--radio-bg: var(--bg-1);--radio-fill: #635b65;--radio-fill-hover: #534c57;--radio-fill-active: #49424c;--radio-border-neutral: #d4ced4;--radio-border: var(--radio-border-neutral);--radio-border-hover: #c1b9c1;--radio-border-active: #9f99a1;--radio-dot: #ffffff;--radio-dot-disabled: #c1b9c1;--radio-bg-disabled: color-mix(in oklch, #44374b 10%, transparent);--radio-border-disabled: color-mix(in oklch, #44374b 15%, transparent);--radio-label-color: var(--text-2);--radio-label-color-disabled: var(--text-4);--radio-hint-color: var(--text-3);--radio-label-fs: 15px;--radio-label-lh: 20px;--radio-hint-fs: 14px;--radio-hint-lh: 17px;display:inline-grid;grid-template-columns:auto 1fr;align-items:center;column-gap:var(--radio-gap);cursor:pointer;user-select:none;-webkit-user-drag:none;vertical-align:middle;outline:none;color:var(--radio-label-color);font-family:var(--sans-serif);font-size:var(--radio-label-fs);line-height:var(--radio-label-lh);font-feature-settings:"ss02","ss05";&:before{content:"";grid-column:1;grid-row:1 / -1;align-self:center;box-sizing:border-box;inline-size:var(--radio-control-size);block-size:var(--radio-control-size);border-radius:50%;background:var(--radio-bg);border:var(--radio-border-width) solid var(--radio-border);transition:background-color .15s ease-out,border-color .15s ease-out}&:after{content:"";grid-column:1;grid-row:1 / -1;align-self:center;justify-self:center;inline-size:calc(var(--radio-dot-size) - var(--_radio-dot-adjust));block-size:calc(var(--radio-dot-size) - var(--_radio-dot-adjust));border-radius:50%;background:var(--radio-dot);transform:scale(0);transition:transform .12s ease-out;pointer-events:none}@media(hover:hover)and (pointer:fine){&:not([disabled]):hover:before{border-color:var(--radio-border-hover);transition:background-color 75ms ease-in,border-color 75ms ease-in}&:not([disabled]):hover:state(selected):before{background:var(--radio-fill-hover);border-color:var(--radio-fill-hover)}}&:not([disabled]):active:before{border-color:var(--radio-border-active);transition:background-color 50ms linear,border-color 50ms linear}&:not([disabled]):active:state(selected):before{background:var(--radio-fill-active);border-color:var(--radio-fill-active)}&:state(selected){&:before{background:var(--radio-fill);border-color:var(--radio-fill)}&:after{transform:scale(1)}}&:focus-visible:before{outline:1px solid var(--focus-ring);outline-offset:1px}&[disabled]{cursor:not-allowed;color:var(--radio-label-color-disabled);&:before{background:var(--radio-bg-disabled);border-color:var(--radio-border-disabled);transition:none}&:state(selected):after{background:var(--radio-dot-disabled)}a-radio-hint{color:var(--radio-label-color-disabled)}}&[size=small]{--radio-control-size: 14px;--radio-dot-size: 5px;--radio-gap: 6px;--radio-label-fs: 13px;--radio-label-lh: 16px;--radio-hint-fs: 12px;--radio-hint-lh: 14px}&[size=large]{--radio-control-size: 18px;--radio-dot-size: 7px;--radio-label-fs: 17px;--radio-label-lh: 24px;--radio-hint-fs: 16px;--radio-hint-lh: 21px}}a-radio-label,a-radio-hint{display:block;grid-column:2;min-width:0}a-radio-hint{color:var(--radio-hint-color);font-size:var(--radio-hint-fs);line-height:var(--radio-hint-lh);margin-block-start:2px}a-radio-group:focus-visible a-radio:state(selected):before{outline:1px solid var(--focus-ring);outline-offset:1px}a-radio[priority=secondary],a-radio-group[priority=secondary] a-radio:not([priority]){&:not([disabled]):state(selected){&:before{background:var(--radio-bg);border-color:var(--radio-fill)}&:after{background:var(--radio-fill)}}@media(hover:hover)and (pointer:fine){&:not([disabled]):hover:state(selected){&:before{background:var(--radio-bg);border-color:var(--radio-fill-hover)}&:after{background:var(--radio-fill-hover)}}}&:not([disabled]):active:state(selected){&:before{background:var(--radio-bg);border-color:var(--radio-fill-active)}&:after{background:var(--radio-fill-active)}}}.dark a-radio[priority=secondary],.dark a-radio-group[priority=secondary] a-radio:not([priority]){&:not([disabled]):state(selected){&:before{border-color:var(--radio-fill-active)}&:after{background:var(--radio-fill-active)}}@media(hover:hover)and (pointer:fine){&:not([disabled]):hover:state(selected){&:before{border-color:oklch(from var(--radio-fill-active) calc(l + .07) c h)}&:after{background:oklch(from var(--radio-fill-active) calc(l + .07) c h)}}}&:not([disabled]):active:state(selected){&:before{border-color:oklch(from var(--radio-fill-active) calc(l + .12) c h)}&:after{background:oklch(from var(--radio-fill-active) calc(l + .12) c h)}}}a-radio[tone=brand],a-radio-group[tone=brand] a-radio:not([tone]){--radio-label-color: var(--text-2-brand);--radio-hint-color: var(--text-3-brand);--radio-fill: #5f4bc3;--radio-fill-hover: #503cb4;--radio-fill-active: #483493}a-radio[tone=neutral],a-radio-group[tone=neutral] a-radio:not([tone]){--radio-fill: #635b65;--radio-fill-hover: #534c57;--radio-fill-active: #49424c}a-radio[tone=info],a-radio-group[tone=info] a-radio:not([tone]){--radio-label-color: var(--text-2-info);--radio-hint-color: var(--text-3-info);--radio-fill: #1f6eb2;--radio-fill-hover: #1a5b93;--radio-fill-active: #175082}a-radio[tone=success],a-radio-group[tone=success] a-radio:not([tone]){--radio-label-color: var(--text-2-success);--radio-hint-color: var(--text-3-success);--radio-fill: #2a7e43;--radio-fill-hover: #226737;--radio-fill-active: #1f5c31}a-radio[tone=warning],a-radio-group[tone=warning] a-radio:not([tone]){--radio-label-color: var(--text-2-warning);--radio-hint-color: var(--text-3-warning);--radio-fill: #c37416;--radio-fill-hover: #ae6613;--radio-fill-active: #995200}a-radio[tone=critical],a-radio-group[tone=critical] a-radio:not([tone]){--radio-label-color: var(--text-2-critical);--radio-hint-color: var(--text-3-critical);--radio-fill: #c9302c;--radio-fill-hover: #b02120;--radio-fill-active: #a01c1c}a-radio[tone]:not([tone=""],[tone=neutral]),a-radio-group[tone]:not([tone=""],[tone=neutral]) a-radio:not([tone]){--_radio-border-base: color-mix(in oklch, var(--radio-fill) 70%, var(--radio-border-neutral));--radio-border: oklch(from var(--_radio-border-base) calc(l + .17) c h);--radio-border-hover: oklch(from var(--_radio-border-base) calc(l + .1) c h);--radio-border-active: var(--_radio-border-base);.dark &{--radio-border: var(--_radio-border-base);--radio-border-hover: oklch(from var(--_radio-border-base) calc(l + .1) c h);--radio-border-active: oklch(from var(--_radio-border-base) calc(l + .17) c h)}}a-radio[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]){--radio-tone-source: attr(tone type(<color>), transparent)}a-radio[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]),a-radio-group[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=info],[tone=success],[tone=warning],[tone=critical]) a-radio:not([tone]){--_tone-l-rest: .5;--_tone-l-hover: .45;--_tone-l-active: .4;--radio-fill: oklch(from var(--radio-tone-source) var(--_tone-l-rest) c h);--radio-fill-hover: oklch(from var(--radio-tone-source) var(--_tone-l-hover) c h);--radio-fill-active: oklch(from var(--radio-tone-source) var(--_tone-l-active) c h);--radio-label-color: oklch(from var(--radio-tone-source) .5 c h);--radio-hint-color: oklch(from var(--radio-tone-source) .5 c h / .8);.dark &{--_tone-l-rest: .45;--_tone-l-hover: .5;--_tone-l-active: .57;--radio-label-color: oklch(from var(--radio-tone-source) .8 c h);--radio-hint-color: oklch(from var(--radio-tone-source) .8 c h / .8)}}.dark a-radio{--_radio-dot-adjust: 1px;&:after{box-shadow:0 0 1px 1px #000}--radio-border-neutral: #49424c;--radio-border-hover: #635b65;--radio-border-active: #776e77;--radio-fill: #534c57;--radio-fill-hover: #635b65;--radio-fill-active: #938d96;--radio-dot-disabled: #635b65;--radio-bg-disabled: color-mix(in oklch, #e4d1ef 10%, transparent);--radio-border-disabled: color-mix(in oklch, #e4d1ef 15%, transparent)}.dark a-radio[tone=brand],.dark a-radio-group[tone=brand] a-radio:not([tone]){--radio-fill: #503cb4;--radio-fill-hover: #5f4bc3;--radio-fill-active: #7460d7}.dark a-radio[tone=neutral],.dark a-radio-group[tone=neutral] a-radio:not([tone]){--radio-fill: #534c57;--radio-fill-hover: #635b65;--radio-fill-active: #938d96}.dark a-radio[tone=info],.dark a-radio-group[tone=info] a-radio:not([tone]){--radio-fill: #1a5b93;--radio-fill-hover: #1f6eb2;--radio-fill-active: #2686d9}.dark a-radio[tone=success],.dark a-radio-group[tone=success] a-radio:not([tone]){--radio-fill: #226737;--radio-fill-hover: #2a7e43;--radio-fill-active: #329550}.dark a-radio[tone=warning],.dark a-radio-group[tone=warning] a-radio:not([tone]){--radio-fill: #7f410b;--radio-fill-hover: #995200;--radio-fill-active: #ae6613}.dark a-radio[tone=critical],.dark a-radio-group[tone=critical] a-radio:not([tone]){--radio-fill: #b02120;--radio-fill-hover: #c9302c;--radio-fill-active: #de4545}}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { HTMLElementBase } from "../anta_helpers";
|
|
2
|
+
import "./a-radio.css";
|
|
3
|
+
export declare class ARadioElement 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_radio(): void;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { HTMLElementBase } from "../anta_helpers";
|
|
2
|
+
import "./a-radio.css";
|
|
3
|
+
class ARadioElement extends HTMLElementBase {
|
|
4
|
+
static observedAttributes = ["selected"];
|
|
5
|
+
internals;
|
|
6
|
+
constructor() {
|
|
7
|
+
super();
|
|
8
|
+
this.internals = this.attachInternals?.();
|
|
9
|
+
}
|
|
10
|
+
connectedCallback() {
|
|
11
|
+
this.applyState(this.hasAttribute("selected"));
|
|
12
|
+
}
|
|
13
|
+
attributeChangedCallback(name) {
|
|
14
|
+
if (name === "selected") this.applyState(this.hasAttribute("selected"));
|
|
15
|
+
}
|
|
16
|
+
get selected() {
|
|
17
|
+
return this.internals?.states.has("selected") ?? this.hasAttribute("selected");
|
|
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-checked` through ElementInternals (the accessibility tree,
|
|
27
|
+
// not a DOM attribute). The group only sets `r.selected`; the radio owns how it
|
|
28
|
+
// reflects that. role="radio" comes from the wrapper, which gives ariaChecked
|
|
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.ariaChecked = on ? "true" : "false";
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function register_a_radio() {
|
|
38
|
+
if (typeof customElements === "undefined") return;
|
|
39
|
+
if (!customElements.get("a-radio"))
|
|
40
|
+
customElements.define("a-radio", ARadioElement);
|
|
41
|
+
}
|
|
42
|
+
register_a_radio();
|
|
43
|
+
export {
|
|
44
|
+
ARadioElement,
|
|
45
|
+
register_a_radio
|
|
46
|
+
};
|
package/dist/elements/a-tag.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer anta{a-tag{--tag-text: var(--text-3);--tag-bg: var(--bg-
|
|
1
|
+
@layer anta{a-tag{--tag-text: var(--text-3);--tag-tint: #44374b;--tag-fill: #776e77;--tag-edge: var(--tag-tint);--_tag-bg-alpha: 7%;--_tag-border-alpha: 15%;--_tag-edge-alpha: 25%;--tag-bg: color-mix(in oklch, var(--tag-tint) var(--_tag-bg-alpha), transparent);--tag-border: color-mix(in oklch, var(--tag-tint) var(--_tag-border-alpha), transparent);--tag-separator: color-mix(in oklch, var(--tag-text) 30%, transparent);--tag-padding-block: 1.5px;--tag-padding-inline: 6.5px;--tag-icon-size: 13px;--tag-label-weight: 600;--tag-gap: .6ch;display:inline-flex;align-items:center;gap:var(--tag-gap);box-sizing:border-box;max-width:100%;vertical-align:middle;overflow:hidden;white-space:nowrap;-webkit-user-drag:none;color:var(--tag-text);background:var(--tag-bg);border:.5px solid var(--tag-border);border-radius:22px;padding-block:var(--tag-padding-block);padding-inline:var(--tag-padding-inline);font-family:var(--sans-serif);font-weight:450;font-size:11px;line-height:16px;text-transform:uppercase;letter-spacing:.08ch;font-feature-settings:"tnum" 1,"ss05" 1,"ss01","case","calt"}a-tag a-icon{--icon-size: var(--tag-icon-size);flex:none}a-tag a-tag-label,a-tag a-tag-value{display:inline-block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}a-tag a-tag-value{font-weight:450}a-tag a-tag-label{font-weight:var(--tag-label-weight)}a-tag:has(>a-icon:first-child){padding-inline-start:max(0px,var(--tag-padding-inline) - 2px)}a-tag:has(>a-icon:last-child){padding-inline-end:max(0px,var(--tag-padding-inline) - 2px)}a-tag>:not(a-icon,a-tag-label,a-tag-value)~:not(a-icon,a-tag-label,a-tag-value){padding-left:var(--tag-gap);border-left:.5px solid var(--tag-separator)}a-tag[tone=brand]{--tag-text: var(--text-3-brand);--tag-tint: #7460d7;--tag-fill: #7460d7;--tag-edge: var(--text-2-brand);--_tag-bg-alpha: 10%;--_tag-edge-alpha: 20%}a-tag[tone=info]{--tag-text: var(--text-3-info);--tag-tint: #2686d9;--tag-fill: #2686d9;--tag-edge: var(--text-2-info);--_tag-bg-alpha: 10%;--_tag-edge-alpha: 20%}a-tag[tone=success]{--tag-text: var(--text-3-success);--tag-tint: #329550;--tag-fill: #329550;--tag-edge: var(--text-2-success);--_tag-bg-alpha: 10%;--_tag-edge-alpha: 20%}a-tag[tone=warning]{--tag-text: var(--text-3-warning);--tag-tint: #c37416;--tag-fill: #ae6613;--tag-edge: var(--text-2-warning);--_tag-bg-alpha: 10%;--_tag-edge-alpha: 20%}a-tag[tone=critical]{--tag-text: var(--text-3-critical);--tag-tint: #de4545;--tag-fill: #de4545;--tag-edge: var(--text-2-critical);--_tag-bg-alpha: 10%;--_tag-edge-alpha: 20%}.dark a-tag:not([tone]),.dark a-tag[tone=neutral]{--tag-tint: #e4d1ef;--tag-fill: #635b65;--_tag-bg-alpha: 12%}.dark a-tag[tone=brand],.dark a-tag[tone=info],.dark a-tag[tone=success],.dark a-tag[tone=warning],.dark a-tag[tone=critical]{--_tag-bg-alpha: 20%;--_tag-border-alpha: 25%;--_tag-edge-alpha: 30%}.dark a-tag[tone=brand]{--tag-fill: #5f4bc3}.dark a-tag[tone=info]{--tag-fill: #1f6eb2}.dark a-tag[tone=success]{--tag-fill: #2a7e43}.dark a-tag[tone=warning]{--tag-fill: #995200}.dark a-tag[tone=critical]{--tag-fill: #c9302c}a-tag[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--tag-tone-source: attr(tone type(<color>), currentColor);--_tag-bg-alpha: 10%;--_tag-border-alpha: 15%;--_tag-edge-alpha: 20%;--_tag-tint-l: .54;--_tag-tint-c: .16;--tag-tint: oklch(from var(--tag-tone-source) var(--_tag-tint-l) var(--_tag-tint-c) h);--_tag-fill-l: .5;--tag-fill: oklch(from var(--tag-tone-source) var(--_tag-fill-l) var(--_tag-tint-c) h);--_tag-text-l: .4;--_tag-text-c: .15;--tag-text: color-mix(in oklch, oklch(from var(--tag-tone-source) var(--_tag-text-l) var(--_tag-text-c) h) 80%, transparent);--tag-edge: oklch(from var(--tag-tone-source) var(--_tag-text-l) var(--_tag-text-c) h)}.dark a-tag[tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--_tag-bg-alpha: 20%;--_tag-border-alpha: 25%;--_tag-edge-alpha: 30%;--_tag-tint-l: .58;--_tag-fill-l: .45;--_tag-text-l: .75;--_tag-text-c: .11}a-tag[priority=primary]{--tag-bg: var(--tag-fill);--tag-text: #fff}a-tag[priority=primary][tone]:not([tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--tag-text: #fff}a-tag[priority=tertiary]{--tag-bg: transparent;--tag-border: color-mix(in oklch, var(--tag-edge) var(--_tag-edge-alpha), transparent)}a-tag[size=small]{--tag-padding-block: .5px;--tag-padding-inline: 4.5px;--tag-icon-size: 11px;font-size:10px;line-height:14px}a-tag[size=large]{--tag-padding-block: 2.5px;--tag-padding-inline: 8.5px;--tag-icon-size: 15px;font-size:12px;line-height:18px}a-tag[nocaps]{font-size:12px;text-transform:none;letter-spacing:.02ch;font-feature-settings:"tnum" 1,"ss05" 1,"lnum","ss01","ss04","case","calt"}a-tag[size=large][nocaps]{font-size:13px}}
|
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;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"}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,11 +1,50 @@
|
|
|
1
1
|
import { HTMLElementBase } from '../anta_helpers';
|
|
2
2
|
import './a-text.css';
|
|
3
|
+
/**
|
|
4
|
+
* `<a-text>` — body text element with truncation / expansion.
|
|
5
|
+
*
|
|
6
|
+
* Styling notes (`a-text.css` ships comment-free):
|
|
7
|
+
* - `a-text[truncate] { min-width: 0 }` is the one external requirement of
|
|
8
|
+
* the shadow clamp: the host must be allowed to shrink inside flex/grid
|
|
9
|
+
* parents so the inner clamp can actually clip content.
|
|
10
|
+
* - The default (no `priority`) is the SECONDARY level — body text reads at
|
|
11
|
+
* `--text-2` on the base rule; `priority="primary"` opts into the
|
|
12
|
+
* strongest `--text-1`.
|
|
13
|
+
* - Priority/tone link colors: levels 1–2 keep the brand link color; levels
|
|
14
|
+
* 3–5 mute the link to `currentColor` and step the hover up one level
|
|
15
|
+
* (3→2, 4→3, 5→4). Tinted variants do the same within their
|
|
16
|
+
* `--text-{N}-{tone}` ramp (level 1 has nothing above it — hover keeps the
|
|
17
|
+
* color and only the underline alpha changes).
|
|
18
|
+
* - The `a-text a` rules layer on anta's global `a` defaults from
|
|
19
|
+
* `reset.css`, overriding only color and the one-step-up hover color
|
|
20
|
+
* (underline thickness/offset/alpha are inherited); the hover repeats the
|
|
21
|
+
* underline color so it tracks the priority color. Hover is gated to
|
|
22
|
+
* `(hover: hover) and (pointer: fine)` to avoid sticky hover after a tap.
|
|
23
|
+
*/
|
|
3
24
|
export declare class ATextElement extends HTMLElementBase {
|
|
4
25
|
static observedAttributes: string[];
|
|
5
26
|
private slotEl;
|
|
6
|
-
|
|
27
|
+
/** The expand/collapse chevron — built lazily, only while the element is
|
|
28
|
+
* expandable (a plain `<a-text>` never creates a button or a listener).
|
|
29
|
+
* Removed when `expandable` is dropped, and when a one-way expand completes. */
|
|
30
|
+
private expandBtn?;
|
|
31
|
+
/** Expanded state lives here, on the element — a stateless wrapper can't hold
|
|
32
|
+
* it and the app DOM may be reconciled off the UI thread. */
|
|
33
|
+
private expanded;
|
|
7
34
|
constructor();
|
|
8
|
-
|
|
9
|
-
|
|
35
|
+
connectedCallback(): void;
|
|
36
|
+
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
37
|
+
private get isExpandable();
|
|
38
|
+
private get isCollapsible();
|
|
39
|
+
/** Create or remove the chevron button to match `expandable`, then refresh
|
|
40
|
+
* its label/visibility — the single place the button's lifecycle lives. */
|
|
41
|
+
private syncExpandButton;
|
|
42
|
+
private handleToggle;
|
|
43
|
+
private setExpanded;
|
|
44
|
+
/** Reflect the current state onto the button: label + `aria-expanded` + the
|
|
45
|
+
* `.expanded` class (CSS keeps it visible and rotates the chevron up). A
|
|
46
|
+
* one-way expand (no `collapsible`) removes the button once expanded — there
|
|
47
|
+
* is nothing to collapse back to. */
|
|
48
|
+
private refreshButton;
|
|
10
49
|
}
|
|
11
50
|
export declare function register_a_text(): void;
|
package/dist/elements/a-text.js
CHANGED
|
@@ -9,9 +9,6 @@ const SHADOW_STYLE = `
|
|
|
9
9
|
display: inline-block;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
/* Default: slot disappears from layout so slotted nodes flow as
|
|
13
|
-
direct children of the host. Truncation rules below give the slot
|
|
14
|
-
a real display so it becomes the wrapper that holds the clamp. */
|
|
15
12
|
slot {
|
|
16
13
|
display: contents;
|
|
17
14
|
}
|
|
@@ -23,27 +20,22 @@ const SHADOW_STYLE = `
|
|
|
23
20
|
overflow: hidden;
|
|
24
21
|
}
|
|
25
22
|
|
|
26
|
-
/* Expandable \u2014 vertical fade for multi-line. */
|
|
27
23
|
:host([truncate][expandable]) slot:not(.expanded) {
|
|
28
24
|
-webkit-mask-image: linear-gradient(to bottom, black calc(100% - 2em), transparent 97%);
|
|
29
25
|
mask-image: linear-gradient(to bottom, black calc(100% - 2em), transparent 97%);
|
|
30
26
|
}
|
|
31
27
|
|
|
32
|
-
/* Expandable \u2014 horizontal right-edge fade for single-line. */
|
|
33
28
|
:host([truncate="1"][expandable]) slot:not(.expanded) {
|
|
34
29
|
-webkit-mask-image: linear-gradient(to right, black calc(100% - 7ch), transparent 97%);
|
|
35
30
|
mask-image: linear-gradient(to right, black calc(100% - 7ch), transparent 97%);
|
|
36
31
|
}
|
|
37
32
|
|
|
38
|
-
/* Expanded \u2014 drop truncation entirely. */
|
|
39
33
|
:host([truncate]) slot.expanded {
|
|
40
34
|
display: block;
|
|
41
35
|
-webkit-line-clamp: unset;
|
|
42
36
|
overflow: visible;
|
|
43
37
|
}
|
|
44
38
|
|
|
45
|
-
/* Expand button. The whole button is the click target; the chevron
|
|
46
|
-
icon is positioned absolutely in the button's bottom-right corner. */
|
|
47
39
|
.expand-btn {
|
|
48
40
|
appearance: none;
|
|
49
41
|
background: transparent;
|
|
@@ -78,10 +70,10 @@ const SHADOW_STYLE = `
|
|
|
78
70
|
mask-repeat: no-repeat;
|
|
79
71
|
-webkit-mask-size: contain;
|
|
80
72
|
mask-size: contain;
|
|
73
|
+
transition: transform 150ms ease-out;
|
|
81
74
|
}
|
|
82
75
|
|
|
83
|
-
|
|
84
|
-
:host([truncate][expandable]) .expand-btn:not(.hidden) {
|
|
76
|
+
:host([truncate][expandable]) .expand-btn {
|
|
85
77
|
display: block;
|
|
86
78
|
left: 0;
|
|
87
79
|
right: 0;
|
|
@@ -89,48 +81,96 @@ const SHADOW_STYLE = `
|
|
|
89
81
|
height: 1.5em;
|
|
90
82
|
}
|
|
91
83
|
|
|
92
|
-
|
|
93
|
-
:host([truncate="1"][expandable]) .expand-btn:not(.hidden) {
|
|
84
|
+
:host([truncate="1"][expandable]) .expand-btn {
|
|
94
85
|
left: auto;
|
|
95
86
|
top: 0;
|
|
96
87
|
bottom: 0;
|
|
97
88
|
width: 3em;
|
|
98
89
|
}
|
|
99
90
|
|
|
100
|
-
:host([truncate][expandable]:hover) .expand-btn
|
|
101
|
-
:host([truncate][expandable]:focus-within) .expand-btn
|
|
91
|
+
:host([truncate][expandable]:hover) .expand-btn,
|
|
92
|
+
:host([truncate][expandable]:focus-within) .expand-btn,
|
|
93
|
+
.expand-btn.expanded {
|
|
102
94
|
opacity: 1;
|
|
103
95
|
}
|
|
96
|
+
|
|
97
|
+
.expand-btn.expanded::before {
|
|
98
|
+
transform: rotate(180deg);
|
|
99
|
+
}
|
|
104
100
|
`;
|
|
105
101
|
class ATextElement extends HTMLElementBase {
|
|
106
|
-
static observedAttributes = ["expandable", "truncate"];
|
|
102
|
+
static observedAttributes = ["expandable", "truncate", "collapsible"];
|
|
107
103
|
slotEl;
|
|
104
|
+
/** The expand/collapse chevron — built lazily, only while the element is
|
|
105
|
+
* expandable (a plain `<a-text>` never creates a button or a listener).
|
|
106
|
+
* Removed when `expandable` is dropped, and when a one-way expand completes. */
|
|
108
107
|
expandBtn;
|
|
108
|
+
/** Expanded state lives here, on the element — a stateless wrapper can't hold
|
|
109
|
+
* it and the app DOM may be reconciled off the UI thread. */
|
|
110
|
+
expanded = false;
|
|
109
111
|
constructor() {
|
|
110
112
|
super();
|
|
111
113
|
const shadow = this.attachShadow({ mode: "open" });
|
|
112
114
|
const style = document.createElement("style");
|
|
113
115
|
style.textContent = SHADOW_STYLE;
|
|
114
116
|
this.slotEl = document.createElement("slot");
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
this.
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
this.
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
117
|
+
shadow.append(style, this.slotEl);
|
|
118
|
+
}
|
|
119
|
+
connectedCallback() {
|
|
120
|
+
this.syncExpandButton();
|
|
121
|
+
}
|
|
122
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
123
|
+
if (oldValue === newValue) return;
|
|
124
|
+
if (name === "truncate" || name === "expandable") this.setExpanded(false);
|
|
125
|
+
this.syncExpandButton();
|
|
126
|
+
}
|
|
127
|
+
get isExpandable() {
|
|
128
|
+
return this.hasAttribute("truncate") && this.hasAttribute("expandable");
|
|
129
|
+
}
|
|
130
|
+
get isCollapsible() {
|
|
131
|
+
return this.hasAttribute("collapsible");
|
|
132
|
+
}
|
|
133
|
+
/** Create or remove the chevron button to match `expandable`, then refresh
|
|
134
|
+
* its label/visibility — the single place the button's lifecycle lives. */
|
|
135
|
+
syncExpandButton() {
|
|
136
|
+
if (this.isExpandable && !this.expandBtn) {
|
|
137
|
+
const btn = document.createElement("button");
|
|
138
|
+
btn.className = "expand-btn";
|
|
139
|
+
btn.type = "button";
|
|
140
|
+
btn.addEventListener("click", this.handleToggle);
|
|
141
|
+
this.shadowRoot.append(btn);
|
|
142
|
+
this.expandBtn = btn;
|
|
143
|
+
} else if (!this.isExpandable && this.expandBtn) {
|
|
144
|
+
this.expandBtn.remove();
|
|
145
|
+
this.expandBtn = void 0;
|
|
146
|
+
}
|
|
147
|
+
this.refreshButton();
|
|
148
|
+
}
|
|
149
|
+
handleToggle = () => {
|
|
150
|
+
this.setExpanded(!this.expanded);
|
|
133
151
|
};
|
|
152
|
+
setExpanded(next) {
|
|
153
|
+
if (next === this.expanded) return;
|
|
154
|
+
this.expanded = next;
|
|
155
|
+
this.slotEl.classList.toggle("expanded", next);
|
|
156
|
+
this.refreshButton();
|
|
157
|
+
}
|
|
158
|
+
/** Reflect the current state onto the button: label + `aria-expanded` + the
|
|
159
|
+
* `.expanded` class (CSS keeps it visible and rotates the chevron up). A
|
|
160
|
+
* one-way expand (no `collapsible`) removes the button once expanded — there
|
|
161
|
+
* is nothing to collapse back to. */
|
|
162
|
+
refreshButton() {
|
|
163
|
+
const btn = this.expandBtn;
|
|
164
|
+
if (!btn) return;
|
|
165
|
+
if (this.expanded && !this.isCollapsible) {
|
|
166
|
+
btn.remove();
|
|
167
|
+
this.expandBtn = void 0;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
btn.setAttribute("aria-expanded", this.expanded ? "true" : "false");
|
|
171
|
+
btn.setAttribute("aria-label", this.expanded ? "Show less" : "Show more");
|
|
172
|
+
btn.classList.toggle("expanded", this.expanded);
|
|
173
|
+
}
|
|
134
174
|
}
|
|
135
175
|
function register_a_text() {
|
|
136
176
|
if (typeof customElements === "undefined") return;
|