@roadlittledawn/docs-design-system-react 0.8.0 → 0.10.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.
@@ -0,0 +1,44 @@
1
+ import type { Meta, StoryObj } from "@storybook/react";
2
+ import { Table } from "./Table";
3
+ /**
4
+ * Table displays structured data in rows and columns. It supports sortable
5
+ * columns, a sticky header, a borderless variant, and responsive horizontal
6
+ * scrolling for mobile viewports.
7
+ */
8
+ declare const meta: Meta<typeof Table>;
9
+ export default meta;
10
+ type Story = StoryObj<typeof Table>;
11
+ /**
12
+ * A basic table with all borders (the default variant).
13
+ */
14
+ export declare const Default: Story;
15
+ /**
16
+ * Borderless variant — only row dividers are shown; no outer or column borders.
17
+ * Common in modern documentation sites.
18
+ */
19
+ export declare const Borderless: Story;
20
+ /**
21
+ * Sortable columns — clicking a column header sorts the table ascending then
22
+ * descending, and a third click resets sort order.
23
+ */
24
+ export declare const Sortable: Story;
25
+ /**
26
+ * Sticky header — the thead stays fixed at the top of the scroll container as
27
+ * the user scrolls through a long table. Use `style={{ maxHeight: '...' }}` to
28
+ * constrain the table height so the header can stick.
29
+ */
30
+ export declare const StickyHeader: Story;
31
+ /**
32
+ * A custom header background color applied via the `headerBg` prop.
33
+ */
34
+ export declare const CustomHeaderBg: Story;
35
+ /**
36
+ * Column cells can be aligned left (default), center, or right using the
37
+ * `align` prop on `TableHeaderCell` and `TableCell`.
38
+ */
39
+ export declare const ColumnAlignment: Story;
40
+ /**
41
+ * A typical API-reference table for documenting component props or
42
+ * configuration options.
43
+ */
44
+ export declare const ApiReference: Story;
@@ -0,0 +1,258 @@
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
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
13
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
14
+ if (ar || !(i in from)) {
15
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
16
+ ar[i] = from[i];
17
+ }
18
+ }
19
+ return to.concat(ar || Array.prototype.slice.call(from));
20
+ };
21
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
22
+ import { useState } from "react";
23
+ import { Table, TableHead, TableBody, TableRow, TableHeaderCell, TableCell, } from "./Table";
24
+ /**
25
+ * Table displays structured data in rows and columns. It supports sortable
26
+ * columns, a sticky header, a borderless variant, and responsive horizontal
27
+ * scrolling for mobile viewports.
28
+ */
29
+ var meta = {
30
+ title: "Components/Table",
31
+ component: Table,
32
+ tags: ["autodocs"],
33
+ argTypes: {
34
+ variant: {
35
+ control: "radio",
36
+ options: ["default", "borderless"],
37
+ description: '`"default"` renders all borders; `"borderless"` shows only row top/bottom borders.',
38
+ table: { defaultValue: { summary: '"default"' } },
39
+ },
40
+ stickyHeader: {
41
+ control: "boolean",
42
+ description: "When true the thead sticks to the top of the viewport while scrolling.",
43
+ table: { defaultValue: { summary: "false" } },
44
+ },
45
+ headerBg: {
46
+ control: "color",
47
+ description: "Background color applied to the header row. Accepts any valid CSS color value.",
48
+ },
49
+ onSort: {
50
+ control: false,
51
+ description: "Callback fired when a sortable column header is clicked. Useful for server-side sorting.",
52
+ },
53
+ children: {
54
+ control: false,
55
+ description: "Table content — typically `TableHead` and `TableBody`.",
56
+ },
57
+ className: {
58
+ control: "text",
59
+ description: "Additional CSS classes applied to the outer wrapper.",
60
+ table: { defaultValue: { summary: '""' } },
61
+ },
62
+ },
63
+ parameters: {
64
+ docs: {
65
+ description: {
66
+ component: "\nTable displays structured, relational data in rows and columns for technical documentation pages.\n\n## When to Use\n\n- Displaying configuration options, API parameters, or reference data\n- Comparing multiple items across the same set of attributes\n- Presenting tabular data that users may want to sort or scan quickly\n\n## When Not to Use\n\n- For layout purposes \u2014 use CSS Grid or Flexbox instead\n- When data has fewer than two columns (use a list instead)\n- When rows have vastly different data shapes\n\n## Accessibility\n\n- `<th>` elements have `scope=\"col\"` for screen readers\n- Sortable headers expose `aria-sort` (`ascending`, `descending`, or `none`)\n- Sortable headers are focusable via keyboard and respond to Enter/Space\n ",
67
+ },
68
+ },
69
+ },
70
+ };
71
+ export default meta;
72
+ var employees = [
73
+ { name: "Alice Johnson", role: "Engineer", department: "Platform", status: "Active" },
74
+ { name: "Bob Smith", role: "Designer", department: "UX", status: "Active" },
75
+ { name: "Carol White", role: "Manager", department: "Platform", status: "On Leave" },
76
+ { name: "Dan Brown", role: "Engineer", department: "Frontend", status: "Active" },
77
+ { name: "Eve Davis", role: "Analyst", department: "Data", status: "Inactive" },
78
+ ];
79
+ // -----------------------------------------------------------------------
80
+ // Default
81
+ // -----------------------------------------------------------------------
82
+ /**
83
+ * A basic table with all borders (the default variant).
84
+ */
85
+ export var Default = {
86
+ args: {
87
+ variant: "default",
88
+ stickyHeader: false,
89
+ },
90
+ parameters: {
91
+ docs: {
92
+ source: {
93
+ code: "<Table>\n <TableHead>\n <TableRow>\n <TableHeaderCell>Name</TableHeaderCell>\n <TableHeaderCell>Role</TableHeaderCell>\n <TableHeaderCell>Department</TableHeaderCell>\n <TableHeaderCell>Status</TableHeaderCell>\n </TableRow>\n </TableHead>\n <TableBody>\n <TableRow>\n <TableCell>Alice Johnson</TableCell>\n <TableCell>Engineer</TableCell>\n <TableCell>Platform</TableCell>\n <TableCell>Active</TableCell>\n </TableRow>\n </TableBody>\n</Table>",
94
+ },
95
+ },
96
+ },
97
+ render: function (args) { return (_jsxs(Table, __assign({}, args, { children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableHeaderCell, { children: "Name" }), _jsx(TableHeaderCell, { children: "Role" }), _jsx(TableHeaderCell, { children: "Department" }), _jsx(TableHeaderCell, { children: "Status" })] }) }), _jsx(TableBody, { children: employees.map(function (e) { return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: e.name }), _jsx(TableCell, { children: e.role }), _jsx(TableCell, { children: e.department }), _jsx(TableCell, { children: e.status })] }, e.name)); }) })] }))); },
98
+ };
99
+ // -----------------------------------------------------------------------
100
+ // Borderless
101
+ // -----------------------------------------------------------------------
102
+ /**
103
+ * Borderless variant — only row dividers are shown; no outer or column borders.
104
+ * Common in modern documentation sites.
105
+ */
106
+ export var Borderless = {
107
+ args: {
108
+ variant: "borderless",
109
+ },
110
+ parameters: {
111
+ docs: {
112
+ source: {
113
+ code: "<Table variant=\"borderless\">\n <TableHead>\n <TableRow>\n <TableHeaderCell>Name</TableHeaderCell>\n <TableHeaderCell>Role</TableHeaderCell>\n <TableHeaderCell>Department</TableHeaderCell>\n <TableHeaderCell>Status</TableHeaderCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {/* rows */}\n </TableBody>\n</Table>",
114
+ },
115
+ },
116
+ },
117
+ render: function (args) { return (_jsxs(Table, __assign({}, args, { children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableHeaderCell, { children: "Name" }), _jsx(TableHeaderCell, { children: "Role" }), _jsx(TableHeaderCell, { children: "Department" }), _jsx(TableHeaderCell, { children: "Status" })] }) }), _jsx(TableBody, { children: employees.map(function (e) { return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: e.name }), _jsx(TableCell, { children: e.role }), _jsx(TableCell, { children: e.department }), _jsx(TableCell, { children: e.status })] }, e.name)); }) })] }))); },
118
+ };
119
+ // -----------------------------------------------------------------------
120
+ // Sortable (client-side)
121
+ // -----------------------------------------------------------------------
122
+ /**
123
+ * Sortable columns — clicking a column header sorts the table ascending then
124
+ * descending, and a third click resets sort order.
125
+ */
126
+ export var Sortable = {
127
+ parameters: {
128
+ docs: {
129
+ source: {
130
+ code: "function SortableExample() {\n const [rows, setRows] = React.useState(data);\n\n const handleSort = (key, direction) => {\n if (!direction) {\n setRows(data);\n return;\n }\n const sorted = [...rows].sort((a, b) => {\n const cmp = a[key].localeCompare(b[key]);\n return direction === 'asc' ? cmp : -cmp;\n });\n setRows(sorted);\n };\n\n return (\n <Table onSort={handleSort}>\n <TableHead>\n <TableRow>\n <TableHeaderCell sortKey=\"name\">Name</TableHeaderCell>\n <TableHeaderCell sortKey=\"role\">Role</TableHeaderCell>\n <TableHeaderCell sortKey=\"department\">Department</TableHeaderCell>\n <TableHeaderCell sortKey=\"status\">Status</TableHeaderCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {rows.map((e) => (\n <TableRow key={e.name}>\n <TableCell>{e.name}</TableCell>\n <TableCell>{e.role}</TableCell>\n <TableCell>{e.department}</TableCell>\n <TableCell>{e.status}</TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n );\n}",
131
+ },
132
+ },
133
+ },
134
+ render: function SortableExample() {
135
+ var _a = useState(employees), rows = _a[0], setRows = _a[1];
136
+ var handleSort = function (key, direction) {
137
+ if (!direction) {
138
+ setRows(employees);
139
+ return;
140
+ }
141
+ var sorted = __spreadArray([], rows, true).sort(function (a, b) {
142
+ var aVal = a[key];
143
+ var bVal = b[key];
144
+ var cmp = aVal.localeCompare(bVal);
145
+ return direction === "asc" ? cmp : -cmp;
146
+ });
147
+ setRows(sorted);
148
+ };
149
+ return (_jsxs(Table, { onSort: handleSort, children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableHeaderCell, { sortKey: "name", children: "Name" }), _jsx(TableHeaderCell, { sortKey: "role", children: "Role" }), _jsx(TableHeaderCell, { sortKey: "department", children: "Department" }), _jsx(TableHeaderCell, { sortKey: "status", children: "Status" })] }) }), _jsx(TableBody, { children: rows.map(function (e) { return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: e.name }), _jsx(TableCell, { children: e.role }), _jsx(TableCell, { children: e.department }), _jsx(TableCell, { children: e.status })] }, e.name)); }) })] }));
150
+ },
151
+ };
152
+ // -----------------------------------------------------------------------
153
+ // Sticky Header
154
+ // -----------------------------------------------------------------------
155
+ /**
156
+ * Sticky header — the thead stays fixed at the top of the scroll container as
157
+ * the user scrolls through a long table. Use `style={{ maxHeight: '...' }}` to
158
+ * constrain the table height so the header can stick.
159
+ */
160
+ export var StickyHeader = {
161
+ args: {
162
+ stickyHeader: true,
163
+ },
164
+ parameters: {
165
+ docs: {
166
+ source: {
167
+ code: "<Table stickyHeader style={{ maxHeight: '300px' }}>\n <TableHead>\n <TableRow>\n <TableHeaderCell>#</TableHeaderCell>\n <TableHeaderCell>Name</TableHeaderCell>\n <TableHeaderCell>Role</TableHeaderCell>\n <TableHeaderCell>Department</TableHeaderCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {/* many rows */}\n </TableBody>\n</Table>",
168
+ },
169
+ },
170
+ },
171
+ render: function (args) {
172
+ var manyRows = Array.from({ length: 20 }, function (_, i) { return (__assign(__assign({}, employees[i % employees.length]), { name: "".concat(employees[i % employees.length].name, " ").concat(i + 1) })); });
173
+ return (_jsxs(Table, __assign({}, args, { style: { maxHeight: "300px" }, children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableHeaderCell, { children: "#" }), _jsx(TableHeaderCell, { children: "Name" }), _jsx(TableHeaderCell, { children: "Role" }), _jsx(TableHeaderCell, { children: "Department" })] }) }), _jsx(TableBody, { children: manyRows.map(function (e, i) { return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: i + 1 }), _jsx(TableCell, { children: e.name }), _jsx(TableCell, { children: e.role }), _jsx(TableCell, { children: e.department })] }, i)); }) })] })));
174
+ },
175
+ };
176
+ // -----------------------------------------------------------------------
177
+ // Custom Header Background
178
+ // -----------------------------------------------------------------------
179
+ /**
180
+ * A custom header background color applied via the `headerBg` prop.
181
+ */
182
+ export var CustomHeaderBg = {
183
+ args: {
184
+ headerBg: "#dbeafe",
185
+ },
186
+ parameters: {
187
+ docs: {
188
+ source: {
189
+ code: "<Table headerBg=\"#dbeafe\">\n <TableHead>\n <TableRow>\n <TableHeaderCell>Name</TableHeaderCell>\n <TableHeaderCell>Role</TableHeaderCell>\n <TableHeaderCell>Department</TableHeaderCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {/* rows */}\n </TableBody>\n</Table>",
190
+ },
191
+ },
192
+ },
193
+ render: function (args) { return (_jsxs(Table, __assign({}, args, { children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableHeaderCell, { children: "Name" }), _jsx(TableHeaderCell, { children: "Role" }), _jsx(TableHeaderCell, { children: "Department" }), _jsx(TableHeaderCell, { children: "Status" })] }) }), _jsx(TableBody, { children: employees.map(function (e) { return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: e.name }), _jsx(TableCell, { children: e.role }), _jsx(TableCell, { children: e.department }), _jsx(TableCell, { children: e.status })] }, e.name)); }) })] }))); },
194
+ };
195
+ // -----------------------------------------------------------------------
196
+ // Column Alignment
197
+ // -----------------------------------------------------------------------
198
+ /**
199
+ * Column cells can be aligned left (default), center, or right using the
200
+ * `align` prop on `TableHeaderCell` and `TableCell`.
201
+ */
202
+ export var ColumnAlignment = {
203
+ parameters: {
204
+ docs: {
205
+ source: {
206
+ code: "<Table>\n <TableHead>\n <TableRow>\n <TableHeaderCell align=\"left\">Name</TableHeaderCell>\n <TableHeaderCell align=\"center\">Version</TableHeaderCell>\n <TableHeaderCell align=\"right\">Downloads</TableHeaderCell>\n </TableRow>\n </TableHead>\n <TableBody>\n <TableRow>\n <TableCell align=\"left\">react</TableCell>\n <TableCell align=\"center\">18.3.0</TableCell>\n <TableCell align=\"right\">24,000,000</TableCell>\n </TableRow>\n </TableBody>\n</Table>",
207
+ },
208
+ },
209
+ },
210
+ render: function () { return (_jsxs(Table, { children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableHeaderCell, { align: "left", children: "Package" }), _jsx(TableHeaderCell, { align: "center", children: "Version" }), _jsx(TableHeaderCell, { align: "right", children: "Weekly Downloads" })] }) }), _jsx(TableBody, { children: [
211
+ { name: "react", version: "18.3.0", downloads: "24,000,000" },
212
+ { name: "typescript", version: "5.4.5", downloads: "58,000,000" },
213
+ { name: "vite", version: "5.2.11", downloads: "9,800,000" },
214
+ { name: "tailwindcss", version: "3.4.4", downloads: "11,200,000" },
215
+ ].map(function (pkg) { return (_jsxs(TableRow, { children: [_jsx(TableCell, { align: "left", children: pkg.name }), _jsx(TableCell, { align: "center", children: pkg.version }), _jsx(TableCell, { align: "right", children: pkg.downloads })] }, pkg.name)); }) })] })); },
216
+ };
217
+ // -----------------------------------------------------------------------
218
+ // API Reference (documentation use-case)
219
+ // -----------------------------------------------------------------------
220
+ /**
221
+ * A typical API-reference table for documenting component props or
222
+ * configuration options.
223
+ */
224
+ export var ApiReference = {
225
+ parameters: {
226
+ docs: {
227
+ source: {
228
+ code: "<Table variant=\"borderless\">\n <TableHead>\n <TableRow>\n <TableHeaderCell>Prop</TableHeaderCell>\n <TableHeaderCell>Type</TableHeaderCell>\n <TableHeaderCell>Default</TableHeaderCell>\n <TableHeaderCell>Description</TableHeaderCell>\n </TableRow>\n </TableHead>\n <TableBody>\n {/* prop rows */}\n </TableBody>\n</Table>",
229
+ },
230
+ },
231
+ },
232
+ render: function () { return (_jsxs(Table, { variant: "borderless", children: [_jsx(TableHead, { children: _jsxs(TableRow, { children: [_jsx(TableHeaderCell, { children: "Prop" }), _jsx(TableHeaderCell, { children: "Type" }), _jsx(TableHeaderCell, { children: "Default" }), _jsx(TableHeaderCell, { children: "Description" })] }) }), _jsx(TableBody, { children: [
233
+ {
234
+ prop: "variant",
235
+ type: '"default" | "borderless"',
236
+ defaultVal: '"default"',
237
+ desc: "Visual style of the table.",
238
+ },
239
+ {
240
+ prop: "stickyHeader",
241
+ type: "boolean",
242
+ defaultVal: "false",
243
+ desc: "Pins the header row to the top of the viewport while scrolling.",
244
+ },
245
+ {
246
+ prop: "headerBg",
247
+ type: "string",
248
+ defaultVal: "—",
249
+ desc: "CSS color applied to the header background.",
250
+ },
251
+ {
252
+ prop: "onSort",
253
+ type: "(key, direction) => void",
254
+ defaultVal: "—",
255
+ desc: "Callback for server-side sorting.",
256
+ },
257
+ ].map(function (row) { return (_jsxs(TableRow, { children: [_jsx(TableCell, { children: _jsx("code", { children: row.prop }) }), _jsx(TableCell, { children: _jsx("code", { children: row.type }) }), _jsx(TableCell, { children: _jsx("code", { children: row.defaultVal }) }), _jsx(TableCell, { children: row.desc })] }, row.prop)); }) })] })); },
258
+ };
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- interface TabsProps {
2
+ export interface TabsProps {
3
3
  /** ID of the initially active tab */
4
4
  defaultActiveTab?: string;
5
5
  /** Controlled active tab ID */
@@ -12,14 +12,14 @@ interface TabsProps {
12
12
  className?: string;
13
13
  }
14
14
  export declare function Tabs({ defaultActiveTab, activeTab: controlledActiveTab, onTabChange, children, className, }: TabsProps): import("react/jsx-runtime").JSX.Element;
15
- interface TabListProps {
15
+ export interface TabListProps {
16
16
  /** Tab buttons */
17
17
  children: React.ReactNode;
18
18
  /** Additional CSS classes */
19
19
  className?: string;
20
20
  }
21
21
  export declare function TabList({ children, className }: TabListProps): import("react/jsx-runtime").JSX.Element;
22
- interface TabProps {
22
+ export interface TabProps {
23
23
  /** Unique identifier for this tab */
24
24
  id: string;
25
25
  /** Tab label */
@@ -28,7 +28,7 @@ interface TabProps {
28
28
  className?: string;
29
29
  }
30
30
  export declare function Tab({ id, children, className }: TabProps): import("react/jsx-runtime").JSX.Element;
31
- interface TabPanelProps {
31
+ export interface TabPanelProps {
32
32
  /** ID matching the corresponding Tab */
33
33
  id: string;
34
34
  /** Panel content */
@@ -37,4 +37,3 @@ interface TabPanelProps {
37
37
  className?: string;
38
38
  }
39
39
  export declare function TabPanel({ id, children, className }: TabPanelProps): import("react/jsx-runtime").JSX.Element | null;
40
- export {};
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- interface TypographyProps {
2
+ export interface TypographyProps {
3
3
  /**
4
4
  * Typography style variant
5
5
  * @default 'p'
@@ -11,4 +11,3 @@ interface TypographyProps {
11
11
  className?: string;
12
12
  }
13
13
  export declare const Typography: React.FC<TypographyProps>;
14
- export {};
package/dist/index.d.ts CHANGED
@@ -11,5 +11,7 @@ export * from './components/Typography';
11
11
  export * from './components/Heading';
12
12
  export * from './components/Link';
13
13
  export * from './components/List';
14
+ export * from './components/Table';
14
15
  export * from './components/Grid';
16
+ export * from './components/Breadcrumb';
15
17
  export * from './hooks/useKeyPress';
package/dist/index.js CHANGED
@@ -12,6 +12,8 @@ export * from './components/Typography';
12
12
  export * from './components/Heading';
13
13
  export * from './components/Link';
14
14
  export * from './components/List';
15
+ export * from './components/Table';
15
16
  export * from './components/Grid';
17
+ export * from './components/Breadcrumb';
16
18
  // Export hooks
17
19
  export * from './hooks/useKeyPress';