@antadesign/anta 0.3.22 → 0.3.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/avatar-core.d.ts +160 -0
- package/dist/avatar-core.js +271 -0
- package/dist/bundle.css +1 -0
- package/dist/bundle.d.ts +11 -0
- package/dist/bundle.js +1245 -0
- package/dist/components/Avatar.d.ts +63 -0
- package/dist/components/Avatar.js +29 -0
- package/dist/components/Breadcrumbs.css +1 -0
- package/dist/components/Breadcrumbs.d.ts +127 -0
- package/dist/components/Breadcrumbs.js +145 -0
- package/dist/components/Button.d.ts +14 -7
- package/dist/components/Button.js +2 -0
- package/dist/components/Input.d.ts +3 -1
- package/dist/components/Input.js +2 -0
- package/dist/components/InputTime.d.ts +3 -1
- package/dist/components/InputTime.js +2 -0
- package/dist/components/Loader.d.ts +5 -1
- package/dist/components/Loader.js +2 -1
- package/dist/components/MenuItemCopy.d.ts +14 -3
- package/dist/components/MenuItemCopy.js +9 -3
- package/dist/components/Slider.d.ts +1 -1
- package/dist/components/Steps.css +1 -0
- package/dist/components/Steps.d.ts +93 -0
- package/dist/components/Steps.js +128 -0
- package/dist/components/Tabs.d.ts +10 -5
- package/dist/components/Tabs.js +5 -2
- package/dist/components/Tooltip.d.ts +5 -5
- package/dist/elements/a-avatar.css +1 -0
- package/dist/elements/a-avatar.d.ts +31 -0
- package/dist/elements/a-avatar.js +98 -0
- package/dist/elements/a-button.css +1 -1
- package/dist/elements/a-dialog.js +3 -1
- package/dist/elements/a-icon.shapes.css +1 -1
- package/dist/elements/a-icon.shapes.d.ts +2 -9
- package/dist/elements/a-icon.shapes.js +2 -16
- package/dist/elements/a-input-time.d.ts +2 -0
- package/dist/elements/a-input-time.js +7 -0
- package/dist/elements/a-input.css +1 -1
- package/dist/elements/a-input.d.ts +4 -0
- package/dist/elements/a-input.js +9 -0
- package/dist/elements/a-loader.css +1 -1
- package/dist/elements/a-slider.css +1 -1
- package/dist/elements/a-tabs.css +1 -1
- package/dist/elements/a-tooltip.d.ts +4 -4
- package/dist/elements/a-tooltip.js +18 -15
- package/dist/elements/index.d.ts +1 -0
- package/dist/elements/index.js +3 -0
- package/dist/general_types.d.ts +42 -0
- package/dist/index.d.ts +9 -1
- package/dist/index.js +30 -0
- package/dist/jsx-runtime.d.ts +8 -1
- package/dist/search-index.json +0 -0
- package/docs/changelog.md +60 -0
- package/docs/comparison.md +10 -5
- package/docs/components/banner.md +1 -1
- package/docs/components/breadcrumbs.md +177 -0
- package/docs/components/button.md +7 -4
- package/docs/components/card.md +1 -1
- package/docs/components/dialog.md +4 -4
- package/docs/components/expander.md +1 -1
- package/docs/components/input-time.md +1 -0
- package/docs/components/input.md +2 -1
- package/docs/components/loader.md +1 -0
- package/docs/components/menu.md +7 -2
- package/docs/components/radio.md +1 -1
- package/docs/components/slider.md +1 -1
- package/docs/components/steps.md +324 -0
- package/docs/components/tabs.md +24 -8
- package/docs/components/tag.md +3 -3
- package/docs/components/tooltip.md +5 -5
- package/docs/index.md +2 -0
- package/docs/install-config.md +17 -0
- package/package.json +9 -3
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import type { IconShape } from "../elements/a-icon.shapes";
|
|
2
|
+
import type { OptionPresentationProps } from "../general_types";
|
|
3
|
+
import type { TabsProps } from "./Tabs";
|
|
4
|
+
import "./Steps.css";
|
|
5
|
+
/** Named Anta tone used by Steps. */
|
|
6
|
+
export type StepTone = "neutral" | "brand" | "info" | "success" | "warning" | "critical";
|
|
7
|
+
/** Process state shown by one step. */
|
|
8
|
+
export type StepState = "incomplete" | "loading" | "completed" | "error";
|
|
9
|
+
/** Visual emphasis for the step markers and completed connectors. */
|
|
10
|
+
export type StepPriority = "primary" | "secondary" | "tertiary";
|
|
11
|
+
/** A static step marker: a number or any registered Anta icon shape. */
|
|
12
|
+
export type StepMarker = number | IconShape;
|
|
13
|
+
/** Snapshot passed to `renderMarker` for a step. */
|
|
14
|
+
export interface StepMarkerState {
|
|
15
|
+
/** This step's application-owned process state. */
|
|
16
|
+
state: StepState;
|
|
17
|
+
/** Whether this step is the selected tab. */
|
|
18
|
+
selected: boolean;
|
|
19
|
+
/** Whether this step cannot be selected. */
|
|
20
|
+
disabled: boolean;
|
|
21
|
+
}
|
|
22
|
+
/** One phase rendered by `<Steps>`. Inherited `className` and `style` land on
|
|
23
|
+
* the individual `<a-tab>`, not on the enclosing Steps sequence. */
|
|
24
|
+
export interface StepOption extends OptionPresentationProps {
|
|
25
|
+
/** Stable phase identity. Values must be unique within the sequence. */
|
|
26
|
+
value: string;
|
|
27
|
+
/** Visible phase label. It ellipsizes in a constrained step; its full content
|
|
28
|
+
* is available in a tooltip only when clipped. */
|
|
29
|
+
label: React.ReactNode;
|
|
30
|
+
/** Secondary text shown below the label. It ellipsizes in a constrained step;
|
|
31
|
+
* its full content is available in a tooltip only when clipped. */
|
|
32
|
+
hint?: React.ReactNode;
|
|
33
|
+
/** Application-owned process state. Selection and availability are separate;
|
|
34
|
+
* `error` keeps a critical icon and outline, and selection adds the fill. */
|
|
35
|
+
state: StepState;
|
|
36
|
+
/** Tone for this phase. It colors the label, hint, marker, and completed
|
|
37
|
+
* connector. Overrides the Steps `tone`; error steps stay critical and
|
|
38
|
+
* disabled steps stay neutral.
|
|
39
|
+
* @defaultValue inherits Steps `tone` */
|
|
40
|
+
tone?: StepTone | "";
|
|
41
|
+
/** Replaces the marker derived from `state`. A number is shown directly; an
|
|
42
|
+
* Anta icon shape is rendered as an `<Icon>`. */
|
|
43
|
+
marker?: StepMarker;
|
|
44
|
+
/** Disables this phase. A custom `marker` or `renderMarker` result is kept;
|
|
45
|
+
* otherwise it uses the incomplete marker. */
|
|
46
|
+
disabled?: boolean;
|
|
47
|
+
}
|
|
48
|
+
/** Public props for `<Steps>`. Selection, panels, events, orientation, size,
|
|
49
|
+
* and disabled behavior match `<Tabs>`. */
|
|
50
|
+
export interface StepsProps extends Omit<TabsProps, "options" | "priority" | "tone" | "noslide" | "round"> {
|
|
51
|
+
/** Ordered process phases. */
|
|
52
|
+
options: StepOption[];
|
|
53
|
+
/** Visual emphasis. Primary uses a solid selected marker and a stronger
|
|
54
|
+
* completed connector; secondary is the outlined default; tertiary is compact
|
|
55
|
+
* and borderless.
|
|
56
|
+
* @defaultValue 'secondary' */
|
|
57
|
+
priority?: StepPriority;
|
|
58
|
+
/** Tone applied to every step without its own `tone`. Error steps stay
|
|
59
|
+
* critical and disabled steps stay neutral.
|
|
60
|
+
* @defaultValue 'neutral' */
|
|
61
|
+
tone?: StepTone | "";
|
|
62
|
+
/** Builds a custom marker from a step and its current state. A returned node
|
|
63
|
+
* replaces `marker` and the built-in state marker; return `undefined` to use
|
|
64
|
+
* those fallbacks, or `null` for an empty ring. */
|
|
65
|
+
renderMarker?: (option: StepOption, state: StepMarkerState) => React.ReactNode;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* A process stepper that switches tab-like content.
|
|
69
|
+
*
|
|
70
|
+
* The application owns phase states and transitions. `Steps` owns the tab
|
|
71
|
+
* interaction pattern, state presentation, and optional panels. Compose
|
|
72
|
+
* application-owned navigation controls beside it when the flow needs actions
|
|
73
|
+
* such as Back or Continue.
|
|
74
|
+
*
|
|
75
|
+
* It supports controlled (`value`) and uncontrolled (`defaultValue`) selection.
|
|
76
|
+
* When neither is supplied, the first option is selected. Explicitly disabled
|
|
77
|
+
* phases cannot be activated. Arrow-key behavior, panel pairing,
|
|
78
|
+
* duplicate-value warnings, and change events match `<Tabs>`.
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```tsx
|
|
82
|
+
* <Steps
|
|
83
|
+
* defaultValue="setup"
|
|
84
|
+
* label="Setup progress"
|
|
85
|
+
* options={[
|
|
86
|
+
* { value: "build", label: "Build", state: "completed" },
|
|
87
|
+
* { value: "setup", label: "Setup", state: "loading" },
|
|
88
|
+
* { value: "next", label: "Next steps", state: "incomplete", disabled: true },
|
|
89
|
+
* ]}
|
|
90
|
+
* />
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export declare const Steps: ({ options, value, defaultValue, onStateChange, onChange, onValueChange, onFocus, onBlur, label, priority, tone, renderMarker, size, orientation, fill, disabled, children, className, style, id, ...rest }: StepsProps) => any;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
+
import { optionPresentationAttrs } from "../anta_helpers";
|
|
3
|
+
import { useState } from "../jsx-runtime";
|
|
4
|
+
import { Icon } from "./Icon";
|
|
5
|
+
import { Loader } from "./Loader";
|
|
6
|
+
import { Tabs } from "./Tabs";
|
|
7
|
+
import "./Steps.css";
|
|
8
|
+
const STATE_ICON = {
|
|
9
|
+
incomplete: "circle-large",
|
|
10
|
+
completed: "check",
|
|
11
|
+
error: "x"
|
|
12
|
+
};
|
|
13
|
+
const Steps = ({
|
|
14
|
+
options,
|
|
15
|
+
value,
|
|
16
|
+
defaultValue,
|
|
17
|
+
onStateChange,
|
|
18
|
+
onChange,
|
|
19
|
+
onValueChange,
|
|
20
|
+
onFocus,
|
|
21
|
+
onBlur,
|
|
22
|
+
label,
|
|
23
|
+
priority = "secondary",
|
|
24
|
+
tone,
|
|
25
|
+
renderMarker,
|
|
26
|
+
size,
|
|
27
|
+
orientation,
|
|
28
|
+
fill,
|
|
29
|
+
disabled,
|
|
30
|
+
children,
|
|
31
|
+
className,
|
|
32
|
+
style,
|
|
33
|
+
id,
|
|
34
|
+
...rest
|
|
35
|
+
}) => {
|
|
36
|
+
const controlled = value !== void 0;
|
|
37
|
+
const [internalValue, setInternalValue] = useState(
|
|
38
|
+
defaultValue
|
|
39
|
+
);
|
|
40
|
+
const currentValue = controlled ? value : internalValue ?? options[0]?.value;
|
|
41
|
+
const handleStateChange = (event, detail) => {
|
|
42
|
+
onStateChange?.(event, detail);
|
|
43
|
+
if (controlled || event.defaultPrevented) return;
|
|
44
|
+
setInternalValue(detail.next ?? void 0);
|
|
45
|
+
};
|
|
46
|
+
const tabs = options.map((option) => {
|
|
47
|
+
const { className: optionClassName, style: optionStyle, ...optionAttrs } = optionPresentationAttrs(option);
|
|
48
|
+
const optionTone = option.tone || void 0;
|
|
49
|
+
const stepTone = option.disabled ? "neutral" : option.state === "error" ? "critical" : optionTone || tone || "neutral";
|
|
50
|
+
const customMarker = renderMarker?.(option, {
|
|
51
|
+
state: option.state,
|
|
52
|
+
selected: option.value === currentValue,
|
|
53
|
+
disabled: !!option.disabled
|
|
54
|
+
});
|
|
55
|
+
const builtInMarker = option.disabled ? /* @__PURE__ */ jsx(Icon, { shape: STATE_ICON.incomplete }) : option.state === "loading" ? /* @__PURE__ */ jsx(Loader, { tone: stepTone }) : /* @__PURE__ */ jsx(Icon, { shape: STATE_ICON[option.state] });
|
|
56
|
+
const marker = customMarker !== void 0 ? customMarker : option.marker !== void 0 ? typeof option.marker === "number" ? option.marker : /* @__PURE__ */ jsx(Icon, { shape: option.marker }) : builtInMarker;
|
|
57
|
+
return {
|
|
58
|
+
...optionAttrs,
|
|
59
|
+
value: option.value,
|
|
60
|
+
disabled: option.disabled,
|
|
61
|
+
"data-step-state": option.state,
|
|
62
|
+
// Steps propagates its tone to each generated tab. A local option tone
|
|
63
|
+
// wins, while error and disabled states retain their fixed semantics.
|
|
64
|
+
tone: stepTone,
|
|
65
|
+
tooltip: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
66
|
+
option.label,
|
|
67
|
+
option.hint != null && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
68
|
+
" \u2014 ",
|
|
69
|
+
option.hint
|
|
70
|
+
] })
|
|
71
|
+
] }),
|
|
72
|
+
className: optionClassName,
|
|
73
|
+
style: optionStyle,
|
|
74
|
+
children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
75
|
+
/* @__PURE__ */ jsx("a-step-marker", { "aria-hidden": "true", children: marker }),
|
|
76
|
+
/* @__PURE__ */ jsxs("a-step-desc", { children: [
|
|
77
|
+
/* @__PURE__ */ jsx("a-tab-label", { children: option.label }),
|
|
78
|
+
option.hint != null && /* @__PURE__ */ jsx("a-step-hint", { children: option.hint })
|
|
79
|
+
] })
|
|
80
|
+
] })
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
const currentIndex = options.findIndex(
|
|
84
|
+
(option) => option.value === currentValue
|
|
85
|
+
);
|
|
86
|
+
const vertical = orientation === "vertical";
|
|
87
|
+
const hasPanels = children != null && children !== false;
|
|
88
|
+
const hasVerticalPanel = vertical && hasPanels;
|
|
89
|
+
const panelRow = (currentIndex >= 0 ? currentIndex : options.length - 1) + 2;
|
|
90
|
+
const rootStyle = hasVerticalPanel ? {
|
|
91
|
+
...style,
|
|
92
|
+
"--steps-panel-row": panelRow
|
|
93
|
+
} : style;
|
|
94
|
+
return /* @__PURE__ */ jsx(
|
|
95
|
+
"a-steps",
|
|
96
|
+
{
|
|
97
|
+
class: className,
|
|
98
|
+
style: rootStyle,
|
|
99
|
+
id,
|
|
100
|
+
...rest,
|
|
101
|
+
"data-orientation": vertical ? "vertical" : void 0,
|
|
102
|
+
children: /* @__PURE__ */ jsx(
|
|
103
|
+
Tabs,
|
|
104
|
+
{
|
|
105
|
+
options: tabs,
|
|
106
|
+
value: currentValue,
|
|
107
|
+
onStateChange: handleStateChange,
|
|
108
|
+
onChange,
|
|
109
|
+
onValueChange,
|
|
110
|
+
onFocus,
|
|
111
|
+
onBlur,
|
|
112
|
+
label,
|
|
113
|
+
size,
|
|
114
|
+
orientation,
|
|
115
|
+
fill,
|
|
116
|
+
priority,
|
|
117
|
+
noslide: true,
|
|
118
|
+
disabled,
|
|
119
|
+
"data-steps": "",
|
|
120
|
+
children
|
|
121
|
+
}
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
};
|
|
126
|
+
export {
|
|
127
|
+
Steps
|
|
128
|
+
};
|
|
@@ -41,9 +41,10 @@ export interface TabOption extends OptionPresentationProps {
|
|
|
41
41
|
/** Disable just this tab — skipped by keyboard nav and dropped from the tab order
|
|
42
42
|
* (a disabled-but-selected tab stays reachable, per the ARIA pattern). */
|
|
43
43
|
disabled?: boolean;
|
|
44
|
-
/** Tooltip for this tab — a string or any node — shown **only when
|
|
45
|
-
* is truncated** (tabs ellipsize when the strip
|
|
46
|
-
* its full text on hover while a tab that
|
|
44
|
+
/** Tooltip for this tab — a string or any node — shown **only when one of the
|
|
45
|
+
* tab's ellipsizing label parts is truncated** (tabs ellipsize when the strip
|
|
46
|
+
* overflows), so clipped content reveals its full text on hover while a tab that
|
|
47
|
+
* fits shows nothing. Rendered as a
|
|
47
48
|
* `truncatedOnly` `<Tooltip>` anchored to the tab. For an always-visible tooltip or
|
|
48
49
|
* other custom trigger content, use `children` with your own `<Tooltip>` instead. */
|
|
49
50
|
tooltip?: React.ReactNode;
|
|
@@ -58,7 +59,8 @@ export interface TabsProps extends Omit<BaseProps, "onChange"> {
|
|
|
58
59
|
children?: React.ReactNode;
|
|
59
60
|
/** The tabs, as a data array (the strip's single source). Each entry is a
|
|
60
61
|
* `TabOption` (`value`, `label` or `children`, `icon`, `iconTrailing`, `tone`,
|
|
61
|
-
* `disabled`, `round`).
|
|
62
|
+
* `disabled`, `round`, `className`, `style`). `className` and `style` land on
|
|
63
|
+
* that option's individual `<a-tab>`, not on the strip. */
|
|
62
64
|
options?: TabOption[];
|
|
63
65
|
/** Controlled active value — the tab `value` to mark selected (and, when a
|
|
64
66
|
* `<TabPanel value="…">` shares it, the panel to reveal). When set, you own
|
|
@@ -103,6 +105,9 @@ export interface TabsProps extends Omit<BaseProps, "onChange"> {
|
|
|
103
105
|
* is opt-in via CSS); vertical stacks them.
|
|
104
106
|
* @defaultValue 'horizontal' */
|
|
105
107
|
orientation?: "horizontal" | "vertical";
|
|
108
|
+
/** Makes horizontal tabs share the available inline space equally.
|
|
109
|
+
* @defaultValue false */
|
|
110
|
+
fill?: boolean;
|
|
106
111
|
/** Disable the sliding indicator. By default the selected-tab indicator animates
|
|
107
112
|
* between tabs (a single rectangle, via CSS anchor positioning); `noslide` paints it
|
|
108
113
|
* per tab so it snaps with no movement. (Browsers without anchor positioning get that
|
|
@@ -149,5 +154,5 @@ export interface TabsProps extends Omit<BaseProps, "onChange"> {
|
|
|
149
154
|
* </Tabs>
|
|
150
155
|
* ```
|
|
151
156
|
*/
|
|
152
|
-
export declare const Tabs: ({ children, options, value, defaultValue, onStateChange, onChange, onValueChange, onFocus, onBlur, label, priority, tone, size, orientation, noslide, round, disabled, className, style, id, ...rest }: TabsProps) => any;
|
|
157
|
+
export declare const Tabs: ({ children, options, value, defaultValue, onStateChange, onChange, onValueChange, onFocus, onBlur, label, priority, tone, size, orientation, fill, noslide, round, disabled, className, style, id, ...rest }: TabsProps) => any;
|
|
153
158
|
export {};
|
package/dist/components/Tabs.js
CHANGED
|
@@ -17,6 +17,7 @@ const Tabs = ({
|
|
|
17
17
|
tone,
|
|
18
18
|
size,
|
|
19
19
|
orientation,
|
|
20
|
+
fill,
|
|
20
21
|
noslide,
|
|
21
22
|
round,
|
|
22
23
|
disabled,
|
|
@@ -61,6 +62,7 @@ const Tabs = ({
|
|
|
61
62
|
tone: tone && tone !== "neutral" ? tone : void 0,
|
|
62
63
|
size: size && size !== "medium" ? size : void 0,
|
|
63
64
|
orientation: vertical ? "vertical" : void 0,
|
|
65
|
+
fill: fill ? "" : void 0,
|
|
64
66
|
noslide: noslide ? "" : void 0,
|
|
65
67
|
round: roundAttr(round),
|
|
66
68
|
disabled: disabled ? "" : void 0,
|
|
@@ -76,13 +78,13 @@ const Tabs = ({
|
|
|
76
78
|
const tabDisabled = disabled || p.disabled;
|
|
77
79
|
const isSelected = p.value === currentValue;
|
|
78
80
|
const { className: optionClassName, style: optionStyle, ...optionAttrs } = optionPresentationAttrs(p);
|
|
79
|
-
|
|
81
|
+
const tab = /* @__PURE__ */ jsxs(
|
|
80
82
|
"a-tab",
|
|
81
83
|
{
|
|
82
84
|
...optionAttrs,
|
|
83
85
|
role: "tab",
|
|
84
86
|
value: p.value,
|
|
85
|
-
tone: p.tone
|
|
87
|
+
tone: p.tone || void 0,
|
|
86
88
|
"aria-disabled": tabDisabled ? "true" : void 0,
|
|
87
89
|
tabIndex: tabDisabled && !isSelected ? -1 : 0,
|
|
88
90
|
disabled: tabDisabled ? "" : void 0,
|
|
@@ -98,6 +100,7 @@ const Tabs = ({
|
|
|
98
100
|
},
|
|
99
101
|
p.value
|
|
100
102
|
);
|
|
103
|
+
return tab;
|
|
101
104
|
})
|
|
102
105
|
}
|
|
103
106
|
);
|
|
@@ -25,12 +25,12 @@ export interface TooltipProps extends BaseProps {
|
|
|
25
25
|
interactive?: boolean;
|
|
26
26
|
/** Only show when the target is actually truncated (its text overflows and is
|
|
27
27
|
* ellipsized); a label that fits gets no tooltip. The check is a UI-thread
|
|
28
|
-
* layout read, re-measured on each show. By default it measures
|
|
29
|
-
*
|
|
30
|
-
*
|
|
28
|
+
* layout read, re-measured on each show. By default it measures every Anta
|
|
29
|
+
* ellipsizing label part inside the anchor, then the anchor itself —
|
|
30
|
+
* override with `truncatedSelector`. */
|
|
31
31
|
truncatedOnly?: boolean;
|
|
32
|
-
/** CSS selector (resolved within the anchor) for the element
|
|
33
|
-
* decides whether a `truncatedOnly` tooltip shows. */
|
|
32
|
+
/** CSS selector (resolved within the anchor) for the element or elements
|
|
33
|
+
* whose overflow decides whether a `truncatedOnly` tooltip shows. */
|
|
34
34
|
truncatedSelector?: string;
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@layer anta{a-avatar{--avatar-size: 44px;--avatar-radius: 22%;--avatar-placeholder-bg: var(--bg-3);--avatar-badge-ratio: .24;--avatar-badge-size: calc(var(--avatar-size) * var(--avatar-badge-ratio));--avatar-badge-inset: 0px;--avatar-badge-gap: 2px;--avatar-badge-mask: none;--avatar-badge-tone-source: var(--anta-seed-neutral);--avatar-badge-chroma: .17;--avatar-badge-color: oklch(from var(--avatar-badge-tone-source) .62 var(--avatar-badge-chroma) h);display:inline-block;inline-size:var(--avatar-size);block-size:var(--avatar-size);vertical-align:middle}a-avatar[round]{--avatar-round: attr(round type(<length>));--avatar-radius: var(--avatar-round, 50%);--avatar-badge-inset: calc(var(--avatar-size) * .03)}a-avatar[size=small]{--avatar-size: 32px;--avatar-badge-gap: 1.5px}a-avatar[size=large]{--avatar-size: 64px;--avatar-badge-gap: 2.5px}a-avatar[badge]:not([badge=""],[badge=none]){--avatar-badge-mask: radial-gradient( circle calc(var(--avatar-badge-size) / 2 + var(--avatar-badge-gap)) at calc(100% - var(--avatar-badge-inset) - var(--avatar-badge-size) / 2) calc(100% - var(--avatar-badge-inset) - var(--avatar-badge-size) / 2), transparent 99%, #000 100% )}a-avatar:not(:defined){display:inline-block;inline-size:var(--avatar-size);block-size:var(--avatar-size);border-radius:var(--avatar-radius);background:var(--avatar-placeholder-bg);vertical-align:middle}a-avatar[badge=neutral]{--avatar-badge-chroma: .005}a-avatar[badge=brand]{--avatar-badge-tone-source: var(--anta-seed-brand)}a-avatar[badge=info]{--avatar-badge-tone-source: var(--anta-seed-info)}a-avatar[badge=success]{--avatar-badge-tone-source: var(--anta-seed-success)}a-avatar[badge=warning]{--avatar-badge-tone-source: var(--anta-seed-warning)}a-avatar[badge=critical]{--avatar-badge-tone-source: var(--anta-seed-critical)}@supports (color: attr(badge type(<color>),transparent)){a-avatar[badge]:not([badge=""],[badge=neutral],[badge=brand],[badge=info],[badge=success],[badge=warning],[badge=critical]){--avatar-badge-tone-source: attr(badge type(<color>), transparent)}}.dark a-avatar{--avatar-badge-color: oklch(from var(--avatar-badge-tone-source) .68 var(--avatar-badge-chroma) h)}.dark a-avatar[badge=neutral]{--avatar-badge-chroma: .008}}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { HTMLElementBase } from '../anta_helpers';
|
|
2
|
+
import './a-avatar.css';
|
|
3
|
+
/**
|
|
4
|
+
* `<a-avatar>` — a userpic container. It shows one of three things, in priority
|
|
5
|
+
* order: the `src` image, a seed-generated figure, or initials from `name`.
|
|
6
|
+
*
|
|
7
|
+
* Generation runs in `avatar-core` (pure) and is drawn into the shadow root as
|
|
8
|
+
* SVG. `seed` (falling back to `name`) drives the deterministic result; the
|
|
9
|
+
* brand constraints ride on the `config` attribute as a JSON string, so the
|
|
10
|
+
* element stays declarative — it works from server-rendered HTML and hand-
|
|
11
|
+
* authored markup, not only through the wrapper. With no `config`,
|
|
12
|
+
* `DEFAULT_CONFIG` produces a varied figure; a config whose head and body shapes
|
|
13
|
+
* are both `off` renders initials.
|
|
14
|
+
*
|
|
15
|
+
* Shadow structure — the picture is the box, with no wrapper around it:
|
|
16
|
+
*
|
|
17
|
+
* :host
|
|
18
|
+
* <svg> | <img> ← the generated figure or the image, part="frame"
|
|
19
|
+
* .badge ← the optional corner badge, part="badge"
|
|
20
|
+
*
|
|
21
|
+
* The picture carries the frame's radius and the badge cutout; the host stays
|
|
22
|
+
* unclipped so the badge can sit at the very corner.
|
|
23
|
+
*/
|
|
24
|
+
export declare class AAvatarElement extends HTMLElementBase {
|
|
25
|
+
#private;
|
|
26
|
+
static observedAttributes: string[];
|
|
27
|
+
constructor();
|
|
28
|
+
connectedCallback(): void;
|
|
29
|
+
attributeChangedCallback(): void;
|
|
30
|
+
}
|
|
31
|
+
export declare function register_a_avatar(): void;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { HTMLElementBase } from "../anta_helpers";
|
|
2
|
+
import { resolveAvatar, avatarToSvg, getInitials, DEFAULT_CONFIG } from "../avatar-core";
|
|
3
|
+
import "./a-avatar.css";
|
|
4
|
+
class AAvatarElement extends HTMLElementBase {
|
|
5
|
+
static observedAttributes = ["seed", "name", "src", "size", "badge", "config"];
|
|
6
|
+
#badge;
|
|
7
|
+
#picture;
|
|
8
|
+
constructor() {
|
|
9
|
+
super();
|
|
10
|
+
const shadow = this.attachShadow({ mode: "open" });
|
|
11
|
+
const style = document.createElement("style");
|
|
12
|
+
style.textContent = SHADOW_STYLE;
|
|
13
|
+
this.#badge = document.createElement("span");
|
|
14
|
+
this.#badge.className = "badge";
|
|
15
|
+
this.#badge.setAttribute("part", "badge");
|
|
16
|
+
this.#badge.style.display = "none";
|
|
17
|
+
shadow.append(style, this.#badge);
|
|
18
|
+
}
|
|
19
|
+
/** Swap in the picture, keeping it between the style and the indicator. */
|
|
20
|
+
#setPicture(node) {
|
|
21
|
+
if (this.#picture) this.#picture.replaceWith(node);
|
|
22
|
+
else this.#badge.before(node);
|
|
23
|
+
this.#picture = node;
|
|
24
|
+
}
|
|
25
|
+
connectedCallback() {
|
|
26
|
+
this.#render();
|
|
27
|
+
}
|
|
28
|
+
attributeChangedCallback() {
|
|
29
|
+
this.#render();
|
|
30
|
+
}
|
|
31
|
+
/** Parse the `config` JSON attribute; fall back to the varied default. */
|
|
32
|
+
#parseConfig() {
|
|
33
|
+
const raw = this.getAttribute("config");
|
|
34
|
+
if (!raw) return DEFAULT_CONFIG;
|
|
35
|
+
try {
|
|
36
|
+
const parsed = JSON.parse(raw);
|
|
37
|
+
return parsed && typeof parsed === "object" ? parsed : DEFAULT_CONFIG;
|
|
38
|
+
} catch {
|
|
39
|
+
return DEFAULT_CONFIG;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
#render() {
|
|
43
|
+
const badge = this.getAttribute("badge");
|
|
44
|
+
this.#badge.style.display = badge && badge !== "none" ? "" : "none";
|
|
45
|
+
const name = this.getAttribute("name") ?? void 0;
|
|
46
|
+
const src = this.getAttribute("src");
|
|
47
|
+
if (src) {
|
|
48
|
+
const img = document.createElement("img");
|
|
49
|
+
img.setAttribute("part", "frame image");
|
|
50
|
+
img.src = src;
|
|
51
|
+
img.alt = name ?? "";
|
|
52
|
+
img.loading = "lazy";
|
|
53
|
+
this.#setPicture(img);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const seed = this.getAttribute("seed") ?? name ?? "";
|
|
57
|
+
const resolved = resolveAvatar(this.#parseConfig(), seed);
|
|
58
|
+
const tpl = document.createElement("template");
|
|
59
|
+
tpl.innerHTML = avatarToSvg(resolved, { initials: getInitials(name), title: name });
|
|
60
|
+
const svg = tpl.content.firstElementChild;
|
|
61
|
+
if (svg) {
|
|
62
|
+
svg.setAttribute("part", "frame");
|
|
63
|
+
this.#setPicture(svg);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const SHADOW_STYLE = `
|
|
68
|
+
:host { display: inline-block; position: relative; vertical-align: middle; }
|
|
69
|
+
svg, img {
|
|
70
|
+
display: block;
|
|
71
|
+
inline-size: 100%;
|
|
72
|
+
block-size: 100%;
|
|
73
|
+
border-radius: var(--avatar-radius);
|
|
74
|
+
background: var(--avatar-placeholder-bg);
|
|
75
|
+
mask-image: var(--avatar-badge-mask);
|
|
76
|
+
}
|
|
77
|
+
img { object-fit: cover; }
|
|
78
|
+
.badge {
|
|
79
|
+
position: absolute;
|
|
80
|
+
right: var(--avatar-badge-inset);
|
|
81
|
+
bottom: var(--avatar-badge-inset);
|
|
82
|
+
inline-size: var(--avatar-badge-size);
|
|
83
|
+
block-size: var(--avatar-badge-size);
|
|
84
|
+
border-radius: 50%;
|
|
85
|
+
background: var(--avatar-badge-color);
|
|
86
|
+
}
|
|
87
|
+
`;
|
|
88
|
+
function register_a_avatar() {
|
|
89
|
+
if (typeof customElements === "undefined") return;
|
|
90
|
+
if (!customElements.get("a-avatar")) {
|
|
91
|
+
customElements.define("a-avatar", AAvatarElement);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
register_a_avatar();
|
|
95
|
+
export {
|
|
96
|
+
AAvatarElement,
|
|
97
|
+
register_a_avatar
|
|
98
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer anta{a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]){--button-primary-fg: #ffffff;--bg-primary-disabled: #ece9ec;--bg-secondary-disabled: #f6f4f6;--fg-disabled-primary: #afa9b1;--fg-disabled: #afa9b1;--button-loading-stripe: 14px;--button-loading-stripe-gap: 16px;--button-loading-period: calc( var(--button-loading-stripe) + var(--button-loading-stripe-gap) );--button-loading-angle: 125deg;--button-loading-x-period: calc( var(--button-loading-period) / cos(var(--button-loading-angle) - 90deg) );--button-loading-opacity: .15;--button-loading-blur: 5px;--_src: var(--anta-seed-neutral);--_tone-pl-rest: .5;--_tone-pl-hover: .45;--_tone-pl-active: .4;--_tone-pl-c: .02;--_tone-fg-l: .46;--_tone-fg-strong-l: .4;--_tone-fg-c: .008;--_tone-fg-shift: .05;--_tone-bg-l: .54;--_tone-bg-c: .03;--_tone-a-rest: .1;--_tone-a-hover: .15;--_tone-a-active: .2;--_tone-quat-hover-l: .38;--_tone-quat-rest-a: .85;--button-bg-primary-rest: oklch(from var(--_src) var(--_tone-pl-rest) var(--_tone-pl-c) h);--button-bg-primary-hover: oklch(from var(--_src) var(--_tone-pl-hover) var(--_tone-pl-c) h);--button-bg-primary-active: oklch(from var(--_src) var(--_tone-pl-active) var(--_tone-pl-c) h);--button-fg-primary-rest: var(--button-primary-fg);--button-fg-secondary-rest: oklch(from var(--_src) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-secondary-hover: oklch(from var(--_src) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-fg-secondary-l-shift: var(--_tone-fg-shift);--button-fg-tertiary-rest: oklch(from var(--_src) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-tertiary-hover: oklch(from var(--_src) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-bg-tertiary-hover: oklch(from var(--_src) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-a-rest));--button-bg-tertiary-active: oklch(from var(--_src) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-a-hover));--button-fg-quaternary-rest: oklch(from var(--_src) var(--_tone-fg-l) var(--_tone-fg-c) h / var(--_tone-quat-rest-a));--button-fg-quaternary-hover: oklch(from var(--_src) var(--_tone-quat-hover-l) var(--_tone-fg-c) h);--button-bg-secondary-rest: oklch(from var(--_src) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-a-rest));--button-bg-secondary-hover: oklch(from var(--_src) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-a-hover));--button-bg-secondary-active: oklch(from var(--_src) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-a-active));--_fs: 15px;--_lh: 20px;--_pb: 1px;--button-padding-x: 9px;--button-padding-y: calc((8px - var(--_pb)) / 2);--button-timing-in: 75ms ease-in;--button-timing-active: 50ms linear;--button-timing-out: .15s ease-out;--button-loading-duration: .5s}a-button[round],a[role=button][data-anta][round],button[data-anta][round],input[data-anta]:is([type=reset],[type=submit])[round]{--button-round: attr(round type(<length>), 999px);border-radius:var(--button-round, 999px)}a-button[tone]:not([tone=""],[tone=neutral]),a[role=button][data-anta][tone]:not([tone=""],[tone=neutral]),button[data-anta][tone]:not([tone=""],[tone=neutral]),input[data-anta]:is([type=reset],[type=submit])[tone]:not([tone=""],[tone=neutral]){--_tone-pl-rest: .51;--_tone-pl-hover: .46;--_tone-pl-active: .41;--_tone-pl-c: .17;--_tone-fg-l: .46;--_tone-fg-strong-l: .4;--_tone-fg-c: .17;--_tone-fg-shift: .05;--_tone-bg-l: .54;--_tone-bg-c: .17;--_tone-a-rest: .1;--_tone-a-hover: .15;--_tone-a-active: .2;--_tone-quat-hover-l: .38;--_tone-quat-rest-a: .85}a-button[tone=brand],a[role=button][data-anta][tone=brand],button[data-anta][tone=brand],input[data-anta]:is([type=reset],[type=submit])[tone=brand]{--_src: var(--anta-seed-brand)}a-button[tone=info],a[role=button][data-anta][tone=info],button[data-anta][tone=info],input[data-anta]:is([type=reset],[type=submit])[tone=info]{--_src: var(--anta-seed-info)}a-button[tone=success],a[role=button][data-anta][tone=success],button[data-anta][tone=success],input[data-anta]:is([type=reset],[type=submit])[tone=success]{--_src: var(--anta-seed-success)}a-button[tone=warning],a[role=button][data-anta][tone=warning],button[data-anta][tone=warning],input[data-anta]:is([type=reset],[type=submit])[tone=warning]{--_src: var(--anta-seed-warning)}a-button[tone=critical],a[role=button][data-anta][tone=critical],button[data-anta][tone=critical],input[data-anta]:is([type=reset],[type=submit])[tone=critical]{--_src: var(--anta-seed-critical)}a-button[tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]),a[role=button][data-anta][tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]),button[data-anta][tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]),input[data-anta]:is([type=reset],[type=submit])[tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--_src: var(--button-tone-source, attr(tone type(<color>), transparent))}.dark a-button,.dark a[role=button][data-anta],.dark button[data-anta],.dark input[data-anta]:is([type=reset],[type=submit]){--bg-primary-disabled: #272329;--bg-secondary-disabled: #1d1a1e;--fg-disabled-primary: #776e77;--fg-disabled: #635b65;--_tone-pl-rest: .4;--_tone-pl-hover: .44;--_tone-pl-active: .48;--_tone-pl-c: .015;--_tone-fg-l: .86;--_tone-fg-strong-l: .86;--_tone-fg-c: .015;--_tone-fg-shift: 0;--_tone-bg-l: .44;--_tone-bg-c: .01;--_tone-a-rest: .24;--_tone-a-hover: .34;--_tone-a-active: .44;--_tone-quat-hover-l: .9;--_tone-quat-rest-a: .85}.dark a-button[tone]:not([tone=""],[tone=neutral]),.dark a[role=button][data-anta][tone]:not([tone=""],[tone=neutral]),.dark button[data-anta][tone]:not([tone=""],[tone=neutral]),.dark input[data-anta]:is([type=reset],[type=submit])[tone]:not([tone=""],[tone=neutral]){--_tone-pl-rest: .4;--_tone-pl-hover: .44;--_tone-pl-active: .48;--_tone-pl-c: .16;--_tone-fg-l: .86;--_tone-fg-strong-l: .86;--_tone-fg-c: .13;--_tone-fg-shift: 0;--_tone-bg-l: .58;--_tone-bg-c: .16;--_tone-a-rest: .215;--_tone-a-hover: .29;--_tone-a-active: .34;--_tone-quat-hover-l: .9;--_tone-quat-rest-a: .85}button[data-anta],input[data-anta]:is([type=reset],[type=submit]){box-sizing:border-box;margin:0;appearance:none;-webkit-appearance:none;border:none}a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]){user-select:none;display:inline-flex;align-items:center;gap:.5ch;overflow:hidden;cursor:pointer;&:has(>a-copy):not(:has(>a-icon)){cursor:copy}flex-shrink:0;color:var(--button-fg);background-color:var(--button-bg);border-radius:4px;text-decoration:none;box-shadow:inset 0 0 1px color-mix(in oklch,currentColor,transparent 90%);font-size:var(--_fs);font-family:var(--sans-serif);font-weight:450;font-variation-settings:"wdth" 88,"slnt" 0,"ital" 0;font-feature-settings:"ss02","ss05","tnum";line-height:var(--_lh);letter-spacing:.05ch;text-overflow:ellipsis;text-wrap:nowrap;white-space:nowrap;max-width:100%;padding-inline:var(--button-padding-x);padding-block:var(--button-padding-y);min-height:28px;>a-button-label{display:inline-block;text-overflow:ellipsis;text-wrap:nowrap;white-space:nowrap;overflow:hidden;min-width:0;line-height:var(--_lh);padding-bottom:var(--_pb);&:has(>*){display:inline-flex;gap:.25ch}}>*{pointer-events:none}& a-icon{transition:color var(--button-timing-out)}transition:color var(--button-timing-out),background-color var(--button-timing-out);&:hover,&:focus-visible{transition:color var(--button-timing-in),background-color var(--button-timing-in);& a-icon{transition:color var(--button-timing-in)}}&:active,&[selected]{transition:color var(--button-timing-active),background-color var(--button-timing-active);& a-icon{transition:color var(--button-timing-active)}}&[disabled]{pointer-events:none;cursor:not-allowed;transition:none;& a-icon{transition:none}}&:focus-visible{outline:1px solid var(--focus-ring);outline-offset:1px}&[priority=quaternary]{--button-timing-in: 0s;--button-timing-active: 0s;--button-timing-out: 0s}&[size=small]{--button-padding-x: 7px;--_fs: 13px;--_lh: 16px;--_pb: .5px;min-height:24px;& a-icon{--icon-size: 14px}}&[size=large]{--button-padding-x: 13px;--_fs: 17px;--_lh: 24px;--_pb: 1.5px;min-height:32px;& a-icon{--icon-size: 18px}}&[priority=tertiary],&[priority=quaternary]{&[underline=solid]{text-decoration:underline solid}&[underline=dashed]{text-decoration:underline dashed}&[underline=dotted]{text-decoration:underline dotted}&[underline]{text-decoration-color:color-mix(in srgb,currentColor 75%,transparent);text-decoration-thickness:1px;text-underline-offset:3px;&[selected]{text-decoration-color:var(--button-fg);text-decoration-thickness:1px}@media(hover:hover)and (pointer:fine){&:hover{text-decoration-color:var(--button-fg);text-decoration-thickness:1px}}}}&[priority=quaternary][paddingless]{--button-padding-x: 0;--button-padding-y: 0;min-height:0}&:has(>a-icon):not(:has(>a-icon~a-icon)):not(:has(>:not(a-icon):not(a-tooltip):not(a-copy))){--button-padding-y: 5px;--button-padding-x: 5px;min-width:28px;justify-content:center;&[size=small]{--button-padding-y: 3px;--button-padding-x: 3px;min-width:24px}&[size=large]{--button-padding-y: 7px;--button-padding-x: 7px;min-width:32px}}&:is(:has(>a-icon:first-child),:has(>a-tooltip:first-child+a-icon)):is(:has(>a-icon~a-icon),:has(>:not(a-icon):not(a-tooltip):not(a-copy))){padding-inline-start:max(0px,var(--button-padding-x) - 2px)}&:is(:has(>a-icon:last-child),:has(>a-icon+a-tooltip:last-child)):is(:has(>a-icon~a-icon),:has(>:not(a-icon):not(a-tooltip):not(a-copy))){padding-inline-end:max(0px,var(--button-padding-x) - 2px)}&[loading]{position:relative;pointer-events:none;cursor:wait;&:before{content:"";position:absolute;top:0;bottom:0;left:calc(0px - var(--button-loading-x-period));right:0;pointer-events:none;background:repeating-linear-gradient(var(--button-loading-angle),transparent 0,transparent var(--button-loading-stripe-gap),currentColor var(--button-loading-stripe-gap),currentColor calc(var(--button-loading-stripe-gap) + var(--button-loading-stripe)));opacity:var(--button-loading-opacity);filter:blur(var(--button-loading-blur));will-change:transform;animation:btn-loading-slide var(--button-loading-duration) linear infinite;animation-delay:-9999s}}--button-fg: oklch(from var(--button-fg-secondary-rest) calc(l - var(--button-fg-secondary-l-shift)) c h);--button-bg: var(--button-bg-secondary-rest);@media(hover:hover)and (pointer:fine){&:hover{--button-fg: var(--button-fg-secondary-hover);--button-bg: var(--button-bg-secondary-hover)}}&:active{--button-fg: var(--button-fg-secondary-hover);--button-bg: var(--button-bg-secondary-active)}&[selected]{--button-fg: var(--button-fg-secondary-hover);--button-bg: var(--button-bg-secondary-hover)}&[priority=primary]{--button-fg: var(--button-fg-primary-rest);--button-bg: var(--button-bg-primary-rest);box-shadow:none;@media(hover:hover)and (pointer:fine){&:hover{--button-bg: var(--button-bg-primary-hover)}}&:active{--button-bg: var(--button-bg-primary-active)}&[selected]{--button-bg: var(--button-bg-primary-hover)}}&[priority=tertiary]{--button-fg: var(--button-fg-tertiary-rest);--button-bg: transparent;box-shadow:none;@media(hover:hover)and (pointer:fine){&:hover{--button-fg: var(--button-fg-tertiary-hover);--button-bg: var(--button-bg-tertiary-hover)}}&:active{--button-fg: var(--button-fg-tertiary-hover);--button-bg: var(--button-bg-tertiary-active)}&[selected]{--button-fg: var(--button-fg-tertiary-hover);--button-bg: var(--button-bg-tertiary-hover)}}&[priority=quaternary]{--button-fg: var(--button-fg-quaternary-rest);--button-bg: transparent;box-shadow:none;font-weight:400;letter-spacing:.06ch;@media(hover:hover)and (pointer:fine){&:hover{--button-fg: var(--button-fg-quaternary-hover)}}&:active{--button-fg: var(--button-fg-quaternary-rest)}&[selected]{--button-fg: var(--button-fg-quaternary-hover)}}&[selected]{box-shadow:inset 0 0 0 .5px currentColor}&[disabled]{background-color:var(--bg-secondary-disabled);color:var(--fg-disabled);&[priority=primary]{background-color:var(--bg-primary-disabled);color:var(--fg-disabled-primary)}&[priority=tertiary],&[priority=quaternary]{background-color:transparent;color:var(--fg-disabled)}}}@media(forced-colors:active){:is(a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit])){--anta-forced-foreground: ButtonText;color:ButtonText;background-color:ButtonFace;border:1px solid ButtonText;box-shadow:none}:is(a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]))[priority=primary]{--anta-forced-foreground: ButtonFace;color:ButtonFace;background-color:ButtonText;border-color:ButtonText}a-button:is([priority=primary],[selected]){forced-color-adjust:none}:is(a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]))[priority=tertiary]{--anta-forced-foreground: CanvasText;color:CanvasText;background-color:Canvas;border:0}@media(hover:hover)and (pointer:fine){:is(a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]))[priority=tertiary]:hover:not(:focus-visible){outline:1px solid ButtonText;outline-offset:0}}:is(a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]))[priority=quaternary]{--anta-forced-foreground: LinkText;color:LinkText;background-color:ButtonFace;border:0;text-decoration:none}:is(a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]))[selected]{--anta-forced-foreground: HighlightText;color:HighlightText;background-color:Highlight;border-color:Highlight}:is(a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]))[disabled]{--anta-forced-foreground: GrayText;color:GrayText;background-color:Canvas;border-color:GrayText;text-decoration-color:GrayText}}}@keyframes btn-loading-slide{to{transform:translate(var(--button-loading-x-period))}}
|
|
1
|
+
@layer anta{a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]){--button-primary-fg: #ffffff;--bg-primary-disabled: #ece9ec;--bg-secondary-disabled: #f6f4f6;--fg-disabled-primary: #afa9b1;--fg-disabled: #afa9b1;--button-loading-stripe: 14px;--button-loading-stripe-gap: 16px;--button-loading-period: calc( var(--button-loading-stripe) + var(--button-loading-stripe-gap) );--button-loading-angle: 125deg;--button-loading-x-period: calc( var(--button-loading-period) / cos(var(--button-loading-angle) - 90deg) );--button-loading-opacity: .15;--button-loading-blur: 5px;--_src: var(--anta-seed-neutral);--_tone-pl-rest: .5;--_tone-pl-hover: .45;--_tone-pl-active: .4;--_tone-pl-c: .02;--_tone-fg-l: .46;--_tone-fg-strong-l: .4;--_tone-fg-c: .008;--_tone-fg-shift: .05;--_tone-bg-l: .54;--_tone-bg-c: .03;--_tone-a-rest: .1;--_tone-a-hover: .15;--_tone-a-active: .2;--_tone-quat-hover-l: .38;--_tone-quat-rest-a: .85;--button-bg-primary-rest: oklch(from var(--_src) var(--_tone-pl-rest) var(--_tone-pl-c) h);--button-bg-primary-hover: oklch(from var(--_src) var(--_tone-pl-hover) var(--_tone-pl-c) h);--button-bg-primary-active: oklch(from var(--_src) var(--_tone-pl-active) var(--_tone-pl-c) h);--button-fg-primary-rest: var(--button-primary-fg);--button-fg-secondary-rest: oklch(from var(--_src) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-secondary-hover: oklch(from var(--_src) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-fg-secondary-l-shift: var(--_tone-fg-shift);--button-fg-tertiary-rest: oklch(from var(--_src) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-tertiary-hover: oklch(from var(--_src) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-bg-tertiary-hover: oklch(from var(--_src) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-a-rest));--button-bg-tertiary-active: oklch(from var(--_src) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-a-hover));--button-fg-quaternary-rest: oklch(from var(--_src) var(--_tone-fg-l) var(--_tone-fg-c) h / var(--_tone-quat-rest-a));--button-fg-quaternary-hover: oklch(from var(--_src) var(--_tone-quat-hover-l) var(--_tone-fg-c) h);--button-bg-secondary-rest: oklch(from var(--_src) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-a-rest));--button-bg-secondary-hover: oklch(from var(--_src) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-a-hover));--button-bg-secondary-active: oklch(from var(--_src) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-a-active));--_fs: 15px;--_lh: 20px;--_pb: 1px;--button-padding-x: 9px;--button-padding-y: calc((8px - var(--_pb)) / 2);--button-timing-in: 75ms ease-in;--button-timing-active: 50ms linear;--button-timing-out: .15s ease-out;--button-loading-duration: .5s}a-button[round],a[role=button][data-anta][round],button[data-anta][round],input[data-anta]:is([type=reset],[type=submit])[round]{--button-round: attr(round type(<length>), 999px);border-radius:var(--button-round, 999px)}a-button[tone]:not([tone=""],[tone=neutral]),a[role=button][data-anta][tone]:not([tone=""],[tone=neutral]),button[data-anta][tone]:not([tone=""],[tone=neutral]),input[data-anta]:is([type=reset],[type=submit])[tone]:not([tone=""],[tone=neutral]){--_tone-pl-rest: .51;--_tone-pl-hover: .46;--_tone-pl-active: .41;--_tone-pl-c: .17;--_tone-fg-l: .46;--_tone-fg-strong-l: .4;--_tone-fg-c: .17;--_tone-fg-shift: .05;--_tone-bg-l: .54;--_tone-bg-c: .17;--_tone-a-rest: .1;--_tone-a-hover: .15;--_tone-a-active: .2;--_tone-quat-hover-l: .38;--_tone-quat-rest-a: .85}a-button[tone=brand],a[role=button][data-anta][tone=brand],button[data-anta][tone=brand],input[data-anta]:is([type=reset],[type=submit])[tone=brand]{--_src: var(--anta-seed-brand)}a-button[tone=info],a[role=button][data-anta][tone=info],button[data-anta][tone=info],input[data-anta]:is([type=reset],[type=submit])[tone=info]{--_src: var(--anta-seed-info)}a-button[tone=success],a[role=button][data-anta][tone=success],button[data-anta][tone=success],input[data-anta]:is([type=reset],[type=submit])[tone=success]{--_src: var(--anta-seed-success)}a-button[tone=warning],a[role=button][data-anta][tone=warning],button[data-anta][tone=warning],input[data-anta]:is([type=reset],[type=submit])[tone=warning]{--_src: var(--anta-seed-warning)}a-button[tone=critical],a[role=button][data-anta][tone=critical],button[data-anta][tone=critical],input[data-anta]:is([type=reset],[type=submit])[tone=critical]{--_src: var(--anta-seed-critical)}a-button[tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]),a[role=button][data-anta][tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]),button[data-anta][tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]),input[data-anta]:is([type=reset],[type=submit])[tone]:not([tone=""],[tone=neutral],[tone=brand],[tone=info],[tone=success],[tone=warning],[tone=critical]){--_src: var(--button-tone-source, attr(tone type(<color>), transparent))}.dark a-button,.dark a[role=button][data-anta],.dark button[data-anta],.dark input[data-anta]:is([type=reset],[type=submit]){--bg-primary-disabled: #272329;--bg-secondary-disabled: #1d1a1e;--fg-disabled-primary: #776e77;--fg-disabled: #635b65;--_tone-pl-rest: .4;--_tone-pl-hover: .44;--_tone-pl-active: .48;--_tone-pl-c: .015;--_tone-fg-l: .86;--_tone-fg-strong-l: .86;--_tone-fg-c: .015;--_tone-fg-shift: 0;--_tone-bg-l: .44;--_tone-bg-c: .01;--_tone-a-rest: .24;--_tone-a-hover: .34;--_tone-a-active: .44;--_tone-quat-hover-l: .9;--_tone-quat-rest-a: .85}.dark a-button[tone]:not([tone=""],[tone=neutral]),.dark a[role=button][data-anta][tone]:not([tone=""],[tone=neutral]),.dark button[data-anta][tone]:not([tone=""],[tone=neutral]),.dark input[data-anta]:is([type=reset],[type=submit])[tone]:not([tone=""],[tone=neutral]){--_tone-pl-rest: .4;--_tone-pl-hover: .44;--_tone-pl-active: .48;--_tone-pl-c: .16;--_tone-fg-l: .86;--_tone-fg-strong-l: .86;--_tone-fg-c: .13;--_tone-fg-shift: 0;--_tone-bg-l: .58;--_tone-bg-c: .16;--_tone-a-rest: .215;--_tone-a-hover: .29;--_tone-a-active: .34;--_tone-quat-hover-l: .9;--_tone-quat-rest-a: .85}button[data-anta],input[data-anta]:is([type=reset],[type=submit]){box-sizing:border-box;margin:0;appearance:none;-webkit-appearance:none;border:none}a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]){user-select:none;display:inline-flex;align-items:center;gap:.5ch;overflow:hidden;cursor:pointer;&:has(>a-copy):not(:has(>a-icon)){cursor:copy}flex-shrink:0;color:var(--button-fg);background-color:var(--button-bg);border-radius:4px;text-decoration:none;box-shadow:inset 0 0 1px color-mix(in oklch,currentColor,transparent 90%);font-size:var(--_fs);font-family:var(--sans-serif);font-weight:450;font-variation-settings:"wdth" 88,"slnt" 0,"ital" 0;font-feature-settings:"ss02","ss05","tnum";line-height:var(--_lh);letter-spacing:.05ch;text-overflow:ellipsis;text-wrap:nowrap;white-space:nowrap;max-width:100%;padding-inline:var(--button-padding-x);padding-block:var(--button-padding-y);min-height:28px;>a-button-label{display:inline-block;text-overflow:ellipsis;text-wrap:nowrap;white-space:nowrap;overflow:hidden;min-width:0;line-height:var(--_lh);padding-bottom:var(--_pb);&:has(>*){display:inline-flex;gap:.25ch}}>*{pointer-events:none}& a-icon{transition:color var(--button-timing-out)}transition:color var(--button-timing-out),background-color var(--button-timing-out);&:hover,&:focus-visible{transition:color var(--button-timing-in),background-color var(--button-timing-in);& a-icon{transition:color var(--button-timing-in)}}&:active,&[selected]{transition:color var(--button-timing-active),background-color var(--button-timing-active);& a-icon{transition:color var(--button-timing-active)}}&[disabled]{pointer-events:none;cursor:not-allowed;transition:none;& a-icon{transition:none}}&:focus-visible{outline:1px solid var(--focus-ring);outline-offset:1px}&[priority=quaternary]{--button-timing-in: 0s;--button-timing-active: 0s;--button-timing-out: 0s}&[size=small]{--button-padding-x: 7px;--_fs: 13px;--_lh: 16px;--_pb: .5px;min-height:24px;& a-icon{--icon-size: 14px}}&[size=large]{--button-padding-x: 13px;--_fs: 17px;--_lh: 24px;--_pb: 1.5px;min-height:32px;& a-icon{--icon-size: 18px}}&[priority=tertiary],&[priority=quaternary]{&[underline=solid]{text-decoration:underline solid}&[underline=dashed]{text-decoration:underline dashed}&[underline=dotted]{text-decoration:underline dotted}&[underline]{text-decoration-color:color-mix(in oklch,currentColor 75%,transparent);text-decoration-thickness:1px;text-underline-offset:3px;&[selected]{text-decoration-color:var(--button-fg);text-decoration-thickness:1px}@media(hover:hover)and (pointer:fine){&:hover{text-decoration-color:var(--button-fg);text-decoration-thickness:1px}}}&[underline][underline-on-hover]{text-decoration-color:transparent;&[selected]{text-decoration-color:transparent}@media(hover:hover)and (pointer:fine){&:hover{text-decoration-color:var(--button-fg)}}}}&[priority=quaternary][paddingless]{--button-padding-x: 0;--button-padding-y: 0;min-height:0}&:has(>a-icon):not(:has(>a-icon~a-icon)):not(:has(>:not(a-icon):not(a-tooltip):not(a-copy))){--button-padding-y: 5px;--button-padding-x: 5px;min-width:28px;justify-content:center;&[size=small]{--button-padding-y: 3px;--button-padding-x: 3px;min-width:24px}&[size=large]{--button-padding-y: 7px;--button-padding-x: 7px;min-width:32px}}&:is(:has(>a-icon:first-child),:has(>a-tooltip:first-child+a-icon)):is(:has(>a-icon~a-icon),:has(>:not(a-icon):not(a-tooltip):not(a-copy))){padding-inline-start:max(0px,var(--button-padding-x) - 2px)}&:is(:has(>a-icon:last-child),:has(>a-icon+a-tooltip:last-child)):is(:has(>a-icon~a-icon),:has(>:not(a-icon):not(a-tooltip):not(a-copy))){padding-inline-end:max(0px,var(--button-padding-x) - 2px)}&[loading]{position:relative;pointer-events:none;cursor:wait;&:before{content:"";position:absolute;top:0;bottom:0;left:calc(0px - var(--button-loading-x-period));right:0;pointer-events:none;background:repeating-linear-gradient(var(--button-loading-angle),transparent 0,transparent var(--button-loading-stripe-gap),currentColor var(--button-loading-stripe-gap),currentColor calc(var(--button-loading-stripe-gap) + var(--button-loading-stripe)));opacity:var(--button-loading-opacity);filter:blur(var(--button-loading-blur));will-change:transform;animation:btn-loading-slide var(--button-loading-duration) linear infinite;animation-delay:-9999s}}--button-fg: oklch(from var(--button-fg-secondary-rest) calc(l - var(--button-fg-secondary-l-shift)) c h);--button-bg: var(--button-bg-secondary-rest);@media(hover:hover)and (pointer:fine){&:hover{--button-fg: var(--button-fg-secondary-hover);--button-bg: var(--button-bg-secondary-hover)}}&:active{--button-fg: var(--button-fg-secondary-hover);--button-bg: var(--button-bg-secondary-active)}&[selected]{--button-fg: var(--button-fg-secondary-hover);--button-bg: var(--button-bg-secondary-hover)}&[priority=primary]{--button-fg: var(--button-fg-primary-rest);--button-bg: var(--button-bg-primary-rest);box-shadow:none;@media(hover:hover)and (pointer:fine){&:hover{--button-bg: var(--button-bg-primary-hover)}}&:active{--button-bg: var(--button-bg-primary-active)}&[selected]{--button-bg: var(--button-bg-primary-hover)}}&[priority=tertiary]{--button-fg: var(--button-fg-tertiary-rest);--button-bg: transparent;box-shadow:none;@media(hover:hover)and (pointer:fine){&:hover{--button-fg: var(--button-fg-tertiary-hover);--button-bg: var(--button-bg-tertiary-hover)}}&:active{--button-fg: var(--button-fg-tertiary-hover);--button-bg: var(--button-bg-tertiary-active)}&[selected]{--button-fg: var(--button-fg-tertiary-hover);--button-bg: var(--button-bg-tertiary-hover)}}&[priority=quaternary]{--button-fg: var(--button-fg-quaternary-rest);--button-bg: transparent;box-shadow:none;font-weight:400;letter-spacing:.06ch;@media(hover:hover)and (pointer:fine){&:hover{--button-fg: var(--button-fg-quaternary-hover)}}&:active{--button-fg: var(--button-fg-quaternary-rest)}&[selected]{--button-fg: var(--button-fg-quaternary-hover)}}&[selected]{box-shadow:inset 0 0 0 .5px currentColor}&[disabled]{background-color:var(--bg-secondary-disabled);color:var(--fg-disabled);&[priority=primary]{background-color:var(--bg-primary-disabled);color:var(--fg-disabled-primary)}&[priority=tertiary],&[priority=quaternary]{background-color:transparent;color:var(--fg-disabled)}}}@media(forced-colors:active){:is(a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit])){--anta-forced-foreground: ButtonText;color:ButtonText;background-color:ButtonFace;border:1px solid ButtonText;box-shadow:none}:is(a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]))[priority=primary]{--anta-forced-foreground: ButtonFace;color:ButtonFace;background-color:ButtonText;border-color:ButtonText}a-button:is([priority=primary],[selected]){forced-color-adjust:none}:is(a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]))[priority=tertiary]{--anta-forced-foreground: CanvasText;color:CanvasText;background-color:Canvas;border:0}@media(hover:hover)and (pointer:fine){:is(a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]))[priority=tertiary]:hover:not(:focus-visible){outline:1px solid ButtonText;outline-offset:0}}:is(a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]))[priority=quaternary]{--anta-forced-foreground: LinkText;color:LinkText;background-color:ButtonFace;border:0;text-decoration:none}:is(a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]))[selected]{--anta-forced-foreground: HighlightText;color:HighlightText;background-color:Highlight;border-color:Highlight}:is(a-button,a[role=button][data-anta],button[data-anta],input[data-anta]:is([type=reset],[type=submit]))[disabled]{--anta-forced-foreground: GrayText;color:GrayText;background-color:Canvas;border-color:GrayText;text-decoration-color:GrayText}}}@keyframes btn-loading-slide{to{transform:translate(var(--button-loading-x-period))}}
|
|
@@ -331,7 +331,9 @@ class ADialogElement extends HTMLElementBase {
|
|
|
331
331
|
this.#wantOpen = true;
|
|
332
332
|
if (this.dialog.open || !this.isConnected) return;
|
|
333
333
|
this.dialog.showModal();
|
|
334
|
-
|
|
334
|
+
const autofocus = this.querySelector("[autofocus]");
|
|
335
|
+
if (autofocus) autofocus.focus({ preventScroll: true });
|
|
336
|
+
else this.dialog.focus();
|
|
335
337
|
}
|
|
336
338
|
/** Raw close. Records the closed intent and counts the pending `close` event as
|
|
337
339
|
* ours so the listener doesn't reconcile it. (The disconnect teardown closes
|