@roadlittledawn/docs-design-system-react 0.9.1 → 0.11.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 +25 -3
- package/USAGE.md +1070 -0
- package/dist/components/Breadcrumb.d.ts +41 -0
- package/dist/components/Breadcrumb.js +49 -0
- package/dist/components/Breadcrumb.stories.d.ts +40 -0
- package/dist/components/Breadcrumb.stories.js +216 -0
- package/dist/components/Button.d.ts +1 -2
- package/dist/components/Callout.d.ts +1 -2
- package/dist/components/Card.d.ts +1 -2
- package/dist/components/CardGrid.d.ts +1 -2
- package/dist/components/CodeBlock.d.ts +1 -2
- package/dist/components/CollapserGroup.d.ts +1 -0
- package/dist/components/Heading.d.ts +1 -2
- package/dist/components/Icon.d.ts +52 -0
- package/dist/components/Icon.js +49 -0
- package/dist/components/Icon.stories.d.ts +31 -0
- package/dist/components/Icon.stories.js +141 -0
- package/dist/components/Link.d.ts +1 -2
- package/dist/components/List.d.ts +1 -2
- package/dist/components/Tabs.d.ts +4 -5
- package/dist/components/Typography.d.ts +1 -2
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/styles.css +147 -0
- package/package.json +3 -2
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
export interface BreadcrumbItem {
|
|
3
|
+
/** Display text for the breadcrumb segment */
|
|
4
|
+
label: string;
|
|
5
|
+
/** Optional URL for the segment; omit for the current (last) page */
|
|
6
|
+
href?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface BreadcrumbProps {
|
|
9
|
+
/** Ordered list of path segments, root first */
|
|
10
|
+
items: BreadcrumbItem[];
|
|
11
|
+
/**
|
|
12
|
+
* Separator between segments. Accepts a string or any ReactNode (e.g. an SVG chevron icon).
|
|
13
|
+
* @default "/"
|
|
14
|
+
*/
|
|
15
|
+
delimiter?: ReactNode;
|
|
16
|
+
/**
|
|
17
|
+
* Size variant controlling font size.
|
|
18
|
+
* @default "md"
|
|
19
|
+
*/
|
|
20
|
+
size?: "sm" | "md";
|
|
21
|
+
/**
|
|
22
|
+
* On narrow viewports, collapse middle segments behind an expandable ellipsis (…).
|
|
23
|
+
* The first and last segments are always visible. Click/tap the ellipsis to reveal all.
|
|
24
|
+
* @default false
|
|
25
|
+
*/
|
|
26
|
+
collapseOnMobile?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* On narrow viewports, let the full breadcrumb trail scroll horizontally instead of
|
|
29
|
+
* wrapping to multiple lines. Can be combined with `collapseOnMobile`.
|
|
30
|
+
* @default false
|
|
31
|
+
*/
|
|
32
|
+
scrollOnMobile?: boolean;
|
|
33
|
+
/** Additional CSS classes for consumer extensibility */
|
|
34
|
+
className?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Breadcrumb navigation component. Renders a `<nav aria-label="Breadcrumb">` with an ordered
|
|
38
|
+
* list of segments. The last (current) item receives `aria-current="page"`. Delimiter characters
|
|
39
|
+
* are marked `aria-hidden` so screen readers skip them.
|
|
40
|
+
*/
|
|
41
|
+
export declare function Breadcrumb({ items, delimiter, size, collapseOnMobile, scrollOnMobile, className, }: BreadcrumbProps): import("react/jsx-runtime").JSX.Element | null;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var __assign = (this && this.__assign) || function () {
|
|
3
|
+
__assign = Object.assign || function(t) {
|
|
4
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
+
s = arguments[i];
|
|
6
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
+
t[p] = s[p];
|
|
8
|
+
}
|
|
9
|
+
return t;
|
|
10
|
+
};
|
|
11
|
+
return __assign.apply(this, arguments);
|
|
12
|
+
};
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
14
|
+
import { useState } from "react";
|
|
15
|
+
/**
|
|
16
|
+
* Breadcrumb navigation component. Renders a `<nav aria-label="Breadcrumb">` with an ordered
|
|
17
|
+
* list of segments. The last (current) item receives `aria-current="page"`. Delimiter characters
|
|
18
|
+
* are marked `aria-hidden` so screen readers skip them.
|
|
19
|
+
*/
|
|
20
|
+
export function Breadcrumb(_a) {
|
|
21
|
+
var items = _a.items, _b = _a.delimiter, delimiter = _b === void 0 ? "/" : _b, _c = _a.size, size = _c === void 0 ? "md" : _c, _d = _a.collapseOnMobile, collapseOnMobile = _d === void 0 ? false : _d, _e = _a.scrollOnMobile, scrollOnMobile = _e === void 0 ? false : _e, _f = _a.className, className = _f === void 0 ? "" : _f;
|
|
22
|
+
var _g = useState(false), isExpanded = _g[0], setIsExpanded = _g[1];
|
|
23
|
+
if (items.length === 0)
|
|
24
|
+
return null;
|
|
25
|
+
var isCollapsible = collapseOnMobile && items.length > 2;
|
|
26
|
+
var navClasses = [
|
|
27
|
+
"dds-breadcrumb",
|
|
28
|
+
"dds-breadcrumb--".concat(size),
|
|
29
|
+
isCollapsible ? "dds-breadcrumb--collapsible" : "",
|
|
30
|
+
scrollOnMobile ? "dds-breadcrumb--scroll" : "",
|
|
31
|
+
className,
|
|
32
|
+
]
|
|
33
|
+
.filter(Boolean)
|
|
34
|
+
.join(" ");
|
|
35
|
+
var firstItem = items[0];
|
|
36
|
+
var lastItem = items[items.length - 1];
|
|
37
|
+
var middleItems = items.length > 1 ? items.slice(1, -1) : [];
|
|
38
|
+
var hasMiddle = middleItems.length > 0;
|
|
39
|
+
return (_jsx("nav", __assign({ className: navClasses, "aria-label": "Breadcrumb" }, (isCollapsible ? { "data-expanded": String(isExpanded) } : {}), { children: _jsxs("ol", { className: "dds-breadcrumb-list", children: [_jsxs("li", { className: "dds-breadcrumb-item", children: [items.length === 1 ? (_jsx("span", { className: "dds-breadcrumb-current", "aria-current": "page", children: firstItem.label })) : firstItem.href ? (_jsx("a", { href: firstItem.href, className: "dds-breadcrumb-link", children: firstItem.label })) : (_jsx("span", { className: "dds-breadcrumb-link", children: firstItem.label })), items.length > 1 && (_jsx("span", { className: "dds-breadcrumb-delimiter", "aria-hidden": "true", children: delimiter }))] }), isCollapsible && hasMiddle && (_jsxs("li", { className: "dds-breadcrumb-item dds-breadcrumb-item--ellipsis", children: [_jsx("button", { type: "button", className: "dds-breadcrumb-ellipsis", "aria-label": "Show all breadcrumb items", onClick: function () { return setIsExpanded(true); }, children: "\u2026" }), _jsx("span", { className: "dds-breadcrumb-delimiter", "aria-hidden": "true", children: delimiter })] })), hasMiddle &&
|
|
40
|
+
middleItems.map(function (item, relIndex) {
|
|
41
|
+
var _a;
|
|
42
|
+
return (_jsxs("li", { className: [
|
|
43
|
+
"dds-breadcrumb-item",
|
|
44
|
+
isCollapsible ? "dds-breadcrumb-item--middle" : "",
|
|
45
|
+
]
|
|
46
|
+
.filter(Boolean)
|
|
47
|
+
.join(" "), children: [item.href ? (_jsx("a", { href: item.href, className: "dds-breadcrumb-link", children: item.label })) : (_jsx("span", { className: "dds-breadcrumb-link", children: item.label })), _jsx("span", { className: "dds-breadcrumb-delimiter", "aria-hidden": "true", children: delimiter })] }, "".concat((_a = item.href) !== null && _a !== void 0 ? _a : '', "-").concat(item.label, "-").concat(relIndex)));
|
|
48
|
+
}), items.length > 1 && (_jsx("li", { className: "dds-breadcrumb-item", children: lastItem.href ? (_jsx("a", { href: lastItem.href, className: "dds-breadcrumb-link dds-breadcrumb-current", "aria-current": "page", children: lastItem.label })) : (_jsx("span", { className: "dds-breadcrumb-current", "aria-current": "page", children: lastItem.label })) }))] }) })));
|
|
49
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from "@storybook/react";
|
|
2
|
+
import { Breadcrumb } from "./Breadcrumb";
|
|
3
|
+
declare const meta: Meta<typeof Breadcrumb>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof Breadcrumb>;
|
|
6
|
+
/**
|
|
7
|
+
* The default breadcrumb with a three-segment path and the "/" delimiter.
|
|
8
|
+
*/
|
|
9
|
+
export declare const Default: Story;
|
|
10
|
+
/**
|
|
11
|
+
* A single-item breadcrumb — just the current page with no parent links.
|
|
12
|
+
*/
|
|
13
|
+
export declare const SingleItem: Story;
|
|
14
|
+
/**
|
|
15
|
+
* Custom string delimiter using "›" instead of "/".
|
|
16
|
+
*/
|
|
17
|
+
export declare const CustomStringDelimiter: Story;
|
|
18
|
+
/**
|
|
19
|
+
* Custom SVG chevron as the delimiter — demonstrates ReactNode delimiter support.
|
|
20
|
+
*/
|
|
21
|
+
export declare const SvgChevronDelimiter: Story;
|
|
22
|
+
/**
|
|
23
|
+
* Small size variant — useful in compact page headers.
|
|
24
|
+
*/
|
|
25
|
+
export declare const SmallSize: Story;
|
|
26
|
+
/**
|
|
27
|
+
* `collapseOnMobile` — middle segments collapse to an ellipsis on narrow viewports.
|
|
28
|
+
* Resize the browser window or use a mobile emulator to see this in action.
|
|
29
|
+
* Click the "…" to expand all items.
|
|
30
|
+
*/
|
|
31
|
+
export declare const CollapseOnMobile: Story;
|
|
32
|
+
/**
|
|
33
|
+
* `scrollOnMobile` — the breadcrumb trail scrolls horizontally on narrow viewports
|
|
34
|
+
* rather than wrapping onto multiple lines.
|
|
35
|
+
*/
|
|
36
|
+
export declare const ScrollOnMobile: Story;
|
|
37
|
+
/**
|
|
38
|
+
* All size and delimiter variants displayed together for visual comparison.
|
|
39
|
+
*/
|
|
40
|
+
export declare const AllVariants: Story;
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Breadcrumb } from "./Breadcrumb";
|
|
3
|
+
var meta = {
|
|
4
|
+
title: "Components/Breadcrumb",
|
|
5
|
+
component: Breadcrumb,
|
|
6
|
+
tags: ["autodocs"],
|
|
7
|
+
argTypes: {
|
|
8
|
+
items: {
|
|
9
|
+
description: "Ordered array of path segments (root first). Each item requires a `label`; `href` is optional and omitted for the current page.",
|
|
10
|
+
},
|
|
11
|
+
delimiter: {
|
|
12
|
+
control: "text",
|
|
13
|
+
description: "Separator between segments. Accepts a string or any ReactNode (e.g. an SVG icon). Rendered `aria-hidden`.",
|
|
14
|
+
table: { defaultValue: { summary: '"/"' } },
|
|
15
|
+
},
|
|
16
|
+
size: {
|
|
17
|
+
control: { type: "select" },
|
|
18
|
+
options: ["sm", "md"],
|
|
19
|
+
description: "Font-size variant.",
|
|
20
|
+
table: { defaultValue: { summary: '"md"' } },
|
|
21
|
+
},
|
|
22
|
+
collapseOnMobile: {
|
|
23
|
+
control: "boolean",
|
|
24
|
+
description: "Collapse middle segments behind an ellipsis on narrow viewports. Click the ellipsis to expand.",
|
|
25
|
+
table: { defaultValue: { summary: "false" } },
|
|
26
|
+
},
|
|
27
|
+
scrollOnMobile: {
|
|
28
|
+
control: "boolean",
|
|
29
|
+
description: "Let the full breadcrumb scroll horizontally on narrow viewports instead of wrapping. Can be combined with `collapseOnMobile`.",
|
|
30
|
+
table: { defaultValue: { summary: "false" } },
|
|
31
|
+
},
|
|
32
|
+
className: {
|
|
33
|
+
control: "text",
|
|
34
|
+
description: "Additional CSS classes.",
|
|
35
|
+
table: { defaultValue: { summary: '""' } },
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
parameters: {
|
|
39
|
+
docs: {
|
|
40
|
+
description: {
|
|
41
|
+
component: "\nThe Breadcrumb component renders a hierarchical navigation trail for documentation pages.\n\n## When to Use\n\n- To show the user's current location within a multi-level documentation hierarchy\n- To provide quick navigation back to parent sections\n- On pages nested 2 or more levels deep\n\n## When Not to Use\n\n- On top-level landing pages where hierarchy is obvious\n- For purely sequential step indicators (use a stepper/progress component instead)\n\n## Accessibility\n\n- Renders as `<nav aria-label=\"Breadcrumb\">` with an `<ol>` list so screen readers announce it correctly\n- The current (last) page item receives `aria-current=\"page\"`\n- Delimiter characters are marked `aria-hidden` and are not read aloud\n- The ellipsis expand button has an accessible `aria-label`\n ",
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
export default meta;
|
|
47
|
+
var docsItems = [
|
|
48
|
+
{ label: "Docs", href: "/docs" },
|
|
49
|
+
{ label: "Components", href: "/docs/components" },
|
|
50
|
+
{ label: "Breadcrumb" },
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* The default breadcrumb with a three-segment path and the "/" delimiter.
|
|
54
|
+
*/
|
|
55
|
+
export var Default = {
|
|
56
|
+
args: {
|
|
57
|
+
items: docsItems,
|
|
58
|
+
},
|
|
59
|
+
parameters: {
|
|
60
|
+
docs: {
|
|
61
|
+
source: {
|
|
62
|
+
code: "<Breadcrumb\n items={[\n { label: 'Docs', href: '/docs' },\n { label: 'Components', href: '/docs/components' },\n { label: 'Breadcrumb' },\n ]}\n/>",
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* A single-item breadcrumb — just the current page with no parent links.
|
|
69
|
+
*/
|
|
70
|
+
export var SingleItem = {
|
|
71
|
+
args: {
|
|
72
|
+
items: [{ label: "Getting Started" }],
|
|
73
|
+
},
|
|
74
|
+
parameters: {
|
|
75
|
+
docs: {
|
|
76
|
+
source: {
|
|
77
|
+
code: "<Breadcrumb items={[{ label: 'Getting Started' }]} />",
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
/**
|
|
83
|
+
* Custom string delimiter using "›" instead of "/".
|
|
84
|
+
*/
|
|
85
|
+
export var CustomStringDelimiter = {
|
|
86
|
+
args: {
|
|
87
|
+
items: docsItems,
|
|
88
|
+
delimiter: "›",
|
|
89
|
+
},
|
|
90
|
+
parameters: {
|
|
91
|
+
docs: {
|
|
92
|
+
source: {
|
|
93
|
+
code: "<Breadcrumb\n items={[\n { label: 'Docs', href: '/docs' },\n { label: 'Components', href: '/docs/components' },\n { label: 'Breadcrumb' },\n ]}\n delimiter=\"\u203A\"\n/>",
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Custom SVG chevron as the delimiter — demonstrates ReactNode delimiter support.
|
|
100
|
+
*/
|
|
101
|
+
export var SvgChevronDelimiter = {
|
|
102
|
+
args: {
|
|
103
|
+
items: docsItems,
|
|
104
|
+
delimiter: (_jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", style: { flexShrink: 0 }, children: _jsx("polyline", { points: "9 18 15 12 9 6" }) })),
|
|
105
|
+
},
|
|
106
|
+
parameters: {
|
|
107
|
+
docs: {
|
|
108
|
+
source: {
|
|
109
|
+
code: "const ChevronRight = (\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\"\n stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\"\n strokeLinejoin=\"round\" aria-hidden=\"true\">\n <polyline points=\"9 18 15 12 9 6\" />\n </svg>\n);\n\n<Breadcrumb\n items={[\n { label: 'Docs', href: '/docs' },\n { label: 'Components', href: '/docs/components' },\n { label: 'Breadcrumb' },\n ]}\n delimiter={ChevronRight}\n/>",
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* Small size variant — useful in compact page headers.
|
|
116
|
+
*/
|
|
117
|
+
export var SmallSize = {
|
|
118
|
+
args: {
|
|
119
|
+
items: docsItems,
|
|
120
|
+
size: "sm",
|
|
121
|
+
},
|
|
122
|
+
parameters: {
|
|
123
|
+
docs: {
|
|
124
|
+
source: {
|
|
125
|
+
code: "<Breadcrumb\n size=\"sm\"\n items={[\n { label: 'Docs', href: '/docs' },\n { label: 'Components', href: '/docs/components' },\n { label: 'Breadcrumb' },\n ]}\n/>",
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* `collapseOnMobile` — middle segments collapse to an ellipsis on narrow viewports.
|
|
132
|
+
* Resize the browser window or use a mobile emulator to see this in action.
|
|
133
|
+
* Click the "…" to expand all items.
|
|
134
|
+
*/
|
|
135
|
+
export var CollapseOnMobile = {
|
|
136
|
+
args: {
|
|
137
|
+
collapseOnMobile: true,
|
|
138
|
+
items: [
|
|
139
|
+
{ label: "Docs", href: "/docs" },
|
|
140
|
+
{ label: "Guides", href: "/docs/guides" },
|
|
141
|
+
{ label: "Components", href: "/docs/guides/components" },
|
|
142
|
+
{ label: "Navigation", href: "/docs/guides/components/navigation" },
|
|
143
|
+
{ label: "Breadcrumb" },
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
parameters: {
|
|
147
|
+
docs: {
|
|
148
|
+
source: {
|
|
149
|
+
code: "<Breadcrumb\n collapseOnMobile\n items={[\n { label: 'Docs', href: '/docs' },\n { label: 'Guides', href: '/docs/guides' },\n { label: 'Components', href: '/docs/guides/components' },\n { label: 'Navigation', href: '/docs/guides/components/navigation' },\n { label: 'Breadcrumb' },\n ]}\n/>",
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* `scrollOnMobile` — the breadcrumb trail scrolls horizontally on narrow viewports
|
|
156
|
+
* rather than wrapping onto multiple lines.
|
|
157
|
+
*/
|
|
158
|
+
export var ScrollOnMobile = {
|
|
159
|
+
args: {
|
|
160
|
+
scrollOnMobile: true,
|
|
161
|
+
items: [
|
|
162
|
+
{ label: "Docs", href: "/docs" },
|
|
163
|
+
{ label: "Guides", href: "/docs/guides" },
|
|
164
|
+
{ label: "Components", href: "/docs/guides/components" },
|
|
165
|
+
{ label: "Navigation", href: "/docs/guides/components/navigation" },
|
|
166
|
+
{ label: "Breadcrumb" },
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
parameters: {
|
|
170
|
+
docs: {
|
|
171
|
+
source: {
|
|
172
|
+
code: "<Breadcrumb\n scrollOnMobile\n items={[\n { label: 'Docs', href: '/docs' },\n { label: 'Guides', href: '/docs/guides' },\n { label: 'Components', href: '/docs/guides/components' },\n { label: 'Navigation', href: '/docs/guides/components/navigation' },\n { label: 'Breadcrumb' },\n ]}\n/>",
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* All size and delimiter variants displayed together for visual comparison.
|
|
179
|
+
*/
|
|
180
|
+
export var AllVariants = {
|
|
181
|
+
parameters: {
|
|
182
|
+
docs: {
|
|
183
|
+
source: {
|
|
184
|
+
code: "<div style={{ display: 'flex', flexDirection: 'column', gap: '1.5rem' }}>\n <Breadcrumb\n items={[\n { label: 'Docs', href: '/docs' },\n { label: 'Components', href: '/docs/components' },\n { label: 'Breadcrumb' },\n ]}\n />\n <Breadcrumb\n size=\"sm\"\n items={[\n { label: 'Docs', href: '/docs' },\n { label: 'Components', href: '/docs/components' },\n { label: 'Breadcrumb' },\n ]}\n />\n <Breadcrumb\n delimiter=\"\u203A\"\n items={[\n { label: 'Docs', href: '/docs' },\n { label: 'Components', href: '/docs/components' },\n { label: 'Breadcrumb' },\n ]}\n />\n</div>",
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
},
|
|
188
|
+
render: function () { return (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "1.5rem" }, children: [_jsxs("div", { children: [_jsx("p", { style: {
|
|
189
|
+
color: "var(--dds-breadcrumb-current-color)",
|
|
190
|
+
fontFamily: "sans-serif",
|
|
191
|
+
fontSize: "0.75rem",
|
|
192
|
+
marginBottom: "0.25rem",
|
|
193
|
+
}, children: "Default (md)" }), _jsx(Breadcrumb, { items: [
|
|
194
|
+
{ label: "Docs", href: "/docs" },
|
|
195
|
+
{ label: "Components", href: "/docs/components" },
|
|
196
|
+
{ label: "Breadcrumb" },
|
|
197
|
+
] })] }), _jsxs("div", { children: [_jsx("p", { style: {
|
|
198
|
+
color: "var(--dds-breadcrumb-current-color)",
|
|
199
|
+
fontFamily: "sans-serif",
|
|
200
|
+
fontSize: "0.75rem",
|
|
201
|
+
marginBottom: "0.25rem",
|
|
202
|
+
}, children: "Small (sm)" }), _jsx(Breadcrumb, { size: "sm", items: [
|
|
203
|
+
{ label: "Docs", href: "/docs" },
|
|
204
|
+
{ label: "Components", href: "/docs/components" },
|
|
205
|
+
{ label: "Breadcrumb" },
|
|
206
|
+
] })] }), _jsxs("div", { children: [_jsx("p", { style: {
|
|
207
|
+
color: "var(--dds-breadcrumb-current-color)",
|
|
208
|
+
fontFamily: "sans-serif",
|
|
209
|
+
fontSize: "0.75rem",
|
|
210
|
+
marginBottom: "0.25rem",
|
|
211
|
+
}, children: "Custom delimiter \"\u203A\"" }), _jsx(Breadcrumb, { delimiter: "\u203A", items: [
|
|
212
|
+
{ label: "Docs", href: "/docs" },
|
|
213
|
+
{ label: "Components", href: "/docs/components" },
|
|
214
|
+
{ label: "Breadcrumb" },
|
|
215
|
+
] })] })] })); },
|
|
216
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
2
|
+
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
3
3
|
/**
|
|
4
4
|
* Visual style variant of the button
|
|
5
5
|
* @default 'primary'
|
|
@@ -14,4 +14,3 @@ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
|
|
14
14
|
children: React.ReactNode;
|
|
15
15
|
}
|
|
16
16
|
export declare const Button: React.FC<ButtonProps>;
|
|
17
|
-
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
export type CalloutVariant = "caution" | "important" | "tip" | "course";
|
|
3
|
-
interface CalloutProps {
|
|
3
|
+
export interface CalloutProps {
|
|
4
4
|
/** Visual style variant of the callout (caution, important, tip, or course) */
|
|
5
5
|
variant: CalloutVariant;
|
|
6
6
|
/**
|
|
@@ -14,4 +14,3 @@ interface CalloutProps {
|
|
|
14
14
|
className?: string;
|
|
15
15
|
}
|
|
16
16
|
export declare function Callout({ variant, title, children, className, }: CalloutProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
-
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
|
-
interface CardProps {
|
|
2
|
+
export interface CardProps {
|
|
3
3
|
/** Optional title displayed at the top of the card */
|
|
4
4
|
title?: string;
|
|
5
5
|
/**
|
|
@@ -20,4 +20,3 @@ interface CardProps {
|
|
|
20
20
|
className?: string;
|
|
21
21
|
}
|
|
22
22
|
export declare function Card({ title, titleColor, backgroundColor, href, children, className, }: CardProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
-
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
|
-
interface CardGridProps {
|
|
2
|
+
export interface CardGridProps {
|
|
3
3
|
/**
|
|
4
4
|
* Number of columns in the grid
|
|
5
5
|
* @default 3
|
|
@@ -17,4 +17,3 @@ interface CardGridProps {
|
|
|
17
17
|
className?: string;
|
|
18
18
|
}
|
|
19
19
|
export declare function CardGrid({ columns, equalHeight, children, className }: CardGridProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
-
export {};
|
|
@@ -25,7 +25,7 @@ export interface CodeSnippet {
|
|
|
25
25
|
/** Optional line numbers to highlight (1-indexed) */
|
|
26
26
|
highlightLines?: number[];
|
|
27
27
|
}
|
|
28
|
-
interface CodeBlockProps {
|
|
28
|
+
export interface CodeBlockProps {
|
|
29
29
|
/** Single code snippet (for simple usage) */
|
|
30
30
|
code?: string;
|
|
31
31
|
/** Language for syntax highlighting */
|
|
@@ -55,4 +55,3 @@ interface CodeBlockProps {
|
|
|
55
55
|
*/
|
|
56
56
|
export declare function registerLanguages(loader: () => Promise<void>): Promise<void>;
|
|
57
57
|
export declare function CodeBlock({ code, language, filename, highlightLines, snippets, path, className, }: CodeBlockProps): import("react/jsx-runtime").JSX.Element | null;
|
|
58
|
-
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
interface HeadingProps {
|
|
2
|
+
export interface HeadingProps {
|
|
3
3
|
/** Optionally override auto-generation of `id` attribute */
|
|
4
4
|
id?: string;
|
|
5
5
|
/** Heading level (h1, h2, h3, or h4) */
|
|
@@ -10,4 +10,3 @@ interface HeadingProps {
|
|
|
10
10
|
className?: string;
|
|
11
11
|
}
|
|
12
12
|
export declare function Heading({ level, children, id, className }: HeadingProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
-
export {};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface IconProps {
|
|
3
|
+
/**
|
|
4
|
+
* SVG to render. Accepts a React SVG component (e.g. imported with SVGR or
|
|
5
|
+
* defined inline) or a raw SVG string.
|
|
6
|
+
*
|
|
7
|
+
* **Accessibility note:** when passing a React SVG component, do not include
|
|
8
|
+
* `aria-hidden`, `role`, or `aria-label` attributes in the component itself.
|
|
9
|
+
* The `Icon` component applies the correct accessibility attributes based on
|
|
10
|
+
* whether an `aria-label` prop is provided.
|
|
11
|
+
*
|
|
12
|
+
* **Security note:** when passing a raw SVG string, ensure the content is
|
|
13
|
+
* from a trusted source. The string is injected via `dangerouslySetInnerHTML`
|
|
14
|
+
* without sanitization.
|
|
15
|
+
*/
|
|
16
|
+
svg: React.ComponentType<React.SVGProps<SVGSVGElement>> | string;
|
|
17
|
+
/**
|
|
18
|
+
* Width and height in pixels.
|
|
19
|
+
* @default 16
|
|
20
|
+
*/
|
|
21
|
+
size?: number;
|
|
22
|
+
/** Additional CSS class names to apply to the icon element. */
|
|
23
|
+
className?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Accessible label for the icon. When provided the icon is announced by
|
|
26
|
+
* screen readers with `role="img"`. When omitted the icon is treated as
|
|
27
|
+
* decorative and hidden from assistive technology (`aria-hidden="true"`).
|
|
28
|
+
*/
|
|
29
|
+
'aria-label'?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Renders an SVG icon. Accepts either a React SVG component (e.g. imported
|
|
33
|
+
* with SVGR) or a raw SVG string, making it easy to use your own icon library
|
|
34
|
+
* without being tied to a specific icon set.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* // React SVG component
|
|
38
|
+
* import { ReactComponent as ChevronIcon } from './chevron.svg';
|
|
39
|
+
* <Icon svg={ChevronIcon} size={20} aria-label="Expand" />
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* // Inline SVG function
|
|
43
|
+
* const StarIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
|
44
|
+
* <svg viewBox="0 0 24 24" {...props}>...</svg>
|
|
45
|
+
* );
|
|
46
|
+
* <Icon svg={StarIcon} size={16} />
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* // Raw SVG string
|
|
50
|
+
* <Icon svg='<svg viewBox="0 0 24 24">...</svg>' size={24} />
|
|
51
|
+
*/
|
|
52
|
+
export declare function Icon({ svg, size, className, 'aria-label': ariaLabel, }: IconProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
+
/**
|
|
14
|
+
* Renders an SVG icon. Accepts either a React SVG component (e.g. imported
|
|
15
|
+
* with SVGR) or a raw SVG string, making it easy to use your own icon library
|
|
16
|
+
* without being tied to a specific icon set.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // React SVG component
|
|
20
|
+
* import { ReactComponent as ChevronIcon } from './chevron.svg';
|
|
21
|
+
* <Icon svg={ChevronIcon} size={20} aria-label="Expand" />
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* // Inline SVG function
|
|
25
|
+
* const StarIcon = (props: React.SVGProps<SVGSVGElement>) => (
|
|
26
|
+
* <svg viewBox="0 0 24 24" {...props}>...</svg>
|
|
27
|
+
* );
|
|
28
|
+
* <Icon svg={StarIcon} size={16} />
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* // Raw SVG string
|
|
32
|
+
* <Icon svg='<svg viewBox="0 0 24 24">...</svg>' size={24} />
|
|
33
|
+
*/
|
|
34
|
+
export function Icon(_a) {
|
|
35
|
+
var svg = _a.svg, _b = _a.size, size = _b === void 0 ? 16 : _b, _c = _a.className, className = _c === void 0 ? '' : _c, ariaLabel = _a["aria-label"];
|
|
36
|
+
var isDecorative = !ariaLabel;
|
|
37
|
+
var classNames = ['dds-icon', className].filter(Boolean).join(' ');
|
|
38
|
+
if (typeof svg === 'string') {
|
|
39
|
+
return (_jsx("span", __assign({ className: classNames, style: { width: size, height: size },
|
|
40
|
+
// eslint-disable-next-line react/no-danger
|
|
41
|
+
dangerouslySetInnerHTML: { __html: svg } }, (isDecorative
|
|
42
|
+
? { 'aria-hidden': true }
|
|
43
|
+
: { role: 'img', 'aria-label': ariaLabel }))));
|
|
44
|
+
}
|
|
45
|
+
var SvgComponent = svg;
|
|
46
|
+
return (_jsx(SvgComponent, __assign({ className: classNames, width: size, height: size }, (isDecorative
|
|
47
|
+
? { 'aria-hidden': true }
|
|
48
|
+
: { role: 'img', 'aria-label': ariaLabel }))));
|
|
49
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { Icon } from './Icon';
|
|
3
|
+
declare const meta: Meta<typeof Icon>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof Icon>;
|
|
6
|
+
/**
|
|
7
|
+
* Pass any React SVG component to the `svg` prop. The component is rendered
|
|
8
|
+
* directly with the provided `size` applied as `width` and `height`.
|
|
9
|
+
*/
|
|
10
|
+
export declare const WithReactComponent: Story;
|
|
11
|
+
/**
|
|
12
|
+
* Pass a raw SVG string to the `svg` prop. The string is injected using
|
|
13
|
+
* `dangerouslySetInnerHTML` — ensure the content is from a trusted source.
|
|
14
|
+
*/
|
|
15
|
+
export declare const WithSvgString: Story;
|
|
16
|
+
/**
|
|
17
|
+
* When an `aria-label` is provided the icon receives `role="img"` and is
|
|
18
|
+
* announced by screen readers with the given label. Use this when the icon
|
|
19
|
+
* conveys meaning without surrounding text.
|
|
20
|
+
*/
|
|
21
|
+
export declare const WithAriaLabel: Story;
|
|
22
|
+
/**
|
|
23
|
+
* Sizes from small (12 px) to large (48 px). The `size` prop sets both
|
|
24
|
+
* `width` and `height` so the icon is always square.
|
|
25
|
+
*/
|
|
26
|
+
export declare const Sizes: Story;
|
|
27
|
+
/**
|
|
28
|
+
* Icons inherit `currentColor` for their stroke/fill, so they automatically
|
|
29
|
+
* adapt to the surrounding text color.
|
|
30
|
+
*/
|
|
31
|
+
export declare const InheritedColor: Story;
|