@antadesign/anta 0.3.8 → 0.3.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/anta_helpers.d.ts +18 -0
- package/dist/anta_helpers.js +16 -1
- package/dist/components/Button.d.ts +45 -2
- package/dist/components/Button.js +25 -6
- package/dist/components/ButtonCopy.d.ts +32 -0
- package/dist/components/ButtonCopy.js +10 -0
- package/dist/components/MenuItem.d.ts +66 -32
- package/dist/components/MenuItem.js +50 -11
- package/dist/components/MenuItemCopy.d.ts +33 -0
- package/dist/components/MenuItemCopy.js +10 -0
- package/dist/components/Title.d.ts +11 -7
- package/dist/elements/a-button.css +1 -1
- package/dist/elements/a-button.d.ts +4 -0
- package/dist/elements/a-button.js +8 -0
- package/dist/elements/a-icon.shapes.css +1 -1
- package/dist/elements/a-icon.shapes.d.ts +2 -1
- package/dist/elements/a-icon.shapes.js +1 -0
- package/dist/elements/a-menu-item.css +1 -1
- package/dist/elements/a-menu-item.d.ts +13 -0
- package/dist/elements/a-menu-item.js +16 -6
- package/dist/elements/a-menu.d.ts +6 -0
- package/dist/elements/a-menu.js +14 -4
- package/dist/elements/a-text.css +1 -1
- package/dist/elements/a-title.css +1 -1
- package/dist/elements/copy-behavior.d.ts +36 -0
- package/dist/elements/copy-behavior.js +68 -0
- package/dist/general_types.d.ts +44 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +4 -0
- package/package.json +1 -1
package/dist/anta_helpers.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { IconShape } from "./elements/a-icon.shapes";
|
|
1
2
|
export declare function hasChildren(children: React.ReactNode): boolean;
|
|
2
3
|
/**
|
|
3
4
|
* Normalize a wrapper's label content the way `Button` / `Tabs` do: a bare string
|
|
@@ -74,6 +75,23 @@ export declare function roundStyle(round: boolean | number | string | undefined,
|
|
|
74
75
|
* `false` / `undefined` / `''`). Mirrors what `roundStyle` emits a variable for.
|
|
75
76
|
*/
|
|
76
77
|
export declare function roundAttr(round: boolean | number | string | undefined): '' | undefined;
|
|
78
|
+
/**
|
|
79
|
+
* Copy-feedback state for `ButtonCopy` / `MenuItemCopy` (and any future copy
|
|
80
|
+
* preset). The `<a-button>` / `<a-menu-item>` element performs the clipboard
|
|
81
|
+
* write and fires a `copydone` event; this hook holds the transient result and
|
|
82
|
+
* maps it to the icon + tone the wrapper renders: a `check` / `success` on
|
|
83
|
+
* success, an `x` / `critical` on failure, otherwise the caller's own values.
|
|
84
|
+
* Returns the `handleCopied` listener the wrapper wires to `onCopied`.
|
|
85
|
+
*
|
|
86
|
+
* Kept here (not duplicated per preset) so the timing, glyph choice, and timer
|
|
87
|
+
* cleanup live in one place. Hooks come through the `jsx-runtime` indirection, so
|
|
88
|
+
* a custom non-React runtime supplies its own via `configure()`.
|
|
89
|
+
*/
|
|
90
|
+
export declare function useCopyFeedback(icon: IconShape | undefined, tone: string | undefined, onCopied?: (ok: boolean) => void): {
|
|
91
|
+
shownIcon: IconShape | undefined;
|
|
92
|
+
shownTone: string | undefined;
|
|
93
|
+
handleCopied: (ok: boolean) => void;
|
|
94
|
+
};
|
|
77
95
|
/**
|
|
78
96
|
* The rect a floating-element anchor advertises for positioning. Any element may
|
|
79
97
|
* implement `getAnchorRect(): DOMRect` to point positioners (`a-menu`,
|
package/dist/anta_helpers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx } from "./jsx-runtime";
|
|
1
|
+
import { jsx, useState, useMemo } from "./jsx-runtime";
|
|
2
2
|
function hasChildren(children) {
|
|
3
3
|
return Array.isArray(children) ? children.length > 0 : children != null;
|
|
4
4
|
}
|
|
@@ -40,6 +40,20 @@ function roundStyle(round, varName, base) {
|
|
|
40
40
|
function roundAttr(round) {
|
|
41
41
|
return round || round === 0 ? "" : void 0;
|
|
42
42
|
}
|
|
43
|
+
const COPY_FEEDBACK_MS = 2e3;
|
|
44
|
+
function useCopyFeedback(icon, tone, onCopied) {
|
|
45
|
+
const [status, setStatus] = useState("idle");
|
|
46
|
+
const box = useMemo(() => ({ timer: void 0 }), []);
|
|
47
|
+
const handleCopied = (ok) => {
|
|
48
|
+
clearTimeout(box.timer);
|
|
49
|
+
setStatus(ok ? "ok" : "fail");
|
|
50
|
+
box.timer = setTimeout(() => setStatus("idle"), COPY_FEEDBACK_MS);
|
|
51
|
+
onCopied?.(ok);
|
|
52
|
+
};
|
|
53
|
+
const shownIcon = status === "ok" ? "check" : status === "fail" ? "x" : icon;
|
|
54
|
+
const shownTone = status === "ok" ? "success" : status === "fail" ? "critical" : tone;
|
|
55
|
+
return { shownIcon, shownTone, handleCopied };
|
|
56
|
+
}
|
|
43
57
|
function anchorRect(el) {
|
|
44
58
|
const fn = el.getAnchorRect;
|
|
45
59
|
return typeof fn === "function" ? fn.call(el) : el.getBoundingClientRect();
|
|
@@ -127,5 +141,6 @@ export {
|
|
|
127
141
|
roundStyle,
|
|
128
142
|
setMenuPresence,
|
|
129
143
|
toneStyle,
|
|
144
|
+
useCopyFeedback,
|
|
130
145
|
wrapLabel
|
|
131
146
|
};
|
|
@@ -100,7 +100,50 @@ export type PriorityMode = {
|
|
|
100
100
|
/** Drops outer padding to zero. */
|
|
101
101
|
paddingless?: boolean;
|
|
102
102
|
};
|
|
103
|
-
|
|
103
|
+
/** Copy axis — turns the button into a copy control that writes to the clipboard
|
|
104
|
+
* on click and flashes a success / failure state (see `<a-button>`'s copy
|
|
105
|
+
* behavior). **Exactly one** of `copy`, `copyNode`, or `copyLazy` may be set;
|
|
106
|
+
* the union makes the others `never` in each mode. For the batteries-included
|
|
107
|
+
* preset, use `ButtonCopy`. */
|
|
108
|
+
export type CopyMode = {
|
|
109
|
+
copy?: never;
|
|
110
|
+
copyNode?: never;
|
|
111
|
+
copyLazy?: never;
|
|
112
|
+
onCopied?: never;
|
|
113
|
+
onCopyRequest?: never;
|
|
114
|
+
} | {
|
|
115
|
+
/** Text copied to the clipboard on click. */
|
|
116
|
+
copy: string;
|
|
117
|
+
copyNode?: never;
|
|
118
|
+
copyLazy?: never;
|
|
119
|
+
onCopyRequest?: never;
|
|
120
|
+
/** Fires after the copy attempt with whether it succeeded. */
|
|
121
|
+
onCopied?: (ok: boolean) => void;
|
|
122
|
+
} | {
|
|
123
|
+
/** Copy a DOM node as rich text instead of a string. `true` copies the
|
|
124
|
+
* nearest ancestor marked `data-copy-source`; a string is a CSS selector
|
|
125
|
+
* for an ancestor region (`closest`). The copy control is stripped from
|
|
126
|
+
* the copied output. */
|
|
127
|
+
copyNode: boolean | string;
|
|
128
|
+
copy?: never;
|
|
129
|
+
copyLazy?: never;
|
|
130
|
+
onCopyRequest?: never;
|
|
131
|
+
/** Fires after the copy attempt with whether it succeeded. */
|
|
132
|
+
onCopied?: (ok: boolean) => void;
|
|
133
|
+
} | {
|
|
134
|
+
/** Lazy copy: the content isn't computed or held in the DOM until the
|
|
135
|
+
* click. The click fires `onCopyRequest(provide)`; call `provide(text)`
|
|
136
|
+
* with the value — synchronously, or after an `await` (the browser's
|
|
137
|
+
* transient-activation window still covers the write). */
|
|
138
|
+
copyLazy: true;
|
|
139
|
+
copy?: never;
|
|
140
|
+
copyNode?: never;
|
|
141
|
+
/** Supplies the lazily-computed content on click: call `provide(text)`. */
|
|
142
|
+
onCopyRequest: (provide: (text: string) => void) => void;
|
|
143
|
+
/** Fires after the copy attempt with whether it succeeded. */
|
|
144
|
+
onCopied?: (ok: boolean) => void;
|
|
145
|
+
};
|
|
146
|
+
export type ButtonProps = BaseButtonProps & PriorityMode & ContentMode & SubmitMode & CopyMode & BaseProps;
|
|
104
147
|
/**
|
|
105
148
|
* Action button.
|
|
106
149
|
*
|
|
@@ -121,4 +164,4 @@ export type ButtonProps = BaseButtonProps & PriorityMode & ContentMode & SubmitM
|
|
|
121
164
|
* <Button href="/docs" target="_blank" label="Read the docs" />
|
|
122
165
|
* ```
|
|
123
166
|
*/
|
|
124
|
-
export declare const Button: ({ priority, tone, underline, icon, iconTrailing, paddingless, label, size, loading, disabled, selected, round, href, type, form, className, style, children, ...rest }: ButtonProps) => any;
|
|
167
|
+
export declare const Button: ({ priority, tone, underline, icon, iconTrailing, paddingless, label, size, loading, disabled, selected, round, href, type, form, copy, copyNode, copyLazy, onCopied, onCopyRequest, className, style, children, ...rest }: ButtonProps) => any;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
-
import { toneStyle, roundStyle, roundAttr, wrapLabel } from "../anta_helpers";
|
|
2
|
+
import { toneStyle, roundStyle, roundAttr, wrapLabel, nativeStateChange } from "../anta_helpers";
|
|
3
3
|
const Button = ({
|
|
4
4
|
priority,
|
|
5
5
|
tone,
|
|
@@ -16,14 +16,21 @@ const Button = ({
|
|
|
16
16
|
href,
|
|
17
17
|
type,
|
|
18
18
|
form,
|
|
19
|
+
copy,
|
|
20
|
+
copyNode,
|
|
21
|
+
copyLazy,
|
|
22
|
+
onCopied,
|
|
23
|
+
onCopyRequest,
|
|
19
24
|
className,
|
|
20
25
|
style,
|
|
21
26
|
children,
|
|
22
27
|
...rest
|
|
23
28
|
}) => {
|
|
29
|
+
const isCopy = copy != null || copyNode != null || copyLazy === true;
|
|
24
30
|
const toneAttr = tone || void 0;
|
|
25
31
|
const computedStyle = roundStyle(round, "--button-round", toneStyle(toneAttr, "--button-tone-source", style));
|
|
26
|
-
const
|
|
32
|
+
const leadingIcon = icon ?? (isCopy ? "copy" : void 0);
|
|
33
|
+
const isIconOnly = leadingIcon != null && label == null && children == null && iconTrailing == null;
|
|
27
34
|
const sharedAttrs = {
|
|
28
35
|
// `<a-button>` is a custom element with no implicit ARIA role, so AT would
|
|
29
36
|
// announce it as a generic clickable — and `aria-pressed` below is only
|
|
@@ -53,14 +60,26 @@ const Button = ({
|
|
|
53
60
|
"aria-disabled": disabled || loading ? "true" : void 0,
|
|
54
61
|
"aria-busy": loading ? "true" : void 0,
|
|
55
62
|
"aria-pressed": selected ? "true" : void 0,
|
|
56
|
-
// Icon-only buttons get an accessible name
|
|
57
|
-
//
|
|
58
|
-
|
|
63
|
+
// Icon-only buttons get an accessible name: "Copy" for a copy control (its
|
|
64
|
+
// glyph carries no text), else the icon shape. Consumer's own `aria-label`
|
|
65
|
+
// (via ...rest) wins by spread order.
|
|
66
|
+
"aria-label": isIconOnly ? isCopy ? "Copy" : icon : void 0,
|
|
67
|
+
// Copy behavior — the element reads these and performs the write itself.
|
|
68
|
+
copy: copy != null ? copy : void 0,
|
|
69
|
+
"copy-node": copyNode === true ? "" : typeof copyNode === "string" ? copyNode : void 0,
|
|
70
|
+
"copy-lazy": copyLazy ? "" : void 0,
|
|
71
|
+
// Marks the control so `copy-node` serialization strips it from the copied
|
|
72
|
+
// node (a copy button inside the copied region shouldn't paste itself).
|
|
73
|
+
"data-copy-node-button": copyNode != null && copyNode !== false ? "" : void 0,
|
|
74
|
+
oncopydone: onCopied ? (e) => onCopied(nativeStateChange(e).detail?.ok ?? false) : void 0,
|
|
75
|
+
// The element hands `provide` on the request event; forward it so the
|
|
76
|
+
// consumer supplies the lazily-computed content.
|
|
77
|
+
oncopyrequest: onCopyRequest ? (e) => onCopyRequest(nativeStateChange(e).detail.provide) : void 0,
|
|
59
78
|
class: className,
|
|
60
79
|
style: computedStyle
|
|
61
80
|
};
|
|
62
81
|
const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
63
|
-
|
|
82
|
+
leadingIcon && /* @__PURE__ */ jsx("a-icon", { shape: leadingIcon, "aria-hidden": "true" }),
|
|
64
83
|
label != null && /* @__PURE__ */ jsx("a-button-label", { children: label }),
|
|
65
84
|
wrapLabel(children, "a-button-label"),
|
|
66
85
|
iconTrailing && /* @__PURE__ */ jsx("a-icon", { shape: iconTrailing, "aria-hidden": "true" })
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type ButtonProps } from './Button';
|
|
2
|
+
/** `ButtonProps` narrowed so a copy target is required — a copy button must copy
|
|
3
|
+
* something. Intersecting with the target union drops the "no copy prop" member
|
|
4
|
+
* of `CopyMode` (its `copy?: never` makes each combination `never`). */
|
|
5
|
+
export type ButtonCopyProps = ButtonProps & ({
|
|
6
|
+
copy: string;
|
|
7
|
+
} | {
|
|
8
|
+
copyNode: boolean | string;
|
|
9
|
+
} | {
|
|
10
|
+
copyLazy: true;
|
|
11
|
+
});
|
|
12
|
+
/**
|
|
13
|
+
* Copy button — a `Button` preset for copy-to-clipboard. Set `copy` for a literal
|
|
14
|
+
* string, `copyNode` to copy a DOM region, or `copyLazy` + `onCopyRequest` to
|
|
15
|
+
* compute the content on click. The `<a-button>` element performs the write and
|
|
16
|
+
* reports the result; this wrapper flips the leading icon to a check (success) or
|
|
17
|
+
* ✕ (failure) and retones to `success` / `critical` for ~2s — a JSX re-render, no
|
|
18
|
+
* element state (see `useCopyFeedback`).
|
|
19
|
+
*
|
|
20
|
+
* With a `label` it's a labeled button; without one it's an icon-only copy button.
|
|
21
|
+
* Everything else is a normal `Button` prop — `tone`, `priority`, `size`, `icon`
|
|
22
|
+
* (the resting glyph), `onCopied`.
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```tsx
|
|
26
|
+
* <ButtonCopy copy="npm i @antadesign/anta" label="Copy install" />
|
|
27
|
+
* <ButtonCopy copy="https://anta.design" /> // icon-only
|
|
28
|
+
* <ButtonCopy copyNode=".snippet" label="Copy block" priority="tertiary" />
|
|
29
|
+
* <ButtonCopy copyLazy label="Copy report" onCopyRequest={(p) => p(buildReport())} />
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare const ButtonCopy: ({ icon, tone, onCopied, ...rest }: ButtonCopyProps) => any;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx } from "@antadesign/anta/jsx-runtime";
|
|
2
|
+
import { Button } from "./Button";
|
|
3
|
+
import { useCopyFeedback } from "../anta_helpers";
|
|
4
|
+
const ButtonCopy = ({ icon, tone, onCopied, ...rest }) => {
|
|
5
|
+
const { shownIcon, shownTone, handleCopied } = useCopyFeedback(icon, tone, onCopied);
|
|
6
|
+
return /* @__PURE__ */ jsx(Button, { icon: shownIcon, tone: shownTone, onCopied: handleCopied, ...rest });
|
|
7
|
+
};
|
|
8
|
+
export {
|
|
9
|
+
ButtonCopy
|
|
10
|
+
};
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { BaseProps } from '../general_types';
|
|
2
2
|
import type { IconShape } from '../elements/a-icon.shapes';
|
|
3
|
-
|
|
3
|
+
import type { CopyMode } from './Button';
|
|
4
|
+
/** Props shared by every menu item, link or not. */
|
|
5
|
+
export interface MenuItemCommonProps extends BaseProps {
|
|
4
6
|
/** Leading icon shape. */
|
|
5
7
|
icon?: IconShape;
|
|
6
8
|
/** The item's text. Usually a string, but any node is accepted — e.g. a filtered
|
|
@@ -17,33 +19,15 @@ export interface MenuItemProps extends BaseProps {
|
|
|
17
19
|
* chevron (omit it to keep the chevron); on a normal item it's the trailing
|
|
18
20
|
* glyph (omit for none). */
|
|
19
21
|
iconTrailing?: IconShape;
|
|
20
|
-
/** Disable the item: greyed out, not focusable for activation, no close.
|
|
22
|
+
/** Disable the item: greyed out, not focusable for activation, no close. A
|
|
23
|
+
* disabled link also drops its `href`, so it can't navigate. */
|
|
21
24
|
disabled?: boolean;
|
|
22
25
|
/** Mark the item as selected. On a plain row (no `selectionIndicator`) this is
|
|
23
|
-
* a persistent background tint, the same resting fill a pressed row shows
|
|
24
|
-
*
|
|
25
|
-
* `
|
|
26
|
+
* a persistent background tint, the same resting fill a pressed row shows —
|
|
27
|
+
* also the way to flag the current page on a link item. On a checkable row
|
|
28
|
+
* (`selectionIndicator` set) it instead drives the leading `checkbox` / `radio`
|
|
29
|
+
* indicator and the row's `aria-checked`. */
|
|
26
30
|
selected?: boolean;
|
|
27
|
-
/** Turn the row into a checkable item, driven by `selected` (the row stays the
|
|
28
|
-
* control and carries `aria-checked`):
|
|
29
|
-
* - `'checkbox'` → `role="menuitemcheckbox"`, a leading passive `<a-checkbox>`
|
|
30
|
-
* (before `icon`); the tint is dropped (the box carries state).
|
|
31
|
-
* - `'radio'` → `role="menuitemradio"`, a leading passive `<a-radio>`; tint dropped.
|
|
32
|
-
* - `'check'` → `role="menuitemradio"`, a trailing check glyph on the selected
|
|
33
|
-
* row *and* the background tint (the canonical single-select look).
|
|
34
|
-
* Omit for a plain row (the default). */
|
|
35
|
-
selectionIndicator?: 'checkbox' | 'radio' | 'check';
|
|
36
|
-
/** Only meaningful with `selectionIndicator="checkbox"`: render the box in the
|
|
37
|
-
* mixed state (`aria-checked="mixed"`) — e.g. a "Select all" row when some but
|
|
38
|
-
* not all of its options are selected. */
|
|
39
|
-
indeterminate?: boolean;
|
|
40
|
-
/** Replace the built-in selection-indicator *visual* with your own node,
|
|
41
|
-
* rendered at the **leading** edge (where the checkbox / radio sit). Pair with
|
|
42
|
-
* `selectionIndicator` to keep the semantics — the row stays the control and
|
|
43
|
-
* carries `role` + `aria-checked`; only the drawn mark changes. Suppresses the
|
|
44
|
-
* built-in checkbox / radio and the trailing `check` glyph. The node is made
|
|
45
|
-
* passive (aria-hidden, no pointer events) so the row owns the click. */
|
|
46
|
-
indicator?: React.ReactNode;
|
|
47
31
|
/** Semantic tone — colors the label, icon, and hover/selected tint (and the
|
|
48
32
|
* `checkbox`/`radio` indicator, which adopts it). A named tone, or any literal
|
|
49
33
|
* CSS color (`'#ff1493'`, `'rebeccapurple'`) for a one-off custom tone whose
|
|
@@ -58,10 +42,6 @@ export interface MenuItemProps extends BaseProps {
|
|
|
58
42
|
* `toneSelected` wins over `tone` when both are set.
|
|
59
43
|
* @defaultValue neutral */
|
|
60
44
|
toneSelected?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
|
|
61
|
-
/** Marks this item as a submenu parent: adds the trailing chevron,
|
|
62
|
-
* `aria-haspopup="menu"`, and an `aria-expanded` baseline (kept in sync by
|
|
63
|
-
* the nested menu). Nest the flyout as a `<Menu>` child. */
|
|
64
|
-
submenu?: boolean;
|
|
65
45
|
/** An opaque value identifying this item, handed back in `onSelect`'s detail
|
|
66
46
|
* so a shared handler can tell which row was chosen without a per-item
|
|
67
47
|
* closure. */
|
|
@@ -69,8 +49,9 @@ export interface MenuItemProps extends BaseProps {
|
|
|
69
49
|
/** Activation handler — fires when *this* item is chosen (click / Enter /
|
|
70
50
|
* Space), unless it's `disabled`. It does **not** fire for a submenu parent
|
|
71
51
|
* (clicking that opens the flyout, which isn't a selection) nor for a
|
|
72
|
-
* selection bubbling up from a nested submenu.
|
|
73
|
-
* `{ value, label }`
|
|
52
|
+
* selection bubbling up from a nested submenu. On a link item it fires
|
|
53
|
+
* alongside the navigation. Receives the event plus a `{ value, label }`
|
|
54
|
+
* detail. */
|
|
74
55
|
onSelect?: (event: any, detail: {
|
|
75
56
|
value?: string | number;
|
|
76
57
|
label?: React.ReactNode;
|
|
@@ -87,6 +68,59 @@ export interface MenuItemProps extends BaseProps {
|
|
|
87
68
|
* notably the nested `<Menu>` for a submenu parent. */
|
|
88
69
|
children?: React.ReactNode;
|
|
89
70
|
}
|
|
71
|
+
export type MenuItemLinkMode = {
|
|
72
|
+
/** Renders the item as `<a role="menuitem" data-anta-menu-item href>`. */
|
|
73
|
+
href: string;
|
|
74
|
+
/** Anchor target, e.g. `'_blank'`. */
|
|
75
|
+
target?: string;
|
|
76
|
+
/** Anchor rel. */
|
|
77
|
+
rel?: string;
|
|
78
|
+
/** Download the resource instead of navigating: `true` / `''` uses the
|
|
79
|
+
* resource's default filename, a string overrides it. */
|
|
80
|
+
download?: string | boolean;
|
|
81
|
+
/** Space-separated URLs the browser pings on navigation. */
|
|
82
|
+
ping?: string;
|
|
83
|
+
submenu?: never;
|
|
84
|
+
selectionIndicator?: never;
|
|
85
|
+
indeterminate?: never;
|
|
86
|
+
indicator?: never;
|
|
87
|
+
copy?: never;
|
|
88
|
+
copyNode?: never;
|
|
89
|
+
copyLazy?: never;
|
|
90
|
+
onCopied?: never;
|
|
91
|
+
onCopyRequest?: never;
|
|
92
|
+
};
|
|
93
|
+
export type MenuItemActionMode = {
|
|
94
|
+
href?: never;
|
|
95
|
+
target?: never;
|
|
96
|
+
rel?: never;
|
|
97
|
+
download?: never;
|
|
98
|
+
ping?: never;
|
|
99
|
+
/** Marks this item as a submenu parent: adds the trailing chevron and
|
|
100
|
+
* `aria-haspopup="menu"`. Nest the flyout as a `<Menu>` child. */
|
|
101
|
+
submenu?: boolean;
|
|
102
|
+
/** Turn the row into a checkable item, driven by `selected` (the row stays the
|
|
103
|
+
* control and carries `aria-checked`):
|
|
104
|
+
* - `'checkbox'` → `role="menuitemcheckbox"`, a leading passive `<a-checkbox>`
|
|
105
|
+
* (before `icon`); the tint is dropped (the box carries state).
|
|
106
|
+
* - `'radio'` → `role="menuitemradio"`, a leading passive `<a-radio>`; tint dropped.
|
|
107
|
+
* - `'check'` → `role="menuitemradio"`, a trailing check glyph on the selected
|
|
108
|
+
* row *and* the background tint (the canonical single-select look).
|
|
109
|
+
* Omit for a plain row (the default). */
|
|
110
|
+
selectionIndicator?: 'checkbox' | 'radio' | 'check';
|
|
111
|
+
/** Only meaningful with `selectionIndicator="checkbox"`: render the box in the
|
|
112
|
+
* mixed state (`aria-checked="mixed"`) — e.g. a "Select all" row when some but
|
|
113
|
+
* not all of its options are selected. */
|
|
114
|
+
indeterminate?: boolean;
|
|
115
|
+
/** Replace the built-in selection-indicator *visual* with your own node,
|
|
116
|
+
* rendered at the **leading** edge (where the checkbox / radio sit). Pair with
|
|
117
|
+
* `selectionIndicator` to keep the semantics — the row stays the control and
|
|
118
|
+
* carries `role` + `aria-checked`; only the drawn mark changes. Suppresses the
|
|
119
|
+
* built-in checkbox / radio and the trailing `check` glyph. The node is made
|
|
120
|
+
* passive (aria-hidden, no pointer events) so the row owns the click. */
|
|
121
|
+
indicator?: React.ReactNode;
|
|
122
|
+
};
|
|
123
|
+
export type MenuItemProps = MenuItemCommonProps & (MenuItemLinkMode | (MenuItemActionMode & CopyMode));
|
|
90
124
|
/**
|
|
91
125
|
* MenuItem — a single selectable row inside a `Menu`. Composes a leading
|
|
92
126
|
* `icon`, a `label` (or `children`), an optional trailing `kbd` hint, and an
|
|
@@ -107,4 +141,4 @@ export interface MenuItemProps extends BaseProps {
|
|
|
107
141
|
* </MenuItem>
|
|
108
142
|
* ```
|
|
109
143
|
*/
|
|
110
|
-
export declare const MenuItem: ({ icon, label, hint, kbd, iconTrailing, disabled, selected, selectionIndicator, indeterminate, indicator, tone, toneSelected, submenu, value, onSelect, role: roleOverride, className, style, children, ...rest }: MenuItemProps) => any;
|
|
144
|
+
export declare const MenuItem: ({ icon, label, hint, kbd, iconTrailing, disabled, selected, selectionIndicator, indeterminate, indicator, tone, toneSelected, submenu, value, onSelect, href, target, rel, download, ping, copy, copyNode, copyLazy, onCopied, onCopyRequest, role: roleOverride, className, style, children, ...rest }: MenuItemProps) => any;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
-
import { toneStyle } from "../anta_helpers";
|
|
2
|
+
import { toneStyle, nativeStateChange } from "../anta_helpers";
|
|
3
3
|
const MenuItem = ({
|
|
4
4
|
icon,
|
|
5
5
|
label,
|
|
@@ -16,18 +16,59 @@ const MenuItem = ({
|
|
|
16
16
|
submenu,
|
|
17
17
|
value,
|
|
18
18
|
onSelect,
|
|
19
|
+
href,
|
|
20
|
+
target,
|
|
21
|
+
rel,
|
|
22
|
+
download,
|
|
23
|
+
ping,
|
|
24
|
+
copy,
|
|
25
|
+
copyNode,
|
|
26
|
+
copyLazy,
|
|
27
|
+
onCopied,
|
|
28
|
+
onCopyRequest,
|
|
19
29
|
role: roleOverride,
|
|
20
30
|
className,
|
|
21
31
|
style,
|
|
22
32
|
children,
|
|
23
33
|
...rest
|
|
24
34
|
}) => {
|
|
35
|
+
const isCopy = copy != null || copyNode != null || copyLazy === true;
|
|
36
|
+
const leadingIcon = icon ?? (isCopy ? "copy" : void 0);
|
|
25
37
|
const checkable = selectionIndicator === "checkbox" || selectionIndicator === "radio" || selectionIndicator === "check";
|
|
26
38
|
const role = selectionIndicator === "checkbox" ? "menuitemcheckbox" : selectionIndicator === "radio" || selectionIndicator === "check" ? "menuitemradio" : "menuitem";
|
|
27
39
|
const ariaChecked = !checkable ? void 0 : selectionIndicator === "checkbox" && indeterminate ? "mixed" : selected ? "true" : "false";
|
|
28
40
|
const keepTint = selected && (selectionIndicator === void 0 || selectionIndicator === "check");
|
|
29
41
|
const effectiveTone = selected && toneSelected || tone;
|
|
30
42
|
const toneAttr = effectiveTone && effectiveTone !== "neutral" ? effectiveTone : void 0;
|
|
43
|
+
const labelNode = label != null && (hint != null ? /* @__PURE__ */ jsxs("a-menu-item-text", { children: [
|
|
44
|
+
/* @__PURE__ */ jsx("a-menu-item-label", { children: label }),
|
|
45
|
+
/* @__PURE__ */ jsx("a-menu-item-hint", { children: hint })
|
|
46
|
+
] }) : /* @__PURE__ */ jsx("a-menu-item-label", { children: label }));
|
|
47
|
+
if (href != null) {
|
|
48
|
+
const linkAttrs = {
|
|
49
|
+
"data-anta-menu-item": "",
|
|
50
|
+
role: roleOverride ?? "menuitem",
|
|
51
|
+
href: disabled ? void 0 : href,
|
|
52
|
+
target,
|
|
53
|
+
rel,
|
|
54
|
+
download: download === true ? "" : download || void 0,
|
|
55
|
+
ping,
|
|
56
|
+
tabIndex: disabled ? -1 : 0,
|
|
57
|
+
"aria-disabled": disabled ? "true" : void 0,
|
|
58
|
+
"aria-current": selected ? "true" : void 0,
|
|
59
|
+
tone: toneAttr,
|
|
60
|
+
style: toneStyle(effectiveTone, "--menu-item-tone-source", style),
|
|
61
|
+
onClick: onSelect && !disabled ? (e) => onSelect(e, { value, label }) : void 0,
|
|
62
|
+
class: className
|
|
63
|
+
};
|
|
64
|
+
return /* @__PURE__ */ jsxs("a", { ...linkAttrs, ...rest, children: [
|
|
65
|
+
icon && /* @__PURE__ */ jsx("a-icon", { shape: icon, "aria-hidden": "true" }),
|
|
66
|
+
labelNode,
|
|
67
|
+
children,
|
|
68
|
+
kbd && /* @__PURE__ */ jsx("kbd", { children: kbd }),
|
|
69
|
+
iconTrailing && /* @__PURE__ */ jsx("a-icon", { shape: iconTrailing, "aria-hidden": "true" })
|
|
70
|
+
] });
|
|
71
|
+
}
|
|
31
72
|
return /* @__PURE__ */ jsxs(
|
|
32
73
|
"a-menu-item",
|
|
33
74
|
{
|
|
@@ -42,6 +83,12 @@ const MenuItem = ({
|
|
|
42
83
|
"aria-haspopup": submenu ? "menu" : void 0,
|
|
43
84
|
"aria-disabled": disabled ? "true" : void 0,
|
|
44
85
|
onmenuselect: onSelect ? (e) => onSelect(e, { value, label }) : void 0,
|
|
86
|
+
copy: copy != null ? copy : void 0,
|
|
87
|
+
"copy-node": copyNode === true ? "" : typeof copyNode === "string" ? copyNode : void 0,
|
|
88
|
+
"copy-lazy": copyLazy ? "" : void 0,
|
|
89
|
+
"data-copy-node-button": copyNode != null && copyNode !== false ? "" : void 0,
|
|
90
|
+
oncopydone: onCopied ? (e) => onCopied(nativeStateChange(e).detail?.ok ?? false) : void 0,
|
|
91
|
+
oncopyrequest: onCopyRequest ? (e) => onCopyRequest(nativeStateChange(e).detail.provide) : void 0,
|
|
45
92
|
class: className,
|
|
46
93
|
...rest,
|
|
47
94
|
children: [
|
|
@@ -82,16 +129,8 @@ const MenuItem = ({
|
|
|
82
129
|
}
|
|
83
130
|
)
|
|
84
131
|
) : null,
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
// A hint stacks under the label in a column; the icon / kbd / trailing
|
|
88
|
-
// icon stay in the row (the item's `align-items: center` centers them
|
|
89
|
-
// against the two-line block).
|
|
90
|
-
/* @__PURE__ */ jsxs("a-menu-item-text", { children: [
|
|
91
|
-
/* @__PURE__ */ jsx("a-menu-item-label", { children: label }),
|
|
92
|
-
/* @__PURE__ */ jsx("a-menu-item-hint", { children: hint })
|
|
93
|
-
] })
|
|
94
|
-
) : /* @__PURE__ */ jsx("a-menu-item-label", { children: label })),
|
|
132
|
+
leadingIcon && /* @__PURE__ */ jsx("a-icon", { shape: leadingIcon, "aria-hidden": "true" }),
|
|
133
|
+
labelNode,
|
|
95
134
|
children,
|
|
96
135
|
kbd && /* @__PURE__ */ jsx("kbd", { children: kbd }),
|
|
97
136
|
(() => {
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type MenuItemCommonProps, type MenuItemActionMode } from './MenuItem';
|
|
2
|
+
import type { CopyMode } from './Button';
|
|
3
|
+
/** The action-mode menu-item props plus a required copy target (a copying row
|
|
4
|
+
* must copy something). The target intersection drops `CopyMode`'s "no copy
|
|
5
|
+
* prop" member. */
|
|
6
|
+
export type MenuItemCopyProps = MenuItemCommonProps & MenuItemActionMode & CopyMode & ({
|
|
7
|
+
copy: string;
|
|
8
|
+
} | {
|
|
9
|
+
copyNode: boolean | string;
|
|
10
|
+
} | {
|
|
11
|
+
copyLazy: true;
|
|
12
|
+
});
|
|
13
|
+
/**
|
|
14
|
+
* Copying menu item — a `MenuItem` preset for copy-to-clipboard rows inside a
|
|
15
|
+
* `Menu`. Set `copy` for a literal string, `copyNode` to copy a DOM region, or
|
|
16
|
+
* `copyLazy` + `onCopyRequest` to compute the content on select. The
|
|
17
|
+
* `<a-menu-item>` element performs the write when the row is chosen; this wrapper
|
|
18
|
+
* flips the leading icon to a check / ✕ and retones for ~2s (see `useCopyFeedback`).
|
|
19
|
+
*
|
|
20
|
+
* The menu closes on select by default, so the feedback shows only when the row
|
|
21
|
+
* is kept open (`data-menu-open`). Defaults `label` to "Copy" and the leading
|
|
22
|
+
* `icon` to `copy`; override either. Other props pass through — `tone`, `kbd`,
|
|
23
|
+
* `onCopied`.
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```tsx
|
|
27
|
+
* <Menu>
|
|
28
|
+
* <MenuItemCopy copy={shareUrl} label="Copy link" kbd="⌘C" />
|
|
29
|
+
* <MenuItemCopy copyNode=".invoice" label="Copy invoice" data-menu-open />
|
|
30
|
+
* </Menu>
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare const MenuItemCopy: ({ label, icon, tone, onCopied, ...rest }: MenuItemCopyProps) => any;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx } from "@antadesign/anta/jsx-runtime";
|
|
2
|
+
import { MenuItem } from "./MenuItem";
|
|
3
|
+
import { useCopyFeedback } from "../anta_helpers";
|
|
4
|
+
const MenuItemCopy = ({ label = "Copy", icon = "copy", tone, onCopied, ...rest }) => {
|
|
5
|
+
const { shownIcon, shownTone, handleCopied } = useCopyFeedback(icon, tone, onCopied);
|
|
6
|
+
return /* @__PURE__ */ jsx(MenuItem, { label, icon: shownIcon, tone: shownTone, onCopied: handleCopied, ...rest });
|
|
7
|
+
};
|
|
8
|
+
export {
|
|
9
|
+
MenuItemCopy
|
|
10
|
+
};
|
|
@@ -24,18 +24,22 @@ export interface TitleProps extends BaseProps {
|
|
|
24
24
|
* — so there are no `icon` / `iconTrailing` props; just compose
|
|
25
25
|
* inside.
|
|
26
26
|
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
27
|
+
* `<Title>` carries no vertical margins: it's a spacing-neutral atom
|
|
28
|
+
* that drops into any container, and the parent owns spacing (a `gap`
|
|
29
|
+
* or padding). Raw `<h1>`-`<h6>` do keep per-level top/bottom margins
|
|
30
|
+
* (via `src/reset.css`) for document prose rhythm — so use a real
|
|
31
|
+
* heading tag if SEO matters or you want that built-in rhythm and don't
|
|
32
|
+
* need the `tone` / `priority` props.
|
|
30
33
|
*
|
|
31
34
|
* Styling notes (`a-title.css` ships comment-free): `<a-title>` is
|
|
32
35
|
* intentionally CSS-only — no JS, no shadow DOM, not even
|
|
33
36
|
* `customElements.define`; the browser treats it as a generic unknown
|
|
34
37
|
* element and the CSS gives it block layout, the demi-bold variable-font
|
|
35
|
-
* weight, and the per-level type scale
|
|
36
|
-
* `
|
|
37
|
-
*
|
|
38
|
-
*
|
|
38
|
+
* weight, and the per-level type scale. The matching `h1`–`h6` rules in
|
|
39
|
+
* `src/reset.css` share that type scale and weight, so raw markup reads
|
|
40
|
+
* the same as `<Title level={n}>` — they diverge only on margins: raw
|
|
41
|
+
* headings carry the document vertical rhythm, `<a-title>` is margin-free.
|
|
42
|
+
* The tone × priority color matrix has the same shape as `a-text`'s.
|
|
39
43
|
*
|
|
40
44
|
* Requires `@antadesign/anta/elements` to be imported (client-side only)
|
|
41
45
|
* so the CSS ships with the page.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
@layer anta{a-button,a[role=button][data-anta]{--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: 30px;--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: 2.5px;--button-bg-primary-rest: #635b65;--button-bg-primary-hover: #534c57;--button-bg-primary-active: #49424c;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #45374c12;--button-bg-secondary-hover: #44374b1a;--button-bg-secondary-active: #44374b26;--button-fg-secondary-rest: #534c57;--button-fg-secondary-hover: #49424c;--button-fg-secondary-l-shift: .05;--button-fg-tertiary-rest: #635b65;--button-fg-tertiary-hover: #534c57;--button-bg-tertiary-hover: #44374b0d;--button-bg-tertiary-active: #44374b1a;--button-fg-quaternary-rest: #635b65;--button-fg-quaternary-hover: #49424c;--_fs: 15px;--_lh: 20px;--_pb: 1px;--button-padding-x: 9px;--button-padding-y: calc((8px - var(--_pb)) / 2);--button-max-width: 100%;--button-max-height: 100%;--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-round: attr(round type(<length>), 999px);border-radius:var(--button-round, 999px)}a-button[tone=brand],a[role=button][data-anta][tone=brand]{--button-bg-primary-rest: #5f4bc3;--button-bg-primary-hover: #503cb4;--button-bg-primary-active: #483493;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #7460d71a;--button-bg-secondary-hover: #7460d726;--button-bg-secondary-active: #7460d733;--button-fg-secondary-rest: #5f4bc3;--button-fg-secondary-hover: #503cb4;--button-fg-tertiary-rest: #5f4bc3;--button-fg-tertiary-hover: #503cb4;--button-bg-tertiary-hover: #7460d71a;--button-bg-tertiary-active: #7460d726;--button-fg-quaternary-rest: #5f4bc3;--button-fg-quaternary-hover: #483493}a-button[tone=critical],a[role=button][data-anta][tone=critical]{--button-bg-primary-rest: #c9302c;--button-bg-primary-hover: #b02120;--button-bg-primary-active: #a01c1c;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #de45451a;--button-bg-secondary-hover: #de454526;--button-bg-secondary-active: #de454533;--button-fg-secondary-rest: #c9302c;--button-fg-secondary-hover: #b02120;--button-fg-tertiary-rest: #c9302c;--button-fg-tertiary-hover: #b02120;--button-bg-tertiary-hover: #de45451a;--button-bg-tertiary-active: #de454533;--button-fg-quaternary-rest: #c9302c;--button-fg-quaternary-hover: #a01c1c}a-button[tone=info],a[role=button][data-anta][tone=info]{--button-bg-primary-rest: #1f6eb2;--button-bg-primary-hover: #1a5b93;--button-bg-primary-active: #175082;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #2686d91a;--button-bg-secondary-hover: #2686d926;--button-bg-secondary-active: #2686d933;--button-fg-secondary-rest: #1f6eb2;--button-fg-secondary-hover: #1a5b93;--button-fg-tertiary-rest: #1f6eb2;--button-fg-tertiary-hover: #1a5b93;--button-bg-tertiary-hover: #2686d91a;--button-bg-tertiary-active: #2686d926;--button-fg-quaternary-rest: #1f6eb2;--button-fg-quaternary-hover: #175082}a-button[tone=success],a[role=button][data-anta][tone=success]{--button-bg-primary-rest: #2a7e43;--button-bg-primary-hover: #226737;--button-bg-primary-active: #1f5c31;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #3295501a;--button-bg-secondary-hover: #32955026;--button-bg-secondary-active: #32955033;--button-fg-secondary-rest: #2a7e43;--button-fg-secondary-hover: #226737;--button-fg-tertiary-rest: #2a7e43;--button-fg-tertiary-hover: #226737;--button-bg-tertiary-hover: #3295501a;--button-bg-tertiary-active: #32955026;--button-fg-quaternary-rest: #2a7e43;--button-fg-quaternary-hover: #1f5c31}a-button[tone=warning],a[role=button][data-anta][tone=warning]{--button-bg-primary-rest: #c37416;--button-bg-primary-hover: #ae6613;--button-bg-primary-active: #995200;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #c374161a;--button-bg-secondary-hover: #c3741626;--button-bg-secondary-active: #c3741633;--button-fg-secondary-rest: #c37416;--button-fg-secondary-hover: #ae6613;--button-fg-tertiary-rest: #c37416;--button-fg-tertiary-hover: #ae6613;--button-bg-tertiary-hover: #c374161a;--button-bg-tertiary-active: #c3741633;--button-fg-quaternary-rest: #c37416;--button-fg-quaternary-hover: #995200}.dark a-button,.dark a[role=button][data-anta]{--bg-primary-disabled: #272329;--bg-secondary-disabled: #1d1a1e;--fg-disabled-primary: #776e77;--fg-disabled: #635b65;--button-bg-primary-rest: #534c57;--button-bg-primary-hover: #635b65;--button-bg-primary-active: #938d96;--button-bg-secondary-rest: #e4d1ef1c;--button-bg-secondary-hover: #e4d1ef24;--button-bg-secondary-active: #e4d1ef2e;--button-fg-secondary-rest: #c1b9c1;--button-fg-secondary-hover: #d4ced4;--button-fg-secondary-l-shift: 0;--button-fg-tertiary-rest: #afa9b1;--button-fg-tertiary-hover: #afa9b1;--button-bg-tertiary-hover: #e4d1ef14;--button-bg-tertiary-active: #e4d1ef21;--button-fg-quaternary-rest: #afa9b1;--button-fg-quaternary-hover: #cac4ca}.dark a-button[tone=brand],.dark a[role=button][data-anta][tone=brand]{--button-bg-primary-rest: #503cb4;--button-bg-primary-hover: #5f4bc3;--button-bg-primary-active: #7460d7;--button-bg-secondary-rest: #7460d73b;--button-bg-secondary-hover: #7460d747;--button-bg-secondary-active: #7460d754;--button-fg-secondary-rest: #c5baff;--button-fg-secondary-hover: #d2cbf6;--button-fg-tertiary-rest: #ada0ee;--button-fg-tertiary-hover: #bcb1f1;--button-bg-tertiary-hover: #7460d73b;--button-bg-tertiary-active: #7460d747;--button-fg-quaternary-rest: #ada0ee;--button-fg-quaternary-hover: #c7bef4}.dark a-button[tone=critical],.dark a[role=button][data-anta][tone=critical]{--button-bg-primary-rest: #b02120;--button-bg-primary-hover: #c9302c;--button-bg-primary-active: #de4545;--button-bg-secondary-rest: #de45453b;--button-bg-secondary-hover: #de454547;--button-bg-secondary-active: #de454554;--button-fg-secondary-rest: #ffabac;--button-fg-secondary-hover: #f4c2c2;--button-fg-tertiary-rest: #e78e90;--button-fg-tertiary-hover: #efa4a4;--button-bg-tertiary-hover: #de45453b;--button-bg-tertiary-active: #de454547;--button-fg-quaternary-rest: #e78e90;--button-fg-quaternary-hover: #ffabac}.dark a-button[tone=info],.dark a[role=button][data-anta][tone=info]{--button-bg-primary-rest: #1a5b93;--button-bg-primary-hover: #1f6eb2;--button-bg-primary-active: #2686d9;--button-bg-secondary-rest: #2686d93b;--button-bg-secondary-hover: #2686d947;--button-bg-secondary-active: #2686d954;--button-fg-secondary-rest: #9ed2ff;--button-fg-secondary-hover: #bad6f3;--button-fg-tertiary-rest: #7db6e8;--button-fg-tertiary-hover: #93c5ec;--button-bg-tertiary-hover: #2686d93b;--button-bg-tertiary-active: #2686d947;--button-fg-quaternary-rest: #7db6e8;--button-fg-quaternary-hover: #a6cdef}.dark a-button[tone=success],.dark a[role=button][data-anta][tone=success]{--button-bg-primary-rest: #226737;--button-bg-primary-hover: #2a7e43;--button-bg-primary-active: #329550;--button-bg-secondary-rest: #3295503b;--button-bg-secondary-hover: #32955047;--button-bg-secondary-active: #32955054;--button-fg-secondary-rest: #8ceca9;--button-fg-secondary-hover: #b3e5c2;--button-fg-tertiary-rest: #74cd8e;--button-fg-tertiary-hover: #88d7a0;--button-bg-tertiary-hover: #3295503b;--button-bg-tertiary-active: #32955047;--button-fg-quaternary-rest: #74cd8e;--button-fg-quaternary-hover: #9ddeb1}.dark a-button[tone=warning],.dark a[role=button][data-anta][tone=warning]{--button-bg-primary-rest: #7f410b;--button-bg-primary-hover: #995200;--button-bg-primary-active: #ae6613;--button-bg-secondary-rest: #c374163b;--button-bg-secondary-hover: #c3741647;--button-bg-secondary-active: #c3741654;--button-fg-secondary-rest: #f7c06e;--button-fg-secondary-hover: #f3cc91;--button-fg-tertiary-rest: #e1a452;--button-fg-tertiary-hover: #edb25a;--button-bg-tertiary-hover: #c374163b;--button-bg-tertiary-active: #c3741647;--button-fg-quaternary-rest: #e1a452;--button-fg-quaternary-hover: #f0bf75}a-button,a[role=button][data-anta]{user-select:none;display:inline-flex;align-items:center;gap:.5ch;overflow:hidden;cursor:pointer;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:var(--button-max-width);max-height:var(--button-max-height);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))){--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))){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))){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}}&[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=critical],[tone=info],[tone=success],[tone=warning]){--button-tone-source: attr(tone type(<color>), transparent);--_tone-fg-l: .46;--_tone-fg-strong-l: .4;--_tone-fg-c: .17;--_tone-bg-l: .54;--_tone-bg-c: .16;--_tone-bg-a-rest: .1;--_tone-bg-a-hover: .15;--_tone-bg-a-active: .2;--_tone-primary-l-rest: .5;--_tone-primary-l-hover: .45;--_tone-primary-l-active: .4;--button-bg-primary-rest: oklch(from var(--button-tone-source) var(--_tone-primary-l-rest) c h);--button-bg-primary-hover: oklch(from var(--button-tone-source) var(--_tone-primary-l-hover) c h);--button-bg-primary-active: oklch(from var(--button-tone-source) var(--_tone-primary-l-active) c h);--button-fg-primary-rest: var(--button-primary-fg);--button-fg-secondary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-secondary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-fg-tertiary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-tertiary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-fg-quaternary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-quaternary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-bg-secondary-rest: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-rest));--button-bg-secondary-hover: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-hover));--button-bg-secondary-active: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-active));--button-bg-tertiary-hover: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-rest));--button-bg-tertiary-active: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-hover))}.dark &[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=critical],[tone=info],[tone=success],[tone=warning]){--_tone-fg-l: .78;--_tone-fg-strong-l: .85;--_tone-fg-c: .11;--_tone-bg-l: .58;--_tone-bg-a-rest: .23;--_tone-bg-a-hover: .28;--_tone-bg-a-active: .33;--_tone-primary-l-rest: .45;--_tone-primary-l-hover: .5;--_tone-primary-l-active: .57}--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)}}&[selected]{--button-fg: var(--button-fg-quaternary-hover)}&:active{--button-fg: oklch(from var(--button-fg-quaternary-rest) calc(l + .05) c h)}.dark &:active{--button-fg: var(--button-fg-quaternary-rest)}}&[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)}}}}@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]{--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: 30px;--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: 2.5px;--button-bg-primary-rest: #635b65;--button-bg-primary-hover: #534c57;--button-bg-primary-active: #49424c;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #45374c12;--button-bg-secondary-hover: #44374b1a;--button-bg-secondary-active: #44374b26;--button-fg-secondary-rest: #534c57;--button-fg-secondary-hover: #49424c;--button-fg-secondary-l-shift: .05;--button-fg-tertiary-rest: #635b65;--button-fg-tertiary-hover: #534c57;--button-bg-tertiary-hover: #44374b0d;--button-bg-tertiary-active: #44374b1a;--button-fg-quaternary-rest: #635b65;--button-fg-quaternary-hover: #49424c;--_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]{--button-round: attr(round type(<length>), 999px);border-radius:var(--button-round, 999px)}a-button[tone=brand],a[role=button][data-anta][tone=brand],button[data-anta][tone=brand]{--button-bg-primary-rest: #5f4bc3;--button-bg-primary-hover: #503cb4;--button-bg-primary-active: #483493;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #7460d71a;--button-bg-secondary-hover: #7460d726;--button-bg-secondary-active: #7460d733;--button-fg-secondary-rest: #5f4bc3;--button-fg-secondary-hover: #503cb4;--button-fg-tertiary-rest: #5f4bc3;--button-fg-tertiary-hover: #503cb4;--button-bg-tertiary-hover: #7460d71a;--button-bg-tertiary-active: #7460d726;--button-fg-quaternary-rest: #5f4bc3;--button-fg-quaternary-hover: #483493}a-button[tone=critical],a[role=button][data-anta][tone=critical],button[data-anta][tone=critical]{--button-bg-primary-rest: #c9302c;--button-bg-primary-hover: #b02120;--button-bg-primary-active: #a01c1c;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #de45451a;--button-bg-secondary-hover: #de454526;--button-bg-secondary-active: #de454533;--button-fg-secondary-rest: #c9302c;--button-fg-secondary-hover: #b02120;--button-fg-tertiary-rest: #c9302c;--button-fg-tertiary-hover: #b02120;--button-bg-tertiary-hover: #de45451a;--button-bg-tertiary-active: #de454533;--button-fg-quaternary-rest: #c9302c;--button-fg-quaternary-hover: #a01c1c}a-button[tone=info],a[role=button][data-anta][tone=info],button[data-anta][tone=info]{--button-bg-primary-rest: #1f6eb2;--button-bg-primary-hover: #1a5b93;--button-bg-primary-active: #175082;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #2686d91a;--button-bg-secondary-hover: #2686d926;--button-bg-secondary-active: #2686d933;--button-fg-secondary-rest: #1f6eb2;--button-fg-secondary-hover: #1a5b93;--button-fg-tertiary-rest: #1f6eb2;--button-fg-tertiary-hover: #1a5b93;--button-bg-tertiary-hover: #2686d91a;--button-bg-tertiary-active: #2686d926;--button-fg-quaternary-rest: #1f6eb2;--button-fg-quaternary-hover: #175082}a-button[tone=success],a[role=button][data-anta][tone=success],button[data-anta][tone=success]{--button-bg-primary-rest: #2a7e43;--button-bg-primary-hover: #226737;--button-bg-primary-active: #1f5c31;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #3295501a;--button-bg-secondary-hover: #32955026;--button-bg-secondary-active: #32955033;--button-fg-secondary-rest: #2a7e43;--button-fg-secondary-hover: #226737;--button-fg-tertiary-rest: #2a7e43;--button-fg-tertiary-hover: #226737;--button-bg-tertiary-hover: #3295501a;--button-bg-tertiary-active: #32955026;--button-fg-quaternary-rest: #2a7e43;--button-fg-quaternary-hover: #1f5c31}a-button[tone=warning],a[role=button][data-anta][tone=warning],button[data-anta][tone=warning]{--button-bg-primary-rest: #c37416;--button-bg-primary-hover: #ae6613;--button-bg-primary-active: #995200;--button-fg-primary-rest: var(--button-primary-fg);--button-bg-secondary-rest: #c374161a;--button-bg-secondary-hover: #c3741626;--button-bg-secondary-active: #c3741633;--button-fg-secondary-rest: #c37416;--button-fg-secondary-hover: #ae6613;--button-fg-tertiary-rest: #c37416;--button-fg-tertiary-hover: #ae6613;--button-bg-tertiary-hover: #c374161a;--button-bg-tertiary-active: #c3741633;--button-fg-quaternary-rest: #c37416;--button-fg-quaternary-hover: #995200}.dark a-button,.dark a[role=button][data-anta],.dark button[data-anta]{--bg-primary-disabled: #272329;--bg-secondary-disabled: #1d1a1e;--fg-disabled-primary: #776e77;--fg-disabled: #635b65;--button-bg-primary-rest: #534c57;--button-bg-primary-hover: #635b65;--button-bg-primary-active: #938d96;--button-bg-secondary-rest: #e4d1ef1c;--button-bg-secondary-hover: #e4d1ef24;--button-bg-secondary-active: #e4d1ef2e;--button-fg-secondary-rest: #c1b9c1;--button-fg-secondary-hover: #d4ced4;--button-fg-secondary-l-shift: 0;--button-fg-tertiary-rest: #afa9b1;--button-fg-tertiary-hover: #afa9b1;--button-bg-tertiary-hover: #e4d1ef14;--button-bg-tertiary-active: #e4d1ef21;--button-fg-quaternary-rest: #afa9b1;--button-fg-quaternary-hover: #cac4ca}.dark a-button[tone=brand],.dark a[role=button][data-anta][tone=brand],.dark button[data-anta][tone=brand]{--button-bg-primary-rest: #503cb4;--button-bg-primary-hover: #5f4bc3;--button-bg-primary-active: #7460d7;--button-bg-secondary-rest: #7460d73b;--button-bg-secondary-hover: #7460d747;--button-bg-secondary-active: #7460d754;--button-fg-secondary-rest: #c5baff;--button-fg-secondary-hover: #d2cbf6;--button-fg-tertiary-rest: #ada0ee;--button-fg-tertiary-hover: #bcb1f1;--button-bg-tertiary-hover: #7460d73b;--button-bg-tertiary-active: #7460d747;--button-fg-quaternary-rest: #ada0ee;--button-fg-quaternary-hover: #c7bef4}.dark a-button[tone=critical],.dark a[role=button][data-anta][tone=critical],.dark button[data-anta][tone=critical]{--button-bg-primary-rest: #b02120;--button-bg-primary-hover: #c9302c;--button-bg-primary-active: #de4545;--button-bg-secondary-rest: #de45453b;--button-bg-secondary-hover: #de454547;--button-bg-secondary-active: #de454554;--button-fg-secondary-rest: #ffabac;--button-fg-secondary-hover: #f4c2c2;--button-fg-tertiary-rest: #e78e90;--button-fg-tertiary-hover: #efa4a4;--button-bg-tertiary-hover: #de45453b;--button-bg-tertiary-active: #de454547;--button-fg-quaternary-rest: #e78e90;--button-fg-quaternary-hover: #ffabac}.dark a-button[tone=info],.dark a[role=button][data-anta][tone=info],.dark button[data-anta][tone=info]{--button-bg-primary-rest: #1a5b93;--button-bg-primary-hover: #1f6eb2;--button-bg-primary-active: #2686d9;--button-bg-secondary-rest: #2686d93b;--button-bg-secondary-hover: #2686d947;--button-bg-secondary-active: #2686d954;--button-fg-secondary-rest: #9ed2ff;--button-fg-secondary-hover: #bad6f3;--button-fg-tertiary-rest: #7db6e8;--button-fg-tertiary-hover: #93c5ec;--button-bg-tertiary-hover: #2686d93b;--button-bg-tertiary-active: #2686d947;--button-fg-quaternary-rest: #7db6e8;--button-fg-quaternary-hover: #a6cdef}.dark a-button[tone=success],.dark a[role=button][data-anta][tone=success],.dark button[data-anta][tone=success]{--button-bg-primary-rest: #226737;--button-bg-primary-hover: #2a7e43;--button-bg-primary-active: #329550;--button-bg-secondary-rest: #3295503b;--button-bg-secondary-hover: #32955047;--button-bg-secondary-active: #32955054;--button-fg-secondary-rest: #8ceca9;--button-fg-secondary-hover: #b3e5c2;--button-fg-tertiary-rest: #74cd8e;--button-fg-tertiary-hover: #88d7a0;--button-bg-tertiary-hover: #3295503b;--button-bg-tertiary-active: #32955047;--button-fg-quaternary-rest: #74cd8e;--button-fg-quaternary-hover: #9ddeb1}.dark a-button[tone=warning],.dark a[role=button][data-anta][tone=warning],.dark button[data-anta][tone=warning]{--button-bg-primary-rest: #7f410b;--button-bg-primary-hover: #995200;--button-bg-primary-active: #ae6613;--button-bg-secondary-rest: #c374163b;--button-bg-secondary-hover: #c3741647;--button-bg-secondary-active: #c3741654;--button-fg-secondary-rest: #f7c06e;--button-fg-secondary-hover: #f3cc91;--button-fg-tertiary-rest: #e1a452;--button-fg-tertiary-hover: #edb25a;--button-bg-tertiary-hover: #c374163b;--button-bg-tertiary-active: #c3741647;--button-fg-quaternary-rest: #e1a452;--button-fg-quaternary-hover: #f0bf75}button[data-anta]{box-sizing:border-box;margin:0;appearance:none;-webkit-appearance:none;border:none}a-button,a[role=button][data-anta],button[data-anta]{user-select:none;display:inline-flex;align-items:center;gap:.5ch;overflow:hidden;cursor:pointer;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))){--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))){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))){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}}&[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=critical],[tone=info],[tone=success],[tone=warning]){--button-tone-source: attr(tone type(<color>), transparent);--_tone-fg-l: .46;--_tone-fg-strong-l: .4;--_tone-fg-c: .17;--_tone-bg-l: .54;--_tone-bg-c: .16;--_tone-bg-a-rest: .1;--_tone-bg-a-hover: .15;--_tone-bg-a-active: .2;--_tone-primary-l-rest: .5;--_tone-primary-l-hover: .45;--_tone-primary-l-active: .4;--button-bg-primary-rest: oklch(from var(--button-tone-source) var(--_tone-primary-l-rest) c h);--button-bg-primary-hover: oklch(from var(--button-tone-source) var(--_tone-primary-l-hover) c h);--button-bg-primary-active: oklch(from var(--button-tone-source) var(--_tone-primary-l-active) c h);--button-fg-primary-rest: var(--button-primary-fg);--button-fg-secondary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-secondary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-fg-tertiary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-tertiary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-fg-quaternary-rest: oklch(from var(--button-tone-source) var(--_tone-fg-l) var(--_tone-fg-c) h);--button-fg-quaternary-hover: oklch(from var(--button-tone-source) var(--_tone-fg-strong-l) var(--_tone-fg-c) h);--button-bg-secondary-rest: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-rest));--button-bg-secondary-hover: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-hover));--button-bg-secondary-active: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-active));--button-bg-tertiary-hover: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-rest));--button-bg-tertiary-active: oklch(from var(--button-tone-source) var(--_tone-bg-l) var(--_tone-bg-c) h / var(--_tone-bg-a-hover))}.dark &[tone]:not([tone=""],[tone=brand],[tone=neutral],[tone=critical],[tone=info],[tone=success],[tone=warning]){--_tone-fg-l: .78;--_tone-fg-strong-l: .85;--_tone-fg-c: .11;--_tone-bg-l: .58;--_tone-bg-a-rest: .23;--_tone-bg-a-hover: .28;--_tone-bg-a-active: .33;--_tone-primary-l-rest: .45;--_tone-primary-l-hover: .5;--_tone-primary-l-active: .57}--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)}}&[selected]{--button-fg: var(--button-fg-quaternary-hover)}&:active{--button-fg: oklch(from var(--button-fg-quaternary-rest) calc(l + .05) c h)}.dark &:active{--button-fg: var(--button-fg-quaternary-rest)}}&[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)}}}}@keyframes btn-loading-slide{to{transform:translate(var(--button-loading-x-period))}}
|
|
@@ -63,5 +63,9 @@ declare global {
|
|
|
63
63
|
*/
|
|
64
64
|
export declare class AButtonElement extends HTMLElementBase {
|
|
65
65
|
connectedCallback(): void;
|
|
66
|
+
/** Perform a copy if this button is a copy control (`copy` / `copy-node` /
|
|
67
|
+
* `copy-lazy`). Called from the delegated click handler on activation. The
|
|
68
|
+
* outcome is announced via a `copydone` event the wrapper reflects. */
|
|
69
|
+
performCopy(): boolean;
|
|
66
70
|
}
|
|
67
71
|
export declare function register_a_button(): void;
|