@antadesign/anta 0.3.7 → 0.3.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/anta_helpers.d.ts +20 -0
- package/dist/anta_helpers.js +5 -1
- package/dist/components/Button.js +2 -2
- package/dist/components/Card.d.ts +28 -14
- package/dist/components/Card.js +51 -19
- package/dist/components/Card.module.css +35 -0
- package/dist/components/Checkbox.js +2 -2
- package/dist/components/Dialog.js +4 -4
- package/dist/components/Expander.js +4 -4
- package/dist/components/Input.js +2 -2
- package/dist/components/InputTime.js +2 -2
- package/dist/components/Menu.js +4 -4
- package/dist/components/MenuItem.d.ts +60 -32
- package/dist/components/MenuItem.js +35 -9
- package/dist/components/Progress.js +2 -2
- package/dist/components/Tabs.js +3 -3
- package/dist/components/Tag.js +3 -2
- package/dist/components/Text.d.ts +5 -3
- package/dist/components/Text.js +8 -2
- package/dist/components/Title.d.ts +5 -3
- package/dist/components/Title.js +4 -2
- package/dist/components/Tooltip.js +2 -2
- package/dist/elements/a-button.css +1 -1
- package/dist/elements/a-card.css +1 -211
- package/dist/elements/a-card.js +44 -72
- package/dist/elements/a-checkbox.js +0 -2
- package/dist/elements/a-icon.shapes.css +1 -1
- package/dist/elements/a-icon.shapes.d.ts +2 -1
- package/dist/elements/a-icon.shapes.js +1 -0
- package/dist/elements/a-menu-item.css +1 -1
- package/dist/elements/a-menu-item.d.ts +13 -0
- package/dist/elements/a-menu-item.js +14 -6
- package/dist/elements/a-menu.d.ts +6 -0
- package/dist/elements/a-menu.js +14 -4
- package/dist/elements/a-radio-group.d.ts +3 -1
- package/dist/elements/a-radio-group.js +3 -3
- package/dist/elements/a-tabs.d.ts +3 -1
- package/dist/elements/a-tabs.js +3 -3
- package/dist/elements/a-text.css +1 -1
- package/dist/elements/a-title.css +1 -1
- package/dist/elements/index.d.ts +1 -0
- package/dist/elements/index.js +3 -0
- package/dist/general_types.d.ts +55 -6
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/jsx-runtime.d.ts +2 -1
- package/package.json +1 -1
package/dist/anta_helpers.d.ts
CHANGED
|
@@ -15,12 +15,25 @@ export declare function wrapLabel(kids: React.ReactNode, tag: string): React.Rea
|
|
|
15
15
|
* the native event directly. Returns the native event and its `detail`. Shared by
|
|
16
16
|
* every stateful wrapper (`Menu`, `Expander`, `Checkbox`, `RadioGroup`) — don't
|
|
17
17
|
* re-implement it per component.
|
|
18
|
+
*
|
|
19
|
+
* `isOwn` is `true` when the event was dispatched on the element the listener is
|
|
20
|
+
* bound to (`target === currentTarget`), `false` when it bubbled up from a
|
|
21
|
+
* descendant. `statechange` is a shared event name with a per-component `detail`
|
|
22
|
+
* vocabulary, so a container wrapper (`Dialog`, `Menu`, `Expander`) that projects
|
|
23
|
+
* arbitrary children must gate on `isOwn` before acting: a foreign bubbling
|
|
24
|
+
* `statechange` from a nested control would otherwise be read in the wrong
|
|
25
|
+
* vocabulary (a checkbox toggle looking like a dialog close). Anta's own controls
|
|
26
|
+
* no longer bubble `statechange`, so this is defense-in-depth against consumer /
|
|
27
|
+
* third-party elements that do. Read synchronously during dispatch, so
|
|
28
|
+
* `currentTarget` is still live. (Read as `true` for the falsy-event guard so a
|
|
29
|
+
* missing event never spuriously reads as bubbled.)
|
|
18
30
|
*/
|
|
19
31
|
export declare function nativeStateChange<D>(e: CustomEvent<D> | {
|
|
20
32
|
nativeEvent: CustomEvent<D>;
|
|
21
33
|
}): {
|
|
22
34
|
event: CustomEvent<D>;
|
|
23
35
|
detail?: D;
|
|
36
|
+
isOwn: boolean;
|
|
24
37
|
};
|
|
25
38
|
export declare const IS_MAC: boolean;
|
|
26
39
|
/** Default row hint teaching the Alt/⌥-click "select only this" accelerator on
|
|
@@ -54,6 +67,13 @@ export declare function toneStyle(tone: string | undefined, varName: string, bas
|
|
|
54
67
|
* element's default full-round). Returns `base` unchanged when there's no value.
|
|
55
68
|
*/
|
|
56
69
|
export declare function roundStyle(round: boolean | number | string | undefined, varName: string, base?: React.CSSProperties): React.CSSProperties | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Presence flag for a `round` attribute: `''` when a radius applies, else
|
|
72
|
+
* `undefined`. A bare `round ? '' : undefined` wrongly drops `round={0}` — the
|
|
73
|
+
* caller asking for square corners — since `0` is falsy; this keeps it (and drops
|
|
74
|
+
* `false` / `undefined` / `''`). Mirrors what `roundStyle` emits a variable for.
|
|
75
|
+
*/
|
|
76
|
+
export declare function roundAttr(round: boolean | number | string | undefined): '' | undefined;
|
|
57
77
|
/**
|
|
58
78
|
* The rect a floating-element anchor advertises for positioning. Any element may
|
|
59
79
|
* implement `getAnchorRect(): DOMRect` to point positioners (`a-menu`,
|
package/dist/anta_helpers.js
CHANGED
|
@@ -14,7 +14,7 @@ function wrapLabel(kids, tag) {
|
|
|
14
14
|
}
|
|
15
15
|
function nativeStateChange(e) {
|
|
16
16
|
const event = "nativeEvent" in e ? e.nativeEvent : e;
|
|
17
|
-
return { event, detail: event?.detail };
|
|
17
|
+
return { event, detail: event?.detail, isOwn: !event || event.target === event.currentTarget };
|
|
18
18
|
}
|
|
19
19
|
const IS_MAC = typeof navigator !== "undefined" && /Mac|iPhone|iPad/i.test(navigator.userAgent || "");
|
|
20
20
|
const ISOLATE_HINT = IS_MAC ? "\u2325+Click to select only this" : "Alt+Click to select only this";
|
|
@@ -37,6 +37,9 @@ function roundStyle(round, varName, base) {
|
|
|
37
37
|
if (typeof round === "string" && round !== "") return { ...base, [varName]: round };
|
|
38
38
|
return base;
|
|
39
39
|
}
|
|
40
|
+
function roundAttr(round) {
|
|
41
|
+
return round || round === 0 ? "" : void 0;
|
|
42
|
+
}
|
|
40
43
|
function anchorRect(el) {
|
|
41
44
|
const fn = el.getAnchorRect;
|
|
42
45
|
return typeof fn === "function" ? fn.call(el) : el.getBoundingClientRect();
|
|
@@ -120,6 +123,7 @@ export {
|
|
|
120
123
|
isMenuOpen,
|
|
121
124
|
nativeStateChange,
|
|
122
125
|
parseOpenState,
|
|
126
|
+
roundAttr,
|
|
123
127
|
roundStyle,
|
|
124
128
|
setMenuPresence,
|
|
125
129
|
toneStyle,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
-
import { toneStyle, roundStyle, wrapLabel } from "../anta_helpers";
|
|
2
|
+
import { toneStyle, roundStyle, roundAttr, wrapLabel } from "../anta_helpers";
|
|
3
3
|
const Button = ({
|
|
4
4
|
priority,
|
|
5
5
|
tone,
|
|
@@ -42,7 +42,7 @@ const Button = ({
|
|
|
42
42
|
// presence (`[disabled]`, not `[disabled="true"]`), so any present form
|
|
43
43
|
// works. (ARIA attributes below stay string-valued — ARIA needs "true".)
|
|
44
44
|
paddingless: paddingless ? "" : void 0,
|
|
45
|
-
round: round
|
|
45
|
+
round: roundAttr(round),
|
|
46
46
|
loading: loading ? "" : void 0,
|
|
47
47
|
disabled: disabled ? "" : void 0,
|
|
48
48
|
selected: selected ? "" : void 0,
|
|
@@ -1,23 +1,33 @@
|
|
|
1
1
|
import type { BaseProps } from "../general_types";
|
|
2
|
+
import type { IconShape } from "../elements/a-icon.shapes";
|
|
2
3
|
export interface CardProps extends BaseProps {
|
|
3
|
-
/** Header content,
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
/** Header content, in the top zone. A string is wrapped in a `<Title>` — a real
|
|
5
|
+
* heading in the document outline, tinted to match `tone`, at a level that
|
|
6
|
+
* tracks `size` (small → 5, medium → 4, large → 3). Pass your own node
|
|
7
|
+
* (`<Title level={2}>`, an `<h2>`) for a different level or styling. Omit for
|
|
8
|
+
* no header. */
|
|
6
9
|
header?: React.ReactNode;
|
|
10
|
+
/** A secondary line under the header title, rendered as smaller text
|
|
11
|
+
* (`<Text size="small">`) in the heading section. Tinted to match `tone`, like
|
|
12
|
+
* the title. Omit for no subtitle. */
|
|
13
|
+
subtitle?: React.ReactNode;
|
|
14
|
+
/** Leading visual for the header, laid out to the left of the `header` /
|
|
15
|
+
* `subtitle` as one aligned row (so it doesn't sit inline in the title, where it
|
|
16
|
+
* mis-aligns). A **string** is an icon shape, rendered as an `<Icon>` inside a
|
|
17
|
+
* circular chip (sized per the card via `--card-icon-size`); pass an `<img>`,
|
|
18
|
+
* initials (`<Text>`), or any node to use it as-is. Omit for none. */
|
|
19
|
+
icon?: IconShape | (string & {}) | React.ReactNode;
|
|
7
20
|
/** Footer content, usually action buttons. Rendered as a **left-aligned** row
|
|
8
21
|
* (wraps under pressure) — the opposite of `Dialog`'s right-aligned footer. */
|
|
9
22
|
footer?: React.ReactNode;
|
|
10
|
-
/** Controls rendered at the top-right of the header row, OUTSIDE the header
|
|
11
|
-
* (e.g. a "more" button, a tag) — the same slot as `Expander`'s `actions`. */
|
|
12
|
-
actions?: React.ReactNode;
|
|
13
23
|
/** Media (image, illustration) rendered full-bleed to the card edge, clipped to
|
|
14
24
|
* its corners. Position it with `mediaPosition`. */
|
|
15
25
|
media?: React.ReactNode;
|
|
16
26
|
/** Which edge the `media` bleeds to.
|
|
17
27
|
* @defaultValue 'top' */
|
|
18
28
|
mediaPosition?: "top" | "bottom" | "left" | "right";
|
|
19
|
-
/** The card body. A string
|
|
20
|
-
*
|
|
29
|
+
/** The card body. A string is wrapped in a `<Text>` at secondary priority,
|
|
30
|
+
* following the card's `tone` and `size`; pass your own nodes to take over. */
|
|
21
31
|
children?: React.ReactNode;
|
|
22
32
|
/** Semantic tone, or any literal CSS color (`'#ff1493'`, `'rebeccapurple'`) for
|
|
23
33
|
* a one-off custom tone. Named tones re-point the surface + text; a custom
|
|
@@ -60,11 +70,15 @@ export interface CardProps extends BaseProps {
|
|
|
60
70
|
* region plus a `header` / body / `footer` stack. Pass `href` to turn the whole
|
|
61
71
|
* card into a link.
|
|
62
72
|
*
|
|
63
|
-
* Renders an `<a-card>` web component. A
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* `
|
|
67
|
-
*
|
|
73
|
+
* Renders an `<a-card>` web component. A stateless projection — the element owns
|
|
74
|
+
* layout, the link, and the accessible name, and stylizes only its own surface
|
|
75
|
+
* (never its children's typography). The wrapper maps props to attributes,
|
|
76
|
+
* projects content into the `media` / `icon` / `header` / body / `footer`
|
|
77
|
+
* sections, and supplies typography for the two text zones by wrapping a string
|
|
78
|
+
* `header` in `<Title>` and a string body in `<Text>`. A leading `icon` (a shape
|
|
79
|
+
* string, or any node) is laid out beside the title / subtitle by the element.
|
|
80
|
+
* There is no actions slot — lay out any header controls (buttons, tags) inside
|
|
81
|
+
* the `header` yourself.
|
|
68
82
|
*
|
|
69
83
|
* Requires `@antadesign/anta/elements` to be imported (client-side only) to
|
|
70
84
|
* register the underlying custom element.
|
|
@@ -83,4 +97,4 @@ export interface CardProps extends BaseProps {
|
|
|
83
97
|
* </Card>
|
|
84
98
|
* ```
|
|
85
99
|
*/
|
|
86
|
-
export declare const Card: ({ header,
|
|
100
|
+
export declare const Card: ({ header, subtitle, icon, footer, media, mediaPosition, tone, priority, size, selected, loading, round, href, target, rel, ping, className, style, children, ...rest }: CardProps) => any;
|
package/dist/components/Card.js
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
-
import { toneStyle, roundStyle } from "../anta_helpers";
|
|
2
|
+
import { toneStyle, roundStyle, roundAttr } from "../anta_helpers";
|
|
3
|
+
import { Title } from "./Title";
|
|
4
|
+
import { Text } from "./Text";
|
|
5
|
+
import { Icon } from "./Icon";
|
|
3
6
|
const Card = ({
|
|
4
7
|
header,
|
|
8
|
+
subtitle,
|
|
9
|
+
icon,
|
|
5
10
|
footer,
|
|
6
|
-
actions,
|
|
7
11
|
media,
|
|
8
12
|
mediaPosition,
|
|
9
13
|
tone,
|
|
@@ -27,6 +31,7 @@ const Card = ({
|
|
|
27
31
|
"--card-round",
|
|
28
32
|
toneStyle(toneAttr, "--card-tone-source", style)
|
|
29
33
|
);
|
|
34
|
+
const titleLevel = size === "small" ? 5 : size === "large" ? 3 : 4;
|
|
30
35
|
return /* @__PURE__ */ jsxs(
|
|
31
36
|
"a-card",
|
|
32
37
|
{
|
|
@@ -36,7 +41,7 @@ const Card = ({
|
|
|
36
41
|
"media-position": mediaPosition && mediaPosition !== "top" ? mediaPosition : void 0,
|
|
37
42
|
selected: selected ? "" : void 0,
|
|
38
43
|
loading: loading ? "" : void 0,
|
|
39
|
-
round: round
|
|
44
|
+
round: roundAttr(round),
|
|
40
45
|
href,
|
|
41
46
|
target: href ? target : void 0,
|
|
42
47
|
rel: href ? rel : void 0,
|
|
@@ -46,22 +51,49 @@ const Card = ({
|
|
|
46
51
|
...rest,
|
|
47
52
|
children: [
|
|
48
53
|
media != null && /* @__PURE__ */ jsx("div", { slot: "media", children: media }),
|
|
49
|
-
|
|
50
|
-
// header
|
|
51
|
-
//
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
54
|
+
icon != null && // Leading visual for the header — carried in a slot div (like `media` /
|
|
55
|
+
// `header`); the element lays it out beside the title / subtitle (see the
|
|
56
|
+
// `icon` slot in a-card.ts).
|
|
57
|
+
(typeof icon === "string" ? (
|
|
58
|
+
// A shape string → the icon centered in a circular chip, sized per the
|
|
59
|
+
// card via --card-icon-size (32 / 40 / 44 for small / medium / large).
|
|
60
|
+
/* @__PURE__ */ jsx(
|
|
61
|
+
"div",
|
|
62
|
+
{
|
|
63
|
+
slot: "icon",
|
|
64
|
+
style: {
|
|
65
|
+
width: "var(--card-icon-size, 40px)",
|
|
66
|
+
height: "var(--card-icon-size, 40px)",
|
|
67
|
+
borderRadius: "50%",
|
|
68
|
+
background: "var(--card-icon-bg)",
|
|
69
|
+
display: "grid",
|
|
70
|
+
placeItems: "center"
|
|
71
|
+
},
|
|
72
|
+
children: /* @__PURE__ */ jsx(Icon, { shape: icon })
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
) : (
|
|
76
|
+
// Any node → used as-is (no chip).
|
|
77
|
+
/* @__PURE__ */ jsx("div", { slot: "icon", children: icon })
|
|
78
|
+
)),
|
|
79
|
+
header != null && (typeof header === "string" || typeof header === "number" ? (
|
|
80
|
+
// A string header becomes a real <Title> at the size-mapped level (see
|
|
81
|
+
// titleLevel). The header section's padding is the header→body gap; the
|
|
82
|
+
// element zeroes the slotted title's own margins so it doesn't double it.
|
|
83
|
+
// Pass a node (a `<Title level={n}>`, an `<h2>`) for a different level.
|
|
84
|
+
/* @__PURE__ */ jsx(Title, { slot: "header", level: titleLevel, tone: toneAttr, children: header })
|
|
85
|
+
) : /* @__PURE__ */ jsx("div", { slot: "header", children: header })),
|
|
86
|
+
subtitle != null && // A subtitle sits in the header section too, right under the title, as
|
|
87
|
+
// smaller text. Last header child, so its (absent) bottom margin leaves
|
|
88
|
+
// the header→body gap to the section padding, like the title above it.
|
|
89
|
+
/* @__PURE__ */ jsx(Text, { slot: "header", size: "small", priority: "tertiary", tone: toneAttr, children: subtitle }),
|
|
90
|
+
typeof children === "string" || typeof children === "number" ? (
|
|
91
|
+
// A string / number body becomes a <Text> at secondary priority (text-2,
|
|
92
|
+
// the body colour) — stated explicitly rather than leaning on the default —
|
|
93
|
+
// following the card's tone and size. Anything else is a node the caller
|
|
94
|
+
// owns, passed through untouched.
|
|
95
|
+
/* @__PURE__ */ jsx(Text, { priority: "secondary", tone: toneAttr, size, children })
|
|
96
|
+
) : children,
|
|
65
97
|
footer != null && /* @__PURE__ */ jsx("span", { slot: "footer", style: { display: "contents" }, children: footer })
|
|
66
98
|
]
|
|
67
99
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/* Header with a leading avatar. When an `avatar` is passed, the wrapper unites it
|
|
2
|
+
with the title + subtitle as one flex row, so a leading icon / image / initials
|
|
3
|
+
aligns as a unit with the heading instead of sitting inline inside the title
|
|
4
|
+
(where it's baseline-misaligned and has no clean vertical-centering escape).
|
|
5
|
+
The element stays neutral — this layout lives in the light-DOM header node the
|
|
6
|
+
wrapper slots in. */
|
|
7
|
+
.header {
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: flex-start;
|
|
10
|
+
gap: 12px;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.avatar {
|
|
14
|
+
flex: none;
|
|
15
|
+
display: flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/* Title + subtitle column. min-width:0 lets a long title truncate rather than
|
|
20
|
+
push the avatar. */
|
|
21
|
+
.text {
|
|
22
|
+
min-width: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* The title / subtitle are nested here (not direct <a-card> slot children), so the
|
|
26
|
+
element's header-margin rules don't reach them — neutralize the title's own
|
|
27
|
+
document margins and give the subtitle the same 2px gap it gets elsewhere. The
|
|
28
|
+
[level] / tag specificity clears a-title's per-level margins. */
|
|
29
|
+
.text > :is(h1, h2, h3, h4, h5, h6),
|
|
30
|
+
.text > a-title[level] {
|
|
31
|
+
margin-block: 0;
|
|
32
|
+
}
|
|
33
|
+
.text > a-text {
|
|
34
|
+
margin-block-start: 2px;
|
|
35
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
-
import { nativeStateChange, toneStyle, roundStyle } from "../anta_helpers";
|
|
2
|
+
import { nativeStateChange, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
|
|
3
3
|
const valueToState = (v) => v === "indeterminate" ? "indeterminate" : v ? "checked" : "unchecked";
|
|
4
4
|
const stateToValue = (s) => s === "indeterminate" ? "indeterminate" : s === "checked";
|
|
5
5
|
const checkboxAttrsOf = (el) => ({
|
|
@@ -66,7 +66,7 @@ const Checkbox = ({
|
|
|
66
66
|
tone: tone && tone !== "neutral" ? tone : void 0,
|
|
67
67
|
"tone-selected": toneSelected && toneSelected !== "neutral" ? toneSelected : void 0,
|
|
68
68
|
size: size && size !== "medium" ? size : void 0,
|
|
69
|
-
round: round
|
|
69
|
+
round: roundAttr(round),
|
|
70
70
|
tabIndex: disabled ? -1 : tabIndex ?? 0,
|
|
71
71
|
onstatechange,
|
|
72
72
|
onchange,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
-
import { nativeStateChange, roundStyle } from "../anta_helpers";
|
|
2
|
+
import { nativeStateChange, roundStyle, roundAttr } from "../anta_helpers";
|
|
3
3
|
import { Button } from "./Button";
|
|
4
4
|
const ROUND_SIDES = /* @__PURE__ */ new Set(["top", "right", "bottom", "left"]);
|
|
5
5
|
const Dialog = ({
|
|
@@ -27,11 +27,11 @@ const Dialog = ({
|
|
|
27
27
|
"default-state": !controlled && defaultOpen ? "open" : void 0,
|
|
28
28
|
position: position && position !== "center" ? position : void 0,
|
|
29
29
|
persistent: persistent ? "" : void 0,
|
|
30
|
-
round: roundSide ?? (round
|
|
30
|
+
round: roundSide ?? roundAttr(round),
|
|
31
31
|
name: !controlled ? name : void 0,
|
|
32
32
|
onstatechange: onStateChange ? (e) => {
|
|
33
|
-
const { event, detail } = nativeStateChange(e);
|
|
34
|
-
if (detail)
|
|
33
|
+
const { event, detail, isOwn } = nativeStateChange(e);
|
|
34
|
+
if (isOwn && detail)
|
|
35
35
|
onStateChange(event, {
|
|
36
36
|
next: detail.next === "open",
|
|
37
37
|
prev: detail.prev === "open"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
-
import { nativeStateChange, toneStyle, roundStyle } from "../anta_helpers";
|
|
2
|
+
import { nativeStateChange, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
|
|
3
3
|
const Expander = ({
|
|
4
4
|
title,
|
|
5
5
|
level,
|
|
@@ -29,11 +29,11 @@ const Expander = ({
|
|
|
29
29
|
tone: tone && tone !== "neutral" ? tone : void 0,
|
|
30
30
|
priority: priority && priority !== "secondary" ? priority : void 0,
|
|
31
31
|
outdent: outdent ? "" : void 0,
|
|
32
|
-
round: round
|
|
32
|
+
round: roundAttr(round),
|
|
33
33
|
disabled: disabled ? "" : void 0,
|
|
34
34
|
onstatechange: onStateChange ? (e) => {
|
|
35
|
-
const { event, detail } = nativeStateChange(e);
|
|
36
|
-
if (detail)
|
|
35
|
+
const { event, detail, isOwn } = nativeStateChange(e);
|
|
36
|
+
if (isOwn && detail)
|
|
37
37
|
onStateChange(event, {
|
|
38
38
|
next: detail.next === "open",
|
|
39
39
|
prev: detail.prev === "open"
|
package/dist/components/Input.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
-
import { nativeStateChange, toneStyle, roundStyle } from "../anta_helpers";
|
|
2
|
+
import { nativeStateChange, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
|
|
3
3
|
import { Button } from "./Button";
|
|
4
4
|
import { Icon } from "./Icon";
|
|
5
5
|
const presence = (on) => on ? "" : void 0;
|
|
@@ -82,7 +82,7 @@ const Input = ({
|
|
|
82
82
|
"a-input",
|
|
83
83
|
{
|
|
84
84
|
size: size && size !== "medium" ? size : void 0,
|
|
85
|
-
round: round
|
|
85
|
+
round: roundAttr(round),
|
|
86
86
|
value,
|
|
87
87
|
defaultvalue: defaultValue,
|
|
88
88
|
multiline: presence(multiline || rows != null),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
-
import { nativeStateChange, toneStyle, roundStyle } from "../anta_helpers";
|
|
2
|
+
import { nativeStateChange, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
|
|
3
3
|
import { Button } from "./Button";
|
|
4
4
|
import { Icon } from "./Icon";
|
|
5
5
|
const presence = (on) => on ? "" : void 0;
|
|
@@ -56,7 +56,7 @@ const InputTime = ({
|
|
|
56
56
|
"a-input-time",
|
|
57
57
|
{
|
|
58
58
|
size: size && size !== "medium" ? size : void 0,
|
|
59
|
-
round: round
|
|
59
|
+
round: roundAttr(round),
|
|
60
60
|
value,
|
|
61
61
|
defaultvalue: defaultValue,
|
|
62
62
|
locale,
|
package/dist/components/Menu.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx } from "@antadesign/anta/jsx-runtime";
|
|
2
|
-
import { nativeStateChange, roundStyle } from "../anta_helpers";
|
|
2
|
+
import { nativeStateChange, roundStyle, roundAttr } from "../anta_helpers";
|
|
3
3
|
const Menu = ({
|
|
4
4
|
placement,
|
|
5
5
|
context,
|
|
@@ -27,14 +27,14 @@ const Menu = ({
|
|
|
27
27
|
autowidth: autoWidth ? "" : void 0,
|
|
28
28
|
state: open === void 0 ? void 0 : open ? "open" : "closed",
|
|
29
29
|
onstatechange: onStateChange ? (e) => {
|
|
30
|
-
const { event, detail } = nativeStateChange(e);
|
|
31
|
-
if (
|
|
30
|
+
const { event, detail, isOwn } = nativeStateChange(e);
|
|
31
|
+
if (isOwn && detail)
|
|
32
32
|
onStateChange(event, {
|
|
33
33
|
next: detail.next === "open",
|
|
34
34
|
prev: detail.prev === "open"
|
|
35
35
|
});
|
|
36
36
|
} : void 0,
|
|
37
|
-
round: round
|
|
37
|
+
round: roundAttr(round),
|
|
38
38
|
role,
|
|
39
39
|
"aria-orientation": "vertical",
|
|
40
40
|
class: className,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { BaseProps } from '../general_types';
|
|
2
2
|
import type { IconShape } from '../elements/a-icon.shapes';
|
|
3
|
-
|
|
3
|
+
/** Props shared by every menu item, link or not. */
|
|
4
|
+
export interface MenuItemCommonProps extends BaseProps {
|
|
4
5
|
/** Leading icon shape. */
|
|
5
6
|
icon?: IconShape;
|
|
6
7
|
/** The item's text. Usually a string, but any node is accepted — e.g. a filtered
|
|
@@ -17,33 +18,15 @@ export interface MenuItemProps extends BaseProps {
|
|
|
17
18
|
* chevron (omit it to keep the chevron); on a normal item it's the trailing
|
|
18
19
|
* glyph (omit for none). */
|
|
19
20
|
iconTrailing?: IconShape;
|
|
20
|
-
/** Disable the item: greyed out, not focusable for activation, no close.
|
|
21
|
+
/** Disable the item: greyed out, not focusable for activation, no close. A
|
|
22
|
+
* disabled link also drops its `href`, so it can't navigate. */
|
|
21
23
|
disabled?: boolean;
|
|
22
24
|
/** Mark the item as selected. On a plain row (no `selectionIndicator`) this is
|
|
23
|
-
* a persistent background tint, the same resting fill a pressed row shows
|
|
24
|
-
*
|
|
25
|
-
* `
|
|
25
|
+
* a persistent background tint, the same resting fill a pressed row shows —
|
|
26
|
+
* also the way to flag the current page on a link item. On a checkable row
|
|
27
|
+
* (`selectionIndicator` set) it instead drives the leading `checkbox` / `radio`
|
|
28
|
+
* indicator and the row's `aria-checked`. */
|
|
26
29
|
selected?: boolean;
|
|
27
|
-
/** Turn the row into a checkable item, driven by `selected` (the row stays the
|
|
28
|
-
* control and carries `aria-checked`):
|
|
29
|
-
* - `'checkbox'` → `role="menuitemcheckbox"`, a leading passive `<a-checkbox>`
|
|
30
|
-
* (before `icon`); the tint is dropped (the box carries state).
|
|
31
|
-
* - `'radio'` → `role="menuitemradio"`, a leading passive `<a-radio>`; tint dropped.
|
|
32
|
-
* - `'check'` → `role="menuitemradio"`, a trailing check glyph on the selected
|
|
33
|
-
* row *and* the background tint (the canonical single-select look).
|
|
34
|
-
* Omit for a plain row (the default). */
|
|
35
|
-
selectionIndicator?: 'checkbox' | 'radio' | 'check';
|
|
36
|
-
/** Only meaningful with `selectionIndicator="checkbox"`: render the box in the
|
|
37
|
-
* mixed state (`aria-checked="mixed"`) — e.g. a "Select all" row when some but
|
|
38
|
-
* not all of its options are selected. */
|
|
39
|
-
indeterminate?: boolean;
|
|
40
|
-
/** Replace the built-in selection-indicator *visual* with your own node,
|
|
41
|
-
* rendered at the **leading** edge (where the checkbox / radio sit). Pair with
|
|
42
|
-
* `selectionIndicator` to keep the semantics — the row stays the control and
|
|
43
|
-
* carries `role` + `aria-checked`; only the drawn mark changes. Suppresses the
|
|
44
|
-
* built-in checkbox / radio and the trailing `check` glyph. The node is made
|
|
45
|
-
* passive (aria-hidden, no pointer events) so the row owns the click. */
|
|
46
|
-
indicator?: React.ReactNode;
|
|
47
30
|
/** Semantic tone — colors the label, icon, and hover/selected tint (and the
|
|
48
31
|
* `checkbox`/`radio` indicator, which adopts it). A named tone, or any literal
|
|
49
32
|
* CSS color (`'#ff1493'`, `'rebeccapurple'`) for a one-off custom tone whose
|
|
@@ -58,10 +41,6 @@ export interface MenuItemProps extends BaseProps {
|
|
|
58
41
|
* `toneSelected` wins over `tone` when both are set.
|
|
59
42
|
* @defaultValue neutral */
|
|
60
43
|
toneSelected?: 'neutral' | 'brand' | 'info' | 'success' | 'warning' | 'critical' | (string & {});
|
|
61
|
-
/** Marks this item as a submenu parent: adds the trailing chevron,
|
|
62
|
-
* `aria-haspopup="menu"`, and an `aria-expanded` baseline (kept in sync by
|
|
63
|
-
* the nested menu). Nest the flyout as a `<Menu>` child. */
|
|
64
|
-
submenu?: boolean;
|
|
65
44
|
/** An opaque value identifying this item, handed back in `onSelect`'s detail
|
|
66
45
|
* so a shared handler can tell which row was chosen without a per-item
|
|
67
46
|
* closure. */
|
|
@@ -69,8 +48,9 @@ export interface MenuItemProps extends BaseProps {
|
|
|
69
48
|
/** Activation handler — fires when *this* item is chosen (click / Enter /
|
|
70
49
|
* Space), unless it's `disabled`. It does **not** fire for a submenu parent
|
|
71
50
|
* (clicking that opens the flyout, which isn't a selection) nor for a
|
|
72
|
-
* selection bubbling up from a nested submenu.
|
|
73
|
-
* `{ value, label }`
|
|
51
|
+
* selection bubbling up from a nested submenu. On a link item it fires
|
|
52
|
+
* alongside the navigation. Receives the event plus a `{ value, label }`
|
|
53
|
+
* detail. */
|
|
74
54
|
onSelect?: (event: any, detail: {
|
|
75
55
|
value?: string | number;
|
|
76
56
|
label?: React.ReactNode;
|
|
@@ -87,6 +67,54 @@ export interface MenuItemProps extends BaseProps {
|
|
|
87
67
|
* notably the nested `<Menu>` for a submenu parent. */
|
|
88
68
|
children?: React.ReactNode;
|
|
89
69
|
}
|
|
70
|
+
export type MenuItemLinkMode = {
|
|
71
|
+
/** Renders the item as `<a role="menuitem" data-anta-menu-item href>`. */
|
|
72
|
+
href: string;
|
|
73
|
+
/** Anchor target, e.g. `'_blank'`. */
|
|
74
|
+
target?: string;
|
|
75
|
+
/** Anchor rel. */
|
|
76
|
+
rel?: string;
|
|
77
|
+
/** Download the resource instead of navigating: `true` / `''` uses the
|
|
78
|
+
* resource's default filename, a string overrides it. */
|
|
79
|
+
download?: string | boolean;
|
|
80
|
+
/** Space-separated URLs the browser pings on navigation. */
|
|
81
|
+
ping?: string;
|
|
82
|
+
submenu?: never;
|
|
83
|
+
selectionIndicator?: never;
|
|
84
|
+
indeterminate?: never;
|
|
85
|
+
indicator?: never;
|
|
86
|
+
};
|
|
87
|
+
export type MenuItemActionMode = {
|
|
88
|
+
href?: never;
|
|
89
|
+
target?: never;
|
|
90
|
+
rel?: never;
|
|
91
|
+
download?: never;
|
|
92
|
+
ping?: never;
|
|
93
|
+
/** Marks this item as a submenu parent: adds the trailing chevron and
|
|
94
|
+
* `aria-haspopup="menu"`. Nest the flyout as a `<Menu>` child. */
|
|
95
|
+
submenu?: boolean;
|
|
96
|
+
/** Turn the row into a checkable item, driven by `selected` (the row stays the
|
|
97
|
+
* control and carries `aria-checked`):
|
|
98
|
+
* - `'checkbox'` → `role="menuitemcheckbox"`, a leading passive `<a-checkbox>`
|
|
99
|
+
* (before `icon`); the tint is dropped (the box carries state).
|
|
100
|
+
* - `'radio'` → `role="menuitemradio"`, a leading passive `<a-radio>`; tint dropped.
|
|
101
|
+
* - `'check'` → `role="menuitemradio"`, a trailing check glyph on the selected
|
|
102
|
+
* row *and* the background tint (the canonical single-select look).
|
|
103
|
+
* Omit for a plain row (the default). */
|
|
104
|
+
selectionIndicator?: 'checkbox' | 'radio' | 'check';
|
|
105
|
+
/** Only meaningful with `selectionIndicator="checkbox"`: render the box in the
|
|
106
|
+
* mixed state (`aria-checked="mixed"`) — e.g. a "Select all" row when some but
|
|
107
|
+
* not all of its options are selected. */
|
|
108
|
+
indeterminate?: boolean;
|
|
109
|
+
/** Replace the built-in selection-indicator *visual* with your own node,
|
|
110
|
+
* rendered at the **leading** edge (where the checkbox / radio sit). Pair with
|
|
111
|
+
* `selectionIndicator` to keep the semantics — the row stays the control and
|
|
112
|
+
* carries `role` + `aria-checked`; only the drawn mark changes. Suppresses the
|
|
113
|
+
* built-in checkbox / radio and the trailing `check` glyph. The node is made
|
|
114
|
+
* passive (aria-hidden, no pointer events) so the row owns the click. */
|
|
115
|
+
indicator?: React.ReactNode;
|
|
116
|
+
};
|
|
117
|
+
export type MenuItemProps = MenuItemCommonProps & (MenuItemLinkMode | MenuItemActionMode);
|
|
90
118
|
/**
|
|
91
119
|
* MenuItem — a single selectable row inside a `Menu`. Composes a leading
|
|
92
120
|
* `icon`, a `label` (or `children`), an optional trailing `kbd` hint, and an
|
|
@@ -107,4 +135,4 @@ export interface MenuItemProps extends BaseProps {
|
|
|
107
135
|
* </MenuItem>
|
|
108
136
|
* ```
|
|
109
137
|
*/
|
|
110
|
-
export declare const MenuItem: ({ icon, label, hint, kbd, iconTrailing, disabled, selected, selectionIndicator, indeterminate, indicator, tone, toneSelected, submenu, value, onSelect, role: roleOverride, className, style, children, ...rest }: MenuItemProps) => any;
|
|
138
|
+
export declare const MenuItem: ({ icon, label, hint, kbd, iconTrailing, disabled, selected, selectionIndicator, indeterminate, indicator, tone, toneSelected, submenu, value, onSelect, href, target, rel, download, ping, role: roleOverride, className, style, children, ...rest }: MenuItemProps) => any;
|
|
@@ -16,6 +16,11 @@ const MenuItem = ({
|
|
|
16
16
|
submenu,
|
|
17
17
|
value,
|
|
18
18
|
onSelect,
|
|
19
|
+
href,
|
|
20
|
+
target,
|
|
21
|
+
rel,
|
|
22
|
+
download,
|
|
23
|
+
ping,
|
|
19
24
|
role: roleOverride,
|
|
20
25
|
className,
|
|
21
26
|
style,
|
|
@@ -28,6 +33,35 @@ const MenuItem = ({
|
|
|
28
33
|
const keepTint = selected && (selectionIndicator === void 0 || selectionIndicator === "check");
|
|
29
34
|
const effectiveTone = selected && toneSelected || tone;
|
|
30
35
|
const toneAttr = effectiveTone && effectiveTone !== "neutral" ? effectiveTone : void 0;
|
|
36
|
+
const labelNode = label != null && (hint != null ? /* @__PURE__ */ jsxs("a-menu-item-text", { children: [
|
|
37
|
+
/* @__PURE__ */ jsx("a-menu-item-label", { children: label }),
|
|
38
|
+
/* @__PURE__ */ jsx("a-menu-item-hint", { children: hint })
|
|
39
|
+
] }) : /* @__PURE__ */ jsx("a-menu-item-label", { children: label }));
|
|
40
|
+
if (href != null) {
|
|
41
|
+
const linkAttrs = {
|
|
42
|
+
"data-anta-menu-item": "",
|
|
43
|
+
role: roleOverride ?? "menuitem",
|
|
44
|
+
href: disabled ? void 0 : href,
|
|
45
|
+
target,
|
|
46
|
+
rel,
|
|
47
|
+
download: download === true ? "" : download || void 0,
|
|
48
|
+
ping,
|
|
49
|
+
tabIndex: disabled ? -1 : 0,
|
|
50
|
+
"aria-disabled": disabled ? "true" : void 0,
|
|
51
|
+
"aria-current": selected ? "true" : void 0,
|
|
52
|
+
tone: toneAttr,
|
|
53
|
+
style: toneStyle(effectiveTone, "--menu-item-tone-source", style),
|
|
54
|
+
onClick: onSelect && !disabled ? (e) => onSelect(e, { value, label }) : void 0,
|
|
55
|
+
class: className
|
|
56
|
+
};
|
|
57
|
+
return /* @__PURE__ */ jsxs("a", { ...linkAttrs, ...rest, children: [
|
|
58
|
+
icon && /* @__PURE__ */ jsx("a-icon", { shape: icon, "aria-hidden": "true" }),
|
|
59
|
+
labelNode,
|
|
60
|
+
children,
|
|
61
|
+
kbd && /* @__PURE__ */ jsx("kbd", { children: kbd }),
|
|
62
|
+
iconTrailing && /* @__PURE__ */ jsx("a-icon", { shape: iconTrailing, "aria-hidden": "true" })
|
|
63
|
+
] });
|
|
64
|
+
}
|
|
31
65
|
return /* @__PURE__ */ jsxs(
|
|
32
66
|
"a-menu-item",
|
|
33
67
|
{
|
|
@@ -83,15 +117,7 @@ const MenuItem = ({
|
|
|
83
117
|
)
|
|
84
118
|
) : null,
|
|
85
119
|
icon && /* @__PURE__ */ jsx("a-icon", { shape: icon, "aria-hidden": "true" }),
|
|
86
|
-
|
|
87
|
-
// A hint stacks under the label in a column; the icon / kbd / trailing
|
|
88
|
-
// icon stay in the row (the item's `align-items: center` centers them
|
|
89
|
-
// against the two-line block).
|
|
90
|
-
/* @__PURE__ */ jsxs("a-menu-item-text", { children: [
|
|
91
|
-
/* @__PURE__ */ jsx("a-menu-item-label", { children: label }),
|
|
92
|
-
/* @__PURE__ */ jsx("a-menu-item-hint", { children: hint })
|
|
93
|
-
] })
|
|
94
|
-
) : /* @__PURE__ */ jsx("a-menu-item-label", { children: label })),
|
|
120
|
+
labelNode,
|
|
95
121
|
children,
|
|
96
122
|
kbd && /* @__PURE__ */ jsx("kbd", { children: kbd }),
|
|
97
123
|
(() => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "@antadesign/anta/jsx-runtime";
|
|
2
|
-
import { hasChildren, toneStyle, roundStyle } from "../anta_helpers";
|
|
2
|
+
import { hasChildren, toneStyle, roundStyle, roundAttr } from "../anta_helpers";
|
|
3
3
|
const Progress = ({ value, max = 100, tone, round, label, hint, className, style, children, ...rest }) => {
|
|
4
4
|
const percent = max > 0 ? Math.round(Math.min(100, Math.max(0, value / max * 100))) : 0;
|
|
5
5
|
const clampedValue = max > 0 ? Math.min(max, Math.max(0, value)) : 0;
|
|
@@ -10,7 +10,7 @@ const Progress = ({ value, max = 100, tone, round, label, hint, className, style
|
|
|
10
10
|
value,
|
|
11
11
|
max,
|
|
12
12
|
tone: tone && tone !== "neutral" ? tone : void 0,
|
|
13
|
-
round: round
|
|
13
|
+
round: roundAttr(round),
|
|
14
14
|
role: "progressbar",
|
|
15
15
|
"aria-valuenow": clampedValue,
|
|
16
16
|
"aria-valuemin": 0,
|