@robr0/design-system 0.1.0 → 0.3.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 +13 -9
- package/components/Accordion/Accordion.js +0 -1
- package/components/Avatar/Avatar.js +1 -0
- package/components/Breadcrumb/Breadcrumb.css +9 -1
- 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 +38 -16
- package/components/Button/Button.js +76 -58
- package/components/Card/Card.css +6 -0
- package/components/Card/Card.d.ts +17 -5
- package/components/Card/Card.js +101 -80
- package/components/Checkbox/Checkbox.d.ts +24 -12
- package/components/Checkbox/Checkbox.js +99 -85
- package/components/CircularButton/CircularButton.css +11 -0
- package/components/CircularButton/CircularButton.d.ts +7 -1
- package/components/CircularButton/CircularButton.js +15 -4
- 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 +19 -7
- package/components/Combobox/Combobox.js +106 -89
- package/components/CommandPalette/CommandPalette.css +1 -15
- package/components/CommandPalette/CommandPalette.js +6 -5
- package/components/ContextMenu/ContextMenu.css +262 -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 +18 -21
- package/components/DateInput/DateInput.js +76 -64
- package/components/DatePicker/DatePicker.d.ts +9 -2
- package/components/DatePicker/DatePicker.js +137 -128
- package/components/Dialog/Dialog.d.ts +15 -4
- package/components/Dialog/Dialog.js +136 -118
- package/components/Drawer/Drawer.d.ts +15 -4
- package/components/Drawer/Drawer.js +138 -119
- package/components/Dropdown/Dropdown.css +0 -36
- package/components/Dropdown/Dropdown.d.ts +24 -8
- package/components/Dropdown/Dropdown.js +219 -169
- 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 +13 -17
- package/components/FileInput/FileInput.js +168 -141
- package/components/Input/Input.css +0 -43
- package/components/Input/Input.d.ts +23 -22
- package/components/Input/Input.js +93 -66
- package/components/Kbd/Kbd.css +28 -0
- package/components/Kbd/Kbd.d.ts +19 -0
- package/components/Kbd/Kbd.js +14 -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 +26 -13
- package/components/RadioButton/RadioButton.js +95 -70
- package/components/SelectionCard/SelectionCard.css +6 -2
- package/components/SelectionCard/SelectionCard.d.ts +10 -4
- package/components/SelectionCard/SelectionCard.js +72 -56
- package/components/Skeleton/Skeleton.css +2 -0
- package/components/Slider/Slider.d.ts +19 -10
- package/components/Slider/Slider.js +50 -40
- 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.d.ts +10 -2
- package/components/Table/Table.js +58 -58
- package/components/Textarea/Textarea.css +0 -43
- package/components/Textarea/Textarea.d.ts +21 -22
- package/components/Textarea/Textarea.js +78 -67
- package/components/ToggleGroup/ToggleGroup.d.ts +18 -8
- package/components/ToggleGroup/ToggleGroup.js +61 -44
- package/components/ToggleSwitch/ToggleSwitch.css +7 -2
- package/components/ToggleSwitch/ToggleSwitch.d.ts +17 -9
- package/components/ToggleSwitch/ToggleSwitch.js +57 -44
- package/components/registry.d.ts +47 -10
- package/components/registry.js +5 -1
- package/components/registry.json +498 -56
- package/components/registry.json.d.ts +498 -56
- package/components/registry.json.js +4 -1
- package/index.d.ts +8 -1
- package/index.js +16 -1
- package/package.json +1 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
|
|
2
|
+
/** Props owned by Checkbox itself — everything else falls through to the wrapper. */
|
|
3
|
+
type CheckboxOwnProps = {
|
|
3
4
|
/** Label text */
|
|
4
5
|
label?: string;
|
|
5
6
|
/** Whether the checkbox is checked */
|
|
@@ -10,18 +11,25 @@ export interface CheckboxProps {
|
|
|
10
11
|
disabled?: boolean;
|
|
11
12
|
/** Component size */
|
|
12
13
|
size?: 'default' | 'compact';
|
|
13
|
-
/**
|
|
14
|
-
|
|
14
|
+
/** Called with the next checked state when toggled */
|
|
15
|
+
onCheckedChange?: (checked: boolean) => void;
|
|
15
16
|
/** Additional CSS classes */
|
|
16
17
|
className?: string;
|
|
17
|
-
/**
|
|
18
|
+
/** @deprecated Use `onCheckedChange` instead. */
|
|
19
|
+
onChange?: (checked: boolean) => void;
|
|
20
|
+
/** @deprecated Pass the native `aria-label` attribute instead. */
|
|
18
21
|
ariaLabel?: string;
|
|
19
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* @deprecated No-op. This component renders a `<div role="checkbox">`, not a
|
|
24
|
+
* native `<input>`, so it cannot participate in native form submission.
|
|
25
|
+
* Declared only so the attribute is not forwarded to an element that rejects it.
|
|
26
|
+
*/
|
|
20
27
|
name?: string;
|
|
21
|
-
|
|
22
|
-
|
|
28
|
+
};
|
|
29
|
+
export interface CheckboxProps extends CheckboxOwnProps, Omit<React.ComponentPropsWithoutRef<'div'>, keyof CheckboxOwnProps> {
|
|
23
30
|
}
|
|
24
|
-
export
|
|
31
|
+
export declare const Checkbox: React.ForwardRefExoticComponent<CheckboxProps & React.RefAttributes<HTMLDivElement>>;
|
|
32
|
+
type CheckboxGroupOwnProps = {
|
|
25
33
|
/** Group label */
|
|
26
34
|
label?: string;
|
|
27
35
|
/** Checkbox options */
|
|
@@ -36,10 +44,14 @@ export interface CheckboxGroupProps {
|
|
|
36
44
|
direction?: 'vertical' | 'horizontal';
|
|
37
45
|
/** Component size */
|
|
38
46
|
size?: 'default' | 'compact';
|
|
39
|
-
/**
|
|
40
|
-
|
|
47
|
+
/** Called with the next selected values */
|
|
48
|
+
onValuesChange?: (values: string[]) => void;
|
|
41
49
|
/** Additional CSS classes */
|
|
42
50
|
className?: string;
|
|
51
|
+
/** @deprecated Use `onValuesChange` instead. */
|
|
52
|
+
onChange?: (values: string[]) => void;
|
|
53
|
+
};
|
|
54
|
+
export interface CheckboxGroupProps extends CheckboxGroupOwnProps, Omit<React.ComponentPropsWithoutRef<'div'>, keyof CheckboxGroupOwnProps> {
|
|
43
55
|
}
|
|
44
|
-
export declare const CheckboxGroup:
|
|
45
|
-
export
|
|
56
|
+
export declare const CheckboxGroup: React.ForwardRefExoticComponent<CheckboxGroupProps & React.RefAttributes<HTMLDivElement>>;
|
|
57
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
-
import "react";
|
|
2
|
+
import React from "react";
|
|
3
3
|
import "./Checkbox.css";
|
|
4
4
|
const CheckIcon = () => /* @__PURE__ */ jsx(
|
|
5
5
|
"svg",
|
|
@@ -31,94 +31,108 @@ const MinusIcon = () => /* @__PURE__ */ jsx(
|
|
|
31
31
|
viewBox: "0 0 14 14",
|
|
32
32
|
fill: "none",
|
|
33
33
|
"aria-hidden": "true",
|
|
34
|
-
children: /* @__PURE__ */ jsx(
|
|
35
|
-
|
|
34
|
+
children: /* @__PURE__ */ jsx("path", { d: "M2 7H12", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" })
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
const Checkbox = React.forwardRef(
|
|
38
|
+
({
|
|
39
|
+
label,
|
|
40
|
+
checked = false,
|
|
41
|
+
indeterminate = false,
|
|
42
|
+
disabled = false,
|
|
43
|
+
size = "default",
|
|
44
|
+
onCheckedChange,
|
|
45
|
+
onChange,
|
|
46
|
+
className = "",
|
|
47
|
+
ariaLabel,
|
|
48
|
+
name: _name,
|
|
49
|
+
onClick,
|
|
50
|
+
onKeyDown,
|
|
51
|
+
...rest
|
|
52
|
+
}, ref) => {
|
|
53
|
+
const baseClass = "ds-checkbox";
|
|
54
|
+
const classes = [
|
|
55
|
+
baseClass,
|
|
56
|
+
size === "compact" ? `${baseClass}--compact` : "",
|
|
57
|
+
checked ? `${baseClass}--checked` : "",
|
|
58
|
+
indeterminate && !checked ? `${baseClass}--indeterminate` : "",
|
|
59
|
+
disabled ? `${baseClass}--disabled` : "",
|
|
60
|
+
className
|
|
61
|
+
].filter(Boolean).join(" ");
|
|
62
|
+
const toggle = () => {
|
|
63
|
+
if (disabled) return;
|
|
64
|
+
onCheckedChange?.(!checked);
|
|
65
|
+
onChange?.(!checked);
|
|
66
|
+
};
|
|
67
|
+
const handleClick = (e) => {
|
|
68
|
+
onClick?.(e);
|
|
69
|
+
toggle();
|
|
70
|
+
};
|
|
71
|
+
const handleKeyDown = (e) => {
|
|
72
|
+
onKeyDown?.(e);
|
|
73
|
+
if (e.key === " " || e.key === "Enter") {
|
|
74
|
+
e.preventDefault();
|
|
75
|
+
toggle();
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
return /* @__PURE__ */ jsxs(
|
|
79
|
+
"div",
|
|
36
80
|
{
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
81
|
+
...rest,
|
|
82
|
+
ref,
|
|
83
|
+
className: classes,
|
|
84
|
+
onClick: handleClick,
|
|
85
|
+
onKeyDown: handleKeyDown,
|
|
86
|
+
role: "checkbox",
|
|
87
|
+
"aria-checked": indeterminate && !checked ? "mixed" : checked,
|
|
88
|
+
"aria-disabled": disabled,
|
|
89
|
+
"aria-label": ariaLabel || rest["aria-label"] || label,
|
|
90
|
+
tabIndex: disabled ? -1 : 0,
|
|
91
|
+
children: [
|
|
92
|
+
/* @__PURE__ */ jsx("div", { className: `${baseClass}__box`, children: indeterminate && !checked ? /* @__PURE__ */ jsx(MinusIcon, {}) : /* @__PURE__ */ jsx(CheckIcon, {}) }),
|
|
93
|
+
label && /* @__PURE__ */ jsx("span", { className: `${baseClass}__label`, children: label })
|
|
94
|
+
]
|
|
41
95
|
}
|
|
42
|
-
)
|
|
96
|
+
);
|
|
43
97
|
}
|
|
44
98
|
);
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
{
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
size = "default",
|
|
83
|
-
onChange,
|
|
84
|
-
className = "",
|
|
85
|
-
ariaLabel
|
|
86
|
-
}) => {
|
|
87
|
-
const baseClass = "ds-checkbox";
|
|
88
|
-
const checkedClass = checked ? `${baseClass}--checked` : "";
|
|
89
|
-
const indeterminateClass = indeterminate && !checked ? `${baseClass}--indeterminate` : "";
|
|
90
|
-
const disabledClass = disabled ? `${baseClass}--disabled` : "";
|
|
91
|
-
const sizeClass = size === "compact" ? `${baseClass}--compact` : "";
|
|
92
|
-
const classes = [baseClass, sizeClass, checkedClass, indeterminateClass, disabledClass, className].filter(Boolean).join(" ");
|
|
93
|
-
const handleClick = () => {
|
|
94
|
-
if (!disabled && onChange) {
|
|
95
|
-
onChange(!checked);
|
|
96
|
-
}
|
|
97
|
-
};
|
|
98
|
-
const handleKeyDown = (e) => {
|
|
99
|
-
if (e.key === " " || e.key === "Enter") {
|
|
100
|
-
e.preventDefault();
|
|
101
|
-
handleClick();
|
|
102
|
-
}
|
|
103
|
-
};
|
|
104
|
-
return /* @__PURE__ */ jsxs(
|
|
105
|
-
"div",
|
|
106
|
-
{
|
|
107
|
-
className: classes,
|
|
108
|
-
onClick: handleClick,
|
|
109
|
-
onKeyDown: handleKeyDown,
|
|
110
|
-
role: "checkbox",
|
|
111
|
-
"aria-checked": indeterminate && !checked ? "mixed" : checked,
|
|
112
|
-
"aria-disabled": disabled,
|
|
113
|
-
"aria-label": ariaLabel || label,
|
|
114
|
-
tabIndex: disabled ? -1 : 0,
|
|
115
|
-
children: [
|
|
116
|
-
/* @__PURE__ */ jsx("div", { className: `${baseClass}__box`, children: indeterminate && !checked ? /* @__PURE__ */ jsx(MinusIcon, {}) : /* @__PURE__ */ jsx(CheckIcon, {}) }),
|
|
117
|
-
label && /* @__PURE__ */ jsx("span", { className: `${baseClass}__label`, children: label })
|
|
118
|
-
]
|
|
119
|
-
}
|
|
120
|
-
);
|
|
121
|
-
};
|
|
99
|
+
Checkbox.displayName = "Checkbox";
|
|
100
|
+
const CheckboxGroup = React.forwardRef(
|
|
101
|
+
({
|
|
102
|
+
label,
|
|
103
|
+
items,
|
|
104
|
+
values = [],
|
|
105
|
+
direction = "vertical",
|
|
106
|
+
size = "default",
|
|
107
|
+
onValuesChange,
|
|
108
|
+
onChange,
|
|
109
|
+
className = "",
|
|
110
|
+
...rest
|
|
111
|
+
}, ref) => {
|
|
112
|
+
const baseClass = "ds-checkbox-group";
|
|
113
|
+
const classes = [baseClass, `${baseClass}--${direction}`, className].filter(Boolean).join(" ");
|
|
114
|
+
const handleToggle = (itemValue) => {
|
|
115
|
+
const next = values.includes(itemValue) ? values.filter((v) => v !== itemValue) : [...values, itemValue];
|
|
116
|
+
onValuesChange?.(next);
|
|
117
|
+
onChange?.(next);
|
|
118
|
+
};
|
|
119
|
+
return /* @__PURE__ */ jsxs("div", { ...rest, ref, className: classes, role: "group", "aria-label": label, children: [
|
|
120
|
+
label && /* @__PURE__ */ jsx("span", { className: `${baseClass}__label`, children: label }),
|
|
121
|
+
/* @__PURE__ */ jsx("div", { className: `${baseClass}__items`, children: items.map((item) => /* @__PURE__ */ jsx(
|
|
122
|
+
Checkbox,
|
|
123
|
+
{
|
|
124
|
+
label: item.label,
|
|
125
|
+
checked: values.includes(item.value),
|
|
126
|
+
disabled: item.disabled,
|
|
127
|
+
size,
|
|
128
|
+
onCheckedChange: () => handleToggle(item.value)
|
|
129
|
+
},
|
|
130
|
+
item.value
|
|
131
|
+
)) })
|
|
132
|
+
] });
|
|
133
|
+
}
|
|
134
|
+
);
|
|
135
|
+
CheckboxGroup.displayName = "CheckboxGroup";
|
|
122
136
|
export {
|
|
123
137
|
Checkbox,
|
|
124
138
|
CheckboxGroup
|
|
@@ -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
|
============================================ */
|
|
@@ -7,6 +7,12 @@ export interface CircularButtonProps {
|
|
|
7
7
|
state?: 'default' | 'hover' | 'active' | 'disabled';
|
|
8
8
|
/** Button size */
|
|
9
9
|
size?: 'default' | 'compact';
|
|
10
|
+
/**
|
|
11
|
+
* Shows a spinner in place of the icon and blocks interaction while an
|
|
12
|
+
* async action runs. Keeps the variant's full-colour appearance (unlike
|
|
13
|
+
* the disabled state) and sets `aria-busy` on the rendered element.
|
|
14
|
+
*/
|
|
15
|
+
loading?: boolean;
|
|
10
16
|
/** Accessible label */
|
|
11
17
|
ariaLabel: string;
|
|
12
18
|
/** Optional click handler */
|
|
@@ -27,4 +33,4 @@ export interface CircularButtonProps {
|
|
|
27
33
|
* A round button containing a single icon, available in
|
|
28
34
|
* primary and secondary variants with default and compact sizes.
|
|
29
35
|
*/
|
|
30
|
-
export declare const CircularButton: ({ icon, priority, state, size, ariaLabel, onClick, href, target, rel, "aria-describedby": ariaDescribedby, className, }: CircularButtonProps) => import("react").JSX.Element;
|
|
36
|
+
export declare const CircularButton: ({ icon, priority, state, size, loading, ariaLabel, onClick, href, target, rel, "aria-describedby": ariaDescribedby, className, }: CircularButtonProps) => import("react").JSX.Element;
|
|
@@ -1,4 +1,5 @@
|
|
|
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 = ({
|
|
@@ -6,6 +7,7 @@ const CircularButton = ({
|
|
|
6
7
|
priority = "primary",
|
|
7
8
|
state = "default",
|
|
8
9
|
size = "default",
|
|
10
|
+
loading,
|
|
9
11
|
ariaLabel,
|
|
10
12
|
onClick,
|
|
11
13
|
href,
|
|
@@ -18,10 +20,18 @@ const CircularButton = ({
|
|
|
18
20
|
const variantClass = `${baseClass}--${priority}`;
|
|
19
21
|
const stateClass = `${baseClass}--${state}`;
|
|
20
22
|
const sizeClass = `${baseClass}--${size}`;
|
|
21
|
-
const
|
|
23
|
+
const isLoading = Boolean(loading);
|
|
24
|
+
const classes = [
|
|
25
|
+
baseClass,
|
|
26
|
+
variantClass,
|
|
27
|
+
stateClass,
|
|
28
|
+
sizeClass,
|
|
29
|
+
isLoading && `${baseClass}--loading`,
|
|
30
|
+
className
|
|
31
|
+
].filter(Boolean).join(" ");
|
|
22
32
|
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) {
|
|
33
|
+
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 });
|
|
34
|
+
if (href && !isDisabled && !isLoading) {
|
|
25
35
|
return /* @__PURE__ */ jsx(
|
|
26
36
|
"a",
|
|
27
37
|
{
|
|
@@ -42,7 +52,8 @@ const CircularButton = ({
|
|
|
42
52
|
type: "button",
|
|
43
53
|
className: classes,
|
|
44
54
|
onClick,
|
|
45
|
-
disabled: isDisabled,
|
|
55
|
+
disabled: isDisabled || isLoading,
|
|
56
|
+
"aria-busy": isLoading || void 0,
|
|
46
57
|
"aria-label": ariaLabel,
|
|
47
58
|
"aria-describedby": ariaDescribedby,
|
|
48
59
|
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 {
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
COLORPICKER COMPONENT
|
|
3
|
+
Swatch trigger + saturation/hue/alpha panel
|
|
4
|
+
|
|
5
|
+
Colour-mixing constants: the white/black
|
|
6
|
+
gradient overlays and the hue spectrum are
|
|
7
|
+
colour-space physics, not theme decisions —
|
|
8
|
+
they are written as hsl() literals because no
|
|
9
|
+
semantic token can represent them. Everything
|
|
10
|
+
themeable uses tokens as usual.
|
|
11
|
+
|
|
12
|
+
ds-allow-file(color): colour-space physics —
|
|
13
|
+
the gradients and spectrum cannot be theme
|
|
14
|
+
tokens.
|
|
15
|
+
============================================ */
|
|
16
|
+
|
|
17
|
+
/* Base */
|
|
18
|
+
|
|
19
|
+
.ds-colorpicker {
|
|
20
|
+
position: relative;
|
|
21
|
+
/* Field owns no layout — the root class stacks label, trigger and helper */
|
|
22
|
+
display: inline-flex;
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
align-items: flex-start;
|
|
25
|
+
gap: var(--gap-sm);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/* Trigger */
|
|
29
|
+
|
|
30
|
+
.ds-colorpicker__trigger {
|
|
31
|
+
display: inline-flex;
|
|
32
|
+
align-items: center;
|
|
33
|
+
gap: var(--gap-sm);
|
|
34
|
+
padding: var(--padding-xxs);
|
|
35
|
+
border: var(--border-xs) solid var(--color-input-border-primary);
|
|
36
|
+
border-radius: var(--radius-md);
|
|
37
|
+
background-color: transparent;
|
|
38
|
+
cursor: pointer;
|
|
39
|
+
transition: border-color var(--motion-duration-base) var(--motion-ease-standard);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.ds-colorpicker__trigger:hover:not(:disabled) {
|
|
43
|
+
border-color: var(--color-input-border-hover);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.ds-colorpicker__trigger:focus-visible {
|
|
47
|
+
outline: none;
|
|
48
|
+
border-color: var(--color-input-border-selected);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.ds-colorpicker--open .ds-colorpicker__trigger {
|
|
52
|
+
border-color: var(--color-input-border-selected);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.ds-colorpicker__trigger-swatch {
|
|
56
|
+
width: 24px;
|
|
57
|
+
height: 24px;
|
|
58
|
+
border-radius: var(--radius-sm);
|
|
59
|
+
/* Checkerboard shows through translucent colours */
|
|
60
|
+
background-color: var(--color-bg-page-primary);
|
|
61
|
+
background-image:
|
|
62
|
+
linear-gradient(var(--ds-cp-color), var(--ds-cp-color)),
|
|
63
|
+
repeating-conic-gradient(var(--color-bg-container-tertiary) 0% 25%, transparent 0% 50%);
|
|
64
|
+
background-size: 100% 100%, 8px 8px;
|
|
65
|
+
box-shadow: inset 0 0 0 var(--border-xs) var(--color-bg-container-border);
|
|
66
|
+
flex-shrink: 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.ds-colorpicker__trigger-text {
|
|
70
|
+
font-family: var(--font-paragraph-sm-family);
|
|
71
|
+
font-size: var(--font-paragraph-sm-size);
|
|
72
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
73
|
+
color: var(--color-text-primary);
|
|
74
|
+
font-variant-numeric: tabular-nums;
|
|
75
|
+
padding-right: var(--padding-xxs);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/* Sizes */
|
|
79
|
+
|
|
80
|
+
.ds-colorpicker--compact .ds-colorpicker__trigger-swatch {
|
|
81
|
+
width: 20px;
|
|
82
|
+
height: 20px;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* Panel */
|
|
86
|
+
|
|
87
|
+
.ds-colorpicker__panel {
|
|
88
|
+
position: absolute;
|
|
89
|
+
top: 100%;
|
|
90
|
+
left: 0;
|
|
91
|
+
margin-top: var(--gap-xxs);
|
|
92
|
+
width: 240px;
|
|
93
|
+
padding: var(--padding-sm-md);
|
|
94
|
+
display: flex;
|
|
95
|
+
flex-direction: column;
|
|
96
|
+
gap: var(--gap-sm-md);
|
|
97
|
+
background-color: var(--color-bg-page-primary);
|
|
98
|
+
border: var(--border-xs) solid var(--color-input-border-primary);
|
|
99
|
+
border-radius: var(--radius-md);
|
|
100
|
+
box-shadow: var(--shadow-floating);
|
|
101
|
+
z-index: 10;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/* Saturation / brightness area */
|
|
105
|
+
|
|
106
|
+
.ds-colorpicker__saturation {
|
|
107
|
+
position: relative;
|
|
108
|
+
height: 150px;
|
|
109
|
+
border-radius: var(--radius-sm);
|
|
110
|
+
cursor: crosshair;
|
|
111
|
+
touch-action: none;
|
|
112
|
+
background:
|
|
113
|
+
linear-gradient(to top, hsl(0 0% 0%), transparent),
|
|
114
|
+
linear-gradient(to right, hsl(0 0% 100%), transparent),
|
|
115
|
+
hsl(var(--ds-cp-hue) 100% 50%);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.ds-colorpicker__saturation:focus-visible {
|
|
119
|
+
outline: var(--border-md) solid var(--color-input-border-selected);
|
|
120
|
+
outline-offset: var(--border-md);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.ds-colorpicker__handle {
|
|
124
|
+
position: absolute;
|
|
125
|
+
left: var(--ds-cp-x);
|
|
126
|
+
top: var(--ds-cp-y);
|
|
127
|
+
transform: translate(-50%, -50%);
|
|
128
|
+
width: 14px;
|
|
129
|
+
height: 14px;
|
|
130
|
+
border-radius: var(--radius-full);
|
|
131
|
+
border: var(--border-md) solid hsl(0 0% 100%);
|
|
132
|
+
box-shadow: var(--shadow-floating);
|
|
133
|
+
pointer-events: none;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/* Sliders + preview */
|
|
137
|
+
|
|
138
|
+
.ds-colorpicker__controls {
|
|
139
|
+
display: flex;
|
|
140
|
+
align-items: center;
|
|
141
|
+
gap: var(--gap-sm-md);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.ds-colorpicker__sliders {
|
|
145
|
+
flex: 1;
|
|
146
|
+
display: flex;
|
|
147
|
+
flex-direction: column;
|
|
148
|
+
gap: var(--gap-sm);
|
|
149
|
+
min-width: 0;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.ds-colorpicker__hue,
|
|
153
|
+
.ds-colorpicker__alpha {
|
|
154
|
+
appearance: none;
|
|
155
|
+
-webkit-appearance: none;
|
|
156
|
+
width: 100%;
|
|
157
|
+
height: 12px;
|
|
158
|
+
border-radius: var(--radius-full);
|
|
159
|
+
outline: none;
|
|
160
|
+
cursor: pointer;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.ds-colorpicker__hue {
|
|
164
|
+
background: linear-gradient(
|
|
165
|
+
to right,
|
|
166
|
+
hsl(0 100% 50%),
|
|
167
|
+
hsl(60 100% 50%),
|
|
168
|
+
hsl(120 100% 50%),
|
|
169
|
+
hsl(180 100% 50%),
|
|
170
|
+
hsl(240 100% 50%),
|
|
171
|
+
hsl(300 100% 50%),
|
|
172
|
+
hsl(360 100% 50%)
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.ds-colorpicker__alpha {
|
|
177
|
+
background-color: var(--color-bg-page-primary);
|
|
178
|
+
background-image:
|
|
179
|
+
linear-gradient(to right, transparent, var(--ds-cp-solid)),
|
|
180
|
+
repeating-conic-gradient(var(--color-bg-container-tertiary) 0% 25%, transparent 0% 50%);
|
|
181
|
+
background-size: 100% 100%, 8px 8px;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.ds-colorpicker__hue::-webkit-slider-thumb,
|
|
185
|
+
.ds-colorpicker__alpha::-webkit-slider-thumb {
|
|
186
|
+
appearance: none;
|
|
187
|
+
-webkit-appearance: none;
|
|
188
|
+
width: 16px;
|
|
189
|
+
height: 16px;
|
|
190
|
+
border-radius: var(--radius-full);
|
|
191
|
+
background: hsl(0 0% 100%);
|
|
192
|
+
border: var(--border-xs) solid var(--color-bg-container-border);
|
|
193
|
+
box-shadow: var(--shadow-floating);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.ds-colorpicker__hue::-moz-range-thumb,
|
|
197
|
+
.ds-colorpicker__alpha::-moz-range-thumb {
|
|
198
|
+
width: 16px;
|
|
199
|
+
height: 16px;
|
|
200
|
+
border-radius: var(--radius-full);
|
|
201
|
+
background: hsl(0 0% 100%);
|
|
202
|
+
border: var(--border-xs) solid var(--color-bg-container-border);
|
|
203
|
+
box-shadow: var(--shadow-floating);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.ds-colorpicker__hue:focus-visible,
|
|
207
|
+
.ds-colorpicker__alpha:focus-visible {
|
|
208
|
+
outline: var(--border-md) solid var(--color-input-border-selected);
|
|
209
|
+
outline-offset: var(--border-md);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
.ds-colorpicker__preview {
|
|
213
|
+
width: 32px;
|
|
214
|
+
height: 32px;
|
|
215
|
+
border-radius: var(--radius-sm);
|
|
216
|
+
background-color: var(--color-bg-page-primary);
|
|
217
|
+
background-image:
|
|
218
|
+
linear-gradient(var(--ds-cp-color), var(--ds-cp-color)),
|
|
219
|
+
repeating-conic-gradient(var(--color-bg-container-tertiary) 0% 25%, transparent 0% 50%);
|
|
220
|
+
background-size: 100% 100%, 8px 8px;
|
|
221
|
+
box-shadow: inset 0 0 0 var(--border-xs) var(--color-bg-container-border);
|
|
222
|
+
flex-shrink: 0;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* Hex + alpha inputs */
|
|
226
|
+
|
|
227
|
+
.ds-colorpicker__inputs {
|
|
228
|
+
display: flex;
|
|
229
|
+
align-items: center;
|
|
230
|
+
gap: var(--gap-sm);
|
|
231
|
+
padding: var(--padding-xxs) var(--padding-sm);
|
|
232
|
+
border: var(--border-xs) solid var(--color-input-border-primary);
|
|
233
|
+
border-radius: var(--radius-md);
|
|
234
|
+
transition: border-color var(--motion-duration-base) var(--motion-ease-standard);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.ds-colorpicker__inputs:focus-within {
|
|
238
|
+
border-color: var(--color-input-border-selected);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.ds-colorpicker__hash {
|
|
242
|
+
font-family: var(--font-paragraph-sm-family);
|
|
243
|
+
font-size: var(--font-paragraph-sm-size);
|
|
244
|
+
color: var(--color-text-tertiary);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.ds-colorpicker__hex-field {
|
|
248
|
+
flex: 1;
|
|
249
|
+
min-width: 0;
|
|
250
|
+
border: none;
|
|
251
|
+
background: transparent;
|
|
252
|
+
outline: none;
|
|
253
|
+
padding: 0;
|
|
254
|
+
font-family: var(--font-paragraph-sm-family);
|
|
255
|
+
font-size: var(--font-paragraph-sm-size);
|
|
256
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
257
|
+
color: var(--color-text-primary);
|
|
258
|
+
text-transform: uppercase;
|
|
259
|
+
font-variant-numeric: tabular-nums;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
.ds-colorpicker__alpha-value {
|
|
263
|
+
font-family: var(--font-paragraph-sm-family);
|
|
264
|
+
font-size: var(--font-paragraph-sm-size);
|
|
265
|
+
color: var(--color-text-secondary);
|
|
266
|
+
font-variant-numeric: tabular-nums;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/* States */
|
|
270
|
+
|
|
271
|
+
.ds-colorpicker--disabled .ds-colorpicker__trigger {
|
|
272
|
+
opacity: 0.4;
|
|
273
|
+
cursor: not-allowed;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.ds-colorpicker--error .ds-colorpicker__trigger {
|
|
277
|
+
border-color: var(--color-status-error-border);
|
|
278
|
+
}
|