@antadesign/anta 0.3.22 → 0.3.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/avatar-core.d.ts +160 -0
  2. package/dist/avatar-core.js +271 -0
  3. package/dist/bundle.css +1 -0
  4. package/dist/bundle.d.ts +11 -0
  5. package/dist/bundle.js +1245 -0
  6. package/dist/components/Avatar.d.ts +63 -0
  7. package/dist/components/Avatar.js +29 -0
  8. package/dist/components/Breadcrumbs.css +1 -0
  9. package/dist/components/Breadcrumbs.d.ts +127 -0
  10. package/dist/components/Breadcrumbs.js +145 -0
  11. package/dist/components/Button.d.ts +14 -7
  12. package/dist/components/Button.js +2 -0
  13. package/dist/components/Input.d.ts +3 -1
  14. package/dist/components/Input.js +2 -0
  15. package/dist/components/InputTime.d.ts +3 -1
  16. package/dist/components/InputTime.js +2 -0
  17. package/dist/components/Loader.d.ts +5 -1
  18. package/dist/components/Loader.js +2 -1
  19. package/dist/components/MenuItemCopy.d.ts +14 -3
  20. package/dist/components/MenuItemCopy.js +9 -3
  21. package/dist/components/Slider.d.ts +1 -1
  22. package/dist/components/Steps.css +1 -0
  23. package/dist/components/Steps.d.ts +93 -0
  24. package/dist/components/Steps.js +128 -0
  25. package/dist/components/Tabs.d.ts +10 -5
  26. package/dist/components/Tabs.js +5 -2
  27. package/dist/components/Tooltip.d.ts +5 -5
  28. package/dist/elements/a-avatar.css +1 -0
  29. package/dist/elements/a-avatar.d.ts +31 -0
  30. package/dist/elements/a-avatar.js +98 -0
  31. package/dist/elements/a-button.css +1 -1
  32. package/dist/elements/a-dialog.js +3 -1
  33. package/dist/elements/a-icon.shapes.css +1 -1
  34. package/dist/elements/a-icon.shapes.d.ts +2 -9
  35. package/dist/elements/a-icon.shapes.js +2 -16
  36. package/dist/elements/a-input-time.d.ts +2 -0
  37. package/dist/elements/a-input-time.js +7 -0
  38. package/dist/elements/a-input.css +1 -1
  39. package/dist/elements/a-input.d.ts +4 -0
  40. package/dist/elements/a-input.js +9 -0
  41. package/dist/elements/a-loader.css +1 -1
  42. package/dist/elements/a-slider.css +1 -1
  43. package/dist/elements/a-tabs.css +1 -1
  44. package/dist/elements/a-tooltip.d.ts +4 -4
  45. package/dist/elements/a-tooltip.js +18 -15
  46. package/dist/elements/index.d.ts +1 -0
  47. package/dist/elements/index.js +3 -0
  48. package/dist/general_types.d.ts +42 -0
  49. package/dist/index.d.ts +9 -1
  50. package/dist/index.js +30 -0
  51. package/dist/jsx-runtime.d.ts +8 -1
  52. package/dist/search-index.json +0 -0
  53. package/docs/changelog.md +60 -0
  54. package/docs/comparison.md +10 -5
  55. package/docs/components/banner.md +1 -1
  56. package/docs/components/breadcrumbs.md +177 -0
  57. package/docs/components/button.md +7 -4
  58. package/docs/components/card.md +1 -1
  59. package/docs/components/dialog.md +4 -4
  60. package/docs/components/expander.md +1 -1
  61. package/docs/components/input-time.md +1 -0
  62. package/docs/components/input.md +2 -1
  63. package/docs/components/loader.md +1 -0
  64. package/docs/components/menu.md +7 -2
  65. package/docs/components/radio.md +1 -1
  66. package/docs/components/slider.md +1 -1
  67. package/docs/components/steps.md +324 -0
  68. package/docs/components/tabs.md +24 -8
  69. package/docs/components/tag.md +3 -3
  70. package/docs/components/tooltip.md +5 -5
  71. package/docs/index.md +2 -0
  72. package/docs/install-config.md +17 -0
  73. package/package.json +9 -3
@@ -0,0 +1,63 @@
1
+ import type { BaseProps } from "../general_types";
2
+ import type { AvatarGenConfig } from "../avatar-core";
3
+ export interface AvatarProps extends Omit<BaseProps, 'children'> {
4
+ /** Alphanumeric seed that deterministically drives the generated userpic. The
5
+ * same seed always renders the same avatar. Falls back to `name` when omitted,
6
+ * so a stable user id or name is a good value. */
7
+ seed?: string;
8
+ /** Person or entity name. Supplies the initials fallback (up to 3 letters from
9
+ * the first 3 words) and the accessible name, and seeds generation when `seed`
10
+ * is absent. */
11
+ name?: string;
12
+ /** Image URL. When set, the image is shown instead of a generated userpic,
13
+ * cropped to fill the container. */
14
+ src?: string;
15
+ /** Size of the square container. A number is a pixel size.
16
+ * @defaultValue medium */
17
+ size?: 'small' | 'medium' | 'large' | number;
18
+ /** Corner badge, colored by tone. Pass a named tone or any literal CSS color;
19
+ * the application decides what each tone means (`success` for online,
20
+ * `critical` for busy, `neutral` for offline). Omit for no badge. */
21
+ badge?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
22
+ /** Fully-round (circular) frame. Pass a `number` (px) or a CSS length string
23
+ * for a custom radius instead. */
24
+ round?: boolean | number | string;
25
+ /** Brand generation constraints — each dimension is OFF / ANY / RANGE / LIST.
26
+ * Colors cap OKLCH ranges or pass an explicit palette. Omit for the default
27
+ * varied figure. Define one config for the app and reuse it across avatars. */
28
+ generator?: AvatarGenConfig;
29
+ }
30
+ /**
31
+ * Avatar — a userpic container. Shows a supplied image, a seed-generated
32
+ * placeholder figure, or initials, in that priority order.
33
+ *
34
+ * Renders an `<a-avatar>` web component. Generation runs in `avatar-core`; pass a
35
+ * `generator` config to cap the space to your brand (see the color and dimension
36
+ * options on `AvatarGenConfig`). With no `generator`, a varied figure is drawn;
37
+ * a config whose head and body shapes are both `off` renders initials instead.
38
+ *
39
+ * Requires `@antadesign/anta/elements` to be imported (client-side only) to
40
+ * register the underlying custom element.
41
+ *
42
+ * @example Generated userpic
43
+ * ```tsx
44
+ * import { Avatar } from '@antadesign/anta'
45
+ * import '@antadesign/anta/elements'
46
+ *
47
+ * <Avatar seed="user-42" name="Vlad Korobov" />
48
+ * ```
49
+ *
50
+ * @example Image with a badge
51
+ * ```tsx
52
+ * <Avatar src="/vlad.jpg" name="Vlad Korobov" badge="success" />
53
+ * ```
54
+ *
55
+ * @example Initials (no figure shape configured)
56
+ * ```tsx
57
+ * <Avatar
58
+ * name="Vlad Korobov"
59
+ * generator={{ headRadiusTop: { mode: 'off' }, headRadiusBottom: { mode: 'off' }, bodyBorderRadius: { mode: 'off' } }}
60
+ * />
61
+ * ```
62
+ */
63
+ export declare const Avatar: ({ seed, name, src, size, badge, round, generator, className, style, ...rest }: AvatarProps) => any;
@@ -0,0 +1,29 @@
1
+ import { jsx } from "@antadesign/anta/jsx-runtime";
2
+ import { lengthStyle, roundStyle, roundAttr, toneStyle } from "../anta_helpers";
3
+ const Avatar = ({ seed, name, src, size, badge, round, generator, className, style, ...rest }) => {
4
+ const numericSize = typeof size === "number";
5
+ const sized = numericSize ? lengthStyle(size, "--avatar-size", style) : style;
6
+ const rounded = roundStyle(round, "--avatar-radius", sized);
7
+ const mergedStyle = toneStyle(badge, "--avatar-badge-tone-source", rounded);
8
+ return /* @__PURE__ */ jsx(
9
+ "a-avatar",
10
+ {
11
+ seed,
12
+ name,
13
+ src,
14
+ size: !numericSize && size && size !== "medium" ? size : void 0,
15
+ badge,
16
+ round: roundAttr(round),
17
+ config: generator ? JSON.stringify(generator) : void 0,
18
+ role: name ? "img" : void 0,
19
+ "aria-label": name || void 0,
20
+ "aria-hidden": name ? void 0 : "true",
21
+ class: className,
22
+ style: mergedStyle,
23
+ ...rest
24
+ }
25
+ );
26
+ };
27
+ export {
28
+ Avatar
29
+ };
@@ -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,
@@ -1,5 +1,9 @@
1
1
  import type { BaseProps } from '../general_types';
2
+ /** Named Anta color tone for a loader. */
3
+ export type LoaderTone = 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical';
2
4
  export interface LoaderProps extends BaseProps {
5
+ /** Color tone for the loader. Omit it to use the standard text-3 color. */
6
+ tone?: LoaderTone;
3
7
  /** Current progress value. Omit this prop, or pass `false`, for an
4
8
  * indeterminate rotating gradient. */
5
9
  value?: number | false;
@@ -36,4 +40,4 @@ export interface LoaderProps extends BaseProps {
36
40
  * <Loader value={42} label="Uploading files" />
37
41
  * ```
38
42
  */
39
- export declare const Loader: ({ value, max, size, speed, label, className, style, ...rest }: LoaderProps) => any;
43
+ export declare const Loader: ({ tone, value, max, size, speed, label, className, style, ...rest }: LoaderProps) => any;
@@ -1,5 +1,5 @@
1
1
  import { jsx } from "@antadesign/anta/jsx-runtime";
2
- const Loader = ({ value, max = 100, size, speed, label, className, style, ...rest }) => {
2
+ const Loader = ({ tone, value, max = 100, size, speed, label, className, style, ...rest }) => {
3
3
  const determinate = typeof value === "number" && Number.isFinite(value);
4
4
  const safeMax = Number.isFinite(max) && max > 0 ? max : 100;
5
5
  const clampedValue = determinate ? Math.min(safeMax, Math.max(0, value)) : void 0;
@@ -20,6 +20,7 @@ const Loader = ({ value, max = 100, size, speed, label, className, style, ...res
20
20
  return /* @__PURE__ */ jsx(
21
21
  "a-loader",
22
22
  {
23
+ tone,
23
24
  ...determinate ? { value: clampedValue } : {},
24
25
  class: className,
25
26
  style: computedStyle,
@@ -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,
@@ -52,7 +52,7 @@ export interface SliderProps extends BaseProps, DOMEventHandlers {
52
52
  trackSize?: number | string;
53
53
  /** Diameter of the thumb. Numbers use pixels; strings are CSS lengths. Keep
54
54
  * it at least as large as `trackSize`.
55
- * @defaultValue 18 */
55
+ * @defaultValue 16 */
56
56
  thumbSize?: number | string;
57
57
  /** Fill the thumb with its resolved border color. This follows `thumbTone`
58
58
  * and interactive states.
@@ -0,0 +1 @@
1
+ @layer anta{a-steps{--steps-marker-size: 28px;--steps-icon-size: 16px;--steps-marker-border-width: 1.5px;--steps-marker-rest-border: var(--border-4);--steps-item-gap: 6px;--steps-gap: 4px;--steps-connector-color: var(--border-3);--steps-connector-width: 1px;--steps-complete-connector-color: var(--border-2);--steps-tab-padding-x: 9px;--steps-tab-padding-block: 0px;--steps-hint-leading: 16px;display:flex;flex-direction:column;width:100%;min-width:0}a-steps:has(>a-tabs[size=small]){--steps-marker-size: 24px;--steps-icon-size: 14px;--steps-tab-padding-x: 7px;--steps-hint-leading: 14px}a-steps:has(>a-tabs[size=large]){--steps-marker-size: 32px;--steps-icon-size: 18px;--steps-tab-padding-x: 13px;--steps-hint-leading: 20px}a-tabs[data-steps]{--steps-marker-active-border: var(--border-1);--steps-primary-marker-lightness: .5;--steps-primary-marker-chroma: .02;--steps-primary-marker-fg: #ffffff;--tabs-gap: 0px;align-items:center;width:fit-content;align-self:flex-start;overflow-x:auto;scrollbar-width:thin}a-tabs[data-steps][fill]{width:100%;align-self:stretch;justify-content:space-between}a-tabs[data-steps]>a-tab[tone=brand]{--steps-marker-active-border: var(--border-1-brand)}a-tabs[data-steps]>a-tab[tone=info]{--steps-marker-active-border: var(--border-1-info)}a-tabs[data-steps]>a-tab[tone=success]{--steps-marker-active-border: var(--border-1-success)}a-tabs[data-steps]>a-tab[tone=warning]{--steps-marker-active-border: var(--border-1-warning)}a-tabs[data-steps]>a-tab[tone=critical]{--steps-marker-active-border: var(--border-1-critical)}a-tabs[data-steps]>a-tab[tone=neutral]{--steps-marker-active-border: var(--border-1)}a-tabs[data-steps]>a-tab[tone]:not([tone=""],[tone=neutral]){--steps-primary-marker-chroma: .17}.dark a-tabs[data-steps]{--steps-primary-marker-lightness: .4;--steps-primary-marker-chroma: .015}.dark a-tabs[data-steps]>a-tab[tone]:not([tone=""],[tone=neutral]){--steps-primary-marker-chroma: .16}a-tabs[data-steps]:not([priority=secondary],[priority=tertiary]){--steps-marker-border-width: 2px;--steps-marker-rest-border: var(--border-3);--steps-connector-color: var(--border-3);--steps-connector-width: 2px}a-tabs[data-steps][priority=tertiary]{--steps-marker-size: calc(var(--steps-icon-size) + 4px);--steps-marker-border-width: 0px}a-steps>a-tabs[data-steps]{background:transparent;border-radius:0;box-shadow:none}a-tabs[data-steps]>a-tab{--steps-complete-connector-color: var(--tab-selected-border);--steps-primary-marker-bg: oklch( from var(--tabs-tone-source) var(--steps-primary-marker-lightness) var(--steps-primary-marker-chroma) h );--steps-primary-completed-marker-bg: color-mix( in oklch, var(--steps-primary-marker-bg) 80%, transparent );position:relative;flex:1 1 0;min-width:0;max-width:max-content;padding-block:0;justify-content:flex-start;gap:var(--steps-item-gap);transition:color var(--tab-timing),background-color var(--tab-timing),box-shadow var(--tab-timing)}a-steps[data-orientation=vertical]:has(>a-tabs[data-steps]>a-tab:state(selected)[tone=brand]){--steps-complete-connector-color: var(--border-2-brand)}a-steps[data-orientation=vertical]:has(>a-tabs[data-steps]>a-tab:state(selected)[tone=info]){--steps-complete-connector-color: var(--border-2-info)}a-steps[data-orientation=vertical]:has(>a-tabs[data-steps]>a-tab:state(selected)[tone=success]){--steps-complete-connector-color: var(--border-2-success)}a-steps[data-orientation=vertical]:has(>a-tabs[data-steps]>a-tab:state(selected)[tone=warning]){--steps-complete-connector-color: var(--border-2-warning)}a-steps[data-orientation=vertical]:has(>a-tabs[data-steps]>a-tab:state(selected)[tone=critical]){--steps-complete-connector-color: var(--border-2-critical)}a-tabs[data-steps]:not([orientation=vertical])>a-tab:first-child{padding-inline-start:0}a-steps>a-tabs[data-steps][fill]>a-tab:not(:last-child){flex:1 1 0;max-width:none}a-steps>a-tabs[data-steps][fill]>a-tab:last-child{flex:0 1 auto;max-width:max-content}a-steps>a-tabs[data-steps]>a-tab:state(selected){--tab-bg: transparent;box-shadow:none}a-steps>a-tabs[data-steps][priority=tertiary]>a-tab:after{border:0}a-step-desc{display:inline-flex;flex:0 1 auto;flex-direction:column;min-width:0;max-width:100%}a-step-desc>a-tab-label{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:500}a-step-hint{display:block;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--tab-rest-tone, var(--text-3));font-size:calc(1em - 2px);font-weight:400;line-height:var(--steps-hint-leading)}a-step-marker{display:inline-flex;flex:none;align-items:center;justify-content:center;width:var(--steps-marker-size);height:var(--steps-marker-size);box-sizing:border-box;color:var(--text-4);border:var(--steps-marker-border-width) solid var(--steps-marker-rest-border);border-radius:999px;transition:color var(--tab-timing),background-color var(--tab-timing),border-color var(--tab-timing)}a-tabs[data-steps] a-step-marker :is(a-icon,a-loader){--icon-size: var(--steps-icon-size)}a-tabs[data-steps]>a-tab[tone]{--tab-secondary-bg: oklch( from var(--tabs-tone-source) var(--_track-l) var(--_track-c) h / var(--_sec-a) )}a-tabs[data-steps]>a-tab[tone] a-step-marker{color:var(--tab-selected-text)}a-tabs[data-steps]>a-tab:is(:state(selected),[data-step-state=completed]) a-step-marker{border-color:var(--steps-marker-active-border)}a-tabs[data-steps]>a-tab[data-step-state=error]:not(:state(selected)):not([disabled]) a-step-marker{border-color:var(--border-2-critical)}a-tabs[data-steps]:is([priority=secondary],[priority=tertiary])>a-tab[tone]:not([tone=""],[tone=neutral]) a-step-marker{color:var(--tab-fg)}a-tabs[data-steps][priority=secondary] a-tab:state(selected):not([disabled]) a-step-marker{color:var(--tab-selected-text);background-color:var(--tab-secondary-bg);border-color:var(--steps-marker-active-border)}a-tabs[data-steps]:not([priority=secondary],[priority=tertiary]) a-tab:state(selected):not([disabled]) a-step-marker{color:var(--steps-primary-marker-fg);background-color:var(--steps-primary-marker-bg);border-color:var(--steps-primary-marker-bg)}a-tabs[data-steps]:not([priority=secondary],[priority=tertiary]) a-tab[data-step-state=completed]:not(:state(selected)):not([disabled]) a-step-marker{color:var(--steps-primary-marker-fg);background-color:var(--steps-primary-completed-marker-bg);border-color:transparent}a-tabs[data-steps][priority=tertiary] a-tab:state(selected):not([disabled]) a-step-marker{color:var(--tab-selected-text);background-color:transparent;border-color:transparent}a-tabs[data-steps] a-step-marker>a-loader{transition:color var(--tab-timing)}a-tabs[data-steps]:is([priority=secondary],[priority=tertiary]) a-step-marker>a-loader:not([tone=neutral]){color:inherit}a-tabs[data-steps] a-tab:state(selected):not([disabled]) a-step-marker>a-loader{color:inherit}a-tabs[data-steps]:not([orientation=vertical])>a-tab:not(:last-child):before{content:"";order:3;flex:1 1 auto;align-self:center;min-width:calc(var(--steps-marker-size) / 2);height:var(--steps-connector-width);margin-inline-start:calc(1ch - var(--steps-item-gap));margin-inline-end:calc(1ch - 2 * var(--steps-tab-padding-x));background:var(--steps-connector-color);pointer-events:none}a-tabs[data-steps]:not([orientation=vertical])>a-tab[data-step-state=completed]:not(:last-child):before{background:var(--steps-complete-connector-color)}a-tabs[data-steps] a-tab[disabled]{--tab-fg: var(--text-5);opacity:1}a-tabs[data-steps] a-tab[disabled] a-step-marker,a-tabs[data-steps] a-tab[disabled] a-step-marker>a-loader{color:var(--text-5)}a-tabs[data-steps] a-tab[disabled] a-step-hint{color:var(--text-5)}a-steps[data-orientation=vertical]{--steps-content-indent: calc( var(--steps-marker-size) + var(--steps-item-gap) );--steps-vertical-gap: calc(var(--steps-gap) + 4px);display:grid;grid-template-columns:minmax(0,1fr);row-gap:var(--steps-vertical-gap)}a-steps[data-orientation=vertical]>a-tabs[orientation=vertical]{display:contents}a-steps[data-orientation=vertical]>a-tabs[orientation=vertical]>a-tab{flex:none;min-width:0;grid-column:1;width:max-content;max-width:100%;padding-inline-start:0}a-steps[data-orientation=vertical] a-tab:not(:last-child):before{content:"";position:absolute;inset-block-start:calc(var(--steps-tab-padding-block) + var(--steps-marker-size));inset-inline-start:calc(var(--steps-marker-size) / 2 - var(--steps-connector-width) / 2);inset-inline-end:auto;width:var(--steps-connector-width);height:calc(100% - var(--steps-marker-size) + var(--steps-vertical-gap));background:var(--steps-connector-color);transform:none;pointer-events:none}a-steps[data-orientation=vertical]>a-tabpanel{grid-column:1;grid-row:var(--steps-panel-row);width:calc(100% - var(--steps-content-indent));margin-inline-start:var(--steps-content-indent)}a-steps[data-orientation=vertical]:has(>a-tabpanel):has(>a-tabs[orientation=vertical]>a-tab:state(selected):not(:last-child)):after{content:"";grid-column:1;grid-row:var(--steps-panel-row);align-self:stretch;justify-self:start;width:var(--steps-connector-width);min-height:var(--steps-marker-size);margin-inline-start:calc(var(--steps-marker-size) / 2 - var(--steps-connector-width) / 2);margin-block-end:calc(-1 * var(--steps-vertical-gap));background:var(--steps-connector-color);pointer-events:none;z-index:1}a-steps[data-orientation=vertical]>a-tabs[data-steps]>a-tab[data-step-state=completed]:not(:last-child):before{background:var(--steps-complete-connector-color)}a-steps[data-orientation=vertical]:has(>a-tabpanel):has(>a-tabs[data-steps][orientation=vertical]>a-tab[data-step-state=completed]:state(selected):not(:last-child)):after{background:var(--steps-complete-connector-color)}@media(forced-colors:active){a-tabs[data-steps][priority=secondary] a-tab:state(selected){background-color:transparent;border:0;box-shadow:none}a-step-marker{color:CanvasText;background-color:Canvas;border-color:CanvasText}a-tabs[data-steps] a-tab:state(selected):not([disabled]) a-step-marker{border-color:Highlight}}}