@roadlittledawn/docs-design-system-react 0.5.0 → 0.6.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 CHANGED
@@ -1,8 +1,9 @@
1
1
  # @roadlittledawn/docs-design-system-react
2
2
 
3
- React components for building documentation interfaces.
3
+ [![npm version](https://img.shields.io/npm/v/@roadlittledawn/docs-design-system-react.svg)](https://www.npmjs.com/package/@roadlittledawn/docs-design-system-react)
4
+ [![GitHub](https://img.shields.io/badge/github-repo-blue.svg)](https://github.com/roadlittledawn/docs-design-system)
4
5
 
5
- See [package on NPM](https://www.npmjs.com/package/@roadlittledawn/docs-design-system-react).
6
+ React components for documentation content and MDX-driven sites.
6
7
 
7
8
  ## Installation
8
9
 
@@ -30,91 +31,9 @@ import "@roadlittledawn/docs-design-system-react/styles.css";
30
31
 
31
32
  ## Components
32
33
 
33
- ### Callout
34
+ Full component documentation with live examples, usage guidelines, and API documentation is available in Storybook:
34
35
 
35
- Highlight important information, warnings, tips, or notes.
36
-
37
- ```tsx
38
- <Callout variant="tip">This is a helpful tip!</Callout>
39
- ```
40
-
41
- ### CodeBlock
42
-
43
- Syntax-highlighted code with copy functionality.
44
-
45
- ```tsx
46
- <CodeBlock language="javascript">
47
- {`const greeting = "Hello, world!";`}
48
- </CodeBlock>
49
- ```
50
-
51
- ### Collapser
52
-
53
- Expandable/collapsible sections for optional or detailed content.
54
-
55
- ```tsx
56
- <Collapser title="More details">Hidden content revealed on expand.</Collapser>
57
- ```
58
-
59
- ### Card
60
-
61
- Clickable card for navigation or content grouping.
62
-
63
- ```tsx
64
- <Card title="Getting Started" href="/docs/intro">
65
- Learn the basics.
66
- </Card>
67
- ```
68
-
69
- ### CardGrid
70
-
71
- Grid layout for organizing multiple cards.
72
-
73
- ```tsx
74
- <CardGrid columns={3}>
75
- <Card title="Guide 1" href="/guide-1">
76
- Description
77
- </Card>
78
- <Card title="Guide 2" href="/guide-2">
79
- Description
80
- </Card>
81
- </CardGrid>
82
- ```
83
-
84
- ### Typography
85
-
86
- Text component with semantic variants.
87
-
88
- ```tsx
89
- <Typography variant="body">Paragraph text</Typography>
90
- ```
91
-
92
- ### Heading
93
-
94
- Semantic heading levels.
95
-
96
- ```tsx
97
- <Heading level={2}>Section Title</Heading>
98
- ```
99
-
100
- ### Link
101
-
102
- Styled anchor with external link detection.
103
-
104
- ```tsx
105
- <Link href="/docs">Internal link</Link>
106
- <Link href="https://example.com">External link</Link>
107
- ```
108
-
109
- ### Button
110
-
111
- Action button with variants.
112
-
113
- ```tsx
114
- <Button variant="primary" onClick={handleClick}>
115
- Click me
116
- </Button>
117
- ```
36
+ **[View Component Documentation →](https://docs-design-system-storybook.netlify.app/?path=/docs/components-button--docs)**
118
37
 
119
38
  ## Dark Mode
120
39
 
@@ -175,11 +94,7 @@ Listen for keyboard events.
175
94
  const isPressed = useKeyPress("Escape");
176
95
  ```
177
96
 
178
- ## Documentation
179
-
180
- Full component documentation with live examples is available in our Storybook.
181
-
182
- **Storybook URL:** _Coming soon_
97
+ Full hook documentation is available in [Storybook](https://docs-design-system-storybook.netlify.app).
183
98
 
184
99
  ## Development
185
100
 
@@ -0,0 +1,26 @@
1
+ import { ReactNode, FC } from "react";
2
+ export interface ListProps {
3
+ /** List items */
4
+ children: ReactNode;
5
+ /** Additional CSS classes */
6
+ className?: string;
7
+ /** Whether the list is ordered (numbered) or unordered (bullets). Default: true */
8
+ ordered?: boolean;
9
+ /** Custom bullet character for unordered lists (emoji or text). Only applies when ordered=false */
10
+ bullet?: string;
11
+ /** Custom bullet icon (React node, e.g., SVG) for unordered lists. Takes precedence over bullet prop */
12
+ bulletIcon?: ReactNode;
13
+ }
14
+ interface ListItemProps {
15
+ /** List item content */
16
+ children: ReactNode;
17
+ /** Additional CSS classes */
18
+ className?: string;
19
+ /** Internal: bullet icon injected by List parent for unordered lists */
20
+ bulletIcon?: ReactNode;
21
+ }
22
+ export declare function ListItem({ children, className, bulletIcon }: ListItemProps): import("react/jsx-runtime").JSX.Element;
23
+ export declare const List: FC<ListProps> & {
24
+ Item: typeof ListItem;
25
+ };
26
+ export {};
@@ -0,0 +1,36 @@
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, jsxs as _jsxs } from "react/jsx-runtime";
13
+ import React from "react";
14
+ function ListImpl(_a) {
15
+ var children = _a.children, _b = _a.className, className = _b === void 0 ? "" : _b, _c = _a.ordered, ordered = _c === void 0 ? true : _c, bullet = _a.bullet, bulletIcon = _a.bulletIcon;
16
+ var listClasses = ["dds-list", className].filter(Boolean).join(" ");
17
+ var Element = ordered ? "ol" : "ul";
18
+ return (_jsx(Element, { className: listClasses, "data-ordered": ordered, "data-has-icon": !!bulletIcon && !ordered, style: bullet && !bulletIcon
19
+ ? { "--dds-list-bullet": JSON.stringify(bullet) }
20
+ : undefined, children: bulletIcon && !ordered
21
+ ? React.Children.map(children, function (child) {
22
+ if (React.isValidElement(child) && child.type === ListItem) {
23
+ return React.cloneElement(child, __assign(__assign({}, child.props), { bulletIcon: bulletIcon }));
24
+ }
25
+ return child;
26
+ })
27
+ : children }));
28
+ }
29
+ export function ListItem(_a) {
30
+ var children = _a.children, _b = _a.className, className = _b === void 0 ? "" : _b, bulletIcon = _a.bulletIcon;
31
+ var itemClasses = ["dds-list-item", className].filter(Boolean).join(" ");
32
+ return (_jsxs("li", { className: itemClasses, children: [bulletIcon && (_jsx("span", { className: "dds-list-item-icon", "aria-hidden": "true", children: bulletIcon })), children] }));
33
+ }
34
+ export var List = Object.assign(ListImpl, {
35
+ Item: ListItem,
36
+ });
@@ -0,0 +1,28 @@
1
+ import type { StoryObj } from "@storybook/react";
2
+ declare const meta: {
3
+ title: string;
4
+ component: import("react").FC<import("./List").ListProps> & {
5
+ Item: typeof import("./List").ListItem;
6
+ };
7
+ parameters: {
8
+ layout: string;
9
+ docs: {
10
+ description: {
11
+ component: string;
12
+ };
13
+ };
14
+ };
15
+ tags: string[];
16
+ };
17
+ export default meta;
18
+ type Story = StoryObj<typeof meta>;
19
+ /** Default list with multi-line content and code examples */
20
+ export declare const OrderedList: Story;
21
+ /** List with nested components like CodeBlock and Callout */
22
+ export declare const OrderedListWithNestedComponents: Story;
23
+ /** Unordered list with default bullet */
24
+ export declare const Unordered: Story;
25
+ /** Unordered list with custom emoji bullet */
26
+ export declare const UnorderedWithEmoji: Story;
27
+ /** Unordered list with custom icon bullet */
28
+ export declare const UnorderedWithIcon: Story;
@@ -0,0 +1,88 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { List } from "./List";
3
+ import { CodeBlock } from "./CodeBlock";
4
+ import { Callout } from "./Callout";
5
+ var meta = {
6
+ title: "Components/List",
7
+ component: List,
8
+ parameters: {
9
+ layout: "padded",
10
+ docs: {
11
+ description: {
12
+ component: "A visually enhanced list component with numbered badges (ordered) or custom bullets (unordered) and connector lines, designed for complex content that deserves more visual prominence.\n\n## When to Use\n- Tutorial or getting started guides with substantial steps\n- Multi-step workflows where each step contains rich content (paragraphs, code blocks, callouts)\n- Marketing or landing pages that need more visual polish\n- Complex instructions where each step is its own section of content\n- Feature lists or benefits that need custom emoji/icon bullets\n- When you want to nest other components (CodeBlock, Callout, etc.) within list items\n\n## When Not to Use\n- Simple, short lists with brief text items (use standard `<ol>` or `<ul>` instead)\n- Very long lists with many items (consider breaking into sections with Tabs or Collapsers)\n- When visual simplicity is preferred over aesthetic enhancement\n\n## Accessibility\n- Uses semantic `<ol>` or `<ul>` elements for proper screen reader support\n- CSS counters and custom bullets provide visual styling without affecting content\n- Maintains proper reading order and list semantics\n ",
13
+ },
14
+ },
15
+ },
16
+ tags: ["autodocs"],
17
+ };
18
+ export default meta;
19
+ /** Default list with multi-line content and code examples */
20
+ export var OrderedList = {
21
+ args: {
22
+ children: null,
23
+ },
24
+ render: function () { return (_jsxs(List, { children: [_jsxs(List.Item, { children: ["Run the following command in your terminal to start the install wizard:", _jsx("code", { style: { display: "block", marginTop: "0.5rem" }, children: "npm create astro@latest" })] }), _jsxs(List.Item, { children: ["Now that your project has been created, you can ", _jsx("code", { children: "cd" }), " into your new project directory to begin using Astro."] }), _jsx(List.Item, { children: "If you skipped the \"Install dependencies?\" step during the CLI wizard, then be sure to install your dependencies before continuing." }), _jsx(List.Item, { children: "You can now start the Astro dev server and see a live preview of your project while you build!" })] })); },
25
+ parameters: {
26
+ docs: {
27
+ source: {
28
+ code: "<List>\n <List.Item>\n Run the following command in your terminal to start the install wizard:\n <code style={{ display: \"block\", marginTop: \"0.5rem\" }}>\n npm create astro@latest\n </code>\n </List.Item>\n <List.Item>\n Now that your project has been created, you can <code>cd</code> into\n your new project directory to begin using Astro.\n </List.Item>\n <List.Item>\n If you skipped the \"Install dependencies?\" step during the CLI wizard,\n then be sure to install your dependencies before continuing.\n </List.Item>\n <List.Item>\n You can now start the Astro dev server and see a live preview of your\n project while you build!\n </List.Item>\n</List>",
29
+ },
30
+ },
31
+ },
32
+ };
33
+ /** List with nested components like CodeBlock and Callout */
34
+ export var OrderedListWithNestedComponents = {
35
+ args: {
36
+ children: null,
37
+ },
38
+ render: function () { return (_jsxs(List, { children: [_jsxs(List.Item, { children: [_jsx("p", { children: _jsx("b", { children: "Install dependencies" }) }), _jsx("p", { style: { color: "var(--dds-list-text)" }, children: "Run the following command to install all required packages:" }), _jsx(CodeBlock, { language: "bash", code: "npm install" })] }), _jsxs(List.Item, { children: [_jsx("strong", { children: "Configure your project" }), _jsx(Callout, { variant: "tip", title: "Pro Tip", children: "Make sure to review the configuration file before proceeding." })] }), _jsxs(List.Item, { children: [_jsx("p", { children: _jsx("b", { children: "Start development" }) }), _jsx("p", { style: { color: "var(--dds-list-text)" }, children: "Launch the dev server and begin building:" }), _jsx(CodeBlock, { language: "bash", code: "npm run dev" })] })] })); },
39
+ parameters: {
40
+ docs: {
41
+ source: {
42
+ code: "<List>\n <List.Item>\n <strong>Install dependencies</strong>\n <p>Run the following command to install all required packages:</p>\n <CodeBlock language=\"bash\" code=\"npm install\" />\n </List.Item>\n <List.Item>\n <strong>Configure your project</strong>\n <Callout variant=\"tip\" title=\"Pro Tip\">\n Make sure to review the configuration file before proceeding.\n </Callout>\n </List.Item>\n <List.Item>\n <strong>Start development</strong>\n <p>Launch the dev server and begin building:</p>\n <CodeBlock language=\"bash\" code=\"npm run dev\" />\n </List.Item>\n</List>",
43
+ },
44
+ },
45
+ },
46
+ };
47
+ /** Unordered list with default bullet */
48
+ export var Unordered = {
49
+ args: {
50
+ children: null,
51
+ },
52
+ render: function () { return (_jsxs(List, { ordered: false, children: [_jsx(List.Item, { children: "Key feature of the product" }), _jsx(List.Item, { children: "Another important capability" }), _jsx(List.Item, { children: "Additional benefit to highlight" })] })); },
53
+ parameters: {
54
+ docs: {
55
+ source: {
56
+ code: "<List ordered={false}>\n <List.Item>Key feature of the product</List.Item>\n <List.Item>Another important capability</List.Item>\n <List.Item>Additional benefit to highlight</List.Item>\n</List>",
57
+ },
58
+ },
59
+ },
60
+ };
61
+ /** Unordered list with custom emoji bullet */
62
+ export var UnorderedWithEmoji = {
63
+ args: {
64
+ children: null,
65
+ },
66
+ render: function () { return (_jsxs(List, { ordered: false, bullet: "\u2705", children: [_jsx(List.Item, { children: "Beautifully designed components" }), _jsx(List.Item, { children: "Accessible by default" }), _jsx(List.Item, { children: "Fully customizable styling" })] })); },
67
+ parameters: {
68
+ docs: {
69
+ source: {
70
+ code: "<List ordered={false} bullet=\"\u2705\">\n <List.Item>Beautifully designed components</List.Item>\n <List.Item>Accessible by default</List.Item>\n <List.Item>Fully customizable styling</List.Item>\n</List>",
71
+ },
72
+ },
73
+ },
74
+ };
75
+ /** Unordered list with custom icon bullet */
76
+ export var UnorderedWithIcon = {
77
+ args: {
78
+ children: null,
79
+ },
80
+ render: function () { return (_jsxs(List, { ordered: false, bulletIcon: _jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: _jsx("path", { d: "M5 12h14M12 5l7 7-7 7" }) }), children: [_jsx(List.Item, { children: "Navigate to the settings page" }), _jsx(List.Item, { children: "Select your preferences" }), _jsx(List.Item, { children: "Save your changes" })] })); },
81
+ parameters: {
82
+ docs: {
83
+ source: {
84
+ code: "<List\n ordered={false}\n bulletIcon={\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\">\n <path d=\"M5 12h14M12 5l7 7-7 7\" />\n </svg>\n }\n>\n <List.Item>Navigate to the settings page</List.Item>\n <List.Item>Select your preferences</List.Item>\n <List.Item>Save your changes</List.Item>\n</List>",
85
+ },
86
+ },
87
+ },
88
+ };
package/dist/index.d.ts CHANGED
@@ -10,4 +10,5 @@ export * from './components/Popover';
10
10
  export * from './components/Typography';
11
11
  export * from './components/Heading';
12
12
  export * from './components/Link';
13
+ export * from './components/List';
13
14
  export * from './hooks/useKeyPress';
package/dist/index.js CHANGED
@@ -11,5 +11,6 @@ export * from './components/Popover';
11
11
  export * from './components/Typography';
12
12
  export * from './components/Heading';
13
13
  export * from './components/Link';
14
+ export * from './components/List';
14
15
  // Export hooks
15
16
  export * from './hooks/useKeyPress';
package/dist/styles.css CHANGED
@@ -245,6 +245,17 @@
245
245
  --dds-popover-title-size: 0.9375rem; /* ~15px */
246
246
  --dds-popover-text-size: 0.875rem; /* text-sm */
247
247
  --dds-popover-eyebrow-size: 0.6875rem; /* ~11px */
248
+
249
+ /* List */
250
+ --dds-list-margin: 1.5rem 0;
251
+ --dds-list-item-margin-bottom: 1.5rem;
252
+ --dds-list-badge-size: calc(var(--dds-line-height-relaxed) * 1rem);
253
+ --dds-list-badge-font-size: 0.8125rem;
254
+ --dds-list-badge-text: #171a1c; /* gray-900 */
255
+ --dds-list-badge-bg: #eceef2;
256
+ --dds-list-badge-shadow: inset 0 0 0 1px #bfc2c7;
257
+ --dds-list-connector-line: #eceef2; /* gray-200 */
258
+ --dds-list-text: #374151; /* gray-700 */
248
259
  }
249
260
  /* ==========================================================================
250
261
  Dark Mode Tokens
@@ -398,6 +409,13 @@
398
409
  --dds-popover-eyebrow-color: #9ca3af; /* gray-400 */
399
410
  --dds-popover-link-color: #60a5fa; /* blue-400 */
400
411
  --dds-popover-link-color-hover: #93c5fd; /* blue-300 */
412
+
413
+ /* List */
414
+ --dds-list-badge-text: #ffffff;
415
+ --dds-list-badge-bg: #232831;
416
+ --dds-list-badge-shadow: inset 0 0 0 1px #353a42;
417
+ --dds-list-connector-line: #353a42; /* gray-600 */
418
+ --dds-list-text: #e5e7eb; /* gray-200 */
401
419
  }
402
420
  /* Auto dark mode — follows OS preference, opt-out with .dds-light */
403
421
  @media (prefers-color-scheme: dark) {
@@ -546,6 +564,13 @@
546
564
  --dds-popover-eyebrow-color: #9ca3af;
547
565
  --dds-popover-link-color: #60a5fa;
548
566
  --dds-popover-link-color-hover: #93c5fd;
567
+
568
+ /* List */
569
+ --dds-list-badge-text: #ffffff;
570
+ --dds-list-badge-bg: #232831;
571
+ --dds-list-badge-shadow: inset 0 0 0 1px #353a42;
572
+ --dds-list-connector-line: #353a42; /* gray-600 */
573
+ --dds-list-text: #e5e7eb; /* gray-200 */
549
574
  }
550
575
  }
551
576
  /* Explicit dark mode via data attribute (overrides OS preference) */
@@ -1466,6 +1491,93 @@ a.no-text-decoration {
1466
1491
  margin-bottom: 0.25rem; /* mb-1 */
1467
1492
  vertical-align: middle;
1468
1493
  }
1494
+ .dds-list {
1495
+ list-style: none;
1496
+ counter-reset: list-counter;
1497
+ padding-left: 0;
1498
+ margin: var(--dds-list-margin, 1.5rem 0);
1499
+ color: var(--dds-list-text);
1500
+ }
1501
+ .dds-list[data-ordered="false"] {
1502
+ counter-reset: none;
1503
+ }
1504
+ .dds-list-item {
1505
+ counter-increment: list-counter;
1506
+ position: relative;
1507
+ padding-inline-start: calc(var(--dds-list-badge-size) + 1rem);
1508
+ margin-bottom: var(--dds-list-item-margin-bottom, 1.5rem);
1509
+ min-height: var(--dds-list-badge-size);
1510
+ }
1511
+ .dds-list[data-ordered="false"] .dds-list-item {
1512
+ counter-increment: none;
1513
+ }
1514
+ .dds-list-item::after {
1515
+ content: "";
1516
+ position: absolute;
1517
+ top: calc(var(--dds-list-badge-size, 2.5rem) + 0.5rem);
1518
+ bottom: calc(-1 * var(--dds-list-item-margin-bottom, 1.5rem) + 0.5rem);
1519
+ left: calc((var(--dds-list-badge-size, 2.5rem) - 1px) / 2);
1520
+ width: 1px;
1521
+ background-color: var(--dds-list-connector-line);
1522
+ }
1523
+ .dds-list-item:last-child::after {
1524
+ display: none;
1525
+ }
1526
+ /* Ordered list badges */
1527
+ .dds-list[data-ordered="true"] .dds-list-item::before {
1528
+ content: counter(list-counter);
1529
+ position: absolute;
1530
+ left: 0;
1531
+ top: 0;
1532
+ width: var(--dds-list-badge-size, 2.5rem);
1533
+ height: var(--dds-list-badge-size, 2.5rem);
1534
+ line-height: var(--dds-line-height-relaxed);
1535
+ inset-inline-start: 0;
1536
+ display: flex;
1537
+ align-items: center;
1538
+ justify-content: center;
1539
+ font-weight: var(--dds-font-bold, 700);
1540
+ font-size: var(--dds-list-badge-font-size, 1.125rem);
1541
+ color: var(--dds-list-badge-text);
1542
+ background: var(--dds-list-badge-bg);
1543
+ box-shadow: var(--dds-list-badge-shadow);
1544
+ border-radius: 50%;
1545
+ }
1546
+ /* Unordered list bullets */
1547
+ .dds-list[data-ordered="false"] .dds-list-item::before {
1548
+ content: var(--dds-list-bullet, "•");
1549
+ position: absolute;
1550
+ left: 0;
1551
+ top: 0;
1552
+ width: var(--dds-list-badge-size, 2.5rem);
1553
+ height: var(--dds-list-badge-size, 2.5rem);
1554
+ inset-inline-start: 0;
1555
+ display: flex;
1556
+ align-items: center;
1557
+ justify-content: center;
1558
+ font-size: var(--dds-list-bullet-size, 1.5rem);
1559
+ color: var(--dds-list-badge-text);
1560
+ }
1561
+ /* Hide ::before when using custom icon */
1562
+ .dds-list[data-has-icon="true"] .dds-list-item::before {
1563
+ display: none;
1564
+ }
1565
+ /* Custom icon bullet */
1566
+ .dds-list-item-icon {
1567
+ position: absolute;
1568
+ left: 0;
1569
+ top: 0;
1570
+ width: var(--dds-list-badge-size, 2.5rem);
1571
+ height: var(--dds-list-badge-size, 2.5rem);
1572
+ display: flex;
1573
+ align-items: center;
1574
+ justify-content: center;
1575
+ color: var(--dds-list-badge-text);
1576
+ }
1577
+ .dds-list-item-icon svg {
1578
+ width: 1.25rem;
1579
+ height: 1.25rem;
1580
+ }
1469
1581
  /* ==========================================================================
1470
1582
  Popover Component
1471
1583
  Uses the native Popover API for top-layer rendering.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@roadlittledawn/docs-design-system-react",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "license": "MIT",
5
5
  "description": "React components for documentation design system",
6
6
  "repository": {