@roadlittledawn/docs-design-system-react 0.14.0 → 0.15.1
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/USAGE.md +49 -1
- package/dist/components/MermaidDiagram.d.ts +7 -0
- package/dist/components/MermaidDiagram.js +186 -0
- package/dist/components/MermaidDiagram.stories.d.ts +11 -0
- package/dist/components/MermaidDiagram.stories.js +64 -0
- package/dist/components/Tile.d.ts +0 -1
- package/dist/components/Tile.js +0 -1
- package/dist/components/TileGrid.d.ts +0 -1
- package/dist/components/TileGrid.js +0 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/styles.css +54 -0
- package/package.json +2 -1
package/USAGE.md
CHANGED
|
@@ -274,7 +274,7 @@ import { CardGrid } from "@roadlittledawn/docs-design-system-react";
|
|
|
274
274
|
|
|
275
275
|
## Tile
|
|
276
276
|
|
|
277
|
-
A compact, clickable item designed for dense listing patterns — integrations, frameworks, plugins, skills, etc. Unlike `Card`, Tile has a fixed layout (icon left, title right) and a simpler, more opinionated API.
|
|
277
|
+
A compact, clickable item designed for dense listing patterns — integrations, frameworks, plugins, skills, etc. Unlike `Card`, Tile has a fixed layout (icon left, title right) and a simpler, more opinionated API. Styles are provided via `@roadlittledawn/docs-design-system-react/styles.css` — no per-component CSS import is needed.
|
|
278
278
|
|
|
279
279
|
### When to Use
|
|
280
280
|
|
|
@@ -1712,3 +1712,51 @@ const closeIconSvg = `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
|
|
1712
1712
|
<Icon svg={StarIcon} size={16} /> {/* hidden from screen readers */}
|
|
1713
1713
|
<Icon svg={StarIcon} size={16} aria-label="Favorite" /> {/* announced as "Favorite" */}
|
|
1714
1714
|
```
|
|
1715
|
+
|
|
1716
|
+
---
|
|
1717
|
+
|
|
1718
|
+
## MermaidDiagram
|
|
1719
|
+
|
|
1720
|
+
Renders Mermaid diagram syntax as SVG. Automatically switches between light and dark Mermaid themes based on the design system's dark mode state (`.dds-dark`, `data-dds-theme`, or `prefers-color-scheme`). Multiple instances are safely handled with serialized rendering.
|
|
1721
|
+
|
|
1722
|
+
> **Security note:** Mermaid diagrams are rendered to SVG and injected into the DOM via `dangerouslySetInnerHTML`. Only pass trusted, non–user-controlled `chart` strings (similar to the raw SVG guidance in `Icon`); do not render untrusted or arbitrary user input.
|
|
1723
|
+
|
|
1724
|
+
### Import
|
|
1725
|
+
|
|
1726
|
+
```tsx
|
|
1727
|
+
import { MermaidDiagram } from '@roadlittledawn/docs-design-system-react';
|
|
1728
|
+
```
|
|
1729
|
+
|
|
1730
|
+
### Props
|
|
1731
|
+
|
|
1732
|
+
| Prop | Type | Default | Description |
|
|
1733
|
+
|------|------|---------|-------------|
|
|
1734
|
+
| `chart` | `string` | — | Mermaid diagram definition string |
|
|
1735
|
+
| `className` | `string` | `""` | Additional CSS classes |
|
|
1736
|
+
|
|
1737
|
+
### Examples
|
|
1738
|
+
|
|
1739
|
+
#### Flowchart
|
|
1740
|
+
|
|
1741
|
+
```tsx
|
|
1742
|
+
<MermaidDiagram chart={`graph TD
|
|
1743
|
+
A[Start] --> B{Decision}
|
|
1744
|
+
B -->|Yes| C[Do something]
|
|
1745
|
+
B -->|No| D[Do something else]
|
|
1746
|
+
C --> E[End]
|
|
1747
|
+
D --> E`} />
|
|
1748
|
+
```
|
|
1749
|
+
|
|
1750
|
+
#### Gantt Chart
|
|
1751
|
+
|
|
1752
|
+
```tsx
|
|
1753
|
+
<MermaidDiagram chart={`gantt
|
|
1754
|
+
title Project Schedule
|
|
1755
|
+
dateFormat YYYY-MM-DD
|
|
1756
|
+
section Planning
|
|
1757
|
+
Requirements :a1, 2024-01-01, 14d
|
|
1758
|
+
Design :a2, after a1, 10d
|
|
1759
|
+
section Development
|
|
1760
|
+
Implementation :b1, after a2, 21d
|
|
1761
|
+
Testing :b2, after b1, 14d`} />
|
|
1762
|
+
```
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface MermaidDiagramProps {
|
|
2
|
+
/** Mermaid diagram definition string */
|
|
3
|
+
chart: string;
|
|
4
|
+
/** Additional CSS classes */
|
|
5
|
+
className?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function MermaidDiagram({ chart, className }: MermaidDiagramProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
+
function step(op) {
|
|
16
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
+
switch (op[0]) {
|
|
21
|
+
case 0: case 1: t = op; break;
|
|
22
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
+
default:
|
|
26
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
+
if (t[2]) _.ops.pop();
|
|
31
|
+
_.trys.pop(); continue;
|
|
32
|
+
}
|
|
33
|
+
op = body.call(thisArg, _);
|
|
34
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
39
|
+
import { useEffect, useId, useRef, useState, useCallback } from "react";
|
|
40
|
+
import mermaid from "mermaid";
|
|
41
|
+
// Initialize mermaid once at module scope with base configuration
|
|
42
|
+
mermaid.initialize({
|
|
43
|
+
startOnLoad: false,
|
|
44
|
+
securityLevel: "strict",
|
|
45
|
+
});
|
|
46
|
+
// Rendering queue to serialize mermaid operations and prevent global config conflicts
|
|
47
|
+
var renderQueue = Promise.resolve();
|
|
48
|
+
function renderMermaidWithTheme(id, chart, dark) {
|
|
49
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
50
|
+
var resolveResult, rejectResult, resultPromise;
|
|
51
|
+
var _this = this;
|
|
52
|
+
return __generator(this, function (_a) {
|
|
53
|
+
resultPromise = new Promise(function (resolve, reject) {
|
|
54
|
+
resolveResult = resolve;
|
|
55
|
+
rejectResult = reject;
|
|
56
|
+
});
|
|
57
|
+
renderQueue = renderQueue.then(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
58
|
+
var result, error_1;
|
|
59
|
+
return __generator(this, function (_a) {
|
|
60
|
+
switch (_a.label) {
|
|
61
|
+
case 0:
|
|
62
|
+
_a.trys.push([0, 2, , 3]);
|
|
63
|
+
// Configure theme for this specific render
|
|
64
|
+
mermaid.initialize({
|
|
65
|
+
startOnLoad: false,
|
|
66
|
+
theme: dark ? "dark" : "default",
|
|
67
|
+
securityLevel: "strict",
|
|
68
|
+
});
|
|
69
|
+
return [4 /*yield*/, mermaid.render(id, chart)];
|
|
70
|
+
case 1:
|
|
71
|
+
result = _a.sent();
|
|
72
|
+
resolveResult(result);
|
|
73
|
+
return [3 /*break*/, 3];
|
|
74
|
+
case 2:
|
|
75
|
+
error_1 = _a.sent();
|
|
76
|
+
rejectResult(error_1);
|
|
77
|
+
return [3 /*break*/, 3];
|
|
78
|
+
case 3: return [2 /*return*/];
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}); }).catch(function () {
|
|
82
|
+
// Don't break the queue on error, but continue processing
|
|
83
|
+
});
|
|
84
|
+
return [2 /*return*/, resultPromise];
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function isDarkMode(el) {
|
|
89
|
+
var doc = document.documentElement;
|
|
90
|
+
var body = document.body;
|
|
91
|
+
// Explicit light-mode opt-out takes priority over everything, including OS preference
|
|
92
|
+
if (doc.classList.contains("dds-light") ||
|
|
93
|
+
doc.dataset.ddsTheme === "light" ||
|
|
94
|
+
body.classList.contains("dds-light") ||
|
|
95
|
+
body.dataset.ddsTheme === "light" ||
|
|
96
|
+
!!(el && el.closest(".dds-light, [data-dds-theme='light']"))) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
return (doc.classList.contains("dds-dark") ||
|
|
100
|
+
doc.dataset.ddsTheme === "dark" ||
|
|
101
|
+
body.classList.contains("dds-dark") ||
|
|
102
|
+
body.dataset.ddsTheme === "dark" ||
|
|
103
|
+
!!(el && el.closest(".dds-dark, [data-dds-theme='dark']")) ||
|
|
104
|
+
window.matchMedia("(prefers-color-scheme: dark)").matches);
|
|
105
|
+
}
|
|
106
|
+
export function MermaidDiagram(_a) {
|
|
107
|
+
var _this = this;
|
|
108
|
+
var chart = _a.chart, _b = _a.className, className = _b === void 0 ? "" : _b;
|
|
109
|
+
var containerRef = useRef(null);
|
|
110
|
+
var _c = useState(null), svg = _c[0], setSvg = _c[1];
|
|
111
|
+
var _d = useState(null), error = _d[0], setError = _d[1];
|
|
112
|
+
// Stable unique prefix per instance — prevents duplicate IDs across multiple MermaidDiagram components
|
|
113
|
+
var instanceId = useId();
|
|
114
|
+
// Monotonically-increasing generation counter — stale async resolutions are discarded
|
|
115
|
+
var renderGen = useRef(0);
|
|
116
|
+
// Last known dark-mode state — prevents re-renders when attributes change but theme didn't flip
|
|
117
|
+
var lastDark = useRef(null);
|
|
118
|
+
var renderDiagram = useCallback(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
119
|
+
var dark, generation, safePrefix, id, result, err_1;
|
|
120
|
+
var _a;
|
|
121
|
+
return __generator(this, function (_b) {
|
|
122
|
+
switch (_b.label) {
|
|
123
|
+
case 0:
|
|
124
|
+
dark = isDarkMode(containerRef.current);
|
|
125
|
+
lastDark.current = dark;
|
|
126
|
+
generation = ++renderGen.current;
|
|
127
|
+
safePrefix = instanceId.replace(/[^a-zA-Z0-9]/g, "");
|
|
128
|
+
id = "dds-mermaid-".concat(safePrefix, "-").concat(generation);
|
|
129
|
+
_b.label = 1;
|
|
130
|
+
case 1:
|
|
131
|
+
_b.trys.push([1, 3, 4, 5]);
|
|
132
|
+
return [4 /*yield*/, renderMermaidWithTheme(id, chart, dark)];
|
|
133
|
+
case 2:
|
|
134
|
+
result = _b.sent();
|
|
135
|
+
// Discard result if a newer render has since been requested
|
|
136
|
+
if (generation !== renderGen.current)
|
|
137
|
+
return [2 /*return*/];
|
|
138
|
+
setSvg(result.svg);
|
|
139
|
+
setError(null);
|
|
140
|
+
return [3 /*break*/, 5];
|
|
141
|
+
case 3:
|
|
142
|
+
err_1 = _b.sent();
|
|
143
|
+
if (generation !== renderGen.current)
|
|
144
|
+
return [2 /*return*/];
|
|
145
|
+
setError(err_1 instanceof Error ? err_1.message : "Failed to render diagram");
|
|
146
|
+
return [3 /*break*/, 5];
|
|
147
|
+
case 4:
|
|
148
|
+
(_a = document.getElementById(id)) === null || _a === void 0 ? void 0 : _a.remove();
|
|
149
|
+
return [7 /*endfinally*/];
|
|
150
|
+
case 5: return [2 /*return*/];
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}); }, [chart, instanceId]);
|
|
154
|
+
useEffect(function () {
|
|
155
|
+
renderDiagram();
|
|
156
|
+
}, [renderDiagram]);
|
|
157
|
+
useEffect(function () {
|
|
158
|
+
// Only re-render when the effective dark/light state actually flips
|
|
159
|
+
var reRenderIfThemeChanged = function () {
|
|
160
|
+
var dark = isDarkMode(containerRef.current);
|
|
161
|
+
if (dark === lastDark.current)
|
|
162
|
+
return;
|
|
163
|
+
renderDiagram();
|
|
164
|
+
};
|
|
165
|
+
var observer = new MutationObserver(reRenderIfThemeChanged);
|
|
166
|
+
observer.observe(document.documentElement, {
|
|
167
|
+
attributes: true,
|
|
168
|
+
attributeFilter: ["class", "data-dds-theme"],
|
|
169
|
+
});
|
|
170
|
+
observer.observe(document.body, {
|
|
171
|
+
attributes: true,
|
|
172
|
+
attributeFilter: ["class", "data-dds-theme"],
|
|
173
|
+
});
|
|
174
|
+
var mq = window.matchMedia("(prefers-color-scheme: dark)");
|
|
175
|
+
mq.addEventListener("change", reRenderIfThemeChanged);
|
|
176
|
+
return function () {
|
|
177
|
+
observer.disconnect();
|
|
178
|
+
mq.removeEventListener("change", reRenderIfThemeChanged);
|
|
179
|
+
};
|
|
180
|
+
}, [renderDiagram]);
|
|
181
|
+
var classes = ["dds-mermaid", className].filter(Boolean).join(" ");
|
|
182
|
+
if (error) {
|
|
183
|
+
return (_jsx("div", { className: "".concat(classes, " dds-mermaid-error"), role: "alert", children: _jsxs("p", { className: "dds-mermaid-error-text", children: ["Diagram error: ", error] }) }));
|
|
184
|
+
}
|
|
185
|
+
return (_jsx("div", { className: classes, ref: containerRef, role: "img", "aria-label": "Mermaid diagram", dangerouslySetInnerHTML: svg ? { __html: svg } : undefined }));
|
|
186
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { MermaidDiagram } from './MermaidDiagram';
|
|
3
|
+
declare const meta: Meta<typeof MermaidDiagram>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof MermaidDiagram>;
|
|
6
|
+
/** Basic flowchart diagram. */
|
|
7
|
+
export declare const Flowchart: Story;
|
|
8
|
+
/** Gantt chart diagram. */
|
|
9
|
+
export declare const Gantt: Story;
|
|
10
|
+
/** Shows the error state when diagram syntax is invalid. */
|
|
11
|
+
export declare const InvalidSyntax: Story;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { MermaidDiagram } from './MermaidDiagram';
|
|
2
|
+
var meta = {
|
|
3
|
+
title: 'Components/MermaidDiagram',
|
|
4
|
+
component: MermaidDiagram,
|
|
5
|
+
tags: ['autodocs'],
|
|
6
|
+
argTypes: {
|
|
7
|
+
chart: {
|
|
8
|
+
control: 'text',
|
|
9
|
+
description: 'Mermaid diagram definition string.',
|
|
10
|
+
},
|
|
11
|
+
className: {
|
|
12
|
+
control: 'text',
|
|
13
|
+
description: 'Additional CSS classes.',
|
|
14
|
+
table: { defaultValue: { summary: '""' } },
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
parameters: {
|
|
18
|
+
docs: {
|
|
19
|
+
description: {
|
|
20
|
+
component: "\nRenders Mermaid diagram syntax as an SVG. Automatically switches between light and dark Mermaid themes based on the design system's dark mode state.\n\n## When to Use\n\n- Flowcharts, sequence diagrams, Gantt charts, or any Mermaid-supported diagram type\n- Inline diagrams in documentation pages\n- Architecture or process visualizations\n\n## When Not to Use\n\n- For static images or screenshots (use `<img>` or the `Icon` component)\n- For code snippets (use `CodeBlock`)\n- For simple bullet-point lists or tables\n\n## Accessibility\n\n- Container has `role=\"img\"` and `aria-label=\"Mermaid diagram\"`\n- Error states use `role=\"alert\"` for screen reader announcement\n ",
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
export default meta;
|
|
26
|
+
/** Basic flowchart diagram. */
|
|
27
|
+
export var Flowchart = {
|
|
28
|
+
args: {
|
|
29
|
+
chart: "graph TD\n A[Start] --> B{Decision}\n B -->|Yes| C[Do something]\n B -->|No| D[Do something else]\n C --> E[End]\n D --> E",
|
|
30
|
+
},
|
|
31
|
+
parameters: {
|
|
32
|
+
docs: {
|
|
33
|
+
source: {
|
|
34
|
+
code: "<MermaidDiagram chart={`graph TD\n A[Start] --> B{Decision}\n B -->|Yes| C[Do something]\n B -->|No| D[Do something else]\n C --> E[End]\n D --> E`} />",
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
/** Gantt chart diagram. */
|
|
40
|
+
export var Gantt = {
|
|
41
|
+
args: {
|
|
42
|
+
chart: "gantt\n title Project Schedule\n dateFormat YYYY-MM-DD\n section Planning\n Requirements :a1, 2024-01-01, 14d\n Design :a2, after a1, 10d\n section Development\n Implementation :b1, after a2, 21d\n Testing :b2, after b1, 14d",
|
|
43
|
+
},
|
|
44
|
+
parameters: {
|
|
45
|
+
docs: {
|
|
46
|
+
source: {
|
|
47
|
+
code: "<MermaidDiagram chart={`gantt\n title Project Schedule\n dateFormat YYYY-MM-DD\n section Planning\n Requirements :a1, 2024-01-01, 14d\n Design :a2, after a1, 10d\n section Development\n Implementation :b1, after a2, 21d\n Testing :b2, after b1, 14d`} />",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
/** Shows the error state when diagram syntax is invalid. */
|
|
53
|
+
export var InvalidSyntax = {
|
|
54
|
+
args: {
|
|
55
|
+
chart: 'this is not valid mermaid syntax %%%',
|
|
56
|
+
},
|
|
57
|
+
parameters: {
|
|
58
|
+
docs: {
|
|
59
|
+
source: {
|
|
60
|
+
code: "<MermaidDiagram chart=\"this is not valid mermaid syntax %%%\" />",
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
};
|
package/dist/components/Tile.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import "./Tile.css";
|
|
3
2
|
export function Tile(_a) {
|
|
4
3
|
var title = _a.title, icon = _a.icon, description = _a.description, href = _a.href, _b = _a.showArrow, showArrow = _b === void 0 ? false : _b, _c = _a.className, className = _c === void 0 ? "" : _c;
|
|
5
4
|
var tileClasses = [
|
package/dist/index.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export * from './components/Table';
|
|
|
15
15
|
export * from './components/Grid';
|
|
16
16
|
export * from './components/Breadcrumb';
|
|
17
17
|
export * from './components/Icon';
|
|
18
|
+
export * from './components/MermaidDiagram';
|
|
18
19
|
export * from './components/Tile';
|
|
19
20
|
export * from './components/TileGrid';
|
|
20
21
|
export * from './hooks/useKeyPress';
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ export * from './components/Table';
|
|
|
16
16
|
export * from './components/Grid';
|
|
17
17
|
export * from './components/Breadcrumb';
|
|
18
18
|
export * from './components/Icon';
|
|
19
|
+
export * from './components/MermaidDiagram';
|
|
19
20
|
export * from './components/Tile';
|
|
20
21
|
export * from './components/TileGrid';
|
|
21
22
|
// Export hooks
|
package/dist/styles.css
CHANGED
|
@@ -326,6 +326,16 @@
|
|
|
326
326
|
--dds-breadcrumb-delimiter-color: #9ca3af; /* gray-400 */
|
|
327
327
|
--dds-breadcrumb-ellipsis-radius: 0.25rem; /* rounded */
|
|
328
328
|
--dds-breadcrumb-ellipsis-hover-bg: #f3f4f6; /* gray-100 */
|
|
329
|
+
|
|
330
|
+
/* MermaidDiagram */
|
|
331
|
+
--dds-mermaid-border: #e5e7eb; /* gray-200 */
|
|
332
|
+
--dds-mermaid-bg: #ffffff;
|
|
333
|
+
--dds-mermaid-radius: 0.5rem; /* rounded-lg */
|
|
334
|
+
--dds-mermaid-padding: 1.25rem;
|
|
335
|
+
--dds-mermaid-margin: 1rem 0;
|
|
336
|
+
--dds-mermaid-error-border: #fca5a5; /* red-300 */
|
|
337
|
+
--dds-mermaid-error-bg: #fef2f2; /* red-50 */
|
|
338
|
+
--dds-mermaid-error-text: #dc2626; /* red-600 */
|
|
329
339
|
}
|
|
330
340
|
/* ==========================================================================
|
|
331
341
|
Dark Mode Tokens
|
|
@@ -526,6 +536,13 @@
|
|
|
526
536
|
--dds-breadcrumb-current-color: #e5e7eb; /* gray-200 */
|
|
527
537
|
--dds-breadcrumb-delimiter-color: #6b7280; /* gray-500 */
|
|
528
538
|
--dds-breadcrumb-ellipsis-hover-bg: rgba(255, 255, 255, 0.08);
|
|
539
|
+
|
|
540
|
+
/* MermaidDiagram */
|
|
541
|
+
--dds-mermaid-border: #4b5563; /* gray-600 */
|
|
542
|
+
--dds-mermaid-bg: transparent;
|
|
543
|
+
--dds-mermaid-error-border: #991b1b; /* red-800 */
|
|
544
|
+
--dds-mermaid-error-bg: rgba(239, 68, 68, 0.08);
|
|
545
|
+
--dds-mermaid-error-text: #f87171; /* red-400 */
|
|
529
546
|
}
|
|
530
547
|
/* Auto dark mode — follows OS preference, opt-out with .dds-light */
|
|
531
548
|
@media (prefers-color-scheme: dark) {
|
|
@@ -721,6 +738,13 @@
|
|
|
721
738
|
--dds-breadcrumb-current-color: #e5e7eb; /* gray-200 */
|
|
722
739
|
--dds-breadcrumb-delimiter-color: #6b7280; /* gray-500 */
|
|
723
740
|
--dds-breadcrumb-ellipsis-hover-bg: rgba(255, 255, 255, 0.08);
|
|
741
|
+
|
|
742
|
+
/* MermaidDiagram */
|
|
743
|
+
--dds-mermaid-border: #4b5563;
|
|
744
|
+
--dds-mermaid-bg: transparent;
|
|
745
|
+
--dds-mermaid-error-border: #991b1b;
|
|
746
|
+
--dds-mermaid-error-bg: rgba(239, 68, 68, 0.08);
|
|
747
|
+
--dds-mermaid-error-text: #f87171;
|
|
724
748
|
}
|
|
725
749
|
}
|
|
726
750
|
/* Explicit dark mode via data attribute (overrides OS preference) */
|
|
@@ -895,6 +919,13 @@
|
|
|
895
919
|
--dds-breadcrumb-current-color: #e5e7eb; /* gray-200 */
|
|
896
920
|
--dds-breadcrumb-delimiter-color: #6b7280; /* gray-500 */
|
|
897
921
|
--dds-breadcrumb-ellipsis-hover-bg: rgba(255, 255, 255, 0.08);
|
|
922
|
+
|
|
923
|
+
/* MermaidDiagram */
|
|
924
|
+
--dds-mermaid-border: #4b5563;
|
|
925
|
+
--dds-mermaid-bg: transparent;
|
|
926
|
+
--dds-mermaid-error-border: #991b1b;
|
|
927
|
+
--dds-mermaid-error-bg: rgba(239, 68, 68, 0.08);
|
|
928
|
+
--dds-mermaid-error-text: #f87171;
|
|
898
929
|
}
|
|
899
930
|
/* Import PrismJS theme */
|
|
900
931
|
/**
|
|
@@ -2480,6 +2511,29 @@ a.dds-breadcrumb-link:hover {
|
|
|
2480
2511
|
width: 100%;
|
|
2481
2512
|
height: 100%;
|
|
2482
2513
|
}
|
|
2514
|
+
.dds-mermaid {
|
|
2515
|
+
border: 1px solid var(--dds-mermaid-border);
|
|
2516
|
+
border-radius: var(--dds-mermaid-radius);
|
|
2517
|
+
background-color: var(--dds-mermaid-bg);
|
|
2518
|
+
padding: var(--dds-mermaid-padding);
|
|
2519
|
+
margin: var(--dds-mermaid-margin);
|
|
2520
|
+
display: flex;
|
|
2521
|
+
justify-content: center;
|
|
2522
|
+
overflow-x: auto;
|
|
2523
|
+
}
|
|
2524
|
+
.dds-mermaid svg {
|
|
2525
|
+
max-width: 100%;
|
|
2526
|
+
height: auto;
|
|
2527
|
+
}
|
|
2528
|
+
.dds-mermaid-error {
|
|
2529
|
+
border-color: var(--dds-mermaid-error-border);
|
|
2530
|
+
background-color: var(--dds-mermaid-error-bg);
|
|
2531
|
+
}
|
|
2532
|
+
.dds-mermaid-error-text {
|
|
2533
|
+
color: var(--dds-mermaid-error-text);
|
|
2534
|
+
font-size: 0.875rem;
|
|
2535
|
+
margin: 0;
|
|
2536
|
+
}
|
|
2483
2537
|
a.dds-tile-link {
|
|
2484
2538
|
display: block;
|
|
2485
2539
|
text-decoration: none;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@roadlittledawn/docs-design-system-react",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "React components for documentation design system",
|
|
6
6
|
"repository": {
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"type-check": "tsc --noEmit"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
+
"mermaid": "^11.0.0",
|
|
27
28
|
"prismjs": "^1.29.0",
|
|
28
29
|
"react": "^19.0.0",
|
|
29
30
|
"react-dom": "^19.0.0",
|