@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
package/README.md
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# robr0 — Portfolio + Design System
|
|
2
2
|
|
|
3
3
|
[](https://github.com/robritacca-dotcom/design-system/actions/workflows/ci.yml)
|
|
4
|
+
<!-- npm-badge:start -->
|
|
5
|
+
[](https://www.npmjs.com/package/@robr0/design-system)
|
|
6
|
+
<!-- npm-badge:end -->
|
|
4
7
|
|
|
5
8
|
A personal portfolio site built on a custom React design system I designed and engineered from scratch. The DS isn't a side project — it's the backbone every portfolio page is built on, ensuring the work is presented consistently and with the same craft standards I apply professionally.
|
|
6
9
|
|
|
@@ -107,7 +110,7 @@ Full spec in [`design.md`](design.md).
|
|
|
107
110
|
Every push and pull request runs a GitHub Actions pipeline ([`ci.yml`](.github/workflows/ci.yml)) with four jobs: **lint + library build**, **story tests** (every Storybook story rendered in headless Chromium via Vitest), **Storybook build**, and **website build**. The same checklist runs locally with one command:
|
|
108
111
|
|
|
109
112
|
```bash
|
|
110
|
-
npm run verify # lint + library build + story tests + Storybook build + website build
|
|
113
|
+
npm run verify # lint + library type-check + package build + story tests + Storybook build + website build
|
|
111
114
|
```
|
|
112
115
|
|
|
113
116
|
CI also guards against documentation drift: generated surfaces (this README's component count and list, the website's skills pages, the published CLAUDE.md/design.md blueprints) are rebuilt from their source registries on every build, and CI fails if the committed copies are stale. The numbers on the site are never hand-written.
|
|
@@ -120,8 +123,7 @@ CI also guards against documentation drift: generated surfaces (this README's co
|
|
|
120
123
|
# Storybook (the library's dev sandbox)
|
|
121
124
|
npm run storybook # http://localhost:6006
|
|
122
125
|
|
|
123
|
-
# Portfolio + documentation website
|
|
124
|
-
cd website
|
|
126
|
+
# Portfolio + documentation website (npm workspace — install once at the root)
|
|
125
127
|
npm install
|
|
126
|
-
npm run dev
|
|
128
|
+
npm run dev --workspace website # http://localhost:3000
|
|
127
129
|
```
|
|
@@ -74,8 +74,16 @@
|
|
|
74
74
|
SEPARATOR
|
|
75
75
|
============================================ */
|
|
76
76
|
|
|
77
|
+
/*
|
|
78
|
+
Size via --icon-size, never font-size: .material-symbols-rounded derives
|
|
79
|
+
the glyph size AND the layout box from that one variable. Setting
|
|
80
|
+
font-size alone shrank the glyph but left a 24px box around it, so the
|
|
81
|
+
chevron floated above the text baseline. --icon-size-sm (20px) also
|
|
82
|
+
matches the 20px line-height of the paragraph-sm labels either side.
|
|
83
|
+
*/
|
|
77
84
|
.ds-breadcrumb__separator {
|
|
78
|
-
|
|
85
|
+
--icon-size: var(--icon-size-sm);
|
|
86
|
+
flex: none;
|
|
79
87
|
color: var(--color-text-tertiary);
|
|
80
88
|
user-select: none;
|
|
81
89
|
}
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
|
|
2
|
+
/** Props owned by Button itself — everything else falls through to the DOM node. */
|
|
3
|
+
type ButtonOwnProps = {
|
|
3
4
|
/** Button text content */
|
|
4
5
|
label?: string;
|
|
5
6
|
/** Icon for left side — Material Symbol name (string) or custom element (ReactNode) */
|
|
6
7
|
iconLeft?: string | React.ReactNode;
|
|
7
8
|
/** Icon for right side — Material Symbol name (string) or custom element (ReactNode) */
|
|
8
9
|
iconRight?: string | React.ReactNode;
|
|
9
|
-
/**
|
|
10
|
-
|
|
11
|
-
/** Button state */
|
|
12
|
-
state?: 'default' | 'hover' | 'active' | 'disabled';
|
|
10
|
+
/** Visual treatment */
|
|
11
|
+
variant?: 'primary' | 'secondary' | 'tertiary' | 'destructive';
|
|
13
12
|
/** Button size */
|
|
14
13
|
size?: 'default' | 'compact';
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
/** Optional click handler */
|
|
18
|
-
onClick?: () => void;
|
|
14
|
+
/** Whether the button is disabled */
|
|
15
|
+
disabled?: boolean;
|
|
19
16
|
/** Optional href — renders as <a> instead of <button> */
|
|
20
17
|
href?: string;
|
|
21
18
|
/** Optional target attribute for links */
|
|
@@ -24,16 +21,35 @@ export interface ButtonProps {
|
|
|
24
21
|
rel?: string;
|
|
25
22
|
/** Marks this link as the current page (adds aria-current="page") */
|
|
26
23
|
ariaCurrent?: boolean;
|
|
27
|
-
/** Id of an element describing this button — set automatically by Tooltip */
|
|
28
|
-
'aria-describedby'?: string;
|
|
29
24
|
/** Additional CSS classes */
|
|
30
25
|
className?: string;
|
|
31
|
-
/** @deprecated Use
|
|
26
|
+
/** @deprecated Use `variant` instead. */
|
|
27
|
+
priority?: 'primary' | 'secondary' | 'tertiary' | 'destructive';
|
|
28
|
+
/**
|
|
29
|
+
* @deprecated Use `disabled` for the disabled state.
|
|
30
|
+
*
|
|
31
|
+
* Documentation-only affordance for rendering a *static* interaction state in
|
|
32
|
+
* Storybook and the showcase site. Real hover/active styling comes from CSS
|
|
33
|
+
* pseudo-classes and needs no prop — for docs, prefer `className="ds-button--hover"`.
|
|
34
|
+
*/
|
|
35
|
+
state?: 'default' | 'hover' | 'active' | 'disabled';
|
|
36
|
+
/** @deprecated Use `iconLeft` instead. */
|
|
32
37
|
icon?: string;
|
|
38
|
+
/**
|
|
39
|
+
* @deprecated Will be removed once `label` loses its default in the next major;
|
|
40
|
+
* an icon-only button will simply omit `label`.
|
|
41
|
+
*/
|
|
42
|
+
text?: boolean;
|
|
43
|
+
};
|
|
44
|
+
export interface ButtonProps extends ButtonOwnProps, Omit<React.ComponentPropsWithoutRef<'button'>, keyof ButtonOwnProps | 'type'> {
|
|
33
45
|
}
|
|
34
46
|
/**
|
|
35
|
-
* Button component from Figma design system
|
|
36
|
-
* Supports primary
|
|
37
|
-
* Icons can be placed on the left and/or right side of the text
|
|
47
|
+
* Button component from Figma design system.
|
|
48
|
+
* Supports primary, secondary, tertiary and destructive variants.
|
|
49
|
+
* Icons can be placed on the left and/or right side of the text.
|
|
50
|
+
*
|
|
51
|
+
* Renders a `<button>`, or an `<a>` when `href` is supplied. Forwards a ref to
|
|
52
|
+
* whichever element it renders, and spreads unrecognised props onto it.
|
|
38
53
|
*/
|
|
39
|
-
export declare const Button:
|
|
54
|
+
export declare const Button: React.ForwardRefExoticComponent<ButtonProps & React.RefAttributes<HTMLButtonElement | HTMLAnchorElement>>;
|
|
55
|
+
export {};
|
|
@@ -1,71 +1,79 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
|
-
import "react";
|
|
2
|
+
import React from "react";
|
|
3
3
|
import "./Button.css";
|
|
4
4
|
import "../../fonts/material-symbols.css";
|
|
5
|
-
const Button = (
|
|
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
|
-
|
|
5
|
+
const Button = React.forwardRef(
|
|
6
|
+
({
|
|
7
|
+
label = "Button",
|
|
8
|
+
iconLeft,
|
|
9
|
+
iconRight,
|
|
10
|
+
variant,
|
|
11
|
+
size = "default",
|
|
12
|
+
disabled,
|
|
13
|
+
href,
|
|
14
|
+
target,
|
|
15
|
+
rel,
|
|
16
|
+
ariaCurrent,
|
|
17
|
+
className = "",
|
|
18
|
+
priority,
|
|
19
|
+
state,
|
|
20
|
+
icon,
|
|
21
|
+
text = true,
|
|
22
|
+
...rest
|
|
23
|
+
}, ref) => {
|
|
24
|
+
const baseClass = "ds-button";
|
|
25
|
+
const resolvedVariant = variant ?? priority ?? "primary";
|
|
26
|
+
const isDisabled = disabled ?? state === "disabled";
|
|
27
|
+
const resolvedState = state ?? (isDisabled ? "disabled" : "default");
|
|
28
|
+
const classes = [
|
|
29
|
+
baseClass,
|
|
30
|
+
`${baseClass}--${resolvedVariant}`,
|
|
31
|
+
`${baseClass}--${resolvedState}`,
|
|
32
|
+
`${baseClass}--${size}`,
|
|
33
|
+
className
|
|
34
|
+
].filter(Boolean).join(" ");
|
|
35
|
+
const iconClass = "material-symbols-rounded";
|
|
36
|
+
const leftIcon = iconLeft || icon;
|
|
37
|
+
const renderIcon = (iconProp) => {
|
|
38
|
+
if (typeof iconProp === "string") {
|
|
39
|
+
return /* @__PURE__ */ jsx("span", { className: `${baseClass}__icon ${iconClass}`, "aria-hidden": "true", children: iconProp });
|
|
40
|
+
}
|
|
41
|
+
return /* @__PURE__ */ jsx("span", { className: `${baseClass}__icon`, "aria-hidden": "true", children: iconProp });
|
|
42
|
+
};
|
|
43
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
44
|
+
leftIcon && renderIcon(leftIcon),
|
|
45
|
+
text && /* @__PURE__ */ jsx("span", { className: `${baseClass}__text`, children: label }),
|
|
46
|
+
iconRight && renderIcon(iconRight)
|
|
47
|
+
] });
|
|
48
|
+
if (href && !isDisabled) {
|
|
49
|
+
return /* @__PURE__ */ jsx(
|
|
50
|
+
"a",
|
|
51
|
+
{
|
|
52
|
+
...rest,
|
|
53
|
+
ref,
|
|
54
|
+
className: classes,
|
|
55
|
+
href,
|
|
56
|
+
target,
|
|
57
|
+
rel,
|
|
58
|
+
"aria-current": ariaCurrent ? "page" : void 0,
|
|
59
|
+
children: content
|
|
60
|
+
}
|
|
61
|
+
);
|
|
34
62
|
}
|
|
35
|
-
return /* @__PURE__ */ jsx("span", { className: `${baseClass}__icon`, "aria-hidden": "true", children: iconProp });
|
|
36
|
-
};
|
|
37
|
-
const children = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
38
|
-
leftIcon && renderIcon(leftIcon),
|
|
39
|
-
text && /* @__PURE__ */ jsx("span", { className: `${baseClass}__text`, children: label }),
|
|
40
|
-
iconRight && renderIcon(iconRight)
|
|
41
|
-
] });
|
|
42
|
-
if (href && !isDisabled) {
|
|
43
63
|
return /* @__PURE__ */ jsx(
|
|
44
|
-
"
|
|
64
|
+
"button",
|
|
45
65
|
{
|
|
66
|
+
...rest,
|
|
67
|
+
ref,
|
|
68
|
+
type: "button",
|
|
46
69
|
className: classes,
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
rel,
|
|
50
|
-
"aria-current": ariaCurrent ? "page" : void 0,
|
|
51
|
-
"aria-describedby": ariaDescribedby,
|
|
52
|
-
onClick,
|
|
53
|
-
children
|
|
70
|
+
disabled: isDisabled,
|
|
71
|
+
children: content
|
|
54
72
|
}
|
|
55
73
|
);
|
|
56
74
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
{
|
|
60
|
-
type: "button",
|
|
61
|
-
className: classes,
|
|
62
|
-
onClick,
|
|
63
|
-
disabled: isDisabled,
|
|
64
|
-
"aria-describedby": ariaDescribedby,
|
|
65
|
-
children
|
|
66
|
-
}
|
|
67
|
-
);
|
|
68
|
-
};
|
|
75
|
+
);
|
|
76
|
+
Button.displayName = "Button";
|
|
69
77
|
export {
|
|
70
78
|
Button
|
|
71
79
|
};
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
|
|
2
|
+
/** Props owned by Card itself — everything else falls through to the DOM node. */
|
|
3
|
+
type CardOwnProps = {
|
|
3
4
|
/** Card variant */
|
|
4
5
|
variant?: 'default' | 'case-study';
|
|
5
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* Card title displayed below the preview.
|
|
8
|
+
* Note: this shadows the native `title` tooltip attribute, which Card does not expose.
|
|
9
|
+
*/
|
|
6
10
|
title: string;
|
|
7
11
|
/** Preview content rendered inside the card (default variant only) */
|
|
8
12
|
children?: React.ReactNode;
|
|
9
13
|
/** Whether the card is interactive (hoverable) */
|
|
10
14
|
interactive?: boolean;
|
|
11
|
-
/** Click handler */
|
|
12
|
-
onClick?: () => void;
|
|
13
15
|
/** Additional CSS classes */
|
|
14
16
|
className?: string;
|
|
15
17
|
/** Navigation href — renders the card as an <a> tag */
|
|
@@ -26,5 +28,15 @@ export interface CardProps {
|
|
|
26
28
|
dek?: string;
|
|
27
29
|
/** Render as a disabled placeholder (no href, dimmed, not interactive) */
|
|
28
30
|
placeholder?: boolean;
|
|
31
|
+
};
|
|
32
|
+
export interface CardProps extends CardOwnProps, Omit<React.ComponentPropsWithoutRef<'div'>, keyof CardOwnProps> {
|
|
29
33
|
}
|
|
30
|
-
|
|
34
|
+
/**
|
|
35
|
+
* Card renders a preview tile, or a case-study tile when `variant="case-study"`.
|
|
36
|
+
*
|
|
37
|
+
* Renders a `<div>`, or an `<a>` in the case-study variant when `href` is
|
|
38
|
+
* supplied. Forwards a ref to whichever element it renders and spreads
|
|
39
|
+
* unrecognised props onto it.
|
|
40
|
+
*/
|
|
41
|
+
export declare const Card: React.ForwardRefExoticComponent<CardProps & React.RefAttributes<HTMLDivElement | HTMLAnchorElement>>;
|
|
42
|
+
export {};
|
package/components/Card/Card.js
CHANGED
|
@@ -1,90 +1,111 @@
|
|
|
1
1
|
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
|
-
import "react";
|
|
2
|
+
import React from "react";
|
|
3
3
|
import "./Card.css";
|
|
4
4
|
import "../../fonts/material-symbols.css";
|
|
5
|
-
const Card = (
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
5
|
+
const Card = React.forwardRef(
|
|
6
|
+
({
|
|
7
|
+
variant = "default",
|
|
8
|
+
title,
|
|
9
|
+
children,
|
|
10
|
+
interactive = false,
|
|
11
|
+
onClick,
|
|
12
|
+
onKeyDown,
|
|
13
|
+
className = "",
|
|
14
|
+
href,
|
|
15
|
+
coverSrc,
|
|
16
|
+
coverAlt,
|
|
17
|
+
companyLogo,
|
|
18
|
+
companyName,
|
|
19
|
+
dek,
|
|
20
|
+
placeholder = false,
|
|
21
|
+
...rest
|
|
22
|
+
}, ref) => {
|
|
23
|
+
if (variant === "case-study") {
|
|
24
|
+
const inner = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
25
|
+
/* @__PURE__ */ jsx("div", { className: "ds-card--case-study__cover-wrap", children: coverSrc ? /* @__PURE__ */ jsx(
|
|
26
|
+
"img",
|
|
27
|
+
{
|
|
28
|
+
src: coverSrc,
|
|
29
|
+
alt: coverAlt ?? `${title} cover`,
|
|
30
|
+
className: "ds-card--case-study__cover-image"
|
|
31
|
+
}
|
|
32
|
+
) : /* @__PURE__ */ jsx("div", { className: "ds-card--case-study__cover-placeholder", children: companyLogo && /* @__PURE__ */ jsx(
|
|
33
|
+
"img",
|
|
34
|
+
{
|
|
35
|
+
src: companyLogo,
|
|
36
|
+
alt: "",
|
|
37
|
+
className: "ds-card--case-study__cover-placeholder-logo"
|
|
38
|
+
}
|
|
39
|
+
) }) }),
|
|
40
|
+
/* @__PURE__ */ jsxs("div", { className: "ds-card--case-study__body", children: [
|
|
41
|
+
(companyLogo || companyName) && /* @__PURE__ */ jsxs("div", { className: "ds-card--case-study__eyebrow", children: [
|
|
42
|
+
companyLogo && /* @__PURE__ */ jsx("img", { src: companyLogo, alt: "", className: "ds-card--case-study__company-logo" }),
|
|
43
|
+
companyName && /* @__PURE__ */ jsx("span", { className: "ds-card--case-study__company-name", children: companyName })
|
|
44
|
+
] }),
|
|
45
|
+
/* @__PURE__ */ jsx("h3", { className: "ds-card--case-study__title", children: title }),
|
|
46
|
+
dek && /* @__PURE__ */ jsx("p", { className: "ds-card--case-study__dek", children: dek })
|
|
47
|
+
] })
|
|
48
|
+
] });
|
|
49
|
+
const classes2 = [
|
|
50
|
+
"ds-card",
|
|
51
|
+
"ds-card--case-study",
|
|
52
|
+
placeholder ? "ds-card--case-study--placeholder" : "",
|
|
53
|
+
className
|
|
54
|
+
].filter(Boolean).join(" ");
|
|
55
|
+
if (placeholder || !href) {
|
|
56
|
+
return /* @__PURE__ */ jsx(
|
|
57
|
+
"div",
|
|
58
|
+
{
|
|
59
|
+
...rest,
|
|
60
|
+
ref,
|
|
61
|
+
className: classes2,
|
|
62
|
+
"aria-disabled": "true",
|
|
63
|
+
children: inner
|
|
64
|
+
}
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return /* @__PURE__ */ jsx(
|
|
68
|
+
"a",
|
|
24
69
|
{
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
70
|
+
...rest,
|
|
71
|
+
ref,
|
|
72
|
+
href,
|
|
73
|
+
className: classes2,
|
|
74
|
+
onClick,
|
|
75
|
+
children: inner
|
|
28
76
|
}
|
|
29
|
-
)
|
|
30
|
-
"img",
|
|
31
|
-
{
|
|
32
|
-
src: companyLogo,
|
|
33
|
-
alt: "",
|
|
34
|
-
className: "ds-card--case-study__cover-placeholder-logo"
|
|
35
|
-
}
|
|
36
|
-
) }) }),
|
|
37
|
-
/* @__PURE__ */ jsxs("div", { className: "ds-card--case-study__body", children: [
|
|
38
|
-
(companyLogo || companyName) && /* @__PURE__ */ jsxs("div", { className: "ds-card--case-study__eyebrow", children: [
|
|
39
|
-
companyLogo && /* @__PURE__ */ jsx(
|
|
40
|
-
"img",
|
|
41
|
-
{
|
|
42
|
-
src: companyLogo,
|
|
43
|
-
alt: "",
|
|
44
|
-
className: "ds-card--case-study__company-logo"
|
|
45
|
-
}
|
|
46
|
-
),
|
|
47
|
-
companyName && /* @__PURE__ */ jsx("span", { className: "ds-card--case-study__company-name", children: companyName })
|
|
48
|
-
] }),
|
|
49
|
-
/* @__PURE__ */ jsx("h3", { className: "ds-card--case-study__title", children: title }),
|
|
50
|
-
dek && /* @__PURE__ */ jsx("p", { className: "ds-card--case-study__dek", children: dek })
|
|
51
|
-
] })
|
|
52
|
-
] });
|
|
53
|
-
const classes2 = [
|
|
54
|
-
"ds-card",
|
|
55
|
-
"ds-card--case-study",
|
|
56
|
-
placeholder ? "ds-card--case-study--placeholder" : "",
|
|
57
|
-
className
|
|
58
|
-
].filter(Boolean).join(" ");
|
|
59
|
-
if (placeholder || !href) {
|
|
60
|
-
return /* @__PURE__ */ jsx("div", { className: classes2, "aria-disabled": "true", children: inner });
|
|
77
|
+
);
|
|
61
78
|
}
|
|
62
|
-
|
|
79
|
+
const baseClass = "ds-card";
|
|
80
|
+
const classes = [baseClass, interactive ? `${baseClass}--interactive` : "", className].filter(Boolean).join(" ");
|
|
81
|
+
const handleKeyDown = (e) => {
|
|
82
|
+
onKeyDown?.(e);
|
|
83
|
+
if (!interactive) return;
|
|
84
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
85
|
+
e.preventDefault();
|
|
86
|
+
onClick?.(e);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
return /* @__PURE__ */ jsxs(
|
|
90
|
+
"div",
|
|
91
|
+
{
|
|
92
|
+
...rest,
|
|
93
|
+
ref,
|
|
94
|
+
className: classes,
|
|
95
|
+
onClick: interactive ? onClick : void 0,
|
|
96
|
+
onKeyDown: handleKeyDown,
|
|
97
|
+
role: interactive ? "button" : void 0,
|
|
98
|
+
tabIndex: interactive ? 0 : void 0,
|
|
99
|
+
"aria-label": interactive ? title : void 0,
|
|
100
|
+
children: [
|
|
101
|
+
/* @__PURE__ */ jsx("div", { className: `${baseClass}__preview`, children }),
|
|
102
|
+
/* @__PURE__ */ jsx("h3", { className: `${baseClass}__title`, children: title })
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
);
|
|
63
106
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
const classes = [baseClass, interactiveClass, className].filter(Boolean).join(" ");
|
|
67
|
-
return /* @__PURE__ */ jsxs(
|
|
68
|
-
"div",
|
|
69
|
-
{
|
|
70
|
-
className: classes,
|
|
71
|
-
onClick: interactive ? onClick : void 0,
|
|
72
|
-
onKeyDown: interactive ? (e) => {
|
|
73
|
-
if (e.key === "Enter" || e.key === " ") {
|
|
74
|
-
e.preventDefault();
|
|
75
|
-
onClick?.();
|
|
76
|
-
}
|
|
77
|
-
} : void 0,
|
|
78
|
-
role: interactive ? "button" : void 0,
|
|
79
|
-
tabIndex: interactive ? 0 : void 0,
|
|
80
|
-
"aria-label": interactive ? title : void 0,
|
|
81
|
-
children: [
|
|
82
|
-
/* @__PURE__ */ jsx("div", { className: `${baseClass}__preview`, children }),
|
|
83
|
-
/* @__PURE__ */ jsx("h3", { className: `${baseClass}__title`, children: title })
|
|
84
|
-
]
|
|
85
|
-
}
|
|
86
|
-
);
|
|
87
|
-
};
|
|
107
|
+
);
|
|
108
|
+
Card.displayName = "Card";
|
|
88
109
|
export {
|
|
89
110
|
Card
|
|
90
111
|
};
|
|
@@ -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 {};
|