@antadesign/anta 0.3.23 → 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.
Files changed (38) hide show
  1. package/dist/bundle.css +1 -1
  2. package/dist/bundle.js +31 -25
  3. package/dist/components/Breadcrumbs.css +1 -0
  4. package/dist/components/Breadcrumbs.d.ts +127 -0
  5. package/dist/components/Breadcrumbs.js +145 -0
  6. package/dist/components/Button.d.ts +14 -7
  7. package/dist/components/Button.js +2 -0
  8. package/dist/components/Input.d.ts +3 -1
  9. package/dist/components/Input.js +2 -0
  10. package/dist/components/InputTime.d.ts +3 -1
  11. package/dist/components/InputTime.js +2 -0
  12. package/dist/components/MenuItemCopy.d.ts +14 -3
  13. package/dist/components/MenuItemCopy.js +9 -3
  14. package/dist/elements/a-button.css +1 -1
  15. package/dist/elements/a-dialog.js +3 -1
  16. package/dist/elements/a-icon.shapes.css +1 -1
  17. package/dist/elements/a-icon.shapes.d.ts +2 -2
  18. package/dist/elements/a-icon.shapes.js +2 -2
  19. package/dist/elements/a-input-time.d.ts +2 -0
  20. package/dist/elements/a-input-time.js +7 -0
  21. package/dist/elements/a-input.css +1 -1
  22. package/dist/elements/a-input.d.ts +4 -0
  23. package/dist/elements/a-input.js +9 -0
  24. package/dist/general_types.d.ts +6 -0
  25. package/dist/index.d.ts +3 -1
  26. package/dist/index.js +2 -0
  27. package/dist/jsx-runtime.d.ts +2 -0
  28. package/dist/search-index.json +0 -0
  29. package/docs/changelog.md +21 -1
  30. package/docs/comparison.md +8 -3
  31. package/docs/components/breadcrumbs.md +177 -0
  32. package/docs/components/button.md +4 -1
  33. package/docs/components/dialog.md +4 -4
  34. package/docs/components/input-time.md +1 -0
  35. package/docs/components/input.md +1 -0
  36. package/docs/components/menu.md +6 -1
  37. package/docs/index.md +1 -0
  38. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ @layer anta{a-breadcrumbs{--breadcrumb-gap: 1px;--breadcrumb-separator-color: var(--text-5);--breadcrumb-separator-icon-size: 16px;--breadcrumb-separator-font-size: 15px;display:flex;align-items:center;gap:var(--breadcrumb-gap);width:max-content;min-width:100%;max-width:100%;overflow-x:auto}a-breadcrumbs[data-size=small]{--breadcrumb-separator-icon-size: 14px;--breadcrumb-separator-font-size: 13px}a-breadcrumbs[data-size=large]{--breadcrumb-separator-icon-size: 18px;--breadcrumb-separator-font-size: 17px}a-breadcrumbs[data-paddingless]{--breadcrumb-gap: .75ch}a-breadcrumbs[data-separator-icon]{--breadcrumb-gap: 0}a-breadcrumbs>*{flex:none}a-breadcrumb-separator{display:inline-flex;flex:none;align-items:center;justify-content:center;color:var(--breadcrumb-separator-color);font-family:var(--sans-serif);font-size:var(--breadcrumb-separator-font-size);line-height:1;user-select:none}a-breadcrumb-separator>a-icon{--icon-size: var(--breadcrumb-separator-icon-size)}}
@@ -0,0 +1,127 @@
1
+ import type { IconShape } from '../elements/a-icon.shapes';
2
+ import type { BaseProps } from '../general_types';
3
+ import type { BaseButtonProps } from './Button';
4
+ import type { CopyTarget } from './copy-props';
5
+ import './Breadcrumbs.css';
6
+ /** The text separators built into `<Breadcrumbs>`. Pass an `IconShape` for a
7
+ * graphic separator instead. */
8
+ export type BreadcrumbTextSeparator = '→' | '/' | '•' | '▸';
9
+ /** A built-in text separator or any registered Anta icon shape. */
10
+ export type BreadcrumbSeparator = BreadcrumbTextSeparator | IconShape;
11
+ /** Props shared by every breadcrumb item. They land on the visible `Button`
12
+ * and, when the item is folded, on the corresponding `MenuItem`. */
13
+ type BreadcrumbItemBase = Omit<BaseProps, 'children' | 'key' | 'slot' | 'tabIndex'> & {
14
+ /** Visible item content. It is reused as the folded menu row's label. */
15
+ label: React.ReactNode;
16
+ /** Leading icon shape. */
17
+ icon?: IconShape;
18
+ /** Trailing icon shape. Copy items reserve the trailing icon for their copy
19
+ * feedback and therefore do not accept this prop. */
20
+ iconTrailing?: IconShape;
21
+ /** Semantic tone or a literal CSS color. */
22
+ tone?: BaseButtonProps['tone'];
23
+ /** Disable the item. */
24
+ disabled?: boolean;
25
+ /** Mark this item as the current page. The wrapper passes
26
+ * `aria-current="page"` through to its button or link. */
27
+ current?: boolean;
28
+ /** Runs when an action item is activated. A folded item calls it from the
29
+ * corresponding `MenuItem` selection. */
30
+ onClick?: (event: any) => void;
31
+ };
32
+ /** A breadcrumb that navigates to an href. */
33
+ export type BreadcrumbLinkItem = BreadcrumbItemBase & {
34
+ /** Destination URL. */
35
+ href: string;
36
+ /** Where to open the destination. */
37
+ target?: string;
38
+ copy?: never;
39
+ copyNode?: never;
40
+ copyUrl?: never;
41
+ };
42
+ /** A non-navigating breadcrumb action. */
43
+ export type BreadcrumbActionItem = BreadcrumbItemBase & {
44
+ href?: never;
45
+ target?: never;
46
+ copy?: never;
47
+ copyNode?: never;
48
+ copyUrl?: never;
49
+ };
50
+ /** A breadcrumb that copies a literal value, a marked DOM region, or the page
51
+ * URL. It uses `ButtonCopy` when visible and `MenuItemCopy` when folded. */
52
+ export type BreadcrumbCopyItem = Omit<BreadcrumbItemBase, 'iconTrailing'> & CopyTarget & {
53
+ href?: never;
54
+ target?: never;
55
+ iconTrailing?: never;
56
+ /** Where the copy glyph sits relative to the label — or `'none'` to omit it.
57
+ * @defaultValue 'leading' */
58
+ iconPlacement?: 'leading' | 'trailing' | 'none';
59
+ /** Text in the successful no-icon confirmation.
60
+ * @defaultValue Copied */
61
+ copiedLabel?: string;
62
+ };
63
+ /** One item in a `<Breadcrumbs>` trail. Link, action, and copy items share
64
+ * presentation props while keeping incompatible behaviours type-safe. */
65
+ export type BreadcrumbItem = BreadcrumbLinkItem | BreadcrumbActionItem | BreadcrumbCopyItem;
66
+ /** Public props for `<Breadcrumbs>`. */
67
+ export type BreadcrumbsProps = BaseProps & {
68
+ children?: never;
69
+ } & {
70
+ /** Ordered breadcrumb entries. */
71
+ items: BreadcrumbItem[];
72
+ /** Button size applied to every visible item and the More control.
73
+ * @defaultValue 'medium' */
74
+ size?: 'small' | 'medium' | 'large';
75
+ /** Separator between visible entries.
76
+ * @defaultValue 'chevron-right' */
77
+ separator?: BreadcrumbSeparator;
78
+ /** Maximum number of original breadcrumb items left visible. The More
79
+ * control does not count. Omit to keep every item visible. */
80
+ maxItems?: number;
81
+ /** Number of original items kept before the More control when `maxItems`
82
+ * collapses the trail. The rest of the visible-item budget is kept from the
83
+ * end, so `0` puts More first.
84
+ * @defaultValue 0 */
85
+ itemsBeforeCollapse?: number;
86
+ /** Accessible name for the More control.
87
+ * @defaultValue 'Show more breadcrumbs' */
88
+ moreLabel?: string;
89
+ } & ({
90
+ /** Button priority applied to every visible item and the More control.
91
+ * @defaultValue quaternary */
92
+ priority?: 'quaternary';
93
+ /** Remove horizontal padding from every visible breadcrumb control. */
94
+ paddingless?: boolean;
95
+ } | {
96
+ /** Button priority applied to every visible item and the More control. */
97
+ priority: 'tertiary';
98
+ paddingless?: never;
99
+ }) & ({
100
+ underline?: never;
101
+ underlineOnHover?: never;
102
+ } | {
103
+ /** Underline style applied to every visible breadcrumb control. */
104
+ underline: 'solid' | 'dashed' | 'dotted';
105
+ /** Hide the underline at rest and reveal it on hover. */
106
+ underlineOnHover?: boolean;
107
+ });
108
+ /**
109
+ * Breadcrumbs — hierarchy navigation assembled from Anta Buttons. Entries can
110
+ * be links, actions, or copy controls; an optional `maxItems` replaces one
111
+ * contiguous range with a More menu without measuring the available width.
112
+ *
113
+ * @example
114
+ * ```tsx
115
+ * <Breadcrumbs
116
+ * maxItems={3}
117
+ * items={[
118
+ * { label: 'Home', href: '/' },
119
+ * { label: 'Projects', href: '/projects' },
120
+ * { label: 'Anta', href: '/projects/anta' },
121
+ * { label: 'Button.tsx', current: true, copy: 'src/components/Button.tsx' },
122
+ * ]}
123
+ * />
124
+ * ```
125
+ */
126
+ export declare const Breadcrumbs: ({ items, priority, size, separator, maxItems, itemsBeforeCollapse, moreLabel, underline, underlineOnHover, paddingless, className, style, "aria-label": ariaLabel, ...rest }: BreadcrumbsProps) => any;
127
+ export {};
@@ -0,0 +1,145 @@
1
+ import { jsx } from "@antadesign/anta/jsx-runtime";
2
+ import { Button } from "./Button";
3
+ import { ButtonCopy } from "./ButtonCopy";
4
+ import { Icon } from "./Icon";
5
+ import { Menu } from "./Menu";
6
+ import { MenuItem } from "./MenuItem";
7
+ import { MenuItemCopy } from "./MenuItemCopy";
8
+ import "./Breadcrumbs.css";
9
+ const TEXT_SEPARATORS = /* @__PURE__ */ new Set(["\u2192", "/", "\u2022", "\u25B8"]);
10
+ function isCopyItem(item) {
11
+ return "copy" in item || "copyNode" in item || "copyUrl" in item;
12
+ }
13
+ function buildEntries(items, maxItems, itemsBeforeCollapse) {
14
+ if (maxItems == null || !Number.isFinite(maxItems))
15
+ return items.map((item) => ({ kind: "item", item }));
16
+ const visibleCount = Math.max(1, Math.floor(maxItems));
17
+ if (items.length <= visibleCount) return items.map((item) => ({ kind: "item", item }));
18
+ const beforeCount = Math.min(
19
+ Math.max(0, Number.isFinite(itemsBeforeCollapse) ? Math.floor(itemsBeforeCollapse) : 0),
20
+ visibleCount - 1
21
+ );
22
+ const afterCount = visibleCount - beforeCount;
23
+ const hidden = items.slice(beforeCount, items.length - afterCount);
24
+ return [
25
+ ...items.slice(0, beforeCount).map((item) => ({ kind: "item", item })),
26
+ { kind: "overflow", items: hidden },
27
+ ...items.slice(items.length - afterCount).map((item) => ({ kind: "item", item }))
28
+ ];
29
+ }
30
+ function currentAttrs(item) {
31
+ return item.current ? { "aria-current": "page" } : {};
32
+ }
33
+ function renderButtonItem(item, priority, size, underline, underlineOnHover, paddingless, key) {
34
+ const { label, current, ...props } = item;
35
+ const a11y = currentAttrs(item);
36
+ if (isCopyItem(item)) {
37
+ const copyProps = {
38
+ ...props,
39
+ priority,
40
+ size,
41
+ underline,
42
+ underlineOnHover,
43
+ paddingless,
44
+ ...a11y
45
+ };
46
+ return /* @__PURE__ */ jsx(ButtonCopy, { ...copyProps, children: label }, key);
47
+ }
48
+ const buttonProps = {
49
+ ...props,
50
+ priority,
51
+ size,
52
+ underline,
53
+ underlineOnHover,
54
+ paddingless,
55
+ ...a11y
56
+ };
57
+ return /* @__PURE__ */ jsx(Button, { ...buttonProps, children: label }, key);
58
+ }
59
+ function renderMenuItem(item, key) {
60
+ const { label, current, onClick, ...props } = item;
61
+ const a11y = currentAttrs(item);
62
+ if (isCopyItem(item)) {
63
+ return /* @__PURE__ */ jsx(
64
+ MenuItemCopy,
65
+ {
66
+ ...props,
67
+ label,
68
+ onSelect: onClick,
69
+ ...a11y
70
+ },
71
+ key
72
+ );
73
+ }
74
+ return /* @__PURE__ */ jsx(
75
+ MenuItem,
76
+ {
77
+ ...props,
78
+ label,
79
+ onSelect: onClick,
80
+ ...a11y
81
+ },
82
+ key
83
+ );
84
+ }
85
+ const Breadcrumbs = ({
86
+ items,
87
+ priority = "quaternary",
88
+ size = "medium",
89
+ separator = "chevron-right",
90
+ maxItems,
91
+ itemsBeforeCollapse = 0,
92
+ moreLabel = "Show more breadcrumbs",
93
+ underline,
94
+ underlineOnHover,
95
+ paddingless,
96
+ className,
97
+ style,
98
+ "aria-label": ariaLabel,
99
+ ...rest
100
+ }) => {
101
+ const entries = buildEntries(items, maxItems, itemsBeforeCollapse);
102
+ const textSeparator = TEXT_SEPARATORS.has(separator);
103
+ const separatorNode = textSeparator ? separator : /* @__PURE__ */ jsx(Icon, { shape: separator });
104
+ return /* @__PURE__ */ jsx(
105
+ "a-breadcrumbs",
106
+ {
107
+ role: "navigation",
108
+ "aria-label": ariaLabel ?? "Breadcrumb",
109
+ "data-size": size === "medium" ? void 0 : size,
110
+ "data-paddingless": paddingless ? "" : void 0,
111
+ "data-separator-icon": textSeparator ? void 0 : "",
112
+ class: className,
113
+ style,
114
+ ...rest,
115
+ children: entries.flatMap((entry, index) => {
116
+ const nodes = entry.kind === "overflow" ? [
117
+ /* @__PURE__ */ jsx(
118
+ Button,
119
+ {
120
+ ...{
121
+ priority,
122
+ size,
123
+ paddingless,
124
+ icon: "more",
125
+ "aria-label": moreLabel,
126
+ "aria-haspopup": "menu"
127
+ }
128
+ },
129
+ `more-${index}`
130
+ ),
131
+ /* @__PURE__ */ jsx(Menu, { autoWidth: true, children: entry.items.map((item, hiddenIndex) => renderMenuItem(item, hiddenIndex)) }, `menu-${index}`)
132
+ ] : [renderButtonItem(entry.item, priority, size, underline, underlineOnHover, paddingless, index)];
133
+ if (index < entries.length - 1) {
134
+ nodes.push(
135
+ /* @__PURE__ */ jsx("a-breadcrumb-separator", { "aria-hidden": "true", children: separatorNode }, `separator-${index}`)
136
+ );
137
+ }
138
+ return nodes;
139
+ })
140
+ }
141
+ );
142
+ };
143
+ export {
144
+ Breadcrumbs
145
+ };
@@ -94,6 +94,16 @@ export type SubmitMode = {
94
94
  /** Form id when the button isn't a descendant of its form. */
95
95
  form?: string;
96
96
  };
97
+ /** Underline options shared by tertiary and quaternary buttons. */
98
+ export type UnderlineMode = {
99
+ underline?: never;
100
+ underlineOnHover?: never;
101
+ } | {
102
+ /** Underline style. */
103
+ underline: 'solid' | 'dashed' | 'dotted';
104
+ /** Hide the underline at rest and reveal it on hover. */
105
+ underlineOnHover?: boolean;
106
+ };
97
107
  /** Priority axis — `underline` only on `tertiary` / `quaternary`,
98
108
  * `paddingless` only on `quaternary`. */
99
109
  export type PriorityMode = {
@@ -101,16 +111,13 @@ export type PriorityMode = {
101
111
  * @defaultValue secondary */
102
112
  priority?: 'primary' | 'secondary';
103
113
  underline?: never;
114
+ underlineOnHover?: never;
104
115
  paddingless?: never;
105
- } | {
116
+ } | UnderlineMode & {
106
117
  priority: 'tertiary';
107
- /** Underline style. */
108
- underline?: 'solid' | 'dashed' | 'dotted';
109
118
  paddingless?: never;
110
- } | {
119
+ } | UnderlineMode & {
111
120
  priority: 'quaternary';
112
- /** Underline style. */
113
- underline?: 'solid' | 'dashed' | 'dotted';
114
121
  /** Drops outer padding to zero. */
115
122
  paddingless?: boolean;
116
123
  };
@@ -135,4 +142,4 @@ export type ButtonProps = BaseButtonProps & PriorityMode & ContentMode & SubmitM
135
142
  * <Button href="/docs" target="_blank" label="Read the docs" />
136
143
  * ```
137
144
  */
138
- export declare const Button: ({ priority, tone, underline, icon, iconTrailing, paddingless, label, size, loading, disabled, selected, round, onClick, href, target, rel, download, ping, type, form, className, style, children, ...rest }: ButtonProps) => any;
145
+ export declare const Button: ({ priority, tone, underline, underlineOnHover, icon, iconTrailing, paddingless, label, size, loading, disabled, selected, round, onClick, href, target, rel, download, ping, type, form, className, style, children, ...rest }: ButtonProps) => any;
@@ -4,6 +4,7 @@ const Button = ({
4
4
  priority,
5
5
  tone,
6
6
  underline,
7
+ underlineOnHover,
7
8
  icon,
8
9
  iconTrailing,
9
10
  paddingless,
@@ -40,6 +41,7 @@ const Button = ({
40
41
  priority,
41
42
  tone: toneAttr,
42
43
  underline,
44
+ "underline-on-hover": underlineOnHover ? "" : void 0,
43
45
  // 'medium' (and unset) is the implicit default — emit no DOM attr.
44
46
  size: size && size !== "medium" ? size : void 0,
45
47
  // Boolean attributes: emit a presence attribute (empty string) when on,
@@ -88,6 +88,8 @@ export interface InputProps extends BaseProps, DOMEventHandlers {
88
88
  autoComplete?: 'off' | 'on' | 'name' | 'username' | 'email' | 'current-password' | 'new-password' | 'one-time-code' | 'tel' | 'url' | (string & {});
89
89
  /** Virtual-keyboard hint. Overrides the value derived from `type`. */
90
90
  inputMode?: 'none' | 'text' | 'decimal' | 'numeric' | 'tel' | 'search' | 'email' | 'url';
91
+ /** Focus this field when its containing `Dialog` opens. */
92
+ autoFocus?: boolean;
91
93
  /** Form field name — submitted with the form via ElementInternals. */
92
94
  name?: string;
93
95
  /** Placeholder shown when empty. */
@@ -171,4 +173,4 @@ export interface InputProps extends BaseProps, DOMEventHandlers {
171
173
  * <Input label="Email" type="email" placeholder="you@example.com" clearable />
172
174
  * ```
173
175
  */
174
- export declare const Input: ({ label, hint, status, statusIcon, tone, size, round, value, defaultValue, multiline, rows, maxRows, clearable, leading, trailing, type, autoComplete, inputMode, name, placeholder, truncate, disabled, readOnly, required, dimActions, spellCheck, maxLength, minLength, pattern, min, max, step, onInput, onChange, onValueChange, onClearClick, onClearInput, children, className, style, ...rest }: InputProps) => any;
176
+ export declare const Input: ({ label, hint, status, statusIcon, tone, size, round, value, defaultValue, multiline, rows, maxRows, clearable, leading, trailing, type, autoComplete, inputMode, autoFocus, name, placeholder, truncate, disabled, readOnly, required, dimActions, spellCheck, maxLength, minLength, pattern, min, max, step, onInput, onChange, onValueChange, onClearClick, onClearInput, children, className, style, ...rest }: InputProps) => any;
@@ -49,6 +49,7 @@ const Input = ({
49
49
  type,
50
50
  autoComplete,
51
51
  inputMode,
52
+ autoFocus,
52
53
  name,
53
54
  placeholder,
54
55
  truncate = true,
@@ -101,6 +102,7 @@ const Input = ({
101
102
  "dim-actions": presence(dimActions),
102
103
  autocomplete: autoComplete ?? (!multiline && rows == null && type ? AUTOCOMPLETE_BY_TYPE[type] : void 0),
103
104
  inputmode: inputMode ?? (!multiline && rows == null && type ? INPUTMODE_BY_TYPE[type] : void 0),
105
+ autofocus: autoFocus ? true : void 0,
104
106
  spellcheck: spellCheck != null ? spellCheck ? "true" : "false" : void 0,
105
107
  maxlength: maxLength != null ? String(maxLength) : void 0,
106
108
  minlength: minLength != null ? String(minLength) : void 0,
@@ -70,6 +70,8 @@ export interface InputTimeProps extends BaseProps, DOMEventHandlers {
70
70
  trailing?: React.ReactNode;
71
71
  /** Fully-round the field, or a custom radius (`number` px / CSS length). */
72
72
  round?: boolean | number | string;
73
+ /** Focus this field when its containing `Dialog` opens. */
74
+ autoFocus?: boolean;
73
75
  /** Fires on every edit (`input`), with the native event + an `attrs` snapshot
74
76
  * (`value`, `name`, `empty`, `valid`, `validationMessage`). Also fires on
75
77
  * `change` (blur) and on clear. */
@@ -103,4 +105,4 @@ export interface InputTimeProps extends BaseProps, DOMEventHandlers {
103
105
  * <InputTime label="Start" defaultValue="09:30" onValueChange={(_, { value }) => save(value)} />
104
106
  * ```
105
107
  */
106
- export declare const InputTime: ({ label, hint, status, statusIcon, tone, size, round, value, defaultValue, locale, hour12, min, max, name, disabled, required, icon, clearable, dimActions, trailing, onValueChange, onClearInput, children, className, style, ...rest }: InputTimeProps) => any;
108
+ export declare const InputTime: ({ label, hint, status, statusIcon, tone, size, round, value, defaultValue, locale, hour12, min, max, name, disabled, required, icon, clearable, dimActions, trailing, autoFocus, onValueChange, onClearInput, children, className, style, ...rest }: InputTimeProps) => any;
@@ -43,6 +43,7 @@ const InputTime = ({
43
43
  clearable,
44
44
  dimActions,
45
45
  trailing,
46
+ autoFocus,
46
47
  onValueChange,
47
48
  onClearInput,
48
49
  children,
@@ -69,6 +70,7 @@ const InputTime = ({
69
70
  disabled: presence(disabled),
70
71
  required: presence(required),
71
72
  "dim-actions": presence(dimActions),
73
+ autofocus: autoFocus ? true : void 0,
72
74
  "aria-invalid": status === "critical" ? "true" : void 0,
73
75
  oninput: onValueChange ? (e) => onValueChange(e, attrsOf(e)) : void 0,
74
76
  onchange: onValueChange ? (e) => onValueChange(e, attrsOf(e)) : void 0,
@@ -11,7 +11,17 @@ export type MenuItemCopyProps = MenuItemCommonProps & MenuItemActionMode & {
11
11
  selectionIndicator?: never;
12
12
  indeterminate?: never;
13
13
  indicator?: never;
14
- } & CopyTarget;
14
+ iconTrailing?: never;
15
+ } & CopyTarget & {
16
+ /** Where the copy glyph sits relative to the label — or `'none'` to omit it.
17
+ * Without a glyph, a successful copy shows a confirmation label near the
18
+ * pointer and leaves the row unchanged.
19
+ * @defaultValue 'leading' */
20
+ iconPlacement?: 'leading' | 'trailing' | 'none';
21
+ /** Text in the successful no-icon confirmation.
22
+ * @defaultValue Copied */
23
+ copiedLabel?: string;
24
+ };
15
25
  /**
16
26
  * Copying menu item — a `MenuItem` preset for copy-to-clipboard rows inside a
17
27
  * `Menu`. Set `copy` for a literal string, `copyNode` to copy a DOM region, or
@@ -24,7 +34,8 @@ export type MenuItemCopyProps = MenuItemCommonProps & MenuItemActionMode & {
24
34
  * flips the leading icon to a check / ✕ and retones for ~2s (see `useCopyFeedback`).
25
35
  *
26
36
  * Defaults `label` to "Copy" and the leading `icon` to `copy`; override either.
27
- * Other props pass through — `tone`, `kbd`, `onCopied`.
37
+ * `iconPlacement` moves that glyph to the trailing edge or omits it. Other props
38
+ * pass through — `tone`, `kbd`, `onCopied`.
28
39
  *
29
40
  * @example
30
41
  * ```tsx
@@ -34,4 +45,4 @@ export type MenuItemCopyProps = MenuItemCommonProps & MenuItemActionMode & {
34
45
  * </Menu>
35
46
  * ```
36
47
  */
37
- export declare const MenuItemCopy: ({ label, icon, tone, onCopied, onCopyRequest, copy, copyNode, copyUrl, copyWithUrl, children, ...rest }: MenuItemCopyProps) => any;
48
+ export declare const MenuItemCopy: ({ label, icon, iconPlacement, copiedLabel, tone, onCopied, onCopyRequest, copy, copyNode, copyUrl, copyWithUrl, children, ...rest }: MenuItemCopyProps) => any;
@@ -5,6 +5,8 @@ import { copyElementProps, isNodeCopy } from "./copy-props";
5
5
  const MenuItemCopy = ({
6
6
  label = "Copy",
7
7
  icon = "copy",
8
+ iconPlacement = "leading",
9
+ copiedLabel,
8
10
  tone,
9
11
  onCopied,
10
12
  onCopyRequest,
@@ -15,21 +17,25 @@ const MenuItemCopy = ({
15
17
  children,
16
18
  ...rest
17
19
  }) => {
18
- const { shownIcon, shownTone, handleCopied } = useCopyFeedback(icon, tone, onCopied);
20
+ const restingIcon = iconPlacement === "none" ? void 0 : icon;
21
+ const { shownIcon, shownTone, handleCopied } = useCopyFeedback(restingIcon, tone, onCopied);
22
+ const iconSlot = iconPlacement === "trailing" ? { iconTrailing: shownIcon } : iconPlacement === "none" ? {} : { icon: shownIcon };
19
23
  const copyAttrs = copyElementProps({
20
24
  copy,
21
25
  copyNode,
22
26
  copyUrl,
23
27
  copyWithUrl,
24
28
  onCopyRequest,
25
- onCopied: handleCopied
29
+ onCopied: handleCopied,
30
+ toast: iconPlacement === "none",
31
+ copiedLabel
26
32
  });
27
33
  return /* @__PURE__ */ jsxs(
28
34
  MenuItem,
29
35
  {
30
36
  label,
31
- icon: shownIcon,
32
37
  tone: shownTone,
38
+ ...iconSlot,
33
39
  "data-menu-open": "",
34
40
  "data-copy-node-button": isNodeCopy({ copyNode }) ? "" : void 0,
35
41
  ...rest,
@@ -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
- if (!this.querySelector("[autofocus]")) this.dialog.focus();
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