@robr0/design-system 0.2.0 → 0.4.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 +33 -28
- package/components/Accordion/Accordion.js +0 -1
- package/components/AgentStatus/AgentStatus.css +436 -0
- package/components/AgentStatus/AgentStatus.d.ts +37 -0
- package/components/AgentStatus/AgentStatus.js +53 -0
- package/components/AgentStatus/AgentStatusPatterns.d.ts +17 -0
- package/components/AgentStatus/AgentStatusPatterns.js +20 -0
- package/components/AlertDialog/AlertDialog.css +5 -5
- package/components/Avatar/Avatar.js +1 -0
- package/components/Breadcrumb/Breadcrumb.d.ts +7 -1
- package/components/Breadcrumb/Breadcrumb.js +3 -2
- package/components/Button/Button.css +18 -0
- package/components/Button/Button.d.ts +20 -2
- package/components/Button/Button.js +13 -3
- package/components/ButtonGroup/ButtonGroup.js +2 -9
- package/components/Card/Card.css +6 -0
- package/components/Checkbox/Checkbox.d.ts +17 -3
- package/components/CircularButton/CircularButton.css +11 -0
- package/components/CircularButton/CircularButton.d.ts +15 -3
- package/components/CircularButton/CircularButton.js +19 -6
- package/components/CodeBlock/CodeBlock.js +10 -1
- package/components/ColorPicker/ColorPicker.css +278 -0
- package/components/ColorPicker/ColorPicker.d.ts +50 -0
- package/components/ColorPicker/ColorPicker.js +338 -0
- package/components/Combobox/Combobox.css +0 -36
- package/components/Combobox/Combobox.d.ts +10 -2
- package/components/Combobox/Combobox.js +90 -82
- package/components/CommandPalette/CommandPalette.css +1 -15
- package/components/CommandPalette/CommandPalette.js +6 -5
- package/components/ContextMenu/ContextMenu.css +258 -0
- package/components/ContextMenu/ContextMenu.d.ts +26 -0
- package/components/ContextMenu/ContextMenu.js +350 -0
- package/components/DateInput/DateInput.css +0 -36
- package/components/DateInput/DateInput.d.ts +5 -1
- package/components/DateInput/DateInput.js +37 -33
- package/components/DatePicker/DatePicker.js +45 -34
- package/components/Dialog/Dialog.css +5 -5
- package/components/Dialog/Dialog.js +5 -4
- package/components/Drawer/Drawer.js +7 -2
- package/components/Dropdown/Dropdown.css +2 -40
- package/components/Dropdown/Dropdown.d.ts +10 -2
- package/components/Dropdown/Dropdown.js +119 -109
- package/components/DropdownMenu/DropdownMenu.css +2 -4
- package/components/DropdownMenu/DropdownMenu.js +10 -7
- package/components/Field/Field.css +80 -0
- package/components/Field/Field.d.ts +50 -0
- package/components/Field/Field.js +58 -0
- package/components/Field/FieldContext.d.ts +42 -0
- package/components/Field/FieldContext.js +7 -0
- package/components/FileInput/FileInput.css +0 -36
- package/components/FileInput/FileInput.d.ts +5 -1
- package/components/FileInput/FileInput.js +111 -103
- package/components/Input/Input.css +0 -43
- package/components/Input/Input.d.ts +5 -1
- package/components/Input/Input.js +51 -46
- package/components/Kbd/Kbd.css +28 -0
- package/components/Kbd/Kbd.d.ts +19 -0
- package/components/Kbd/Kbd.js +14 -0
- package/components/LinkList/LinkList.d.ts +1 -0
- package/components/Popover/Popover.d.ts +0 -6
- package/components/Popover/Popover.js +22 -16
- package/components/ProgressBar/ProgressBar.js +1 -1
- package/components/RadioButton/RadioButton.d.ts +17 -3
- package/components/Reasoning/Reasoning.css +152 -0
- package/components/Reasoning/Reasoning.d.ts +36 -0
- package/components/Reasoning/Reasoning.js +69 -0
- package/components/SelectionCard/SelectionCard.css +6 -2
- package/components/SelectionCard/SelectionCard.d.ts +5 -1
- package/components/Skeleton/Skeleton.css +2 -0
- package/components/Slider/Slider.d.ts +5 -1
- package/components/Spinner/Spinner.css +11 -0
- package/components/Spinner/Spinner.d.ts +2 -2
- package/components/Swatch/Swatch.css +52 -0
- package/components/Swatch/Swatch.d.ts +34 -0
- package/components/Swatch/Swatch.js +44 -0
- package/components/Table/Table.css +19 -0
- package/components/Table/Table.js +1 -1
- package/components/Textarea/Textarea.css +0 -43
- package/components/Textarea/Textarea.d.ts +5 -1
- package/components/Textarea/Textarea.js +37 -35
- package/components/Timeline/Timeline.d.ts +2 -0
- package/components/ToggleGroup/ToggleGroup.d.ts +10 -2
- package/components/ToggleSwitch/ToggleSwitch.css +7 -2
- package/components/ToggleSwitch/ToggleSwitch.d.ts +10 -2
- package/components/ToolCall/ToolCall.css +213 -0
- package/components/ToolCall/ToolCall.d.ts +43 -0
- package/components/ToolCall/ToolCall.js +89 -0
- package/components/registry.d.ts +47 -10
- package/components/registry.js +5 -1
- package/components/registry.json +523 -56
- package/components/registry.json.d.ts +523 -56
- package/components/registry.json.js +4 -1
- package/index.d.ts +12 -1
- package/index.js +24 -1
- package/package.json +8 -4
- package/tokens/registry.json +1 -0
- package/tokens/registry.json.d.ts +1 -0
- package/tokens/registry.json.js +1 -1
- package/tokens/tokens-motion.css +3 -1
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import "./AgentStatus.css";
|
|
4
|
+
const DOT_COUNT = 12;
|
|
5
|
+
const DEFAULT_LABELS = {
|
|
6
|
+
idle: "Idle",
|
|
7
|
+
thinking: "Thinking",
|
|
8
|
+
working: "Working",
|
|
9
|
+
waiting: "Waiting for you",
|
|
10
|
+
done: "Done",
|
|
11
|
+
error: "Failed"
|
|
12
|
+
};
|
|
13
|
+
const ACTIVE_STATES = ["thinking", "working", "waiting"];
|
|
14
|
+
const AgentStatus = React.forwardRef(
|
|
15
|
+
({
|
|
16
|
+
state = "thinking",
|
|
17
|
+
label,
|
|
18
|
+
pattern = "orbit",
|
|
19
|
+
shimmer,
|
|
20
|
+
size = "sm",
|
|
21
|
+
variant = "inline",
|
|
22
|
+
className = "",
|
|
23
|
+
children,
|
|
24
|
+
...rest
|
|
25
|
+
}, ref) => {
|
|
26
|
+
const baseClass = "ds-agent-status";
|
|
27
|
+
const isActive = ACTIVE_STATES.includes(state);
|
|
28
|
+
const isShimmering = shimmer ?? isActive;
|
|
29
|
+
const classes = [
|
|
30
|
+
baseClass,
|
|
31
|
+
`${baseClass}--${state}`,
|
|
32
|
+
`${baseClass}--${pattern}`,
|
|
33
|
+
`${baseClass}--${size}`,
|
|
34
|
+
`${baseClass}--${variant}`,
|
|
35
|
+
isActive ? `${baseClass}--animated` : "",
|
|
36
|
+
className
|
|
37
|
+
].filter(Boolean).join(" ");
|
|
38
|
+
return /* @__PURE__ */ jsxs("div", { ...rest, ref, className: classes, role: "status", children: [
|
|
39
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__matrix`, "aria-hidden": "true", children: Array.from({ length: DOT_COUNT }, (_, i) => /* @__PURE__ */ jsx("span", { className: `${baseClass}__dot` }, i)) }),
|
|
40
|
+
/* @__PURE__ */ jsx(
|
|
41
|
+
"span",
|
|
42
|
+
{
|
|
43
|
+
className: `${baseClass}__label${isShimmering ? ` ${baseClass}__label--shimmer` : ""}`,
|
|
44
|
+
children: children ?? label ?? DEFAULT_LABELS[state]
|
|
45
|
+
}
|
|
46
|
+
)
|
|
47
|
+
] });
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
AgentStatus.displayName = "AgentStatus";
|
|
51
|
+
export {
|
|
52
|
+
AgentStatus
|
|
53
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentStatus's vocabulary, kept out of the component file so that module
|
|
3
|
+
* exports only a component (react-refresh) — and exported rather than kept
|
|
4
|
+
* private so a consumer building a pattern picker, and this repo's own docs
|
|
5
|
+
* gallery, can iterate the list instead of restating it.
|
|
6
|
+
*
|
|
7
|
+
* `.tsx` despite holding no JSX: the barrel generator and the
|
|
8
|
+
* `./components/*` export subpath both address `.tsx`, so that extension is
|
|
9
|
+
* what makes this reachable as `@robr0/design-system/components/AgentStatus/AgentStatusPatterns`.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* The dot-matrix animations. Each pattern is a named choreography over the
|
|
13
|
+
* same 4x3 grid, so switching pattern never changes the indicator's footprint.
|
|
14
|
+
*/
|
|
15
|
+
export declare const agentStatusPatterns: readonly ["braille", "orbit", "breathe", "snake", "fill-sweep", "pulse", "columns", "checkerboard", "scan", "rain", "cascade", "sparkle", "wave-rows", "helix", "diagonal-swipe"];
|
|
16
|
+
export type AgentStatusPattern = (typeof agentStatusPatterns)[number];
|
|
17
|
+
export type AgentStatusState = 'idle' | 'thinking' | 'working' | 'waiting' | 'done' | 'error';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const agentStatusPatterns = [
|
|
2
|
+
"braille",
|
|
3
|
+
"orbit",
|
|
4
|
+
"breathe",
|
|
5
|
+
"snake",
|
|
6
|
+
"fill-sweep",
|
|
7
|
+
"pulse",
|
|
8
|
+
"columns",
|
|
9
|
+
"checkerboard",
|
|
10
|
+
"scan",
|
|
11
|
+
"rain",
|
|
12
|
+
"cascade",
|
|
13
|
+
"sparkle",
|
|
14
|
+
"wave-rows",
|
|
15
|
+
"helix",
|
|
16
|
+
"diagonal-swipe"
|
|
17
|
+
];
|
|
18
|
+
export {
|
|
19
|
+
agentStatusPatterns
|
|
20
|
+
};
|
|
@@ -81,11 +81,11 @@
|
|
|
81
81
|
============================================ */
|
|
82
82
|
|
|
83
83
|
.ds-alert-dialog__title {
|
|
84
|
-
font-family: var(--font-heading-
|
|
85
|
-
font-size: var(--font-heading-
|
|
86
|
-
font-weight: var(--font-heading-
|
|
87
|
-
line-height: var(--font-heading-
|
|
88
|
-
letter-spacing: var(--font-heading-
|
|
84
|
+
font-family: var(--font-heading-3-family);
|
|
85
|
+
font-size: var(--font-heading-3-size);
|
|
86
|
+
font-weight: var(--font-heading-3-weight);
|
|
87
|
+
line-height: var(--font-heading-3-line-height);
|
|
88
|
+
letter-spacing: var(--font-heading-3-letter-spacing);
|
|
89
89
|
color: var(--color-text-primary);
|
|
90
90
|
margin: 0;
|
|
91
91
|
}
|
|
@@ -11,9 +11,15 @@ export interface BreadcrumbProps {
|
|
|
11
11
|
maxItems?: number;
|
|
12
12
|
/** Additional CSS classes */
|
|
13
13
|
className?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Accessible name for the nav landmark. Override when more than one
|
|
16
|
+
* Breadcrumb can appear on a page — identically-named landmarks are
|
|
17
|
+
* indistinguishable to assistive technology.
|
|
18
|
+
*/
|
|
19
|
+
ariaLabel?: string;
|
|
14
20
|
}
|
|
15
21
|
/**
|
|
16
22
|
* Breadcrumb shows the user's location within a page hierarchy.
|
|
17
23
|
* Supports automatic collapsing of middle items when the list exceeds maxItems.
|
|
18
24
|
*/
|
|
19
|
-
export declare const Breadcrumb: ({ items, maxItems, className, }: BreadcrumbProps) => import("react").JSX.Element;
|
|
25
|
+
export declare const Breadcrumb: ({ items, maxItems, className, ariaLabel, }: BreadcrumbProps) => import("react").JSX.Element;
|
|
@@ -4,7 +4,8 @@ import "../../fonts/material-symbols.css";
|
|
|
4
4
|
const Breadcrumb = ({
|
|
5
5
|
items,
|
|
6
6
|
maxItems,
|
|
7
|
-
className = ""
|
|
7
|
+
className = "",
|
|
8
|
+
ariaLabel
|
|
8
9
|
}) => {
|
|
9
10
|
const baseClass = "ds-breadcrumb";
|
|
10
11
|
const classes = [baseClass, className].filter(Boolean).join(" ");
|
|
@@ -20,7 +21,7 @@ const Breadcrumb = ({
|
|
|
20
21
|
} else {
|
|
21
22
|
visibleItems = [...items];
|
|
22
23
|
}
|
|
23
|
-
return /* @__PURE__ */ jsx("nav", { className: classes, "aria-label": "Breadcrumb", children: /* @__PURE__ */ jsx("ol", { className: `${baseClass}__list`, children: visibleItems.map((item, index) => {
|
|
24
|
+
return /* @__PURE__ */ jsx("nav", { className: classes, "aria-label": ariaLabel || "Breadcrumb", children: /* @__PURE__ */ jsx("ol", { className: `${baseClass}__list`, children: visibleItems.map((item, index) => {
|
|
24
25
|
const isLast = index === visibleItems.length - 1;
|
|
25
26
|
if (item === "ellipsis") {
|
|
26
27
|
return /* @__PURE__ */ jsxs("li", { className: `${baseClass}__item`, "aria-hidden": "true", children: [
|
|
@@ -371,6 +371,24 @@
|
|
|
371
371
|
color: var(--color-status-error-bg);
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
+
/* ============================================
|
|
375
|
+
LOADING
|
|
376
|
+
Keeps the variant's full-colour appearance (no disabled dim);
|
|
377
|
+
the spinner occupies the left icon slot and inherits its colour.
|
|
378
|
+
============================================ */
|
|
379
|
+
|
|
380
|
+
.ds-button--loading {
|
|
381
|
+
cursor: progress;
|
|
382
|
+
pointer-events: none;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/* The generic icon-slot svg sizing must not distort the spinner —
|
|
386
|
+
it sizes itself from the Spinner size prop */
|
|
387
|
+
.ds-button .ds-button__icon .ds-spinner__circle {
|
|
388
|
+
width: 100%;
|
|
389
|
+
height: 100%;
|
|
390
|
+
}
|
|
391
|
+
|
|
374
392
|
/* ============================================
|
|
375
393
|
FOCUS
|
|
376
394
|
============================================ */
|
|
@@ -13,6 +13,12 @@ type ButtonOwnProps = {
|
|
|
13
13
|
size?: 'default' | 'compact';
|
|
14
14
|
/** Whether the button is disabled */
|
|
15
15
|
disabled?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Shows a spinner in the left icon slot and blocks interaction while an
|
|
18
|
+
* async action runs. Keeps the variant's full-colour appearance (unlike
|
|
19
|
+
* `disabled`) and sets `aria-busy` on the rendered element.
|
|
20
|
+
*/
|
|
21
|
+
loading?: boolean;
|
|
16
22
|
/** Optional href — renders as <a> instead of <button> */
|
|
17
23
|
href?: string;
|
|
18
24
|
/** Optional target attribute for links */
|
|
@@ -23,9 +29,15 @@ type ButtonOwnProps = {
|
|
|
23
29
|
ariaCurrent?: boolean;
|
|
24
30
|
/** Additional CSS classes */
|
|
25
31
|
className?: string;
|
|
26
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Legacy alias for `variant`.
|
|
34
|
+
*
|
|
35
|
+
* @deprecated Use `variant` instead.
|
|
36
|
+
*/
|
|
27
37
|
priority?: 'primary' | 'secondary' | 'tertiary' | 'destructive';
|
|
28
38
|
/**
|
|
39
|
+
* Documentation-only interaction state.
|
|
40
|
+
*
|
|
29
41
|
* @deprecated Use `disabled` for the disabled state.
|
|
30
42
|
*
|
|
31
43
|
* Documentation-only affordance for rendering a *static* interaction state in
|
|
@@ -33,9 +45,15 @@ type ButtonOwnProps = {
|
|
|
33
45
|
* pseudo-classes and needs no prop — for docs, prefer `className="ds-button--hover"`.
|
|
34
46
|
*/
|
|
35
47
|
state?: 'default' | 'hover' | 'active' | 'disabled';
|
|
36
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* Legacy alias for `iconLeft`.
|
|
50
|
+
*
|
|
51
|
+
* @deprecated Use `iconLeft` instead.
|
|
52
|
+
*/
|
|
37
53
|
icon?: string;
|
|
38
54
|
/**
|
|
55
|
+
* Legacy toggle for showing the text label.
|
|
56
|
+
*
|
|
39
57
|
* @deprecated Will be removed once `label` loses its default in the next major;
|
|
40
58
|
* an icon-only button will simply omit `label`.
|
|
41
59
|
*/
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import React from "react";
|
|
3
|
+
import { Spinner } from "../Spinner/Spinner.js";
|
|
3
4
|
import "./Button.css";
|
|
4
5
|
import "../../fonts/material-symbols.css";
|
|
5
6
|
const Button = React.forwardRef(
|
|
@@ -10,6 +11,7 @@ const Button = React.forwardRef(
|
|
|
10
11
|
variant,
|
|
11
12
|
size = "default",
|
|
12
13
|
disabled,
|
|
14
|
+
loading,
|
|
13
15
|
href,
|
|
14
16
|
target,
|
|
15
17
|
rel,
|
|
@@ -25,27 +27,32 @@ const Button = React.forwardRef(
|
|
|
25
27
|
const resolvedVariant = variant ?? priority ?? "primary";
|
|
26
28
|
const isDisabled = disabled ?? state === "disabled";
|
|
27
29
|
const resolvedState = state ?? (isDisabled ? "disabled" : "default");
|
|
30
|
+
const isLoading = Boolean(loading);
|
|
28
31
|
const classes = [
|
|
29
32
|
baseClass,
|
|
30
33
|
`${baseClass}--${resolvedVariant}`,
|
|
31
34
|
`${baseClass}--${resolvedState}`,
|
|
32
35
|
`${baseClass}--${size}`,
|
|
36
|
+
isLoading && `${baseClass}--loading`,
|
|
33
37
|
className
|
|
34
38
|
].filter(Boolean).join(" ");
|
|
35
39
|
const iconClass = "material-symbols-rounded";
|
|
36
|
-
const
|
|
40
|
+
const spinnerSize = size === "compact" ? "sm" : "md";
|
|
41
|
+
const leftIcon = isLoading ? /* @__PURE__ */ jsx(Spinner, { size: spinnerSize, variant: "inherit" }) : iconLeft || icon;
|
|
37
42
|
const renderIcon = (iconProp) => {
|
|
38
43
|
if (typeof iconProp === "string") {
|
|
39
44
|
return /* @__PURE__ */ jsx("span", { className: `${baseClass}__icon ${iconClass}`, "aria-hidden": "true", children: iconProp });
|
|
40
45
|
}
|
|
41
46
|
return /* @__PURE__ */ jsx("span", { className: `${baseClass}__icon`, "aria-hidden": "true", children: iconProp });
|
|
42
47
|
};
|
|
48
|
+
const needsAccessibleName = !text || !label;
|
|
49
|
+
const fallbackAriaLabel = needsAccessibleName && label && !rest["aria-label"] ? label : void 0;
|
|
43
50
|
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
44
51
|
leftIcon && renderIcon(leftIcon),
|
|
45
52
|
text && /* @__PURE__ */ jsx("span", { className: `${baseClass}__text`, children: label }),
|
|
46
53
|
iconRight && renderIcon(iconRight)
|
|
47
54
|
] });
|
|
48
|
-
if (href && !isDisabled) {
|
|
55
|
+
if (href && !isDisabled && !isLoading) {
|
|
49
56
|
return /* @__PURE__ */ jsx(
|
|
50
57
|
"a",
|
|
51
58
|
{
|
|
@@ -56,6 +63,7 @@ const Button = React.forwardRef(
|
|
|
56
63
|
target,
|
|
57
64
|
rel,
|
|
58
65
|
"aria-current": ariaCurrent ? "page" : void 0,
|
|
66
|
+
"aria-label": fallbackAriaLabel ?? rest["aria-label"],
|
|
59
67
|
children: content
|
|
60
68
|
}
|
|
61
69
|
);
|
|
@@ -67,7 +75,9 @@ const Button = React.forwardRef(
|
|
|
67
75
|
ref,
|
|
68
76
|
type: "button",
|
|
69
77
|
className: classes,
|
|
70
|
-
disabled: isDisabled,
|
|
78
|
+
disabled: isDisabled || isLoading,
|
|
79
|
+
"aria-busy": isLoading || void 0,
|
|
80
|
+
"aria-label": fallbackAriaLabel ?? rest["aria-label"],
|
|
71
81
|
children: content
|
|
72
82
|
}
|
|
73
83
|
);
|
|
@@ -17,15 +17,8 @@ const ButtonGroup = ({
|
|
|
17
17
|
children: buttons.map((button, index) => /* @__PURE__ */ jsx(
|
|
18
18
|
Button,
|
|
19
19
|
{
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
label: button.label,
|
|
23
|
-
iconLeft: button.iconLeft,
|
|
24
|
-
iconRight: button.iconRight,
|
|
25
|
-
icon: button.icon,
|
|
26
|
-
onClick: button.onClick,
|
|
27
|
-
href: button.href,
|
|
28
|
-
ariaCurrent: button.ariaCurrent
|
|
20
|
+
...button,
|
|
21
|
+
variant: button.variant ?? button.priority ?? "tertiary"
|
|
29
22
|
},
|
|
30
23
|
index
|
|
31
24
|
))
|
package/components/Card/Card.css
CHANGED
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
|
|
26
26
|
/* Interaction */
|
|
27
27
|
transition: transform var(--motion-duration-slow) var(--motion-ease-standard), box-shadow var(--motion-duration-slow) var(--motion-ease-standard);
|
|
28
|
+
/* ds-allow(color): transparent resting state of the sanctioned Card
|
|
29
|
+
hover-lift shadow (see design.md — Do's and Don'ts). */
|
|
28
30
|
box-shadow: 0 0 0 rgba(0, 0, 0, 0);
|
|
29
31
|
}
|
|
30
32
|
|
|
@@ -34,6 +36,8 @@
|
|
|
34
36
|
|
|
35
37
|
.ds-card--interactive:hover {
|
|
36
38
|
transform: translateY(-4px);
|
|
39
|
+
/* ds-allow(color): the sanctioned Card hover-lift shadow — deliberately
|
|
40
|
+
heavier than --shadow-floating (see design.md — Do's and Don'ts). */
|
|
37
41
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
|
38
42
|
}
|
|
39
43
|
|
|
@@ -80,6 +84,8 @@
|
|
|
80
84
|
|
|
81
85
|
.ds-card--case-study:hover {
|
|
82
86
|
transform: translateY(-4px);
|
|
87
|
+
/* ds-allow(color): same sanctioned hover-lift shadow as the interactive
|
|
88
|
+
variant. */
|
|
83
89
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
|
|
84
90
|
}
|
|
85
91
|
|
|
@@ -15,11 +15,21 @@ type CheckboxOwnProps = {
|
|
|
15
15
|
onCheckedChange?: (checked: boolean) => void;
|
|
16
16
|
/** Additional CSS classes */
|
|
17
17
|
className?: string;
|
|
18
|
-
/**
|
|
18
|
+
/**
|
|
19
|
+
* Legacy change handler, kept for backwards compatibility.
|
|
20
|
+
*
|
|
21
|
+
* @deprecated Use `onCheckedChange` instead.
|
|
22
|
+
*/
|
|
19
23
|
onChange?: (checked: boolean) => void;
|
|
20
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* Legacy accessible-name prop.
|
|
26
|
+
*
|
|
27
|
+
* @deprecated Pass the native `aria-label` attribute instead.
|
|
28
|
+
*/
|
|
21
29
|
ariaLabel?: string;
|
|
22
30
|
/**
|
|
31
|
+
* Legacy form-field name.
|
|
32
|
+
*
|
|
23
33
|
* @deprecated No-op. This component renders a `<div role="checkbox">`, not a
|
|
24
34
|
* native `<input>`, so it cannot participate in native form submission.
|
|
25
35
|
* Declared only so the attribute is not forwarded to an element that rejects it.
|
|
@@ -48,7 +58,11 @@ type CheckboxGroupOwnProps = {
|
|
|
48
58
|
onValuesChange?: (values: string[]) => void;
|
|
49
59
|
/** Additional CSS classes */
|
|
50
60
|
className?: string;
|
|
51
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* Legacy change handler, kept for backwards compatibility.
|
|
63
|
+
*
|
|
64
|
+
* @deprecated Use `onValuesChange` instead.
|
|
65
|
+
*/
|
|
52
66
|
onChange?: (values: string[]) => void;
|
|
53
67
|
};
|
|
54
68
|
export interface CheckboxGroupProps extends CheckboxGroupOwnProps, Omit<React.ComponentPropsWithoutRef<'div'>, keyof CheckboxGroupOwnProps> {
|
|
@@ -196,6 +196,17 @@
|
|
|
196
196
|
background-color: var(--color-action-passive-bg-active);
|
|
197
197
|
}
|
|
198
198
|
|
|
199
|
+
/* ============================================
|
|
200
|
+
LOADING
|
|
201
|
+
Keeps the variant's full-colour appearance (no disabled dim);
|
|
202
|
+
the spinner replaces the icon and inherits its colour.
|
|
203
|
+
============================================ */
|
|
204
|
+
|
|
205
|
+
.ds-circular-button--loading {
|
|
206
|
+
cursor: progress;
|
|
207
|
+
pointer-events: none;
|
|
208
|
+
}
|
|
209
|
+
|
|
199
210
|
/* ============================================
|
|
200
211
|
FOCUS
|
|
201
212
|
============================================ */
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
export interface CircularButtonProps {
|
|
2
2
|
/** Material Symbol icon name */
|
|
3
3
|
icon: string;
|
|
4
|
-
/**
|
|
4
|
+
/** Visual treatment */
|
|
5
|
+
variant?: 'primary' | 'secondary' | 'tertiary';
|
|
6
|
+
/**
|
|
7
|
+
* Legacy alias for `variant`.
|
|
8
|
+
*
|
|
9
|
+
* @deprecated Use `variant` instead.
|
|
10
|
+
*/
|
|
5
11
|
priority?: 'primary' | 'secondary' | 'tertiary';
|
|
6
12
|
/** Button state */
|
|
7
13
|
state?: 'default' | 'hover' | 'active' | 'disabled';
|
|
8
14
|
/** Button size */
|
|
9
15
|
size?: 'default' | 'compact';
|
|
16
|
+
/**
|
|
17
|
+
* Shows a spinner in place of the icon and blocks interaction while an
|
|
18
|
+
* async action runs. Keeps the variant's full-colour appearance (unlike
|
|
19
|
+
* the disabled state) and sets `aria-busy` on the rendered element.
|
|
20
|
+
*/
|
|
21
|
+
loading?: boolean;
|
|
10
22
|
/** Accessible label */
|
|
11
23
|
ariaLabel: string;
|
|
12
24
|
/** Optional click handler */
|
|
@@ -25,6 +37,6 @@ export interface CircularButtonProps {
|
|
|
25
37
|
/**
|
|
26
38
|
* Circular icon button component.
|
|
27
39
|
* A round button containing a single icon, available in
|
|
28
|
-
* primary and
|
|
40
|
+
* primary, secondary and tertiary variants with default and compact sizes.
|
|
29
41
|
*/
|
|
30
|
-
export declare const CircularButton: ({ icon, priority, state, size, ariaLabel, onClick, href, target, rel, "aria-describedby": ariaDescribedby, className, }: CircularButtonProps) => import("react").JSX.Element;
|
|
42
|
+
export declare const CircularButton: ({ icon, variant, priority, state, size, loading, ariaLabel, onClick, href, target, rel, "aria-describedby": ariaDescribedby, className, }: CircularButtonProps) => import("react").JSX.Element;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Spinner } from "../Spinner/Spinner.js";
|
|
2
3
|
import "./CircularButton.css";
|
|
3
4
|
import "../../fonts/material-symbols.css";
|
|
4
5
|
const CircularButton = ({
|
|
5
6
|
icon,
|
|
6
|
-
|
|
7
|
+
variant,
|
|
8
|
+
priority,
|
|
7
9
|
state = "default",
|
|
8
10
|
size = "default",
|
|
11
|
+
loading,
|
|
9
12
|
ariaLabel,
|
|
10
13
|
onClick,
|
|
11
14
|
href,
|
|
@@ -15,13 +18,22 @@ const CircularButton = ({
|
|
|
15
18
|
className = ""
|
|
16
19
|
}) => {
|
|
17
20
|
const baseClass = "ds-circular-button";
|
|
18
|
-
const
|
|
21
|
+
const resolvedVariant = variant ?? priority ?? "primary";
|
|
22
|
+
const variantClass = `${baseClass}--${resolvedVariant}`;
|
|
19
23
|
const stateClass = `${baseClass}--${state}`;
|
|
20
24
|
const sizeClass = `${baseClass}--${size}`;
|
|
21
|
-
const
|
|
25
|
+
const isLoading = Boolean(loading);
|
|
26
|
+
const classes = [
|
|
27
|
+
baseClass,
|
|
28
|
+
variantClass,
|
|
29
|
+
stateClass,
|
|
30
|
+
sizeClass,
|
|
31
|
+
isLoading && `${baseClass}--loading`,
|
|
32
|
+
className
|
|
33
|
+
].filter(Boolean).join(" ");
|
|
22
34
|
const isDisabled = state === "disabled";
|
|
23
|
-
const children = /* @__PURE__ */ jsx("span", { className: `${baseClass}__icon material-symbols-rounded`, "aria-hidden": "true", children: icon });
|
|
24
|
-
if (href && !isDisabled) {
|
|
35
|
+
const children = isLoading ? /* @__PURE__ */ jsx("span", { className: `${baseClass}__icon`, "aria-hidden": "true", children: /* @__PURE__ */ jsx(Spinner, { size: size === "compact" ? "sm" : "md", variant: "inherit" }) }) : /* @__PURE__ */ jsx("span", { className: `${baseClass}__icon material-symbols-rounded`, "aria-hidden": "true", children: icon });
|
|
36
|
+
if (href && !isDisabled && !isLoading) {
|
|
25
37
|
return /* @__PURE__ */ jsx(
|
|
26
38
|
"a",
|
|
27
39
|
{
|
|
@@ -42,7 +54,8 @@ const CircularButton = ({
|
|
|
42
54
|
type: "button",
|
|
43
55
|
className: classes,
|
|
44
56
|
onClick,
|
|
45
|
-
disabled: isDisabled,
|
|
57
|
+
disabled: isDisabled || isLoading,
|
|
58
|
+
"aria-busy": isLoading || void 0,
|
|
46
59
|
"aria-label": ariaLabel,
|
|
47
60
|
"aria-describedby": ariaDescribedby,
|
|
48
61
|
children
|
|
@@ -77,7 +77,16 @@ const CodeBlock = ({
|
|
|
77
77
|
}
|
|
78
78
|
)
|
|
79
79
|
] }),
|
|
80
|
-
/* @__PURE__ */ jsx("div", { id: panelId, className: `${baseClass}__panel`, "aria-hidden": collapsed || void 0, children: /* @__PURE__ */ jsx("div", { className: `${baseClass}__panel-inner`, children: /* @__PURE__ */ jsx(
|
|
80
|
+
/* @__PURE__ */ jsx("div", { id: panelId, className: `${baseClass}__panel`, "aria-hidden": collapsed || void 0, children: /* @__PURE__ */ jsx("div", { className: `${baseClass}__panel-inner`, children: /* @__PURE__ */ jsx(
|
|
81
|
+
"pre",
|
|
82
|
+
{
|
|
83
|
+
className: `${baseClass}__pre`,
|
|
84
|
+
tabIndex: collapsed ? -1 : 0,
|
|
85
|
+
role: "region",
|
|
86
|
+
"aria-label": filename ? `Code: ${filename}` : language ? `Code: ${language}` : "Code",
|
|
87
|
+
children: /* @__PURE__ */ jsx("code", { className: `${baseClass}__code`, children: code })
|
|
88
|
+
}
|
|
89
|
+
) }) })
|
|
81
90
|
] });
|
|
82
91
|
};
|
|
83
92
|
export {
|