@robr0/design-system 0.1.0 → 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 +6 -4
- package/components/Breadcrumb/Breadcrumb.css +9 -1
- package/components/Button/Button.d.ts +32 -16
- package/components/Button/Button.js +66 -58
- 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/Combobox/Combobox.d.ts +19 -7
- package/components/Combobox/Combobox.js +18 -9
- package/components/DateInput/DateInput.d.ts +18 -21
- package/components/DateInput/DateInput.js +71 -63
- package/components/DatePicker/DatePicker.d.ts +9 -2
- package/components/DatePicker/DatePicker.js +127 -129
- package/components/Dialog/Dialog.d.ts +15 -4
- package/components/Dialog/Dialog.js +133 -116
- package/components/Drawer/Drawer.d.ts +15 -4
- package/components/Drawer/Drawer.js +133 -119
- package/components/Dropdown/Dropdown.d.ts +24 -8
- package/components/Dropdown/Dropdown.js +226 -186
- package/components/FileInput/FileInput.d.ts +13 -17
- package/components/FileInput/FileInput.js +177 -158
- package/components/Input/Input.d.ts +23 -22
- package/components/Input/Input.js +87 -65
- package/components/RadioButton/RadioButton.d.ts +26 -13
- package/components/RadioButton/RadioButton.js +95 -70
- package/components/SelectionCard/SelectionCard.d.ts +10 -4
- package/components/SelectionCard/SelectionCard.js +72 -56
- package/components/Slider/Slider.d.ts +19 -10
- package/components/Slider/Slider.js +50 -40
- package/components/Table/Table.d.ts +10 -2
- package/components/Table/Table.js +58 -58
- package/components/Textarea/Textarea.d.ts +21 -22
- package/components/Textarea/Textarea.js +77 -68
- package/components/ToggleGroup/ToggleGroup.d.ts +18 -8
- package/components/ToggleGroup/ToggleGroup.js +61 -44
- package/components/ToggleSwitch/ToggleSwitch.d.ts +17 -9
- package/components/ToggleSwitch/ToggleSwitch.js +57 -44
- package/package.json +1 -1
|
@@ -1,76 +1,101 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
-
import "react";
|
|
2
|
+
import React from "react";
|
|
3
3
|
import "./RadioButton.css";
|
|
4
|
-
const RadioButton = (
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
onClick
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
);
|
|
45
|
-
};
|
|
46
|
-
const RadioGroup = ({
|
|
47
|
-
label,
|
|
48
|
-
value,
|
|
49
|
-
name,
|
|
50
|
-
options,
|
|
51
|
-
direction = "vertical",
|
|
52
|
-
onChange,
|
|
53
|
-
className = ""
|
|
54
|
-
}) => {
|
|
55
|
-
const baseClass = "ds-radio-group";
|
|
56
|
-
const directionClass = `${baseClass}--${direction}`;
|
|
57
|
-
const classes = [baseClass, directionClass, className].filter(Boolean).join(" ");
|
|
58
|
-
return /* @__PURE__ */ jsxs("div", { className: classes, role: "radiogroup", "aria-label": label, children: [
|
|
59
|
-
label && /* @__PURE__ */ jsx("span", { className: `${baseClass}__label`, children: label }),
|
|
60
|
-
/* @__PURE__ */ jsx("div", { className: `${baseClass}__options`, children: options.map((option) => /* @__PURE__ */ jsx(
|
|
61
|
-
RadioButton,
|
|
4
|
+
const RadioButton = React.forwardRef(
|
|
5
|
+
({
|
|
6
|
+
label,
|
|
7
|
+
checked = false,
|
|
8
|
+
disabled = false,
|
|
9
|
+
value = "",
|
|
10
|
+
onValueChange,
|
|
11
|
+
onChange,
|
|
12
|
+
className = "",
|
|
13
|
+
ariaLabel,
|
|
14
|
+
name: _name,
|
|
15
|
+
onClick,
|
|
16
|
+
onKeyDown,
|
|
17
|
+
...rest
|
|
18
|
+
}, ref) => {
|
|
19
|
+
const baseClass = "ds-radio";
|
|
20
|
+
const classes = [
|
|
21
|
+
baseClass,
|
|
22
|
+
checked ? `${baseClass}--checked` : "",
|
|
23
|
+
disabled ? `${baseClass}--disabled` : "",
|
|
24
|
+
className
|
|
25
|
+
].filter(Boolean).join(" ");
|
|
26
|
+
const select = () => {
|
|
27
|
+
if (disabled) return;
|
|
28
|
+
onValueChange?.(value);
|
|
29
|
+
onChange?.(value);
|
|
30
|
+
};
|
|
31
|
+
const handleClick = (e) => {
|
|
32
|
+
onClick?.(e);
|
|
33
|
+
select();
|
|
34
|
+
};
|
|
35
|
+
const handleKeyDown = (e) => {
|
|
36
|
+
onKeyDown?.(e);
|
|
37
|
+
if (e.key === " " || e.key === "Enter") {
|
|
38
|
+
e.preventDefault();
|
|
39
|
+
select();
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
return /* @__PURE__ */ jsxs(
|
|
43
|
+
"div",
|
|
62
44
|
{
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
45
|
+
...rest,
|
|
46
|
+
ref,
|
|
47
|
+
className: classes,
|
|
48
|
+
onClick: handleClick,
|
|
49
|
+
onKeyDown: handleKeyDown,
|
|
50
|
+
role: "radio",
|
|
51
|
+
"aria-checked": checked,
|
|
52
|
+
"aria-disabled": disabled,
|
|
53
|
+
"aria-label": ariaLabel || rest["aria-label"] || label,
|
|
54
|
+
tabIndex: disabled ? -1 : 0,
|
|
55
|
+
children: [
|
|
56
|
+
/* @__PURE__ */ jsx("div", { className: `${baseClass}__circle`, children: /* @__PURE__ */ jsx("div", { className: `${baseClass}__dot` }) }),
|
|
57
|
+
label && /* @__PURE__ */ jsx("span", { className: `${baseClass}__label`, children: label })
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
);
|
|
63
|
+
RadioButton.displayName = "RadioButton";
|
|
64
|
+
const RadioGroup = React.forwardRef(
|
|
65
|
+
({
|
|
66
|
+
label,
|
|
67
|
+
value,
|
|
68
|
+
name: _name,
|
|
69
|
+
options,
|
|
70
|
+
direction = "vertical",
|
|
71
|
+
onValueChange,
|
|
72
|
+
onChange,
|
|
73
|
+
className = "",
|
|
74
|
+
...rest
|
|
75
|
+
}, ref) => {
|
|
76
|
+
const baseClass = "ds-radio-group";
|
|
77
|
+
const classes = [baseClass, `${baseClass}--${direction}`, className].filter(Boolean).join(" ");
|
|
78
|
+
const handleSelect = (next) => {
|
|
79
|
+
onValueChange?.(next);
|
|
80
|
+
onChange?.(next);
|
|
81
|
+
};
|
|
82
|
+
return /* @__PURE__ */ jsxs("div", { ...rest, ref, className: classes, role: "radiogroup", "aria-label": label, children: [
|
|
83
|
+
label && /* @__PURE__ */ jsx("span", { className: `${baseClass}__label`, children: label }),
|
|
84
|
+
/* @__PURE__ */ jsx("div", { className: `${baseClass}__options`, children: options.map((option) => /* @__PURE__ */ jsx(
|
|
85
|
+
RadioButton,
|
|
86
|
+
{
|
|
87
|
+
label: option.label,
|
|
88
|
+
value: option.value,
|
|
89
|
+
checked: value === option.value,
|
|
90
|
+
disabled: option.disabled,
|
|
91
|
+
onValueChange: handleSelect
|
|
92
|
+
},
|
|
93
|
+
option.value
|
|
94
|
+
)) })
|
|
95
|
+
] });
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
RadioGroup.displayName = "RadioGroup";
|
|
74
99
|
export {
|
|
75
100
|
RadioButton,
|
|
76
101
|
RadioGroup
|
|
@@ -9,18 +9,24 @@ export interface SelectionCardOption {
|
|
|
9
9
|
/** Whether this option is disabled */
|
|
10
10
|
disabled?: boolean;
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
/** Props owned by SelectionCard itself — everything else falls through to the group. */
|
|
13
|
+
type SelectionCardOwnProps = {
|
|
13
14
|
/** Selection mode — radio (single), checkbox (multi), or toggle (each card is an on/off switch) */
|
|
14
15
|
mode?: 'radio' | 'checkbox' | 'toggle';
|
|
15
16
|
/** Available options */
|
|
16
17
|
options: SelectionCardOption[];
|
|
17
18
|
/** Currently selected value(s) — string for radio, string[] for checkbox */
|
|
18
19
|
value?: string | string[];
|
|
19
|
-
/**
|
|
20
|
-
|
|
20
|
+
/** Called with the next selection — a string in radio mode, an array otherwise */
|
|
21
|
+
onValueChange?: (value: string | string[]) => void;
|
|
21
22
|
/** Group name (used for aria-label on the group) */
|
|
22
23
|
name?: string;
|
|
23
24
|
/** Additional CSS classes */
|
|
24
25
|
className?: string;
|
|
26
|
+
/** @deprecated Use `onValueChange` instead. */
|
|
27
|
+
onChange?: (value: string | string[]) => void;
|
|
28
|
+
};
|
|
29
|
+
export interface SelectionCardProps extends SelectionCardOwnProps, Omit<React.ComponentPropsWithoutRef<'div'>, keyof SelectionCardOwnProps> {
|
|
25
30
|
}
|
|
26
|
-
export declare const SelectionCard:
|
|
31
|
+
export declare const SelectionCard: React.ForwardRefExoticComponent<SelectionCardProps & React.RefAttributes<HTMLDivElement>>;
|
|
32
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import "react";
|
|
2
|
+
import React from "react";
|
|
3
3
|
import "./SelectionCard.css";
|
|
4
4
|
const CheckIcon = () => /* @__PURE__ */ jsx(
|
|
5
5
|
"svg",
|
|
@@ -22,64 +22,80 @@ const CheckIcon = () => /* @__PURE__ */ jsx(
|
|
|
22
22
|
)
|
|
23
23
|
}
|
|
24
24
|
);
|
|
25
|
-
const SelectionCard = (
|
|
26
|
-
mode = "radio",
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (e.key === " " || e.key === "Enter") {
|
|
47
|
-
e.preventDefault();
|
|
48
|
-
handleSelect(option);
|
|
49
|
-
}
|
|
50
|
-
};
|
|
51
|
-
const groupRole = mode === "radio" ? "radiogroup" : "group";
|
|
52
|
-
const itemRole = mode === "radio" ? "radio" : mode === "toggle" ? "switch" : "checkbox";
|
|
53
|
-
const groupClasses = [`${baseClass}-group`, className].filter(Boolean).join(" ");
|
|
54
|
-
return /* @__PURE__ */ jsx("div", { className: groupClasses, role: groupRole, "aria-label": name, children: options.map((option) => {
|
|
55
|
-
const selected = isSelected(option.value);
|
|
56
|
-
const cardClasses = [
|
|
57
|
-
baseClass,
|
|
58
|
-
selected ? `${baseClass}--selected` : "",
|
|
59
|
-
option.disabled ? `${baseClass}--disabled` : ""
|
|
60
|
-
].filter(Boolean).join(" ");
|
|
61
|
-
return /* @__PURE__ */ jsxs(
|
|
25
|
+
const SelectionCard = React.forwardRef(
|
|
26
|
+
({ mode = "radio", options, value, onValueChange, onChange, name, className = "", ...rest }, ref) => {
|
|
27
|
+
const baseClass = "ds-selection-card";
|
|
28
|
+
const selectedValues = Array.isArray(value) ? value : value !== void 0 ? [value] : [];
|
|
29
|
+
const isSelected = (optionValue) => selectedValues.includes(optionValue);
|
|
30
|
+
const handleSelect = (option) => {
|
|
31
|
+
if (option.disabled) return;
|
|
32
|
+
const next = mode === "radio" ? option.value : isSelected(option.value) ? selectedValues.filter((v) => v !== option.value) : [...selectedValues, option.value];
|
|
33
|
+
onValueChange?.(next);
|
|
34
|
+
onChange?.(next);
|
|
35
|
+
};
|
|
36
|
+
const handleKeyDown = (e, option) => {
|
|
37
|
+
if (e.key === " " || e.key === "Enter") {
|
|
38
|
+
e.preventDefault();
|
|
39
|
+
handleSelect(option);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const groupRole = mode === "radio" ? "radiogroup" : "group";
|
|
43
|
+
const itemRole = mode === "radio" ? "radio" : mode === "toggle" ? "switch" : "checkbox";
|
|
44
|
+
const groupClasses = [`${baseClass}-group`, className].filter(Boolean).join(" ");
|
|
45
|
+
return /* @__PURE__ */ jsx(
|
|
62
46
|
"div",
|
|
63
47
|
{
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
option.
|
|
75
|
-
]
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
48
|
+
...rest,
|
|
49
|
+
ref,
|
|
50
|
+
className: groupClasses,
|
|
51
|
+
role: groupRole,
|
|
52
|
+
"aria-label": name || rest["aria-label"],
|
|
53
|
+
children: options.map((option) => {
|
|
54
|
+
const selected = isSelected(option.value);
|
|
55
|
+
const cardClasses = [
|
|
56
|
+
baseClass,
|
|
57
|
+
selected ? `${baseClass}--selected` : "",
|
|
58
|
+
option.disabled ? `${baseClass}--disabled` : ""
|
|
59
|
+
].filter(Boolean).join(" ");
|
|
60
|
+
return /* @__PURE__ */ jsxs(
|
|
61
|
+
"div",
|
|
62
|
+
{
|
|
63
|
+
className: cardClasses,
|
|
64
|
+
role: itemRole,
|
|
65
|
+
"aria-checked": selected,
|
|
66
|
+
"aria-disabled": option.disabled,
|
|
67
|
+
tabIndex: option.disabled ? -1 : 0,
|
|
68
|
+
onClick: () => handleSelect(option),
|
|
69
|
+
onKeyDown: (e) => handleKeyDown(e, option),
|
|
70
|
+
children: [
|
|
71
|
+
/* @__PURE__ */ jsxs("div", { className: `${baseClass}__content`, children: [
|
|
72
|
+
/* @__PURE__ */ jsx("span", { className: `${baseClass}__label`, children: option.label }),
|
|
73
|
+
option.description && /* @__PURE__ */ jsx("span", { className: `${baseClass}__description`, children: option.description })
|
|
74
|
+
] }),
|
|
75
|
+
/* @__PURE__ */ jsx("div", { className: `${baseClass}__indicator`, children: mode === "radio" ? /* @__PURE__ */ jsx("div", { className: `${baseClass}__radio`, children: /* @__PURE__ */ jsx("div", { className: `${baseClass}__radio-dot` }) }) : mode === "toggle" ? /* @__PURE__ */ jsx(
|
|
76
|
+
"div",
|
|
77
|
+
{
|
|
78
|
+
className: `${baseClass}__toggle ${selected ? "" : `${baseClass}__toggle--off`}`,
|
|
79
|
+
children: /* @__PURE__ */ jsx("div", { className: `${baseClass}__toggle-thumb`, children: /* @__PURE__ */ jsx(
|
|
80
|
+
"span",
|
|
81
|
+
{
|
|
82
|
+
className: "material-symbols-rounded ds-selection-card__toggle-icon",
|
|
83
|
+
"aria-hidden": "true",
|
|
84
|
+
children: "check"
|
|
85
|
+
}
|
|
86
|
+
) })
|
|
87
|
+
}
|
|
88
|
+
) : /* @__PURE__ */ jsx("div", { className: `${baseClass}__checkbox`, children: /* @__PURE__ */ jsx(CheckIcon, {}) }) })
|
|
89
|
+
]
|
|
90
|
+
},
|
|
91
|
+
option.value
|
|
92
|
+
);
|
|
93
|
+
})
|
|
94
|
+
}
|
|
80
95
|
);
|
|
81
|
-
}
|
|
82
|
-
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
SelectionCard.displayName = "SelectionCard";
|
|
83
99
|
export {
|
|
84
100
|
SelectionCard
|
|
85
101
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
|
|
2
|
+
/** Props owned by Slider itself — everything else falls through to the <input type="range">. */
|
|
3
|
+
type SliderOwnProps = {
|
|
3
4
|
/** Current value */
|
|
4
5
|
value?: number;
|
|
5
6
|
/** Minimum value */
|
|
@@ -8,18 +9,26 @@ export interface SliderProps {
|
|
|
8
9
|
max?: number;
|
|
9
10
|
/** Step increment */
|
|
10
11
|
step?: number;
|
|
11
|
-
/**
|
|
12
|
-
disabled?: boolean;
|
|
13
|
-
/** Size */
|
|
12
|
+
/** Component size (not the native character-width `size` attribute) */
|
|
14
13
|
size?: 'default' | 'compact';
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Convenience callback receiving the numeric value directly.
|
|
16
|
+
* Fires alongside `onChange`, which keeps the standard React event signature
|
|
17
|
+
* so form libraries work unmodified.
|
|
18
|
+
*/
|
|
19
|
+
onValueChange?: (value: number) => void;
|
|
20
|
+
/** Additional CSS classes — applied to the wrapper, not the <input> */
|
|
20
21
|
className?: string;
|
|
22
|
+
/** @deprecated Pass the native `aria-label` attribute instead. */
|
|
23
|
+
ariaLabel?: string;
|
|
24
|
+
};
|
|
25
|
+
export interface SliderProps extends SliderOwnProps, Omit<React.ComponentPropsWithoutRef<'input'>, keyof SliderOwnProps | 'type'> {
|
|
21
26
|
}
|
|
22
27
|
/**
|
|
23
28
|
* Slider allows selecting a value from within a given range.
|
|
29
|
+
*
|
|
30
|
+
* Forwards a ref to the underlying `<input type="range">` and spreads
|
|
31
|
+
* unrecognised props onto it.
|
|
24
32
|
*/
|
|
25
|
-
export declare const Slider:
|
|
33
|
+
export declare const Slider: React.ForwardRefExoticComponent<SliderProps & React.RefAttributes<HTMLInputElement>>;
|
|
34
|
+
export {};
|
|
@@ -1,46 +1,56 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
|
-
import "react";
|
|
2
|
+
import React from "react";
|
|
3
3
|
import "./Slider.css";
|
|
4
|
-
const Slider = (
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
4
|
+
const Slider = React.forwardRef(
|
|
5
|
+
({
|
|
6
|
+
value = 50,
|
|
7
|
+
min = 0,
|
|
8
|
+
max = 100,
|
|
9
|
+
step = 1,
|
|
10
|
+
disabled = false,
|
|
11
|
+
size = "default",
|
|
12
|
+
onChange,
|
|
13
|
+
onValueChange,
|
|
14
|
+
ariaLabel = "Slider",
|
|
15
|
+
className = "",
|
|
16
|
+
style,
|
|
17
|
+
...rest
|
|
18
|
+
}, ref) => {
|
|
19
|
+
const baseClass = "ds-slider";
|
|
20
|
+
const classes = [
|
|
21
|
+
baseClass,
|
|
22
|
+
`${baseClass}--${size}`,
|
|
23
|
+
disabled ? `${baseClass}--disabled` : "",
|
|
24
|
+
className
|
|
25
|
+
].filter(Boolean).join(" ");
|
|
26
|
+
const percentage = (value - min) / (max - min) * 100;
|
|
27
|
+
const handleChange = (e) => {
|
|
28
|
+
onChange?.(e);
|
|
29
|
+
onValueChange?.(Number(e.target.value));
|
|
30
|
+
};
|
|
31
|
+
return /* @__PURE__ */ jsx("div", { className: classes, children: /* @__PURE__ */ jsx(
|
|
32
|
+
"input",
|
|
33
|
+
{
|
|
34
|
+
...rest,
|
|
35
|
+
ref,
|
|
36
|
+
type: "range",
|
|
37
|
+
className: `${baseClass}__input`,
|
|
38
|
+
value,
|
|
39
|
+
min,
|
|
40
|
+
max,
|
|
41
|
+
step,
|
|
42
|
+
disabled,
|
|
43
|
+
onChange: handleChange,
|
|
44
|
+
"aria-label": ariaLabel || rest["aria-label"],
|
|
45
|
+
style: {
|
|
46
|
+
background: `linear-gradient(to right, var(--color-action-primary-bg) ${percentage}%, var(--color-bg-container-secondary) ${percentage}%)`,
|
|
47
|
+
...style
|
|
48
|
+
}
|
|
40
49
|
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
50
|
+
) });
|
|
51
|
+
}
|
|
52
|
+
);
|
|
53
|
+
Slider.displayName = "Slider";
|
|
44
54
|
export {
|
|
45
55
|
Slider
|
|
46
56
|
};
|
|
@@ -15,7 +15,8 @@ export interface TableRow {
|
|
|
15
15
|
/** Cell values keyed by column key — each accepts any React node */
|
|
16
16
|
cells: Record<string, React.ReactNode>;
|
|
17
17
|
}
|
|
18
|
-
|
|
18
|
+
/** Props owned by Table itself — everything else falls through to the <table>. */
|
|
19
|
+
type TableOwnProps = {
|
|
19
20
|
/** Column definitions */
|
|
20
21
|
columns: TableColumn[];
|
|
21
22
|
/** Row data */
|
|
@@ -36,10 +37,17 @@ export interface TableProps {
|
|
|
36
37
|
captionHidden?: boolean;
|
|
37
38
|
/** Additional CSS classes */
|
|
38
39
|
className?: string;
|
|
40
|
+
};
|
|
41
|
+
export interface TableProps extends TableOwnProps, Omit<React.ComponentPropsWithoutRef<'table'>, keyof TableOwnProps> {
|
|
39
42
|
}
|
|
40
43
|
/**
|
|
41
44
|
* Table component from Figma design system.
|
|
42
45
|
* Data table with flexible cell content — supports text, icons,
|
|
43
46
|
* inputs, buttons, and any other React nodes inside cells.
|
|
47
|
+
*
|
|
48
|
+
* Forwards a ref to the `<table>` element and spreads unrecognised props onto
|
|
49
|
+
* it. When `bordered`, the table is wrapped in a container div — the ref and
|
|
50
|
+
* spread props still target the inner `<table>`.
|
|
44
51
|
*/
|
|
45
|
-
export declare const Table:
|
|
52
|
+
export declare const Table: React.ForwardRefExoticComponent<TableProps & React.RefAttributes<HTMLTableElement>>;
|
|
53
|
+
export {};
|
|
@@ -1,65 +1,65 @@
|
|
|
1
1
|
import { jsxs, jsx } from "react/jsx-runtime";
|
|
2
|
-
import "react";
|
|
2
|
+
import React from "react";
|
|
3
3
|
import "./Table.css";
|
|
4
|
-
const Table = (
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
4
|
+
const Table = React.forwardRef(
|
|
5
|
+
({
|
|
6
|
+
columns,
|
|
7
|
+
rows,
|
|
8
|
+
size = "default",
|
|
9
|
+
striped = false,
|
|
10
|
+
bordered = false,
|
|
11
|
+
caption,
|
|
12
|
+
captionHidden = false,
|
|
13
|
+
className = "",
|
|
14
|
+
...rest
|
|
15
|
+
}, ref) => {
|
|
16
|
+
const baseClass = "ds-table";
|
|
17
|
+
const classes = [
|
|
18
|
+
baseClass,
|
|
19
|
+
`${baseClass}--${size}`,
|
|
20
|
+
striped ? `${baseClass}--striped` : "",
|
|
21
|
+
bordered ? `${baseClass}--bordered` : "",
|
|
22
|
+
className
|
|
23
|
+
].filter(Boolean).join(" ");
|
|
24
|
+
const table = /* @__PURE__ */ jsxs("table", { ...rest, ref, className: classes, children: [
|
|
25
|
+
caption && /* @__PURE__ */ jsx(
|
|
26
|
+
"caption",
|
|
27
|
+
{
|
|
28
|
+
className: captionHidden ? `${baseClass}__caption--hidden` : `${baseClass}__caption`,
|
|
29
|
+
children: caption
|
|
30
|
+
}
|
|
31
|
+
),
|
|
32
|
+
/* @__PURE__ */ jsx("thead", { className: `${baseClass}__head`, children: /* @__PURE__ */ jsx("tr", { className: `${baseClass}__row ${baseClass}__row--header`, children: columns.map((col) => /* @__PURE__ */ jsx(
|
|
33
|
+
"th",
|
|
34
|
+
{
|
|
35
|
+
className: `${baseClass}__header-cell`,
|
|
36
|
+
scope: "col",
|
|
37
|
+
style: {
|
|
38
|
+
width: col.width,
|
|
39
|
+
textAlign: col.align || "left"
|
|
40
|
+
},
|
|
41
|
+
children: col.header
|
|
35
42
|
},
|
|
36
|
-
|
|
37
|
-
},
|
|
38
|
-
col
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
)
|
|
54
|
-
},
|
|
55
|
-
col.key
|
|
56
|
-
)) }, row.id)) })
|
|
57
|
-
] });
|
|
58
|
-
if (bordered) {
|
|
59
|
-
return /* @__PURE__ */ jsx("div", { className: `${baseClass}__wrapper`, children: table });
|
|
43
|
+
col.key
|
|
44
|
+
)) }) }),
|
|
45
|
+
/* @__PURE__ */ jsx("tbody", { className: `${baseClass}__body`, children: rows.map((row) => /* @__PURE__ */ jsx("tr", { className: `${baseClass}__row`, children: columns.map((col) => /* @__PURE__ */ jsx("td", { className: `${baseClass}__cell`, children: /* @__PURE__ */ jsx(
|
|
46
|
+
"div",
|
|
47
|
+
{
|
|
48
|
+
className: `${baseClass}__cell-content`,
|
|
49
|
+
style: {
|
|
50
|
+
justifyContent: col.align === "center" ? "center" : col.align === "right" ? "flex-end" : "flex-start"
|
|
51
|
+
},
|
|
52
|
+
children: row.cells[col.key]
|
|
53
|
+
}
|
|
54
|
+
) }, col.key)) }, row.id)) })
|
|
55
|
+
] });
|
|
56
|
+
if (bordered) {
|
|
57
|
+
return /* @__PURE__ */ jsx("div", { className: `${baseClass}__wrapper`, children: table });
|
|
58
|
+
}
|
|
59
|
+
return table;
|
|
60
60
|
}
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
);
|
|
62
|
+
Table.displayName = "Table";
|
|
63
63
|
export {
|
|
64
64
|
Table
|
|
65
65
|
};
|