@antadesign/anta 0.1.1-dev.8 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/components/Button.js +4 -3
- package/dist/components/Menu.d.ts +61 -0
- package/dist/components/Menu.js +34 -0
- package/dist/components/MenuGroup.d.ts +24 -0
- package/dist/components/MenuGroup.js +19 -0
- package/dist/components/MenuItem.d.ts +49 -0
- package/dist/components/MenuItem.js +40 -0
- package/dist/components/MenuSeparator.d.ts +14 -0
- package/dist/components/MenuSeparator.js +7 -0
- package/dist/components/Tag.d.ts +55 -0
- package/dist/components/Tag.js +40 -0
- package/dist/components/Text.d.ts +4 -2
- package/dist/components/Tooltip.d.ts +4 -2
- package/dist/elements/a-button.css +31 -8
- package/dist/elements/a-icon.shapes.css +4 -0
- package/dist/elements/a-icon.shapes.d.ts +2 -1
- package/dist/elements/a-icon.shapes.js +3 -1
- package/dist/elements/a-menu-group.css +21 -0
- package/dist/elements/a-menu-group.d.ts +13 -0
- package/dist/elements/a-menu-group.js +15 -0
- package/dist/elements/a-menu-item.css +162 -0
- package/dist/elements/a-menu-item.d.ts +27 -0
- package/dist/elements/a-menu-item.js +29 -0
- package/dist/elements/a-menu-separator.css +15 -0
- package/dist/elements/a-menu-separator.d.ts +12 -0
- package/dist/elements/a-menu-separator.js +15 -0
- package/dist/elements/a-menu.css +34 -0
- package/dist/elements/a-menu.d.ts +120 -0
- package/dist/elements/a-menu.js +649 -0
- package/dist/elements/a-tag.css +196 -0
- package/dist/elements/a-text.css +17 -13
- package/dist/elements/a-tooltip.css +21 -1
- package/dist/elements/a-tooltip.d.ts +7 -0
- package/dist/elements/a-tooltip.js +96 -19
- package/dist/elements/index.d.ts +2 -4
- package/dist/elements/index.js +1 -6
- package/dist/general_types.d.ts +15 -35
- package/dist/index.d.ts +2 -4
- package/dist/index.js +2 -4
- package/dist/jsx-runtime.d.ts +6 -5
- package/dist/reset.css +11 -7
- package/package.json +13 -15
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ Anta exposes four independent imports. Tokens + elements + the JSX layer are the
|
|
|
36
36
|
|
|
37
37
|
The chain matters: the per-element CSS that ships with `/elements` references variables like `var(--text-1)` and `var(--bg-2)`. Those variables are *only defined* by `tokens.css`. Skip the tokens import and the components render with whatever the surrounding cascade provides — usually nothing styled at all.
|
|
38
38
|
|
|
39
|
-
`@antadesign/anta/elements` registers **all** elements — convenient, but it includes every element's code (and deps). To keep your bundle lean, import only the elements you use from their per-element entry points instead: `import '@antadesign/anta/elements/a-tooltip'` registers just `<a-tooltip>` **and loads just its CSS**. Unused elements — and
|
|
39
|
+
`@antadesign/anta/elements` registers **all** elements — convenient, but it includes every element's code (and deps). To keep your bundle lean, import only the elements you use from their per-element entry points instead: `import '@antadesign/anta/elements/a-tooltip'` registers just `<a-tooltip>` **and loads just its CSS**. Unused elements — and any dependencies they pull in — then never enter your bundle. See [Registering elements](#registering-elements).
|
|
40
40
|
|
|
41
41
|
### Cascade layers
|
|
42
42
|
|
|
@@ -79,7 +79,7 @@ import '@antadesign/anta/elements/a-tooltip' // only <a-tooltip> + its CSS
|
|
|
79
79
|
import '@antadesign/anta/elements/a-button' // only <a-button> + its CSS
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
Both styles are side-effect imports (the act of importing registers the element), and both are idempotent and SSR-safe. The granular form keeps unused elements — and
|
|
82
|
+
Both styles are side-effect imports (the act of importing registers the element), and both are idempotent and SSR-safe. The granular form keeps unused elements — and any dependencies they pull in — out of your bundle.
|
|
83
83
|
|
|
84
84
|
The cleanest pattern is a **static, synchronous import at your app's entry file** — outside any component, outside any hook:
|
|
85
85
|
|
|
@@ -38,12 +38,13 @@ const Button = ({
|
|
|
38
38
|
children,
|
|
39
39
|
...rest
|
|
40
40
|
}) => {
|
|
41
|
-
const
|
|
42
|
-
const
|
|
41
|
+
const toneAttr = tone || void 0;
|
|
42
|
+
const isCustomTone = toneAttr != null && !NAMED_TONES.has(toneAttr);
|
|
43
|
+
const computedStyle = isCustomTone ? { ...style, ["--button-tone-source"]: toneAttr } : style;
|
|
43
44
|
const isIconOnly = icon != null && label == null && children == null && iconTrailing == null;
|
|
44
45
|
const sharedAttrs = {
|
|
45
46
|
priority,
|
|
46
|
-
tone,
|
|
47
|
+
tone: toneAttr,
|
|
47
48
|
underline,
|
|
48
49
|
// 'medium' (and unset) is the implicit default — emit no DOM attr.
|
|
49
50
|
size: size && size !== "medium" ? size : void 0,
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { BaseProps } from '../general_types';
|
|
2
|
+
export interface MenuProps extends BaseProps {
|
|
3
|
+
/** Preferred placement relative to the trigger. The cross-axis suffix
|
|
4
|
+
* (`-start` / `-end`) aligns the left / right edges; the menu auto-flips
|
|
5
|
+
* vertically and clamps horizontally when there isn't room.
|
|
6
|
+
* @defaultValue bottom-start */
|
|
7
|
+
placement?: 'bottom-start' | 'bottom-end' | 'top-start' | 'top-end';
|
|
8
|
+
/** Open on right-click (the `contextmenu` event) of the trigger region
|
|
9
|
+
* instead of a left click, positioned at the pointer. */
|
|
10
|
+
context?: boolean;
|
|
11
|
+
/** Open at the pointer coordinates rather than aligned to the trigger box.
|
|
12
|
+
* Pairs naturally with `context`; on its own it positions a left-click
|
|
13
|
+
* menu at the cursor. */
|
|
14
|
+
coord?: boolean;
|
|
15
|
+
/** Marks this menu as a submenu of the enclosing `MenuItem`. Set by passing
|
|
16
|
+
* it as a `MenuItem`'s `submenu`; rarely written by hand. */
|
|
17
|
+
submenu?: boolean;
|
|
18
|
+
/** For a submenu: also open it on hover (with intent timing), not only on
|
|
19
|
+
* click. No effect on a root menu. */
|
|
20
|
+
hover?: boolean;
|
|
21
|
+
/** Gap in pixels between the trigger and the menu.
|
|
22
|
+
* @defaultValue 4 */
|
|
23
|
+
offset?: number;
|
|
24
|
+
/** Controlled open state. Omit for the default **uncontrolled** menu (it
|
|
25
|
+
* opens/closes itself). Pass `'opened'` / `'closed'` to **control** it: the
|
|
26
|
+
* menu's visibility follows this value, and user dismiss (Esc, outside-click,
|
|
27
|
+
* select) fires `openchange` *without* self-closing — you update `state` in
|
|
28
|
+
* response. A string (not a boolean) so there's no `"false"`-as-truthy
|
|
29
|
+
* footgun. Submenus are always uncontrolled regardless of this. */
|
|
30
|
+
state?: 'opened' | 'closed';
|
|
31
|
+
/** The menu's contents: `MenuItem`, `MenuSeparator`, `MenuGroup`, or any
|
|
32
|
+
* custom element. */
|
|
33
|
+
children?: React.ReactNode;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Menu — a dropdown / context menu that anchors to any target and "just
|
|
37
|
+
* works". Place `<Menu>` immediately after the trigger element (a button,
|
|
38
|
+
* say); it opens on click by default. For a whole-area right-click menu, put
|
|
39
|
+
* it after the region and pass `context`.
|
|
40
|
+
*
|
|
41
|
+
* Open state is uncontrolled by default — listen for the `openchange` event
|
|
42
|
+
* (`detail: { open, previousState }`) to observe it, or pass `state` to control
|
|
43
|
+
* it. You can also grab a `ref` and call `.open()` / `.close()` / `.toggle()`.
|
|
44
|
+
* Selecting a `MenuItem` closes the menu;
|
|
45
|
+
* arbitrary injected content does not. Add `data-menu-open` to any item /
|
|
46
|
+
* container to keep it open, or `data-menu-close` to a custom element to let it
|
|
47
|
+
* close.
|
|
48
|
+
*
|
|
49
|
+
* Requires `@antadesign/anta/elements` to be imported (client-side only).
|
|
50
|
+
*
|
|
51
|
+
* @example Dropdown from a button
|
|
52
|
+
* ```tsx
|
|
53
|
+
* <a-button>Actions</a-button>
|
|
54
|
+
* <Menu>
|
|
55
|
+
* <MenuItem icon="edit" label="Edit" kbd="⌘E" onSelect={onEdit} />
|
|
56
|
+
* <MenuSeparator />
|
|
57
|
+
* <MenuItem tone="critical" icon="trash" label="Delete" onSelect={onDelete} />
|
|
58
|
+
* </Menu>
|
|
59
|
+
* ```
|
|
60
|
+
*/
|
|
61
|
+
export declare const Menu: ({ placement, context, coord, submenu, hover, offset, state, className, children, ...rest }: MenuProps) => any;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx } from "@antadesign/anta/jsx-runtime";
|
|
2
|
+
const Menu = ({
|
|
3
|
+
placement,
|
|
4
|
+
context,
|
|
5
|
+
coord,
|
|
6
|
+
submenu,
|
|
7
|
+
hover,
|
|
8
|
+
offset,
|
|
9
|
+
state,
|
|
10
|
+
className,
|
|
11
|
+
children,
|
|
12
|
+
...rest
|
|
13
|
+
}) => {
|
|
14
|
+
return /* @__PURE__ */ jsx(
|
|
15
|
+
"a-menu",
|
|
16
|
+
{
|
|
17
|
+
placement: placement && placement !== "bottom-start" ? placement : void 0,
|
|
18
|
+
context: context ? "" : void 0,
|
|
19
|
+
coord: coord ? "" : void 0,
|
|
20
|
+
submenu: submenu ? "" : void 0,
|
|
21
|
+
hover: hover ? "" : void 0,
|
|
22
|
+
offset: offset != null ? String(offset) : void 0,
|
|
23
|
+
state,
|
|
24
|
+
role: "menu",
|
|
25
|
+
"aria-orientation": "vertical",
|
|
26
|
+
class: className,
|
|
27
|
+
...rest,
|
|
28
|
+
children
|
|
29
|
+
}
|
|
30
|
+
);
|
|
31
|
+
};
|
|
32
|
+
export {
|
|
33
|
+
Menu
|
|
34
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { BaseProps } from '../general_types';
|
|
2
|
+
export interface MenuGroupProps extends BaseProps {
|
|
3
|
+
/** The section heading shown above the grouped items (also the group's
|
|
4
|
+
* accessible name). */
|
|
5
|
+
label?: string;
|
|
6
|
+
/** The grouped `MenuItem`s. */
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* MenuGroup — a titled section that organises related `MenuItem`s. Keyboard
|
|
11
|
+
* navigation flattens items across groups, skipping the heading.
|
|
12
|
+
*
|
|
13
|
+
* Add `data-menu-open` to keep the menu open after any item in the group is
|
|
14
|
+
* chosen (it forwards to the element).
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* <MenuGroup label="Edit">
|
|
19
|
+
* <MenuItem icon="copy" label="Copy" />
|
|
20
|
+
* <MenuItem icon="cut" label="Cut" />
|
|
21
|
+
* </MenuGroup>
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export declare const MenuGroup: ({ label, className, children, ...rest }: MenuGroupProps) => any;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
+
const MenuGroup = ({ label, className, children, ...rest }) => {
|
|
3
|
+
return /* @__PURE__ */ jsxs(
|
|
4
|
+
"a-menu-group",
|
|
5
|
+
{
|
|
6
|
+
role: "group",
|
|
7
|
+
"aria-label": label,
|
|
8
|
+
class: className,
|
|
9
|
+
...rest,
|
|
10
|
+
children: [
|
|
11
|
+
label != null && /* @__PURE__ */ jsx("a-menu-group-label", { "aria-hidden": "true", children: label }),
|
|
12
|
+
children
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
export {
|
|
18
|
+
MenuGroup
|
|
19
|
+
};
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { BaseProps } from '../general_types';
|
|
2
|
+
import type { IconShape } from '../elements/a-icon.shapes';
|
|
3
|
+
export interface MenuItemProps extends BaseProps {
|
|
4
|
+
/** Leading icon shape. */
|
|
5
|
+
icon?: IconShape;
|
|
6
|
+
/** The item's text. Omit and pass `children` for richer content. */
|
|
7
|
+
label?: string;
|
|
8
|
+
/** A trailing keyboard-shortcut hint, e.g. `"⌘E"`. */
|
|
9
|
+
kbd?: string;
|
|
10
|
+
/** A trailing icon (ignored when `submenu` is set — the chevron takes its
|
|
11
|
+
* place). */
|
|
12
|
+
iconTrailing?: IconShape;
|
|
13
|
+
/** Disable the item: greyed out, not focusable for activation, no close. */
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
/** Semantic tone — colors the label, icon, and hover tint. `critical` is the
|
|
16
|
+
* destructive action; `neutral` (the default) is the standard gray.
|
|
17
|
+
* @defaultValue neutral */
|
|
18
|
+
tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical';
|
|
19
|
+
/** Marks this item as a submenu parent: adds the trailing chevron and
|
|
20
|
+
* `aria-haspopup`. Nest the flyout as a `<Menu submenu>` child. */
|
|
21
|
+
submenu?: boolean;
|
|
22
|
+
/** Convenience activation handler — fires on click / Enter / Space unless
|
|
23
|
+
* the item is disabled. (Mapped to the underlying click.) */
|
|
24
|
+
onSelect?: (e: any) => void;
|
|
25
|
+
/** Item content. With `label` set, children are extra content — most
|
|
26
|
+
* notably the nested `<Menu submenu>` for a submenu parent. */
|
|
27
|
+
children?: React.ReactNode;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* MenuItem — a single selectable row inside a `Menu`. Composes a leading
|
|
31
|
+
* `icon`, a `label` (or `children`), an optional trailing `kbd` hint, and an
|
|
32
|
+
* optional trailing icon. For a submenu, set `submenu` and nest a
|
|
33
|
+
* `<Menu submenu>` as a child — a chevron is added automatically.
|
|
34
|
+
*
|
|
35
|
+
* Selecting an item closes the menu; add `data-menu-open` to keep it open
|
|
36
|
+
* (toggles / multi-select) — it forwards to the element.
|
|
37
|
+
*
|
|
38
|
+
* @example
|
|
39
|
+
* ```tsx
|
|
40
|
+
* <MenuItem icon="copy" label="Duplicate" kbd="⌘D" onSelect={dup} />
|
|
41
|
+
* <MenuItem label="Word wrap" data-menu-open onSelect={toggleWrap} />
|
|
42
|
+
* <MenuItem label="Share" submenu>
|
|
43
|
+
* <Menu submenu hover>
|
|
44
|
+
* <MenuItem label="Copy link" onSelect={copyLink} />
|
|
45
|
+
* </Menu>
|
|
46
|
+
* </MenuItem>
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare const MenuItem: ({ icon, label, kbd, iconTrailing, disabled, tone, submenu, onSelect, className, children, ...rest }: MenuItemProps) => any;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
+
const MenuItem = ({
|
|
3
|
+
icon,
|
|
4
|
+
label,
|
|
5
|
+
kbd,
|
|
6
|
+
iconTrailing,
|
|
7
|
+
disabled,
|
|
8
|
+
tone,
|
|
9
|
+
submenu,
|
|
10
|
+
onSelect,
|
|
11
|
+
className,
|
|
12
|
+
children,
|
|
13
|
+
...rest
|
|
14
|
+
}) => {
|
|
15
|
+
return /* @__PURE__ */ jsxs(
|
|
16
|
+
"a-menu-item",
|
|
17
|
+
{
|
|
18
|
+
role: "menuitem",
|
|
19
|
+
tabIndex: 0,
|
|
20
|
+
disabled: disabled ? "" : void 0,
|
|
21
|
+
tone: tone && tone !== "neutral" ? tone : void 0,
|
|
22
|
+
submenu: submenu ? "" : void 0,
|
|
23
|
+
"aria-haspopup": submenu ? "menu" : void 0,
|
|
24
|
+
"aria-disabled": disabled ? "true" : void 0,
|
|
25
|
+
onClick: disabled ? void 0 : onSelect,
|
|
26
|
+
class: className,
|
|
27
|
+
...rest,
|
|
28
|
+
children: [
|
|
29
|
+
icon && /* @__PURE__ */ jsx("a-icon", { shape: icon, "aria-hidden": "true" }),
|
|
30
|
+
label != null && /* @__PURE__ */ jsx("a-menu-item-label", { children: label }),
|
|
31
|
+
kbd && /* @__PURE__ */ jsx("kbd", { children: kbd }),
|
|
32
|
+
submenu ? /* @__PURE__ */ jsx("a-icon", { shape: "chevron-right", "aria-hidden": "true" }) : iconTrailing && /* @__PURE__ */ jsx("a-icon", { shape: iconTrailing, "aria-hidden": "true" }),
|
|
33
|
+
children
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
export {
|
|
39
|
+
MenuItem
|
|
40
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BaseProps } from '../general_types';
|
|
2
|
+
export interface MenuSeparatorProps extends BaseProps {
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* MenuSeparator — a thin divider between groups of `MenuItem`s.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* <MenuItem label="Edit" />
|
|
10
|
+
* <MenuSeparator />
|
|
11
|
+
* <MenuItem tone="critical" label="Delete" />
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
export declare const MenuSeparator: ({ className, ...rest }: MenuSeparatorProps) => any;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { BaseProps } from "../general_types";
|
|
2
|
+
import type { IconShape } from '../elements/a-icon.shapes';
|
|
3
|
+
export interface TagProps extends BaseProps {
|
|
4
|
+
/** A short "key" shown before the value. When paired with `value` it
|
|
5
|
+
* renders bold (weight 600), same color. On its own (no `value`) it's
|
|
6
|
+
* treated as the tag's primary text and keeps the default styling. */
|
|
7
|
+
label?: string;
|
|
8
|
+
/** The tag's primary text — a status, count, version, duration, etc.
|
|
9
|
+
* Rendered in the default color and weight, with no divider from the
|
|
10
|
+
* label; the color + weight contrast does the separating. */
|
|
11
|
+
value?: string;
|
|
12
|
+
/** Semantic tone, or any literal CSS color (`'#ff1493'`, `'rebeccapurple'`)
|
|
13
|
+
* for a one-off custom tone. Named tones map to the `--text-2-{tone}` /
|
|
14
|
+
* `--bg-4-{tone}` palette; a custom color keeps its hue while lightness
|
|
15
|
+
* and chroma are pinned. `'neutral'` (the default) is the gray tag —
|
|
16
|
+
* the same as omitting `tone`.
|
|
17
|
+
* @defaultValue neutral */
|
|
18
|
+
tone?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
|
|
19
|
+
/** Size variant. `small` = 16px tall, `medium` = 20px, `large` = 24px
|
|
20
|
+
* (matching `Button`). Omit the attribute or pass `'medium'` for the
|
|
21
|
+
* default — both render identically and emit no DOM attribute.
|
|
22
|
+
* @defaultValue medium */
|
|
23
|
+
size?: 'small' | 'medium' | 'large';
|
|
24
|
+
/** Render in normal (mixed) case instead of the default uppercase
|
|
25
|
+
* (keeps Anta's small body-text letter-spacing; uppercase tracks wider). */
|
|
26
|
+
nocaps?: boolean;
|
|
27
|
+
/** Leading icon shape. Sits flush before the label, scaled to the pill. */
|
|
28
|
+
icon?: IconShape;
|
|
29
|
+
/** Trailing icon shape. Renders last, after the value. */
|
|
30
|
+
iconTrailing?: IconShape;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Compact pill / chip for status, labels, and metadata.
|
|
34
|
+
*
|
|
35
|
+
* Renders an `<a-tag>` styled tag (no JS, no shadow DOM) — color and size
|
|
36
|
+
* come entirely from attributes. Content is composed from `icon`, `label`,
|
|
37
|
+
* `value`, and `iconTrailing` (like `<Button>`): `value` is the primary
|
|
38
|
+
* text (default styling) and `label`, when paired with a value, renders as
|
|
39
|
+
* a bold "key" before it (same color, no divider). Tabular figures are
|
|
40
|
+
* always on, so counts / versions / timers don't reflow. For an arbitrary
|
|
41
|
+
* multi-part tag, pass `children` instead — each segment after the first
|
|
42
|
+
* gets a hairline divider (the `label` + `value` pair is the no-divider
|
|
43
|
+
* exception).
|
|
44
|
+
*
|
|
45
|
+
* Requires `@antadesign/anta/elements` to be imported (client-side only)
|
|
46
|
+
* so the CSS ships with the page.
|
|
47
|
+
*
|
|
48
|
+
* @example Basic usage
|
|
49
|
+
* ```tsx
|
|
50
|
+
* <Tag tone="success" label="Running" />
|
|
51
|
+
* <Tag tone="info" icon="hourglass" label="Build" value="2m 14s" />
|
|
52
|
+
* <Tag tone="brand" size="small" nocaps value="v2.1.0" />
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
export declare const Tag: ({ icon, iconTrailing, label, value, tone, size, nocaps, className, style, children, ...rest }: TagProps) => any;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
+
const NAMED_TONES = /* @__PURE__ */ new Set(["neutral", "brand", "info", "success", "warning", "critical"]);
|
|
3
|
+
const Tag = ({
|
|
4
|
+
icon,
|
|
5
|
+
iconTrailing,
|
|
6
|
+
label,
|
|
7
|
+
value,
|
|
8
|
+
tone,
|
|
9
|
+
size,
|
|
10
|
+
nocaps,
|
|
11
|
+
className,
|
|
12
|
+
style,
|
|
13
|
+
children,
|
|
14
|
+
...rest
|
|
15
|
+
}) => {
|
|
16
|
+
const isCustomTone = tone != null && !NAMED_TONES.has(tone);
|
|
17
|
+
const computedStyle = isCustomTone ? { ...style, ["--tag-tone-source"]: tone } : style;
|
|
18
|
+
const hasValue = value != null;
|
|
19
|
+
return /* @__PURE__ */ jsxs(
|
|
20
|
+
"a-tag",
|
|
21
|
+
{
|
|
22
|
+
tone,
|
|
23
|
+
size: size && size !== "medium" ? size : void 0,
|
|
24
|
+
nocaps: nocaps ? "" : void 0,
|
|
25
|
+
class: className,
|
|
26
|
+
style: computedStyle,
|
|
27
|
+
...rest,
|
|
28
|
+
children: [
|
|
29
|
+
icon && /* @__PURE__ */ jsx("a-icon", { shape: icon, "aria-hidden": "true" }),
|
|
30
|
+
label != null && (hasValue ? /* @__PURE__ */ jsx("a-tag-label", { children: label }) : /* @__PURE__ */ jsx("a-tag-value", { children: label })),
|
|
31
|
+
hasValue && /* @__PURE__ */ jsx("a-tag-value", { children: value }),
|
|
32
|
+
children,
|
|
33
|
+
iconTrailing && /* @__PURE__ */ jsx("a-icon", { shape: iconTrailing, "aria-hidden": "true" })
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
export {
|
|
39
|
+
Tag
|
|
40
|
+
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { BaseProps } from "../general_types";
|
|
2
2
|
export interface TextProps extends BaseProps {
|
|
3
|
-
/** Visual priority. Maps to text-1..text-5 (`primary` = text-1
|
|
4
|
-
*
|
|
3
|
+
/** Visual priority. Maps to text-1..text-5 (`primary` = text-1, the
|
|
4
|
+
* strongest). The default is `secondary` (text-2) — body text reads a
|
|
5
|
+
* step softer than the strongest foreground; pass `primary` for emphasis.
|
|
6
|
+
* @defaultValue secondary */
|
|
5
7
|
priority?: 'primary' | 'secondary' | 'tertiary' | 'quaternary' | 'quinary';
|
|
6
8
|
/** Color tint. Applies the matching `--text-{N}-{tone}` palette. */
|
|
7
9
|
tone?: 'brand' | 'success' | 'critical' | 'warning' | 'info';
|
|
@@ -25,8 +25,10 @@ export interface TooltipProps extends BaseProps {
|
|
|
25
25
|
* doesn't affect that element's layout.
|
|
26
26
|
*
|
|
27
27
|
* Shows on hover (after `delay`) and on keyboard focus; dismisses on mouse
|
|
28
|
-
* leave, blur, Escape, or when the anchor scrolls away.
|
|
29
|
-
*
|
|
28
|
+
* leave, blur, Escape, or when the anchor scrolls away. On touch devices it
|
|
29
|
+
* opens on press-and-hold (a tap never surfaces it) and lingers briefly after
|
|
30
|
+
* release. Follows the cursor by default — pass `static` to pin it under the
|
|
31
|
+
* anchor instead.
|
|
30
32
|
*
|
|
31
33
|
* Requires `@antadesign/anta/elements` to be imported (client-side only)
|
|
32
34
|
* to register the underlying custom element.
|
|
@@ -36,6 +36,11 @@
|
|
|
36
36
|
--button-bg-secondary-active: #44374b26;
|
|
37
37
|
--button-fg-secondary-rest: #534c57;
|
|
38
38
|
--button-fg-secondary-hover: #49424c;
|
|
39
|
+
/* Darken the rest-state secondary label by this much oklch lightness so
|
|
40
|
+
it reads a touch stronger. Applied dynamically at the --button-fg
|
|
41
|
+
wiring (below), so it covers every tone — named and custom alike.
|
|
42
|
+
Light mode only; the .dark block zeroes it. */
|
|
43
|
+
--button-fg-secondary-l-shift: 0.05;
|
|
39
44
|
|
|
40
45
|
--button-fg-tertiary-rest: #635b65;
|
|
41
46
|
--button-fg-tertiary-hover: #534c57;
|
|
@@ -192,6 +197,8 @@
|
|
|
192
197
|
--button-bg-secondary-active: #e4d1ef2e;
|
|
193
198
|
--button-fg-secondary-rest: #c1b9c1;
|
|
194
199
|
--button-fg-secondary-hover: #d4ced4;
|
|
200
|
+
/* Dark-mode secondary labels are already tuned — no rest darkening. */
|
|
201
|
+
--button-fg-secondary-l-shift: 0;
|
|
195
202
|
|
|
196
203
|
--button-fg-tertiary-rest: #afa9b1;
|
|
197
204
|
--button-fg-tertiary-hover: #afa9b1;
|
|
@@ -323,6 +330,10 @@
|
|
|
323
330
|
background-color: var(--button-bg);
|
|
324
331
|
border-radius: 4px;
|
|
325
332
|
text-decoration: none;
|
|
333
|
+
/* Secondary is the default priority — a 1px hairline in the current
|
|
334
|
+
fg tone (at 50% alpha) gives the chip a subtle edge. Primary,
|
|
335
|
+
tertiary, and quaternary cancel it in their own blocks below. */
|
|
336
|
+
box-shadow: 0 0 1px color-mix(in oklch, currentColor, transparent 50%);
|
|
326
337
|
|
|
327
338
|
font-size: 15px;
|
|
328
339
|
font-family: var(--sans-serif);
|
|
@@ -413,11 +424,6 @@
|
|
|
413
424
|
outline-offset: 1px;
|
|
414
425
|
}
|
|
415
426
|
|
|
416
|
-
/* Selected gets a 0.5px inset ring in the current fg color. */
|
|
417
|
-
&[selected] {
|
|
418
|
-
box-shadow: inset 0 0 0 0.5px currentColor;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
427
|
/* Quaternary: instant in every direction — hover-in, press, and
|
|
422
428
|
return to rest all snap with no transition. */
|
|
423
429
|
&[priority="quaternary"] {
|
|
@@ -559,6 +565,7 @@
|
|
|
559
565
|
on Chrome 133+ / Safari 18.2+. (oklch relative color: Chrome 119+,
|
|
560
566
|
Safari 16.4+, Firefox 128+.) */
|
|
561
567
|
&[tone]:not(
|
|
568
|
+
[tone=""],
|
|
562
569
|
[tone="brand"],
|
|
563
570
|
[tone="neutral"],
|
|
564
571
|
[tone="critical"],
|
|
@@ -609,6 +616,7 @@
|
|
|
609
616
|
/* Custom tone, dark mode — same formulas, re-tuned knobs: lighter fg
|
|
610
617
|
and heavier tint alphas to read against a dark page. */
|
|
611
618
|
.dark &[tone]:not(
|
|
619
|
+
[tone=""],
|
|
612
620
|
[tone="brand"],
|
|
613
621
|
[tone="neutral"],
|
|
614
622
|
[tone="critical"],
|
|
@@ -636,7 +644,7 @@
|
|
|
636
644
|
tertiary, and quaternary match an explicit `[priority="…"]` attr
|
|
637
645
|
and win on specificity (primary's constant fg beats the unscoped
|
|
638
646
|
:hover on source order). */
|
|
639
|
-
--button-fg: var(--button-fg-secondary-rest);
|
|
647
|
+
--button-fg: oklch(from var(--button-fg-secondary-rest) calc(l - var(--button-fg-secondary-l-shift)) c h);
|
|
640
648
|
--button-bg: var(--button-bg-secondary-rest);
|
|
641
649
|
/* Hover styling is gated to real-pointer devices so it doesn't stick
|
|
642
650
|
after a tap on touch screens (where :hover lingers until the next
|
|
@@ -656,6 +664,8 @@
|
|
|
656
664
|
&[priority="primary"] {
|
|
657
665
|
--button-fg: var(--button-fg-primary-rest);
|
|
658
666
|
--button-bg: var(--button-bg-primary-rest);
|
|
667
|
+
/* Solid fill carries its own edge — drop the secondary hairline. */
|
|
668
|
+
box-shadow: none;
|
|
659
669
|
@media (hover: hover) and (pointer: fine) {
|
|
660
670
|
&:hover {
|
|
661
671
|
--button-bg: var(--button-bg-primary-hover);
|
|
@@ -669,6 +679,8 @@
|
|
|
669
679
|
&[priority="tertiary"] {
|
|
670
680
|
--button-fg: var(--button-fg-tertiary-rest);
|
|
671
681
|
--button-bg: transparent;
|
|
682
|
+
/* Background-less — no hairline. */
|
|
683
|
+
box-shadow: none;
|
|
672
684
|
@media (hover: hover) and (pointer: fine) {
|
|
673
685
|
&:hover {
|
|
674
686
|
--button-fg: var(--button-fg-tertiary-hover);
|
|
@@ -682,11 +694,14 @@
|
|
|
682
694
|
}
|
|
683
695
|
}
|
|
684
696
|
&[priority="quaternary"] {
|
|
685
|
-
/* Rest fg is the quaternary tone at
|
|
697
|
+
/* Rest fg is the quaternary tone at 90% alpha — slightly faded, so a
|
|
686
698
|
quaternary button reads as quieter than a (full-opacity) tertiary
|
|
687
699
|
one. Hover / active restore full opacity. */
|
|
688
|
-
--button-fg: color-mix(in oklch, var(--button-fg-quaternary-rest)
|
|
700
|
+
--button-fg: color-mix(in oklch, var(--button-fg-quaternary-rest) 90%, transparent);
|
|
689
701
|
--button-bg: transparent;
|
|
702
|
+
/* Background-less — no hairline. */
|
|
703
|
+
box-shadow: none;
|
|
704
|
+
font-weight: 415;
|
|
690
705
|
@media (hover: hover) and (pointer: fine) {
|
|
691
706
|
&:hover {
|
|
692
707
|
--button-fg: var(--button-fg-quaternary-hover);
|
|
@@ -707,6 +722,14 @@
|
|
|
707
722
|
}
|
|
708
723
|
}
|
|
709
724
|
|
|
725
|
+
/* Selected gets a 1px inset ring in the current fg color. Declared
|
|
726
|
+
after the priority blocks so it overrides their `box-shadow: none`
|
|
727
|
+
cancels — every selected button keeps its ring regardless of
|
|
728
|
+
priority. */
|
|
729
|
+
&[selected] {
|
|
730
|
+
box-shadow: inset 0 0 0 1px currentColor;
|
|
731
|
+
}
|
|
732
|
+
|
|
710
733
|
/* Set bg/color directly (not the vars) so inline-style
|
|
711
734
|
`--button-bg` overrides can't keep a disabled button alive.
|
|
712
735
|
Secondary disabled is the default; other priorities override below. */
|
|
@@ -330,6 +330,10 @@
|
|
|
330
330
|
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M9 3H5a2 2 0 0 0-2 2v4m6-6h10a2 2 0 0 1 2 2v4M9 3v18m0 0h10a2 2 0 0 0 2-2V9M9 21H5a2 2 0 0 1-2-2V9m0 0h18'/%3E%3C/svg%3E%0A");
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
+
a-icon[shape="tag"] {
|
|
334
|
+
--icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12.586 2.586A2 2 0 0 0 11.172 2H4a2 2 0 0 0-2 2v7.172a2 2 0 0 0 .586 1.414l8.704 8.704a2.426 2.426 0 0 0 3.42 0l6.58-6.58a2.426 2.426 0 0 0 0-3.42z'/%3E%3Ccircle cx='7.5' cy='7.5' r='.5' fill='currentColor'/%3E%3C/svg%3E%0A");
|
|
335
|
+
}
|
|
336
|
+
|
|
333
337
|
a-icon[shape="text-highlight"] {
|
|
334
338
|
--icon: url("data:image/svg+xml,%3C%3Fxml version='1.0' encoding='utf-8'%3F%3E%0A%3C!-- Generator: Adobe Illustrator 18.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --%3E%0A%3Csvg version='1.1' id='Layer_1' xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink' x='0px' y='0px'%0A viewBox='0 0 16 16' enable-background='new 0 0 16 16' xml:space='preserve'%3E%0A%3Cg id='text_highlight_1_'%3E%0A %3Cg%3E%0A %3Cpath fill-rule='evenodd' clip-rule='evenodd' d='M9,10H2V6h7V4H1C0.45,4,0,4.45,0,5v6c0,0.55,0.45,1,1,1h8V10z M13,13h-1V3h1%0A c0.55,0,1-0.45,1-1c0-0.55-0.45-1-1-1h-1c-0.37,0-0.7,0.11-1,0.28C10.7,1.11,10.37,1,10,1H9C8.45,1,8,1.45,8,2c0,0.55,0.45,1,1,1%0A h1v10H9c-0.55,0-1,0.45-1,1c0,0.55,0.45,1,1,1h1c0.37,0,0.7-0.11,1-0.28c0.3,0.17,0.63,0.28,1,0.28h1c0.55,0,1-0.45,1-1%0A C14,13.45,13.55,13,13,13z M15,4h-2v2h1v4h-1v2h2c0.55,0,1-0.45,1-1V5C16,4.45,15.55,4,15,4z'/%3E%0A %3C/g%3E%0A%3C/g%3E%0A%3C/svg%3E%0A");
|
|
335
339
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { IconShapes } from '@antadesign/anta';
|
|
2
|
-
export declare const ICON_SHAPES: readonly ["arrow-left-to-line", "arrow-left", "arrow-narrow-down", "arrow-narrow-up-down", "arrow-narrow-up", "arrow-right", "arrow-top-right", "asterisk", "book-open", "braces", "bug", "calendar", "case-sensitive", "chat", "check", "chevron-down", "chevron-left", "chevron-right", "chevron-up", "chevrons-right", "circle-check", "circle-large", "circle", "click", "clock", "cloud-upload", "copy", "corner-down-right", "cube", "dots-vertical", "download", "edit", "education-disk", "external-link", "file-down", "file", "filter", "folder-close", "folder-open", "folder-tree", "github-logo", "gitlab-logo", "hat-glasses", "heart-handshake", "help-disk", "history-tree", "history", "home", "hourglass", "info", "jira-logo", "linear-logo", "link", "list-detail-view", "maximize", "megaphone", "menu", "minimize", "minus", "moon", "more", "move-horizontal", "not-equal", "play", "plus", "pointer", "presentation", "refresh-ccw-dot", "refresh", "regex", "repeat", "rotate-ccw", "rss", "runs-history", "scroll-text", "search-check", "search", "send", "sparkles", "sun", "swatch-book", "table-2", "text-highlight", "text-initial", "timer", "trash", "trello-logo", "view", "warning-triangle", "webhook", "workflow", "x"];
|
|
2
|
+
export declare const ICON_SHAPES: readonly ["arrow-left-to-line", "arrow-left", "arrow-narrow-down", "arrow-narrow-up-down", "arrow-narrow-up", "arrow-right", "arrow-top-right", "asterisk", "book-open", "braces", "bug", "calendar", "case-sensitive", "chat", "check", "chevron-down", "chevron-left", "chevron-right", "chevron-up", "chevrons-right", "circle-check", "circle-large", "circle", "click", "clock", "cloud-upload", "copy", "corner-down-right", "cube", "dots-vertical", "download", "edit", "education-disk", "external-link", "file-down", "file", "filter", "folder-close", "folder-open", "folder-tree", "github-logo", "gitlab-logo", "hat-glasses", "heart-handshake", "help-disk", "history-tree", "history", "home", "hourglass", "info", "jira-logo", "linear-logo", "link", "list-detail-view", "maximize", "megaphone", "menu", "minimize", "minus", "moon", "more", "move-horizontal", "not-equal", "play", "plus", "pointer", "presentation", "refresh-ccw-dot", "refresh", "regex", "repeat", "rotate-ccw", "rss", "runs-history", "scroll-text", "search-check", "search", "send", "sparkles", "sun", "swatch-book", "table-2", "tag", "text-highlight", "text-initial", "timer", "trash", "trello-logo", "view", "warning-triangle", "webhook", "workflow", "x"];
|
|
3
3
|
export declare const ICON_SYNONYMS: Readonly<Record<string, readonly string[]>>;
|
|
4
4
|
declare module '@antadesign/anta' {
|
|
5
5
|
interface IconShapes {
|
|
@@ -85,6 +85,7 @@ declare module '@antadesign/anta' {
|
|
|
85
85
|
'sun': true;
|
|
86
86
|
'swatch-book': true;
|
|
87
87
|
'table-2': true;
|
|
88
|
+
'tag': true;
|
|
88
89
|
'text-highlight': true;
|
|
89
90
|
'text-initial': true;
|
|
90
91
|
'timer': true;
|
|
@@ -81,6 +81,7 @@ const ICON_SHAPES = [
|
|
|
81
81
|
"sun",
|
|
82
82
|
"swatch-book",
|
|
83
83
|
"table-2",
|
|
84
|
+
"tag",
|
|
84
85
|
"text-highlight",
|
|
85
86
|
"text-initial",
|
|
86
87
|
"timer",
|
|
@@ -178,7 +179,8 @@ const ICON_SYNONYMS = {
|
|
|
178
179
|
"download": ["save", "import"],
|
|
179
180
|
"cloud-upload": ["save", "sync", "upload", "send", "export"],
|
|
180
181
|
"link": ["url", "href", "anchor"],
|
|
181
|
-
"more": ["options", "extra"]
|
|
182
|
+
"more": ["options", "extra"],
|
|
183
|
+
"tag": ["label", "badge", "chip"]
|
|
182
184
|
};
|
|
183
185
|
export {
|
|
184
186
|
ICON_SHAPES,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
@layer anta {
|
|
2
|
+
a-menu-group:not(:defined) {
|
|
3
|
+
display: none;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
a-menu-group {
|
|
7
|
+
display: block;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/* Non-focusable section heading. */
|
|
11
|
+
a-menu-group-label {
|
|
12
|
+
display: block;
|
|
13
|
+
padding: 6px 8px 2px;
|
|
14
|
+
color: var(--text-5);
|
|
15
|
+
font-size: 0.75em;
|
|
16
|
+
font-weight: 600;
|
|
17
|
+
letter-spacing: 0.06em;
|
|
18
|
+
text-transform: uppercase;
|
|
19
|
+
user-select: none;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { HTMLElementBase } from '../anta_helpers';
|
|
2
|
+
import './a-menu-group.css';
|
|
3
|
+
/**
|
|
4
|
+
* `<a-menu-group>` — a titled section grouping related menu items.
|
|
5
|
+
* No JS / no shadow DOM; styled by `a-menu-group.css`. The group's heading
|
|
6
|
+
* is a non-focusable `<a-menu-group-label>` child rendered by the
|
|
7
|
+
* `MenuGroup` JSX wrapper; `role="group"` + `aria-label` are added there too.
|
|
8
|
+
* Keyboard navigation in `<a-menu>` flattens items across group boundaries,
|
|
9
|
+
* skipping the heading.
|
|
10
|
+
*/
|
|
11
|
+
export declare class AMenuGroupElement extends HTMLElementBase {
|
|
12
|
+
}
|
|
13
|
+
export declare function register_a_menu_group(): void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { HTMLElementBase } from "../anta_helpers";
|
|
2
|
+
import "./a-menu-group.css";
|
|
3
|
+
class AMenuGroupElement extends HTMLElementBase {
|
|
4
|
+
}
|
|
5
|
+
function register_a_menu_group() {
|
|
6
|
+
if (typeof customElements === "undefined") return;
|
|
7
|
+
if (!customElements.get("a-menu-group")) {
|
|
8
|
+
customElements.define("a-menu-group", AMenuGroupElement);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
register_a_menu_group();
|
|
12
|
+
export {
|
|
13
|
+
AMenuGroupElement,
|
|
14
|
+
register_a_menu_group
|
|
15
|
+
};
|