@rtkelly-labs/design-system 0.0.0-bootstrap.0 → 0.16.0-dev.0.37dedac
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/CHANGELOG.md +347 -0
- package/LICENSE +21 -0
- package/README.md +317 -2
- package/dist/components/AlertDialog.js +95 -0
- package/dist/components/AlertDialog.js.map +1 -0
- package/dist/components/AppShell.js +261 -0
- package/dist/components/AppShell.js.map +1 -0
- package/dist/components/AsciiDivider.js +8 -0
- package/dist/components/AsciiDivider.js.map +1 -0
- package/dist/components/AsciiGauge.js +130 -0
- package/dist/components/AsciiGauge.js.map +1 -0
- package/dist/components/Avatar.js +87 -0
- package/dist/components/Avatar.js.map +1 -0
- package/dist/components/Badge.js +25 -0
- package/dist/components/Badge.js.map +1 -0
- package/dist/components/BarChart.js +288 -0
- package/dist/components/BarChart.js.map +1 -0
- package/dist/components/BracketText.js +23 -0
- package/dist/components/BracketText.js.map +1 -0
- package/dist/components/BulletChart.js +50 -0
- package/dist/components/BulletChart.js.map +1 -0
- package/dist/components/Button.js +130 -0
- package/dist/components/Button.js.map +1 -0
- package/dist/components/Card.js +181 -0
- package/dist/components/Card.js.map +1 -0
- package/dist/components/ChartTooltip.js +54 -0
- package/dist/components/ChartTooltip.js.map +1 -0
- package/dist/components/Checkbox.js +55 -0
- package/dist/components/Checkbox.js.map +1 -0
- package/dist/components/ColophonCard.js +122 -0
- package/dist/components/ColophonCard.js.map +1 -0
- package/dist/components/DataTable.js +299 -0
- package/dist/components/DataTable.js.map +1 -0
- package/dist/components/Divider.js +42 -0
- package/dist/components/Divider.js.map +1 -0
- package/dist/components/Drawer.js +81 -0
- package/dist/components/Drawer.js.map +1 -0
- package/dist/components/EmptyState.js +39 -0
- package/dist/components/EmptyState.js.map +1 -0
- package/dist/components/ErrorSummary.js +122 -0
- package/dist/components/ErrorSummary.js.map +1 -0
- package/dist/components/Fieldset.js +37 -0
- package/dist/components/Fieldset.js.map +1 -0
- package/dist/components/Glyph.js +60 -0
- package/dist/components/Glyph.js.map +1 -0
- package/dist/components/Input.js +111 -0
- package/dist/components/Input.js.map +1 -0
- package/dist/components/LinkProvider.js +76 -0
- package/dist/components/LinkProvider.js.map +1 -0
- package/dist/components/Menu.js +144 -0
- package/dist/components/Menu.js.map +1 -0
- package/dist/components/MetadataGrid.js +184 -0
- package/dist/components/MetadataGrid.js.map +1 -0
- package/dist/components/MobileNav.js +120 -0
- package/dist/components/MobileNav.js.map +1 -0
- package/dist/components/Modal.js +79 -0
- package/dist/components/Modal.js.map +1 -0
- package/dist/components/NerdIcon.js +177 -0
- package/dist/components/NerdIcon.js.map +1 -0
- package/dist/components/NoteBlock.js +84 -0
- package/dist/components/NoteBlock.js.map +1 -0
- package/dist/components/PageHeader.js +34 -0
- package/dist/components/PageHeader.js.map +1 -0
- package/dist/components/PageTitle.js +21 -0
- package/dist/components/PageTitle.js.map +1 -0
- package/dist/components/Pagination.js +96 -0
- package/dist/components/Pagination.js.map +1 -0
- package/dist/components/Popover.js +87 -0
- package/dist/components/Popover.js.map +1 -0
- package/dist/components/Progress.js +83 -0
- package/dist/components/Progress.js.map +1 -0
- package/dist/components/RadioGroup.js +74 -0
- package/dist/components/RadioGroup.js.map +1 -0
- package/dist/components/ReportDocument.js +75 -0
- package/dist/components/ReportDocument.js.map +1 -0
- package/dist/components/SectionContainer.js +18 -0
- package/dist/components/SectionContainer.js.map +1 -0
- package/dist/components/Select.js +199 -0
- package/dist/components/Select.js.map +1 -0
- package/dist/components/SiteFooter.js +29 -0
- package/dist/components/SiteFooter.js.map +1 -0
- package/dist/components/SiteHeader.js +59 -0
- package/dist/components/SiteHeader.js.map +1 -0
- package/dist/components/SiteNav.js +141 -0
- package/dist/components/SiteNav.js.map +1 -0
- package/dist/components/Skeleton.js +51 -0
- package/dist/components/Skeleton.js.map +1 -0
- package/dist/components/SocialIcon.js +77 -0
- package/dist/components/SocialIcon.js.map +1 -0
- package/dist/components/Sparkline.js +104 -0
- package/dist/components/Sparkline.js.map +1 -0
- package/dist/components/Spinner.js +65 -0
- package/dist/components/Spinner.js.map +1 -0
- package/dist/components/StatCard.js +53 -0
- package/dist/components/StatCard.js.map +1 -0
- package/dist/components/StatusPage.js +99 -0
- package/dist/components/StatusPage.js.map +1 -0
- package/dist/components/Swatch.js +55 -0
- package/dist/components/Swatch.js.map +1 -0
- package/dist/components/Switch.js +53 -0
- package/dist/components/Switch.js.map +1 -0
- package/dist/components/TLDR.js +53 -0
- package/dist/components/TLDR.js.map +1 -0
- package/dist/components/Table.js +155 -0
- package/dist/components/Table.js.map +1 -0
- package/dist/components/Tabs.js +325 -0
- package/dist/components/Tabs.js.map +1 -0
- package/dist/components/Tag.js +19 -0
- package/dist/components/Tag.js.map +1 -0
- package/dist/components/TelemetryGauge.js +112 -0
- package/dist/components/TelemetryGauge.js.map +1 -0
- package/dist/components/ThemeProvider.js +87 -0
- package/dist/components/ThemeProvider.js.map +1 -0
- package/dist/components/TickerTape.js +196 -0
- package/dist/components/TickerTape.js.map +1 -0
- package/dist/components/Toast.js +200 -0
- package/dist/components/Toast.js.map +1 -0
- package/dist/components/Tooltip.js +69 -0
- package/dist/components/Tooltip.js.map +1 -0
- package/dist/components/TrackCard.js +206 -0
- package/dist/components/TrackCard.js.map +1 -0
- package/dist/components/blog/BlogPost.js +116 -0
- package/dist/components/blog/BlogPost.js.map +1 -0
- package/dist/components/blog/LoremIpsumPost.js +62 -0
- package/dist/components/blog/LoremIpsumPost.js.map +1 -0
- package/dist/components/blog/author.js +25 -0
- package/dist/components/blog/author.js.map +1 -0
- package/dist/components/booleanControl.js +50 -0
- package/dist/components/booleanControl.js.map +1 -0
- package/dist/components/dialogPopupRef.js +28 -0
- package/dist/components/dialogPopupRef.js.map +1 -0
- package/dist/components/dialogSurface.js +75 -0
- package/dist/components/dialogSurface.js.map +1 -0
- package/dist/components/docs/AnchorHeading.js +80 -0
- package/dist/components/docs/AnchorHeading.js.map +1 -0
- package/dist/components/docs/Breadcrumbs.js +26 -0
- package/dist/components/docs/Breadcrumbs.js.map +1 -0
- package/dist/components/docs/CodeBlock.js +63 -0
- package/dist/components/docs/CodeBlock.js.map +1 -0
- package/dist/components/docs/CodeTabs.js +71 -0
- package/dist/components/docs/CodeTabs.js.map +1 -0
- package/dist/components/docs/DocPager.js +28 -0
- package/dist/components/docs/DocPager.js.map +1 -0
- package/dist/components/docs/DocsHeader.js +124 -0
- package/dist/components/docs/DocsHeader.js.map +1 -0
- package/dist/components/docs/DocsLayout.js +61 -0
- package/dist/components/docs/DocsLayout.js.map +1 -0
- package/dist/components/docs/DocsLinkProvider.js +25 -0
- package/dist/components/docs/DocsLinkProvider.js.map +1 -0
- package/dist/components/docs/DocsSidebar.js +147 -0
- package/dist/components/docs/DocsSidebar.js.map +1 -0
- package/dist/components/docs/Prose.js +56 -0
- package/dist/components/docs/Prose.js.map +1 -0
- package/dist/components/docs/TableOfContents.js +71 -0
- package/dist/components/docs/TableOfContents.js.map +1 -0
- package/dist/components/docs/codeTabsStore.js +75 -0
- package/dist/components/docs/codeTabsStore.js.map +1 -0
- package/dist/components/docs/figures/ActivityGrid.js +116 -0
- package/dist/components/docs/figures/ActivityGrid.js.map +1 -0
- package/dist/components/docs/figures/BeforeAfter.js +64 -0
- package/dist/components/docs/figures/BeforeAfter.js.map +1 -0
- package/dist/components/docs/figures/ChangeSummary.js +74 -0
- package/dist/components/docs/figures/ChangeSummary.js.map +1 -0
- package/dist/components/docs/figures/Decision.js +34 -0
- package/dist/components/docs/figures/Decision.js.map +1 -0
- package/dist/components/docs/figures/DrawingSheet.js +37 -0
- package/dist/components/docs/figures/DrawingSheet.js.map +1 -0
- package/dist/components/docs/figures/FigureFrame.js +226 -0
- package/dist/components/docs/figures/FigureFrame.js.map +1 -0
- package/dist/components/docs/figures/FileChangeTree.js +134 -0
- package/dist/components/docs/figures/FileChangeTree.js.map +1 -0
- package/dist/components/docs/figures/FlowDiagram.js +82 -0
- package/dist/components/docs/figures/FlowDiagram.js.map +1 -0
- package/dist/components/docs/figures/GanttChart.js +79 -0
- package/dist/components/docs/figures/GanttChart.js.map +1 -0
- package/dist/components/docs/figures/IndexedSection.js +45 -0
- package/dist/components/docs/figures/IndexedSection.js.map +1 -0
- package/dist/components/docs/figures/MetricStrip.js +23 -0
- package/dist/components/docs/figures/MetricStrip.js.map +1 -0
- package/dist/components/docs/figures/Steps.js +58 -0
- package/dist/components/docs/figures/Steps.js.map +1 -0
- package/dist/components/docs/figures/SwatchCompare.js +42 -0
- package/dist/components/docs/figures/SwatchCompare.js.map +1 -0
- package/dist/components/docs/figures/TermGrid.js +22 -0
- package/dist/components/docs/figures/TermGrid.js.map +1 -0
- package/dist/components/docs/figures/Terminal.js +37 -0
- package/dist/components/docs/figures/Terminal.js.map +1 -0
- package/dist/components/docs/figures/Timeline.js +61 -0
- package/dist/components/docs/figures/Timeline.js.map +1 -0
- package/dist/components/docs/figures/TokenTable.js +42 -0
- package/dist/components/docs/figures/TokenTable.js.map +1 -0
- package/dist/components/docs/figures/TreeDiagram.js +76 -0
- package/dist/components/docs/figures/TreeDiagram.js.map +1 -0
- package/dist/components/docs/figures/UptimeStrip.js +68 -0
- package/dist/components/docs/figures/UptimeStrip.js.map +1 -0
- package/dist/components/docs/figures/index.js +24 -0
- package/dist/components/docs/figures/index.js.map +1 -0
- package/dist/components/docs/index.js +15 -0
- package/dist/components/docs/index.js.map +1 -0
- package/dist/components/docs/mdxComponents.js +108 -0
- package/dist/components/docs/mdxComponents.js.map +1 -0
- package/dist/components/experiments/DesignSandbox.js +206 -0
- package/dist/components/experiments/DesignSandbox.js.map +1 -0
- package/dist/components/experiments/ExperimentsView.js +138 -0
- package/dist/components/experiments/ExperimentsView.js.map +1 -0
- package/dist/components/fieldFrame.js +200 -0
- package/dist/components/fieldFrame.js.map +1 -0
- package/dist/components/floatingSurface.js +35 -0
- package/dist/components/floatingSurface.js.map +1 -0
- package/dist/components/marketing/CTASection.js +47 -0
- package/dist/components/marketing/CTASection.js.map +1 -0
- package/dist/components/marketing/FeatureGrid.js +49 -0
- package/dist/components/marketing/FeatureGrid.js.map +1 -0
- package/dist/components/marketing/Hero.js +44 -0
- package/dist/components/marketing/Hero.js.map +1 -0
- package/dist/components/marketing/PricingGrid.js +65 -0
- package/dist/components/marketing/PricingGrid.js.map +1 -0
- package/dist/components/marketing/SectionGrid.js +51 -0
- package/dist/components/marketing/SectionGrid.js.map +1 -0
- package/dist/components/paginationRange.js +28 -0
- package/dist/components/paginationRange.js.map +1 -0
- package/dist/components/portalTheme.js +14 -0
- package/dist/components/portalTheme.js.map +1 -0
- package/dist/components/saas/SaasLandingPage.js +201 -0
- package/dist/components/saas/SaasLandingPage.js.map +1 -0
- package/dist/components/siteNavContext.js +24 -0
- package/dist/components/siteNavContext.js.map +1 -0
- package/dist/components/slides/Slide.js +84 -0
- package/dist/components/slides/Slide.js.map +1 -0
- package/dist/components/slides/SlideDeck.js +228 -0
- package/dist/components/slides/SlideDeck.js.map +1 -0
- package/dist/components/themeInitScript.js +16 -0
- package/dist/components/themeInitScript.js.map +1 -0
- package/dist/components/themeScope.js +9 -0
- package/dist/components/themeScope.js.map +1 -0
- package/dist/components/toastLifetime.js +21 -0
- package/dist/components/toastLifetime.js.map +1 -0
- package/dist/fonts/DSSymbols-OFL.txt +98 -0
- package/dist/fonts/DSSymbols-Regular.woff2 +0 -0
- package/dist/fonts/SymbolsNerdFontMono-Regular.woff2 +0 -0
- package/dist/hooks/useActiveHeading.js +59 -0
- package/dist/hooks/useActiveHeading.js.map +1 -0
- package/dist/hooks/useCopyToClipboard.js +58 -0
- package/dist/hooks/useCopyToClipboard.js.map +1 -0
- package/dist/index.d.ts +6394 -0
- package/dist/index.js +117 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/accentClasses.js +87 -0
- package/dist/lib/accentClasses.js.map +1 -0
- package/dist/lib/recipe.js +33 -0
- package/dist/lib/recipe.js.map +1 -0
- package/dist/lib/slug.js +39 -0
- package/dist/lib/slug.js.map +1 -0
- package/dist/lib/theme.js +76 -0
- package/dist/lib/theme.js.map +1 -0
- package/dist/lib/tokenRules.js +51 -0
- package/dist/lib/tokenRules.js.map +1 -0
- package/dist/prose.css +766 -0
- package/dist/styles.css +203 -0
- package/dist/theme/ansi.js +77 -0
- package/dist/theme/ansi.js.map +1 -0
- package/dist/theme/contrast.js +342 -0
- package/dist/theme/contrast.js.map +1 -0
- package/dist/theme/levels.js +234 -0
- package/dist/theme/levels.js.map +1 -0
- package/dist/theme/media.js +115 -0
- package/dist/theme/media.js.map +1 -0
- package/dist/theme/recommended.js +105 -0
- package/dist/theme/recommended.js.map +1 -0
- package/dist/theme.css +538 -0
- package/dist/tokens.js +1 -0
- package/dist/tokens.js.map +1 -0
- package/package.json +209 -6
- package/skills/design-system-usage/SKILL.md +75 -0
- package/terminal/rtk-midnight.alacritty.toml +33 -0
- package/terminal/rtk-midnight.ghostty.conf +24 -0
- package/terminal/rtk-midnight.itermcolors +167 -0
- package/terminal/rtk-midnight.windows-terminal.json +23 -0
- package/terminal/rtk-sketch.alacritty.toml +33 -0
- package/terminal/rtk-sketch.ghostty.conf +24 -0
- package/terminal/rtk-sketch.itermcolors +167 -0
- package/terminal/rtk-sketch.windows-terminal.json +23 -0
- package/tokens/palette.midnight.tokens.json +477 -0
- package/tokens/palette.sketch.tokens.json +477 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// src/components/docs/figures/GanttChart.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../../../lib/recipe.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
var DAY_MS = 864e5;
|
|
6
|
+
var MAX_RANGE_DAYS = 3660;
|
|
7
|
+
var MAX_COLUMNS = 120;
|
|
8
|
+
function parseDate(value) {
|
|
9
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value);
|
|
10
|
+
if (!match) return null;
|
|
11
|
+
const y = Number(match[1]);
|
|
12
|
+
const m = Number(match[2]);
|
|
13
|
+
const d = Number(match[3]);
|
|
14
|
+
const date = /* @__PURE__ */ new Date(0);
|
|
15
|
+
date.setUTCHours(0, 0, 0, 0);
|
|
16
|
+
date.setUTCFullYear(y, m - 1, d);
|
|
17
|
+
return date.getUTCFullYear() === y && date.getUTCMonth() === m - 1 && date.getUTCDate() === d ? date.getTime() : null;
|
|
18
|
+
}
|
|
19
|
+
function iso(time) {
|
|
20
|
+
return new Date(time).toISOString().slice(0, 10);
|
|
21
|
+
}
|
|
22
|
+
function shortDate(time) {
|
|
23
|
+
return new Intl.DateTimeFormat("en", { month: "short", day: "numeric", timeZone: "UTC" }).format(new Date(time));
|
|
24
|
+
}
|
|
25
|
+
var GanttChart = React.forwardRef(function GanttChart2({ items, range, columns = 48, className, ...rest }, ref) {
|
|
26
|
+
const valid = items.map((item) => ({ ...item, startTime: parseDate(item.start), endTime: parseDate(item.end) })).filter((item) => item.startTime !== null && item.endTime !== null && item.startTime <= item.endTime);
|
|
27
|
+
const rangeStart = range ? parseDate(range.start) : valid.length ? Math.min(...valid.map((item) => item.startTime)) : null;
|
|
28
|
+
const rangeEnd = range ? parseDate(range.end) : valid.length ? Math.max(...valid.map((item) => item.endTime)) : null;
|
|
29
|
+
const days = rangeStart == null || rangeEnd == null ? 0 : Math.floor((rangeEnd - rangeStart) / DAY_MS) + 1;
|
|
30
|
+
const visible = rangeStart == null || rangeEnd == null ? [] : valid.filter((item) => item.endTime >= rangeStart && item.startTime <= rangeEnd);
|
|
31
|
+
const empty = !visible.length || rangeStart == null || rangeEnd == null || rangeStart > rangeEnd || days > MAX_RANGE_DAYS;
|
|
32
|
+
const cells = Math.max(1, Math.min(MAX_COLUMNS, Math.round(Number.isFinite(columns) ? columns : 48)));
|
|
33
|
+
if (empty) return /* @__PURE__ */ jsxs("section", { "data-slot": "gantt-chart", ref, "aria-label": "Gantt chart", ...rest, className: cn("font-mono text-sm text-content-primary", className), children: [
|
|
34
|
+
/* @__PURE__ */ jsx("p", { className: "text-content-muted", children: items.length ? "No valid schedule in the selected date range." : "No schedule items to display." }),
|
|
35
|
+
/* @__PURE__ */ jsx("p", { className: "sr-only", children: "Empty schedule." })
|
|
36
|
+
] });
|
|
37
|
+
const span = rangeEnd - rangeStart + DAY_MS;
|
|
38
|
+
const summary = `Schedule date range: ${iso(rangeStart)} through ${iso(rangeEnd)}.`;
|
|
39
|
+
const ticks = Array.from({ length: days }, (_, i) => rangeStart + i * DAY_MS).filter((time) => {
|
|
40
|
+
const day = new Date(time).getUTCDate();
|
|
41
|
+
return days <= 42 ? new Date(time).getUTCDay() === 1 : day === 1;
|
|
42
|
+
});
|
|
43
|
+
if (!ticks.includes(rangeStart)) ticks.unshift(rangeStart);
|
|
44
|
+
const tickLabels = /* @__PURE__ */ new Map();
|
|
45
|
+
for (const time of ticks) {
|
|
46
|
+
const cell = Math.min(cells - 1, Math.floor((time - rangeStart) / span * cells));
|
|
47
|
+
const label = new Date(time).getUTCDate() === 1 && days > 42 ? new Intl.DateTimeFormat("en", { month: "short", timeZone: "UTC" }).format(new Date(time)) : shortDate(time);
|
|
48
|
+
tickLabels.set(cell, label);
|
|
49
|
+
}
|
|
50
|
+
return /* @__PURE__ */ jsxs("section", { "data-slot": "gantt-chart", ref, "aria-label": "Gantt chart", ...rest, className: cn("flex min-w-0 flex-col gap-3 font-mono text-sm text-content-primary", className), children: [
|
|
51
|
+
/* @__PURE__ */ jsx("p", { className: "sr-only", children: summary }),
|
|
52
|
+
/* @__PURE__ */ jsx("ul", { "aria-label": "Scheduled items", className: "flex flex-col gap-2", children: visible.map((item, row) => {
|
|
53
|
+
const start = Math.max(rangeStart, item.startTime);
|
|
54
|
+
const end = Math.min(rangeEnd + DAY_MS, item.endTime + DAY_MS);
|
|
55
|
+
const from = Math.max(0, Math.floor((start - rangeStart) / span * cells));
|
|
56
|
+
const to = Math.min(cells, Math.max(from + 1, Math.ceil((end - rangeStart) / span * cells)));
|
|
57
|
+
const width = Math.max(1, to - from);
|
|
58
|
+
const hasProgress = item.complete != null && Number.isFinite(item.complete);
|
|
59
|
+
const progress = hasProgress ? Math.max(0, Math.min(1, item.complete)) : 1;
|
|
60
|
+
const done = Math.round(width * progress);
|
|
61
|
+
return /* @__PURE__ */ jsxs("li", { "aria-label": `${item.label}, ${item.start} through ${item.end}${hasProgress ? `, ${Math.round(progress * 100)}% complete` : ""}`, className: "grid grid-cols-[minmax(0,8rem)_minmax(0,1fr)] items-center gap-3", children: [
|
|
62
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: item.label }),
|
|
63
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "flex min-w-0 select-none", children: Array.from({ length: cells }, (_, index) => {
|
|
64
|
+
const inside = index >= from && index < to;
|
|
65
|
+
const completed = inside && index < from + done;
|
|
66
|
+
return /* @__PURE__ */ jsx("span", { className: cn("min-w-0 flex-1 overflow-hidden text-center", completed ? "text-accent-primary" : inside ? "text-content-secondary" : "text-content-muted"), children: completed ? "\u2588" : inside ? "\u2591" : "\xB7" }, index);
|
|
67
|
+
}) })
|
|
68
|
+
] }, `${item.label}-${item.start}-${row}`);
|
|
69
|
+
}) }),
|
|
70
|
+
/* @__PURE__ */ jsxs("div", { "aria-hidden": "true", className: "grid grid-cols-[minmax(0,8rem)_minmax(0,1fr)] gap-3", children: [
|
|
71
|
+
/* @__PURE__ */ jsx("span", {}),
|
|
72
|
+
/* @__PURE__ */ jsx("div", { className: "flex h-[2.5em] border-t border-dashed border-edge-subtle", children: Array.from({ length: cells }, (_, index) => /* @__PURE__ */ jsx("span", { className: "relative min-w-0 flex-1", children: tickLabels.has(index) ? /* @__PURE__ */ jsx("span", { className: cn("absolute top-1 whitespace-nowrap text-[0.8em] text-content-secondary", index > cells * 0.84 ? "right-0" : "left-0"), children: tickLabels.get(index) }) : null }, index)) })
|
|
73
|
+
] })
|
|
74
|
+
] });
|
|
75
|
+
});
|
|
76
|
+
export {
|
|
77
|
+
GanttChart
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=GanttChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/docs/figures/GanttChart.tsx"],"sourcesContent":["/**\n * Adapted from mdxcn by Keshav Bagaade, MIT licensed.\n * Source: https://github.com/keshav-exe/mdxcn/blob/2928126ba146ebbae9c2351deca27d27bb40e744/registry/default/graph-gantt/graph-gantt.tsx\n * The local port uses calendar dates, bounded deterministic rendering, and\n * the design system's semantic token classes.\n */\n\nimport * as React from 'react';\nimport { cn } from '../../../lib/recipe';\n\nconst DAY_MS = 86_400_000;\nconst MAX_RANGE_DAYS = 3660;\nconst MAX_COLUMNS = 120;\n\nexport interface GanttItem {\n label: string;\n /** Inclusive calendar start date in ISO `YYYY-MM-DD` form. */\n start: string;\n /** Inclusive calendar end date in ISO `YYYY-MM-DD` form. */\n end: string;\n /** Fraction completed, from 0 to 1. */\n complete?: number;\n}\n\nexport interface GanttChartProps extends React.HTMLAttributes<HTMLElement> {\n /** Dated work items. Invalid or out-of-range items are omitted. */\n items: GanttItem[];\n /** Explicit displayed bounds. Defaults to the earliest start and latest end. */\n range?: { start: string; end: string };\n /** Number of character cells used to draw each bar. Clamped to 1–120. */\n columns?: number;\n /** Additional classes for the renderer root. */\n className?: string;\n}\n\nfunction parseDate(value: string): number | null {\n const match = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value);\n if (!match) return null;\n const y = Number(match[1]); const m = Number(match[2]); const d = Number(match[3]);\n const date = new Date(0);\n date.setUTCHours(0, 0, 0, 0);\n date.setUTCFullYear(y, m - 1, d);\n return date.getUTCFullYear() === y && date.getUTCMonth() === m - 1 && date.getUTCDate() === d ? date.getTime() : null;\n}\nfunction iso(time: number): string { return new Date(time).toISOString().slice(0, 10); }\nfunction shortDate(time: number): string { return new Intl.DateTimeFormat('en', { month: 'short', day: 'numeric', timeZone: 'UTC' }).format(new Date(time)); }\n\n/** Renders a dated schedule on a bounded, fixed-cell calendar scale. */\nexport const GanttChart = React.forwardRef<HTMLElement, GanttChartProps>(function GanttChart({ items, range, columns = 48, className, ...rest }, ref) {\n const valid = items.map((item) => ({ ...item, startTime: parseDate(item.start), endTime: parseDate(item.end) }))\n .filter((item): item is GanttItem & { startTime: number; endTime: number } => item.startTime !== null && item.endTime !== null && item.startTime <= item.endTime);\n const rangeStart = range ? parseDate(range.start) : (valid.length ? Math.min(...valid.map((item) => item.startTime)) : null);\n const rangeEnd = range ? parseDate(range.end) : (valid.length ? Math.max(...valid.map((item) => item.endTime)) : null);\n const days = rangeStart == null || rangeEnd == null ? 0 : Math.floor((rangeEnd - rangeStart) / DAY_MS) + 1;\n const visible = rangeStart == null || rangeEnd == null ? [] : valid.filter((item) => item.endTime >= rangeStart && item.startTime <= rangeEnd);\n const empty = !visible.length || rangeStart == null || rangeEnd == null || rangeStart > rangeEnd || days > MAX_RANGE_DAYS;\n const cells = Math.max(1, Math.min(MAX_COLUMNS, Math.round(Number.isFinite(columns) ? columns : 48)));\n\n if (empty) return <section data-slot=\"gantt-chart\" ref={ref} aria-label=\"Gantt chart\" {...rest} className={cn('font-mono text-sm text-content-primary', className)}><p className=\"text-content-muted\">{items.length ? 'No valid schedule in the selected date range.' : 'No schedule items to display.'}</p><p className=\"sr-only\">Empty schedule.</p></section>;\n\n const span = rangeEnd! - rangeStart! + DAY_MS;\n const summary = `Schedule date range: ${iso(rangeStart!)} through ${iso(rangeEnd!)}.`;\n const ticks = Array.from({ length: days }, (_, i) => rangeStart! + i * DAY_MS)\n .filter((time) => { const day = new Date(time).getUTCDate(); return days <= 42 ? new Date(time).getUTCDay() === 1 : day === 1; });\n if (!ticks.includes(rangeStart!)) ticks.unshift(rangeStart!);\n const tickLabels = new Map<number, string>();\n for (const time of ticks) {\n const cell = Math.min(cells - 1, Math.floor((time - rangeStart!) / span * cells));\n // A short range is ticked weekly (plus its start) with dated labels; a\n // month-start tick beside \"May 4\" printed as \"May May 4\". Longer ranges\n // tick on month starts and name the month.\n const label = new Date(time).getUTCDate() === 1 && days > 42\n ? new Intl.DateTimeFormat('en', { month: 'short', timeZone: 'UTC' }).format(new Date(time))\n : shortDate(time);\n tickLabels.set(cell, label);\n }\n\n return <section data-slot=\"gantt-chart\" ref={ref} aria-label=\"Gantt chart\" {...rest} className={cn('flex min-w-0 flex-col gap-3 font-mono text-sm text-content-primary', className)}>\n <p className=\"sr-only\">{summary}</p>\n <ul aria-label=\"Scheduled items\" className=\"flex flex-col gap-2\">\n {visible.map((item, row) => {\n const start = Math.max(rangeStart!, item.startTime);\n const end = Math.min(rangeEnd! + DAY_MS, item.endTime + DAY_MS);\n const from = Math.max(0, Math.floor((start - rangeStart!) / span * cells));\n const to = Math.min(cells, Math.max(from + 1, Math.ceil((end - rangeStart!) / span * cells)));\n const width = Math.max(1, to - from);\n const hasProgress = item.complete != null && Number.isFinite(item.complete);\n const progress = hasProgress ? Math.max(0, Math.min(1, item.complete!)) : 1;\n const done = Math.round(width * progress);\n return <li aria-label={`${item.label}, ${item.start} through ${item.end}${hasProgress ? `, ${Math.round(progress * 100)}% complete` : ''}`} className=\"grid grid-cols-[minmax(0,8rem)_minmax(0,1fr)] items-center gap-3\" key={`${item.label}-${item.start}-${row}`}>\n <span className=\"truncate\">{item.label}</span><span aria-hidden=\"true\" className=\"flex min-w-0 select-none\">{Array.from({ length: cells }, (_, index) => { const inside = index >= from && index < to; const completed = inside && index < from + done; return <span className={cn('min-w-0 flex-1 overflow-hidden text-center', completed ? 'text-accent-primary' : inside ? 'text-content-secondary' : 'text-content-muted')} key={index}>{completed ? '█' : inside ? '░' : '·'}</span>; })}</span>\n </li>;\n })}\n </ul>\n <div aria-hidden=\"true\" className=\"grid grid-cols-[minmax(0,8rem)_minmax(0,1fr)] gap-3\"><span />\n <div className=\"flex h-[2.5em] border-t border-dashed border-edge-subtle\">{Array.from({ length: cells }, (_, index) => <span className=\"relative min-w-0 flex-1\" key={index}>{tickLabels.has(index) ? <span className={cn('absolute top-1 whitespace-nowrap text-[0.8em] text-content-secondary', index > cells * 0.84 ? 'right-0' : 'left-0')}>{tickLabels.get(index)}</span> : null}</span>)}</div>\n </div>\n </section>;\n});\n"],"mappings":"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","names":["GanttChart"]}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// src/components/docs/figures/IndexedSection.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../../../lib/recipe.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
var IndexedSection = React.forwardRef(function IndexedSection2({ index, title, headingLevel = 3, actions, children, className, ...rest }, ref) {
|
|
6
|
+
const headingId = React.useId();
|
|
7
|
+
const Heading = `h${headingLevel}`;
|
|
8
|
+
return /* @__PURE__ */ jsxs(
|
|
9
|
+
"section",
|
|
10
|
+
{
|
|
11
|
+
ref,
|
|
12
|
+
"aria-labelledby": headingId,
|
|
13
|
+
...rest,
|
|
14
|
+
"data-slot": "indexed-section",
|
|
15
|
+
className: cn("flex min-w-0 flex-col border-2 border-edge-strong bg-surface-base", className),
|
|
16
|
+
children: [
|
|
17
|
+
/* @__PURE__ */ jsxs("header", { "data-slot": "indexed-section-header", className: "flex items-stretch border-b-2 border-edge-strong", children: [
|
|
18
|
+
/* @__PURE__ */ jsx(
|
|
19
|
+
"span",
|
|
20
|
+
{
|
|
21
|
+
"data-slot": "indexed-section-index",
|
|
22
|
+
className: "flex min-w-12 items-center justify-center bg-content-primary px-3 font-mono text-lg font-bold text-content-inverse",
|
|
23
|
+
children: index
|
|
24
|
+
}
|
|
25
|
+
),
|
|
26
|
+
/* @__PURE__ */ jsx(
|
|
27
|
+
Heading,
|
|
28
|
+
{
|
|
29
|
+
id: headingId,
|
|
30
|
+
"data-slot": "indexed-section-title",
|
|
31
|
+
className: "m-0 flex flex-1 items-center px-4 py-3 font-mono text-lg font-bold tracking-tight text-content-primary",
|
|
32
|
+
children: title
|
|
33
|
+
}
|
|
34
|
+
),
|
|
35
|
+
actions != null ? /* @__PURE__ */ jsx("div", { "data-slot": "indexed-section-actions", className: "flex items-center gap-2 px-3", children: actions }) : null
|
|
36
|
+
] }),
|
|
37
|
+
/* @__PURE__ */ jsx("div", { "data-slot": "indexed-section-body", className: "min-w-0 p-4 sm:p-6", children })
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
});
|
|
42
|
+
export {
|
|
43
|
+
IndexedSection
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=IndexedSection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/docs/figures/IndexedSection.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport * as React from 'react';\nimport { cn } from '../../../lib/recipe';\n\nexport interface IndexedSectionProps extends Omit<React.HTMLAttributes<HTMLElement>, 'title'> {\n /** Short reference drawn in the solid tab, such as `A`, `B2`, or `01`. */\n index: ReactNode;\n /** Section heading. */\n title: ReactNode;\n /** Heading level for `title`, so the section sits correctly in the page outline. */\n headingLevel?: 2 | 3 | 4;\n /** Controls drawn at the right of the header, such as a comment button. */\n actions?: ReactNode;\n /** Section content. */\n children?: ReactNode;\n /** Additional classes for the root. */\n className?: string;\n}\n\n/**\n * An indexed section container: a solid high-contrast index tab, a heading, an optional actions\n * slot, and a hard-ruled body. Works on its own, inside an article/spec, or within a `DrawingSheet`.\n */\nexport const IndexedSection = React.forwardRef<HTMLElement, IndexedSectionProps>(function IndexedSection(\n { index, title, headingLevel = 3, actions, children, className, ...rest },\n ref,\n) {\n const headingId = React.useId();\n const Heading = `h${headingLevel}` as const;\n return (\n <section\n ref={ref}\n aria-labelledby={headingId}\n {...rest}\n data-slot=\"indexed-section\"\n className={cn('flex min-w-0 flex-col border-2 border-edge-strong bg-surface-base', className)}\n >\n <header data-slot=\"indexed-section-header\" className=\"flex items-stretch border-b-2 border-edge-strong\">\n <span\n data-slot=\"indexed-section-index\"\n className=\"flex min-w-12 items-center justify-center bg-content-primary px-3 font-mono text-lg font-bold text-content-inverse\"\n >\n {index}\n </span>\n <Heading\n id={headingId}\n data-slot=\"indexed-section-title\"\n className=\"m-0 flex flex-1 items-center px-4 py-3 font-mono text-lg font-bold tracking-tight text-content-primary\"\n >\n {title}\n </Heading>\n {actions != null ? (\n <div data-slot=\"indexed-section-actions\" className=\"flex items-center gap-2 px-3\">\n {actions}\n </div>\n ) : null}\n </header>\n <div data-slot=\"indexed-section-body\" className=\"min-w-0 p-4 sm:p-6\">\n {children}\n </div>\n </section>\n );\n});\n"],"mappings":";AACA,YAAY,WAAW;AACvB,SAAS,UAAU;AAmCb,SACE,KADF;AAdC,IAAM,iBAAuB,iBAA6C,SAASA,gBACxF,EAAE,OAAO,OAAO,eAAe,GAAG,SAAS,UAAU,WAAW,GAAG,KAAK,GACxE,KACA;AACA,QAAM,YAAkB,YAAM;AAC9B,QAAM,UAAU,IAAI,YAAY;AAChC,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,mBAAiB;AAAA,MAChB,GAAG;AAAA,MACJ,aAAU;AAAA,MACV,WAAW,GAAG,qEAAqE,SAAS;AAAA,MAE5F;AAAA,6BAAC,YAAO,aAAU,0BAAyB,WAAU,oDACnD;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,aAAU;AAAA,cACV,WAAU;AAAA,cAET;AAAA;AAAA,UACH;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,IAAI;AAAA,cACJ,aAAU;AAAA,cACV,WAAU;AAAA,cAET;AAAA;AAAA,UACH;AAAA,UACC,WAAW,OACV,oBAAC,SAAI,aAAU,2BAA0B,WAAU,gCAChD,mBACH,IACE;AAAA,WACN;AAAA,QACA,oBAAC,SAAI,aAAU,wBAAuB,WAAU,sBAC7C,UACH;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;","names":["IndexedSection"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// src/components/docs/figures/MetricStrip.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../../../lib/recipe.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
var TONE = {
|
|
6
|
+
neutral: "text-content-primary",
|
|
7
|
+
success: "text-intent-success",
|
|
8
|
+
warning: "text-intent-warning",
|
|
9
|
+
danger: "text-intent-danger"
|
|
10
|
+
};
|
|
11
|
+
var MetricStrip = React.forwardRef(function MetricStrip2({ label = "Metrics", items, className, ...rest }, ref) {
|
|
12
|
+
return /* @__PURE__ */ jsxs("div", { "data-slot": "metric-strip", ref, role: "group", "aria-label": label, ...rest, className: cn(className), children: [
|
|
13
|
+
/* @__PURE__ */ jsx("dl", { className: "m-0 grid grid-cols-2 sm:grid-flow-col sm:auto-cols-fr sm:grid-cols-none", children: items.map((m, i) => /* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col-reverse gap-1 border-b border-edge-subtle p-3 odd:border-r sm:border-r last:border-r-0", children: [
|
|
14
|
+
/* @__PURE__ */ jsx("dt", { className: "font-mono text-[0.65rem] font-bold uppercase tracking-[0.1em] text-content-muted", children: m.label }),
|
|
15
|
+
/* @__PURE__ */ jsx("dd", { className: cn("m-0 font-display text-xl font-extrabold tabular-nums", TONE[m.tone ?? "neutral"]), children: m.value })
|
|
16
|
+
] }, `${m.label}-${i}`)) }),
|
|
17
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: items.length === 0 ? "No metrics." : `${items.length} metric${items.length === 1 ? "" : "s"}.` })
|
|
18
|
+
] });
|
|
19
|
+
});
|
|
20
|
+
export {
|
|
21
|
+
MetricStrip
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=MetricStrip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/docs/figures/MetricStrip.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../../lib/recipe';\n\nexport type MetricTone = 'neutral' | 'success' | 'warning' | 'danger';\n\nexport interface Metric {\n /** The figure itself, already formatted, e.g. `5.5:1` or `+8.4%`. */\n value: string;\n /** What the figure counts, in a few words. */\n label: string;\n /** Colours the value by meaning. Defaults to `neutral`. */\n tone?: MetricTone;\n}\n\nexport interface MetricStripProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Accessible name for the strip. */\n label?: string;\n /** Two to five metrics, left to right. */\n items: readonly Metric[];\n /** Additional classes for the strip. */\n className?: string;\n}\n\nconst TONE: Record<MetricTone, string> = {\n neutral: 'text-content-primary',\n success: 'text-intent-success',\n warning: 'text-intent-warning',\n danger: 'text-intent-danger',\n};\n\n/** A row of headline figures, each with a short label, read before the detail. */\nexport const MetricStrip = React.forwardRef<HTMLDivElement, MetricStripProps>(function MetricStrip(\n { label = 'Metrics', items, className, ...rest },\n ref,\n) {\n return (\n <div data-slot=\"metric-strip\" ref={ref} role=\"group\" aria-label={label} {...rest} className={cn(className)}>\n <dl className=\"m-0 grid grid-cols-2 sm:grid-flow-col sm:auto-cols-fr sm:grid-cols-none\">\n {items.map((m, i) => (\n <div key={`${m.label}-${i}`} className=\"flex min-w-0 flex-col-reverse gap-1 border-b border-edge-subtle p-3 odd:border-r sm:border-r last:border-r-0\">\n <dt className=\"font-mono text-[0.65rem] font-bold uppercase tracking-[0.1em] text-content-muted\">{m.label}</dt>\n <dd className={cn('m-0 font-display text-xl font-extrabold tabular-nums', TONE[m.tone ?? 'neutral'])}>{m.value}</dd>\n </div>\n ))}\n </dl>\n <span className=\"sr-only\">{items.length === 0 ? 'No metrics.' : `${items.length} metric${items.length === 1 ? '' : 's'}.`}</span>\n </div>\n );\n});\n"],"mappings":";AAAA,YAAY,WAAW;AACvB,SAAS,UAAU;AAsCT,SACE,KADF;AAhBV,IAAM,OAAmC;AAAA,EACvC,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,QAAQ;AACV;AAGO,IAAM,cAAoB,iBAA6C,SAASA,aACrF,EAAE,QAAQ,WAAW,OAAO,WAAW,GAAG,KAAK,GAC/C,KACA;AACA,SACE,qBAAC,SAAI,aAAU,gBAAe,KAAU,MAAK,SAAQ,cAAY,OAAQ,GAAG,MAAM,WAAW,GAAG,SAAS,GACvG;AAAA,wBAAC,QAAG,WAAU,2EACX,gBAAM,IAAI,CAAC,GAAG,MACb,qBAAC,SAA4B,WAAU,gHACrC;AAAA,0BAAC,QAAG,WAAU,oFAAoF,YAAE,OAAM;AAAA,MAC1G,oBAAC,QAAG,WAAW,GAAG,wDAAwD,KAAK,EAAE,QAAQ,SAAS,CAAC,GAAI,YAAE,OAAM;AAAA,SAFvG,GAAG,EAAE,KAAK,IAAI,CAAC,EAGzB,CACD,GACH;AAAA,IACA,oBAAC,UAAK,WAAU,WAAW,gBAAM,WAAW,IAAI,gBAAgB,GAAG,MAAM,MAAM,UAAU,MAAM,WAAW,IAAI,KAAK,GAAG,KAAI;AAAA,KAC5H;AAEJ,CAAC;","names":["MetricStrip"]}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// src/components/docs/figures/Steps.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import {
|
|
4
|
+
childItems,
|
|
5
|
+
defineAsciiItem,
|
|
6
|
+
AsciiFrameBody,
|
|
7
|
+
AsciiFrameProse,
|
|
8
|
+
hasHost,
|
|
9
|
+
itemText,
|
|
10
|
+
listItems,
|
|
11
|
+
paragraphsOf,
|
|
12
|
+
splitDash,
|
|
13
|
+
textOf
|
|
14
|
+
} from "./FigureFrame.js";
|
|
15
|
+
import { cn } from "../../../lib/recipe.js";
|
|
16
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
17
|
+
var Step = defineAsciiItem("Step");
|
|
18
|
+
function stepsOf(children) {
|
|
19
|
+
const listed = listItems(children);
|
|
20
|
+
if (listed.length === 0) return childItems(children, Step);
|
|
21
|
+
return listed.map((item) => {
|
|
22
|
+
const content = item.props.children;
|
|
23
|
+
const paras = paragraphsOf(content);
|
|
24
|
+
const title = paras.length > 0 ? textOf((paras[0]?.props).children) : splitDash(itemText(item)).label;
|
|
25
|
+
const body = paras.length > 1 ? paras.slice(1) : paras.length === 0 ? splitDash(itemText(item)).rest || void 0 : void 0;
|
|
26
|
+
const now = hasHost(content, ["strong", "b"]);
|
|
27
|
+
const next = !now && hasHost(content, ["em", "i"]);
|
|
28
|
+
return { title, children: body, state: now ? "now" : next ? "next" : "done" };
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
var Steps = React.forwardRef(function Steps2({ label = "Steps", children, className, ...rest }, ref) {
|
|
32
|
+
const steps = stepsOf(children);
|
|
33
|
+
const digits = String(steps.length).length;
|
|
34
|
+
return /* @__PURE__ */ jsxs(AsciiFrameBody, { "data-slot": "steps", ref, ...rest, className, children: [
|
|
35
|
+
/* @__PURE__ */ jsx("ol", { className: "flex flex-col", "aria-label": `${label} procedure`, children: steps.map((step, index) => {
|
|
36
|
+
const state = step.state ?? "done";
|
|
37
|
+
const last = index === steps.length - 1;
|
|
38
|
+
const number = String(index + 1).padStart(Math.max(2, digits), "0");
|
|
39
|
+
const titleClass = state === "now" ? "text-accent-primary" : state === "next" ? "text-content-muted" : "text-content-primary";
|
|
40
|
+
return /* @__PURE__ */ jsxs("li", { className: "flex flex-col", children: [
|
|
41
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[2.5rem_minmax(0,1fr)] items-baseline gap-x-3", children: [
|
|
42
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("select-none text-center tabular-nums", titleClass), children: number }),
|
|
43
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-2", children: [
|
|
44
|
+
step.title ? /* @__PURE__ */ jsx("p", { className: cn("text-pretty", titleClass), children: step.title }) : null,
|
|
45
|
+
step.children ? /* @__PURE__ */ jsx(AsciiFrameProse, { className: state === "next" ? "text-content-muted" : "text-content-secondary", children: step.children }) : null
|
|
46
|
+
] })
|
|
47
|
+
] }),
|
|
48
|
+
last ? null : /* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: "grid grid-cols-[2.5rem_minmax(0,1fr)] gap-x-3 py-2", children: /* @__PURE__ */ jsx("span", { className: "select-none text-center text-content-muted", children: "\u2502" }) })
|
|
49
|
+
] }, `${index}-${step.title ?? ""}`);
|
|
50
|
+
}) }),
|
|
51
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: steps.length === 0 ? "Empty procedure." : `${steps.length} step${steps.length === 1 ? "" : "s"}.` })
|
|
52
|
+
] });
|
|
53
|
+
});
|
|
54
|
+
export {
|
|
55
|
+
Step,
|
|
56
|
+
Steps
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=Steps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/docs/figures/Steps.tsx"],"sourcesContent":["/**\n * Adapted from mdxcn by Keshav Bagaade, MIT licensed.\n * Source: https://github.com/keshav-exe/mdxcn/blob/2928126ba146ebbae9c2351deca27d27bb40e744/registry/default/steps/steps.tsx\n * The local port removes motion and graph variables while preserving the\n * numbered Markdown procedure and `<Step>` child API.\n */\n\nimport type { ReactNode } from 'react';\nimport * as React from 'react';\nimport {\n childItems,\n defineAsciiItem,\n AsciiFrameBody,\n AsciiFrameProse,\n hasHost,\n itemText,\n listItems,\n paragraphsOf,\n splitDash,\n textOf,\n} from './FigureFrame';\nimport { cn } from '../../../lib/recipe';\n\nexport type StepState = 'done' | 'now' | 'next';\n\nexport interface StepProps {\n /** One-line title drawn beside the number. */\n title?: string;\n /** `now` uses the primary accent, `next` recedes, and `done` stays plain. */\n state?: StepState;\n /** Markdown body for the step. */\n children?: ReactNode;\n}\n\nexport interface StepsProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Accessible name; the enclosing FigureFrame owns the caption. */\n label?: string;\n /** Ordered Markdown list or `<Step>` content. */\n children?: ReactNode;\n /** Additional classes for the procedure. */\n className?: string;\n}\n\n/** MDX-only step item, for example `<Step title=\"Install\">Run the CLI.</Step>`. */\nexport const Step = defineAsciiItem<StepProps>('Step');\n\nfunction stepsOf(children: ReactNode): StepProps[] {\n const listed = listItems(children);\n if (listed.length === 0) return childItems(children, Step);\n return listed.map((item) => {\n const content = (item.props as { children?: ReactNode }).children;\n const paras = paragraphsOf(content);\n const title = paras.length > 0 ? textOf((paras[0]?.props as { children?: ReactNode }).children) : splitDash(itemText(item)).label;\n const body = paras.length > 1 ? paras.slice(1) : paras.length === 0 ? splitDash(itemText(item)).rest || undefined : undefined;\n const now = hasHost(content, ['strong', 'b']);\n const next = !now && hasHost(content, ['em', 'i']);\n return { title, children: body, state: (now ? 'now' : next ? 'next' : 'done') as StepState };\n });\n}\n\n/** Renders a numbered procedure with current and upcoming states preserved in text. */\nexport const Steps = React.forwardRef<HTMLDivElement, StepsProps>(function Steps({ label = 'Steps', children, className, ...rest }, ref) {\n const steps = stepsOf(children);\n const digits = String(steps.length).length;\n return (\n <AsciiFrameBody data-slot=\"steps\" ref={ref} {...rest} className={className}>\n <ol className=\"flex flex-col\" aria-label={`${label} procedure`}>\n {steps.map((step, index) => {\n const state = step.state ?? 'done';\n const last = index === steps.length - 1;\n const number = String(index + 1).padStart(Math.max(2, digits), '0');\n const titleClass = state === 'now' ? 'text-accent-primary' : state === 'next' ? 'text-content-muted' : 'text-content-primary';\n return <li className=\"flex flex-col\" key={`${index}-${step.title ?? ''}`}>\n <div className=\"grid grid-cols-[2.5rem_minmax(0,1fr)] items-baseline gap-x-3\">\n <span aria-hidden=\"true\" className={cn('select-none text-center tabular-nums', titleClass)}>{number}</span>\n <div className=\"flex min-w-0 flex-col gap-2\">\n {step.title ? <p className={cn('text-pretty', titleClass)}>{step.title}</p> : null}\n {step.children ? <AsciiFrameProse className={state === 'next' ? 'text-content-muted' : 'text-content-secondary'}>{step.children}</AsciiFrameProse> : null}\n </div>\n </div>\n {last ? null : <div aria-hidden=\"true\" className=\"grid grid-cols-[2.5rem_minmax(0,1fr)] gap-x-3 py-2\"><span className=\"select-none text-center text-content-muted\">│</span></div>}\n </li>;\n })}\n </ol>\n <span className=\"sr-only\">{steps.length === 0 ? 'Empty procedure.' : `${steps.length} step${steps.length === 1 ? '' : 's'}.`}</span>\n </AsciiFrameBody>\n );\n});\n"],"mappings":";AAQA,YAAY,WAAW;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,UAAU;AAqDH,cACA,YADA;AA9BT,IAAM,OAAO,gBAA2B,MAAM;AAErD,SAAS,QAAQ,UAAkC;AACjD,QAAM,SAAS,UAAU,QAAQ;AACjC,MAAI,OAAO,WAAW,EAAG,QAAO,WAAW,UAAU,IAAI;AACzD,SAAO,OAAO,IAAI,CAAC,SAAS;AAC1B,UAAM,UAAW,KAAK,MAAmC;AACzD,UAAM,QAAQ,aAAa,OAAO;AAClC,UAAM,QAAQ,MAAM,SAAS,IAAI,QAAQ,MAAM,CAAC,GAAG,OAAmC,QAAQ,IAAI,UAAU,SAAS,IAAI,CAAC,EAAE;AAC5H,UAAM,OAAO,MAAM,SAAS,IAAI,MAAM,MAAM,CAAC,IAAI,MAAM,WAAW,IAAI,UAAU,SAAS,IAAI,CAAC,EAAE,QAAQ,SAAY;AACpH,UAAM,MAAM,QAAQ,SAAS,CAAC,UAAU,GAAG,CAAC;AAC5C,UAAM,OAAO,CAAC,OAAO,QAAQ,SAAS,CAAC,MAAM,GAAG,CAAC;AACjD,WAAO,EAAE,OAAO,UAAU,MAAM,OAAQ,MAAM,QAAQ,OAAO,SAAS,OAAqB;AAAA,EAC7F,CAAC;AACH;AAGO,IAAM,QAAc,iBAAuC,SAASA,OAAM,EAAE,QAAQ,SAAS,UAAU,WAAW,GAAG,KAAK,GAAG,KAAK;AACvI,QAAM,QAAQ,QAAQ,QAAQ;AAC9B,QAAM,SAAS,OAAO,MAAM,MAAM,EAAE;AACpC,SACI,qBAAC,kBAAe,aAAU,SAAQ,KAAW,GAAG,MAAM,WACpD;AAAA,wBAAC,QAAG,WAAU,iBAAgB,cAAY,GAAG,KAAK,cAC/C,gBAAM,IAAI,CAAC,MAAM,UAAU;AAC1B,YAAM,QAAQ,KAAK,SAAS;AAC5B,YAAM,OAAO,UAAU,MAAM,SAAS;AACtC,YAAM,SAAS,OAAO,QAAQ,CAAC,EAAE,SAAS,KAAK,IAAI,GAAG,MAAM,GAAG,GAAG;AAClE,YAAM,aAAa,UAAU,QAAQ,wBAAwB,UAAU,SAAS,uBAAuB;AACvG,aAAO,qBAAC,QAAG,WAAU,iBACnB;AAAA,6BAAC,SAAI,WAAU,gEACb;AAAA,8BAAC,UAAK,eAAY,QAAO,WAAW,GAAG,wCAAwC,UAAU,GAAI,kBAAO;AAAA,UACpG,qBAAC,SAAI,WAAU,+BACZ;AAAA,iBAAK,QAAQ,oBAAC,OAAE,WAAW,GAAG,eAAe,UAAU,GAAI,eAAK,OAAM,IAAO;AAAA,YAC7E,KAAK,WAAW,oBAAC,mBAAgB,WAAW,UAAU,SAAS,uBAAuB,0BAA2B,eAAK,UAAS,IAAqB;AAAA,aACvJ;AAAA,WACF;AAAA,QACC,OAAO,OAAO,oBAAC,SAAI,eAAY,QAAO,WAAU,sDAAqD,8BAAC,UAAK,WAAU,8CAA6C,oBAAC,GAAO;AAAA,WARnI,GAAG,KAAK,IAAI,KAAK,SAAS,EAAE,EAStE;AAAA,IACF,CAAC,GACH;AAAA,IACA,oBAAC,UAAK,WAAU,WAAW,gBAAM,WAAW,IAAI,qBAAqB,GAAG,MAAM,MAAM,QAAQ,MAAM,WAAW,IAAI,KAAK,GAAG,KAAI;AAAA,KAC/H;AAEN,CAAC;","names":["Steps"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// src/components/docs/figures/SwatchCompare.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../../../lib/recipe.js";
|
|
4
|
+
import { Swatch } from "../../Swatch.js";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
var VERDICT = {
|
|
7
|
+
neutral: "border-edge-default text-content-secondary",
|
|
8
|
+
success: "border-intent-success text-intent-success",
|
|
9
|
+
warning: "border-intent-warning text-intent-warning",
|
|
10
|
+
info: "border-intent-info text-intent-info"
|
|
11
|
+
};
|
|
12
|
+
var SwatchCompare = React.forwardRef(function SwatchCompare2({ label = "Colour comparison", level, columns, rows, className, ...rest }, ref) {
|
|
13
|
+
return /* @__PURE__ */ jsxs("div", { "data-slot": "swatch-compare", ref, role: "region", tabIndex: 0, "aria-label": `${label} scroll area`, ...rest, "data-theme": level, className: cn("min-w-0 overflow-x-auto bg-surface-sunken p-3", className), children: [
|
|
14
|
+
/* @__PURE__ */ jsxs("table", { "aria-label": label, className: "w-full border-collapse font-mono text-xs", children: [
|
|
15
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
16
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: "sr-only", children: "State" }),
|
|
17
|
+
columns.map((c) => /* @__PURE__ */ jsx("th", { scope: "col", className: "px-1 pb-2 text-center font-bold uppercase tracking-[0.08em] text-content-muted", children: c.name }, c.name))
|
|
18
|
+
] }) }),
|
|
19
|
+
/* @__PURE__ */ jsxs("tbody", { children: [
|
|
20
|
+
rows.map((row, ri) => /* @__PURE__ */ jsxs("tr", { children: [
|
|
21
|
+
/* @__PURE__ */ jsx("th", { scope: "row", className: "pr-3 text-left font-bold uppercase tracking-[0.08em] text-content-muted", children: row.label }),
|
|
22
|
+
columns.map((c, i) => {
|
|
23
|
+
const value = row.values[i] ?? null;
|
|
24
|
+
return /* @__PURE__ */ jsx("td", { className: "px-1 py-1 align-top", children: value === null ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
25
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "block h-10 w-full border-2 border-dashed border-edge-subtle" }),
|
|
26
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: `${row.label}: no ${c.name}` })
|
|
27
|
+
] }) : /* @__PURE__ */ jsx(Swatch, { value, name: value, size: "md", className: "flex-col items-start gap-1 [&>[data-slot=swatch-well]]:w-full" }) }, c.name);
|
|
28
|
+
})
|
|
29
|
+
] }, `${row.label}-${ri}`)),
|
|
30
|
+
columns.some((c) => c.verdict) && /* @__PURE__ */ jsxs("tr", { children: [
|
|
31
|
+
/* @__PURE__ */ jsx("th", { scope: "row", className: "sr-only", children: "Verdict" }),
|
|
32
|
+
columns.map((c) => /* @__PURE__ */ jsx("td", { className: "px-1 pt-2 text-center", children: c.verdict && /* @__PURE__ */ jsx("span", { className: cn("inline-block border-2 px-1 py-0.5 font-bold uppercase", VERDICT[c.tone ?? "neutral"]), children: c.verdict }) }, c.name))
|
|
33
|
+
] })
|
|
34
|
+
] })
|
|
35
|
+
] }),
|
|
36
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: rows.length === 0 || columns.length === 0 ? "No colours." : `${rows.length} row${rows.length === 1 ? "" : "s"} of ${columns.length} colour${columns.length === 1 ? "" : "s"}.` })
|
|
37
|
+
] });
|
|
38
|
+
});
|
|
39
|
+
export {
|
|
40
|
+
SwatchCompare
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=SwatchCompare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/docs/figures/SwatchCompare.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../../lib/recipe';\nimport type { ThemeLevel } from '../../../theme/levels';\nimport { Swatch } from '../../Swatch';\n\nexport type VerdictTone = 'neutral' | 'success' | 'warning' | 'info';\n\nexport interface SwatchColumn {\n /** Column heading, usually a hue or a role. */\n name: string;\n /** Short verdict under the column, e.g. `kept`, `lifted`, `new`. */\n verdict?: string;\n /** How the verdict reads. Defaults to `neutral`. */\n tone?: VerdictTone;\n}\n\nexport interface SwatchRow {\n /** Row label, e.g. `Today` or `Now`. */\n label: string;\n /** One CSS colour per column, or `null` where no value exists. */\n values: readonly (string | null)[];\n}\n\nexport interface SwatchCompareProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Accessible name for the comparison table. */\n label?: string;\n /** Paint the swatches on this Level's ground. Omit to use the page's. */\n level?: ThemeLevel;\n /** The columns, left to right. */\n columns: readonly SwatchColumn[];\n /** One row per state being compared, top to bottom. */\n rows: readonly SwatchRow[];\n /** Additional classes for the outer frame. */\n className?: string;\n}\n\nconst VERDICT: Record<VerdictTone, string> = {\n neutral: 'border-edge-default text-content-secondary',\n success: 'border-intent-success text-intent-success',\n warning: 'border-intent-warning text-intent-warning',\n info: 'border-intent-info text-intent-info',\n};\n\n/** Rows of colour across named columns, so a reader compares a palette before and after a change. */\nexport const SwatchCompare = React.forwardRef<HTMLDivElement, SwatchCompareProps>(function SwatchCompare(\n { label = 'Colour comparison', level, columns, rows, className, ...rest },\n ref,\n) {\n // Focusable and named because it scrolls on a narrow screen; `Table` says why.\n return (\n <div data-slot=\"swatch-compare\" ref={ref} role=\"region\" tabIndex={0} aria-label={`${label} scroll area`} {...rest} data-theme={level} className={cn('min-w-0 overflow-x-auto bg-surface-sunken p-3', className)}>\n <table aria-label={label} className=\"w-full border-collapse font-mono text-xs\">\n <thead>\n <tr>\n <th scope=\"col\" className=\"sr-only\">State</th>\n {columns.map((c) => (\n <th key={c.name} scope=\"col\" className=\"px-1 pb-2 text-center font-bold uppercase tracking-[0.08em] text-content-muted\">\n {c.name}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map((row, ri) => (\n <tr key={`${row.label}-${ri}`}>\n <th scope=\"row\" className=\"pr-3 text-left font-bold uppercase tracking-[0.08em] text-content-muted\">{row.label}</th>\n {columns.map((c, i) => {\n const value = row.values[i] ?? null;\n return (\n <td key={c.name} className=\"px-1 py-1 align-top\">\n {value === null ? (\n <>\n <span aria-hidden=\"true\" className=\"block h-10 w-full border-2 border-dashed border-edge-subtle\" />\n <span className=\"sr-only\">{`${row.label}: no ${c.name}`}</span>\n </>\n ) : (\n <Swatch value={value} name={value} size=\"md\" className=\"flex-col items-start gap-1 [&>[data-slot=swatch-well]]:w-full\" />\n )}\n </td>\n );\n })}\n </tr>\n ))}\n {columns.some((c) => c.verdict) && (\n <tr>\n <th scope=\"row\" className=\"sr-only\">Verdict</th>\n {columns.map((c) => (\n <td key={c.name} className=\"px-1 pt-2 text-center\">\n {c.verdict && (\n <span className={cn('inline-block border-2 px-1 py-0.5 font-bold uppercase', VERDICT[c.tone ?? 'neutral'])}>{c.verdict}</span>\n )}\n </td>\n ))}\n </tr>\n )}\n </tbody>\n </table>\n <span className=\"sr-only\">{rows.length === 0 || columns.length === 0 ? 'No colours.' : `${rows.length} row${rows.length === 1 ? '' : 's'} of ${columns.length} colour${columns.length === 1 ? '' : 's'}.`}</span>\n </div>\n );\n});\n"],"mappings":";AAAA,YAAY,WAAW;AACvB,SAAS,UAAU;AAEnB,SAAS,cAAc;AAkDb,SAkBY,UAjBV,KADF;AAjBV,IAAM,UAAuC;AAAA,EAC3C,SAAS;AAAA,EACT,SAAS;AAAA,EACT,SAAS;AAAA,EACT,MAAM;AACR;AAGO,IAAM,gBAAsB,iBAA+C,SAASA,eACzF,EAAE,QAAQ,qBAAqB,OAAO,SAAS,MAAM,WAAW,GAAG,KAAK,GACxE,KACA;AAEA,SACE,qBAAC,SAAI,aAAU,kBAAiB,KAAU,MAAK,UAAS,UAAU,GAAG,cAAY,GAAG,KAAK,gBAAiB,GAAG,MAAM,cAAY,OAAO,WAAW,GAAG,iDAAiD,SAAS,GAC5M;AAAA,yBAAC,WAAM,cAAY,OAAO,WAAU,4CAClC;AAAA,0BAAC,WACC,+BAAC,QACC;AAAA,4BAAC,QAAG,OAAM,OAAM,WAAU,WAAU,mBAAK;AAAA,QACxC,QAAQ,IAAI,CAAC,MACZ,oBAAC,QAAgB,OAAM,OAAM,WAAU,kFACpC,YAAE,QADI,EAAE,IAEX,CACD;AAAA,SACH,GACF;AAAA,MACA,qBAAC,WACE;AAAA,aAAK,IAAI,CAAC,KAAK,OACd,qBAAC,QACC;AAAA,8BAAC,QAAG,OAAM,OAAM,WAAU,2EAA2E,cAAI,OAAM;AAAA,UAC9G,QAAQ,IAAI,CAAC,GAAG,MAAM;AACrB,kBAAM,QAAQ,IAAI,OAAO,CAAC,KAAK;AAC/B,mBACE,oBAAC,QAAgB,WAAU,uBACxB,oBAAU,OACT,iCACE;AAAA,kCAAC,UAAK,eAAY,QAAO,WAAU,+DAA8D;AAAA,cACjG,oBAAC,UAAK,WAAU,WAAW,aAAG,IAAI,KAAK,QAAQ,EAAE,IAAI,IAAG;AAAA,eAC1D,IAEA,oBAAC,UAAO,OAAc,MAAM,OAAO,MAAK,MAAK,WAAU,iEAAgE,KAPlH,EAAE,IASX;AAAA,UAEJ,CAAC;AAAA,aAhBM,GAAG,IAAI,KAAK,IAAI,EAAE,EAiB3B,CACD;AAAA,QACA,QAAQ,KAAK,CAAC,MAAM,EAAE,OAAO,KAC5B,qBAAC,QACC;AAAA,8BAAC,QAAG,OAAM,OAAM,WAAU,WAAU,qBAAO;AAAA,UAC1C,QAAQ,IAAI,CAAC,MACZ,oBAAC,QAAgB,WAAU,yBACxB,YAAE,WACD,oBAAC,UAAK,WAAW,GAAG,yDAAyD,QAAQ,EAAE,QAAQ,SAAS,CAAC,GAAI,YAAE,SAAQ,KAFlH,EAAE,IAIX,CACD;AAAA,WACH;AAAA,SAEJ;AAAA,OACF;AAAA,IACA,oBAAC,UAAK,WAAU,WAAW,eAAK,WAAW,KAAK,QAAQ,WAAW,IAAI,gBAAgB,GAAG,KAAK,MAAM,OAAO,KAAK,WAAW,IAAI,KAAK,GAAG,OAAO,QAAQ,MAAM,UAAU,QAAQ,WAAW,IAAI,KAAK,GAAG,KAAI;AAAA,KAC5M;AAEJ,CAAC;","names":["SwatchCompare"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// src/components/docs/figures/TermGrid.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../../../lib/recipe.js";
|
|
4
|
+
import { childItems, defineAsciiItem } from "./FigureFrame.js";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
var Term = defineAsciiItem("Term");
|
|
7
|
+
var TermGrid = React.forwardRef(function TermGrid2({ label = "Terms", terms: termsProp, children, className, ...rest }, ref) {
|
|
8
|
+
const terms = termsProp ?? childItems(children, Term);
|
|
9
|
+
return /* @__PURE__ */ jsxs("div", { "data-slot": "term-grid", ref, role: "group", "aria-label": label, ...rest, className: cn(className), children: [
|
|
10
|
+
/* @__PURE__ */ jsx("dl", { className: "m-0 grid sm:grid-cols-2", children: terms.map((t, i) => /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 border-b border-edge-subtle p-4 sm:odd:border-r", children: [
|
|
11
|
+
/* @__PURE__ */ jsx("dt", { className: "font-display text-sm font-bold text-content-primary", children: t.term }),
|
|
12
|
+
t.children && /* @__PURE__ */ jsx("dd", { className: "m-0 text-sm text-content-secondary [&_p]:m-0", children: t.children }),
|
|
13
|
+
t.scale && /* @__PURE__ */ jsx("dd", { className: "m-0 font-mono text-xs text-content-muted", children: t.scale })
|
|
14
|
+
] }, `${t.term}-${i}`)) }),
|
|
15
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: terms.length === 0 ? "No terms." : `${terms.length} term${terms.length === 1 ? "" : "s"}.` })
|
|
16
|
+
] });
|
|
17
|
+
});
|
|
18
|
+
export {
|
|
19
|
+
Term,
|
|
20
|
+
TermGrid
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=TermGrid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/docs/figures/TermGrid.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../../lib/recipe';\nimport { childItems, defineAsciiItem } from './FigureFrame';\n\nexport interface TermItem {\n /** The word being defined. */\n term: string;\n /** A plain-language scale or example, set in mono under the definition. */\n scale?: string;\n /** The definition, in a sentence. */\n children?: React.ReactNode;\n}\n\n/** MDX-only glossary entry, for example `<Term term=\"Chroma\" scale=\"0 = grey\">How colourful.</Term>`. */\nexport const Term = defineAsciiItem<TermItem>('Term');\n\nexport interface TermGridProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Accessible name for the glossary. */\n label?: string;\n /** Data form. If omitted, the component reads `<Term>` children. */\n terms?: readonly TermItem[];\n /** `<Term>` items. */\n children?: React.ReactNode;\n /** Additional classes for the grid. */\n className?: string;\n}\n\n/** A glossary of the words a page depends on, each with a plain-language scale. */\nexport const TermGrid = React.forwardRef<HTMLDivElement, TermGridProps>(function TermGrid(\n { label = 'Terms', terms: termsProp, children, className, ...rest },\n ref,\n) {\n const terms = termsProp ?? childItems(children, Term);\n return (\n <div data-slot=\"term-grid\" ref={ref} role=\"group\" aria-label={label} {...rest} className={cn(className)}>\n <dl className=\"m-0 grid sm:grid-cols-2\">\n {terms.map((t, i) => (\n <div key={`${t.term}-${i}`} className=\"flex flex-col gap-1 border-b border-edge-subtle p-4 sm:odd:border-r\">\n <dt className=\"font-display text-sm font-bold text-content-primary\">{t.term}</dt>\n {t.children && <dd className=\"m-0 text-sm text-content-secondary [&_p]:m-0\">{t.children}</dd>}\n {t.scale && <dd className=\"m-0 font-mono text-xs text-content-muted\">{t.scale}</dd>}\n </div>\n ))}\n </dl>\n <span className=\"sr-only\">{terms.length === 0 ? 'No terms.' : `${terms.length} term${terms.length === 1 ? '' : 's'}.`}</span>\n </div>\n );\n});\n"],"mappings":";AAAA,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,YAAY,uBAAuB;AAmClC,SACE,KADF;AAvBH,IAAM,OAAO,gBAA0B,MAAM;AAc7C,IAAM,WAAiB,iBAA0C,SAASA,UAC/E,EAAE,QAAQ,SAAS,OAAO,WAAW,UAAU,WAAW,GAAG,KAAK,GAClE,KACA;AACA,QAAM,QAAQ,aAAa,WAAW,UAAU,IAAI;AACpD,SACE,qBAAC,SAAI,aAAU,aAAY,KAAU,MAAK,SAAQ,cAAY,OAAQ,GAAG,MAAM,WAAW,GAAG,SAAS,GACpG;AAAA,wBAAC,QAAG,WAAU,2BACX,gBAAM,IAAI,CAAC,GAAG,MACb,qBAAC,SAA2B,WAAU,uEACpC;AAAA,0BAAC,QAAG,WAAU,uDAAuD,YAAE,MAAK;AAAA,MAC3E,EAAE,YAAY,oBAAC,QAAG,WAAU,gDAAgD,YAAE,UAAS;AAAA,MACvF,EAAE,SAAS,oBAAC,QAAG,WAAU,4CAA4C,YAAE,OAAM;AAAA,SAHtE,GAAG,EAAE,IAAI,IAAI,CAAC,EAIxB,CACD,GACH;AAAA,IACA,oBAAC,UAAK,WAAU,WAAW,gBAAM,WAAW,IAAI,cAAc,GAAG,MAAM,MAAM,QAAQ,MAAM,WAAW,IAAI,KAAK,GAAG,KAAI;AAAA,KACxH;AAEJ,CAAC;","names":["TermGrid"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// src/components/docs/figures/Terminal.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { AsciiFrameBody, textOf } from "./FigureFrame.js";
|
|
4
|
+
import { cn } from "../../../lib/recipe.js";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
function parse(source, prompt) {
|
|
7
|
+
const lines = source.replace(/\r\n?/g, "\n").split("\n");
|
|
8
|
+
while (lines.length > 0 && lines[0]?.trim() === "") lines.shift();
|
|
9
|
+
while (lines.length > 0 && lines[lines.length - 1]?.trim() === "") lines.pop();
|
|
10
|
+
return lines.map((raw) => {
|
|
11
|
+
const text = raw.replace(/\s+$/, "");
|
|
12
|
+
if (text.startsWith(`${prompt} `) || text === prompt) return { kind: "command", text: text.slice(prompt.length).trimStart() };
|
|
13
|
+
if (text.startsWith("#")) return { kind: "comment", text };
|
|
14
|
+
if (/^[✓✔√]/.test(text)) return { kind: "ok", text };
|
|
15
|
+
return { kind: "output", text };
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
var Terminal = React.forwardRef(function Terminal2({ label = "Shell", prompt = "$", children, className, ...rest }, ref) {
|
|
19
|
+
const lines = parse(textOf(children), prompt);
|
|
20
|
+
return /* @__PURE__ */ jsxs(AsciiFrameBody, { "data-slot": "terminal", ref, ...rest, className: cn("overflow-x-auto", className), children: [
|
|
21
|
+
/* @__PURE__ */ jsx("pre", { className: "m-0 flex min-w-max flex-col gap-0.5 whitespace-pre leading-relaxed", role: "region", tabIndex: 0, "aria-label": `${label} terminal output`, children: lines.map((line, index) => /* @__PURE__ */ jsxs("code", { className: cn("grid grid-cols-[1.25rem_minmax(0,1fr)] gap-x-2", line.kind === "command" ? "text-content-primary" : line.kind === "ok" ? "text-accent-primary" : "text-content-muted"), children: [
|
|
22
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("select-none text-center", line.kind === "command" ? "text-accent-primary" : "text-transparent"), children: line.kind === "command" ? prompt : " " }),
|
|
23
|
+
/* @__PURE__ */ jsx("span", { children: line.text || " " })
|
|
24
|
+
] }, `${index}-${line.text}`)) }),
|
|
25
|
+
/* @__PURE__ */ jsxs("span", { className: "sr-only", children: [
|
|
26
|
+
"Terminal with ",
|
|
27
|
+
lines.length,
|
|
28
|
+
" line",
|
|
29
|
+
lines.length === 1 ? "" : "s",
|
|
30
|
+
"."
|
|
31
|
+
] })
|
|
32
|
+
] });
|
|
33
|
+
});
|
|
34
|
+
export {
|
|
35
|
+
Terminal
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=Terminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/docs/figures/Terminal.tsx"],"sourcesContent":["/**\n * Adapted from mdxcn by Keshav Bagaade, MIT licensed.\n * Source: https://github.com/keshav-exe/mdxcn/blob/2928126ba146ebbae9c2351deca27d27bb40e744/registry/default/terminal/terminal.tsx\n * The local port replaces motion and graph variables with deterministic\n * rendering, semantic tokens, and a keyboard-focusable scrolling surface.\n */\n\nimport type { ReactNode } from 'react';\nimport * as React from 'react';\nimport { AsciiFrameBody, textOf } from './FigureFrame';\nimport { cn } from '../../../lib/recipe';\n\nexport interface TerminalProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Accessible name; the enclosing FigureFrame owns the caption. */\n label?: string;\n /** Prompt glyph marking a command line. Defaults to `$`. */\n prompt?: string;\n /** Plain lines or a fenced code block. `$ cmd` is a command and `# …` a comment. */\n children?: ReactNode;\n /** Additional classes for this terminal. */\n className?: string;\n}\n\ntype TerminalLine = { kind: 'command' | 'comment' | 'ok' | 'output'; text: string };\n\nfunction parse(source: string, prompt: string): TerminalLine[] {\n const lines = source.replace(/\\r\\n?/g, '\\n').split('\\n');\n while (lines.length > 0 && lines[0]?.trim() === '') lines.shift();\n while (lines.length > 0 && lines[lines.length - 1]?.trim() === '') lines.pop();\n return lines.map((raw) => {\n const text = raw.replace(/\\s+$/, '');\n if (text.startsWith(`${prompt} `) || text === prompt) return { kind: 'command', text: text.slice(prompt.length).trimStart() };\n if (text.startsWith('#')) return { kind: 'comment', text };\n if (/^[✓✔√]/.test(text)) return { kind: 'ok', text };\n return { kind: 'output', text };\n });\n}\n\n/** Renders a shell session with command, comment, success, and output line semantics. */\nexport const Terminal = React.forwardRef<HTMLDivElement, TerminalProps>(function Terminal({ label = 'Shell', prompt = '$', children, className, ...rest }, ref) {\n const lines = parse(textOf(children), prompt);\n return (\n <AsciiFrameBody data-slot=\"terminal\" ref={ref} {...rest} className={cn('overflow-x-auto', className)}>\n <pre className=\"m-0 flex min-w-max flex-col gap-0.5 whitespace-pre leading-relaxed\" role=\"region\" tabIndex={0} aria-label={`${label} terminal output`}>\n {lines.map((line, index) => <code className={cn('grid grid-cols-[1.25rem_minmax(0,1fr)] gap-x-2', line.kind === 'command' ? 'text-content-primary' : line.kind === 'ok' ? 'text-accent-primary' : 'text-content-muted')} key={`${index}-${line.text}`}>\n <span aria-hidden=\"true\" className={cn('select-none text-center', line.kind === 'command' ? 'text-accent-primary' : 'text-transparent')}>{line.kind === 'command' ? prompt : ' '}</span>\n <span>{line.text || ' '}</span>\n </code>)}\n </pre>\n <span className=\"sr-only\">Terminal with {lines.length} line{lines.length === 1 ? '' : 's'}.</span>\n </AsciiFrameBody>\n );\n});\n"],"mappings":";AAQA,YAAY,WAAW;AACvB,SAAS,gBAAgB,cAAc;AACvC,SAAS,UAAU;AAkCmB,SAC1B,KAD0B;AAnBtC,SAAS,MAAM,QAAgB,QAAgC;AAC7D,QAAM,QAAQ,OAAO,QAAQ,UAAU,IAAI,EAAE,MAAM,IAAI;AACvD,SAAO,MAAM,SAAS,KAAK,MAAM,CAAC,GAAG,KAAK,MAAM,GAAI,OAAM,MAAM;AAChE,SAAO,MAAM,SAAS,KAAK,MAAM,MAAM,SAAS,CAAC,GAAG,KAAK,MAAM,GAAI,OAAM,IAAI;AAC7E,SAAO,MAAM,IAAI,CAAC,QAAQ;AACxB,UAAM,OAAO,IAAI,QAAQ,QAAQ,EAAE;AACnC,QAAI,KAAK,WAAW,GAAG,MAAM,GAAG,KAAK,SAAS,OAAQ,QAAO,EAAE,MAAM,WAAW,MAAM,KAAK,MAAM,OAAO,MAAM,EAAE,UAAU,EAAE;AAC5H,QAAI,KAAK,WAAW,GAAG,EAAG,QAAO,EAAE,MAAM,WAAW,KAAK;AACzD,QAAI,SAAS,KAAK,IAAI,EAAG,QAAO,EAAE,MAAM,MAAM,KAAK;AACnD,WAAO,EAAE,MAAM,UAAU,KAAK;AAAA,EAChC,CAAC;AACH;AAGO,IAAM,WAAiB,iBAA0C,SAASA,UAAS,EAAE,QAAQ,SAAS,SAAS,KAAK,UAAU,WAAW,GAAG,KAAK,GAAG,KAAK;AAC9J,QAAM,QAAQ,MAAM,OAAO,QAAQ,GAAG,MAAM;AAC5C,SACI,qBAAC,kBAAe,aAAU,YAAW,KAAW,GAAG,MAAM,WAAW,GAAG,mBAAmB,SAAS,GACjG;AAAA,wBAAC,SAAI,WAAU,sEAAqE,MAAK,UAAS,UAAU,GAAG,cAAY,GAAG,KAAK,oBAChI,gBAAM,IAAI,CAAC,MAAM,UAAU,qBAAC,UAAK,WAAW,GAAG,kDAAkD,KAAK,SAAS,YAAY,yBAAyB,KAAK,SAAS,OAAO,wBAAwB,oBAAoB,GACpN;AAAA,0BAAC,UAAK,eAAY,QAAO,WAAW,GAAG,2BAA2B,KAAK,SAAS,YAAY,wBAAwB,kBAAkB,GAAI,eAAK,SAAS,YAAY,SAAS,KAAI;AAAA,MACjL,oBAAC,UAAM,eAAK,QAAQ,KAAI;AAAA,SAFoM,GAAG,KAAK,IAAI,KAAK,IAAI,EAGnP,CAAO,GACT;AAAA,IACA,qBAAC,UAAK,WAAU,WAAU;AAAA;AAAA,MAAe,MAAM;AAAA,MAAO;AAAA,MAAM,MAAM,WAAW,IAAI,KAAK;AAAA,MAAI;AAAA,OAAC;AAAA,KAC7F;AAEN,CAAC;","names":["Terminal"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// src/components/docs/figures/Timeline.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import {
|
|
4
|
+
childItems,
|
|
5
|
+
defineAsciiItem,
|
|
6
|
+
AsciiFrameBody,
|
|
7
|
+
hasHost,
|
|
8
|
+
itemText,
|
|
9
|
+
listItems,
|
|
10
|
+
splitLabel,
|
|
11
|
+
textOf
|
|
12
|
+
} from "./FigureFrame.js";
|
|
13
|
+
import { cn } from "../../../lib/recipe.js";
|
|
14
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
15
|
+
var Event = defineAsciiItem("Event");
|
|
16
|
+
var MARK = { done: "\u25CF", now: "\u25CF", next: "\u25CB" };
|
|
17
|
+
function stateClass(palette, state) {
|
|
18
|
+
if (state === "now") return "text-accent-primary";
|
|
19
|
+
if (state === "next") return palette === "multi" ? "text-accent-secondary" : "text-content-muted";
|
|
20
|
+
return "text-content-primary";
|
|
21
|
+
}
|
|
22
|
+
function eventsOf(children) {
|
|
23
|
+
const listed = listItems(children).map((item) => {
|
|
24
|
+
const text = itemText(item);
|
|
25
|
+
const time = text.match(/^(\d{1,2}:\d{2})\s*:\s*(.*)$/);
|
|
26
|
+
const { label: date, rest } = time ? { label: time[1] ?? "", rest: time[2] ?? "" } : splitLabel(text);
|
|
27
|
+
const content = item.props.children;
|
|
28
|
+
const now = hasHost(content, ["strong", "b"]);
|
|
29
|
+
const next = !now && hasHost(content, ["em", "i"]);
|
|
30
|
+
return { date, label: rest || date, state: now ? "now" : next ? "next" : "done" };
|
|
31
|
+
});
|
|
32
|
+
if (listed.length > 0) return listed;
|
|
33
|
+
return childItems(children, Event).map((entry) => ({
|
|
34
|
+
...entry,
|
|
35
|
+
label: entry.label ?? textOf(entry.children)
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
var Timeline = React.forwardRef(function Timeline2({ label = "Timeline", events: eventsProp, children, palette, className, ...rest }, ref) {
|
|
39
|
+
const events = eventsProp ?? eventsOf(children);
|
|
40
|
+
return /* @__PURE__ */ jsxs(AsciiFrameBody, { "data-slot": "timeline", ref, ...rest, className, children: [
|
|
41
|
+
/* @__PURE__ */ jsx("ol", { className: "flex flex-col", "aria-label": label, children: events.map((event, index) => {
|
|
42
|
+
const state = event.state ?? "done";
|
|
43
|
+
const last = index === events.length - 1;
|
|
44
|
+
const label2 = event.label ?? "";
|
|
45
|
+
return /* @__PURE__ */ jsxs("li", { className: "flex flex-col", children: [
|
|
46
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-[1.25rem_7rem_minmax(0,1fr)] items-baseline gap-x-4", "aria-label": `${event.date}: ${label2}`, children: [
|
|
47
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("select-none text-center leading-none", stateClass(palette, state)), children: MARK[state] }),
|
|
48
|
+
/* @__PURE__ */ jsx("span", { className: cn("tabular-nums", state === "next" ? "text-content-muted" : "text-content-primary"), children: event.date }),
|
|
49
|
+
/* @__PURE__ */ jsx("span", { className: stateClass(palette, state), children: label2 })
|
|
50
|
+
] }),
|
|
51
|
+
last ? null : /* @__PURE__ */ jsx("div", { "aria-hidden": "true", className: "grid grid-cols-[1.25rem_7rem_minmax(0,1fr)] gap-x-4 py-1", children: /* @__PURE__ */ jsx("span", { className: "select-none text-center text-content-muted", children: "\u2502" }) })
|
|
52
|
+
] }, `${event.date}-${label2}-${index}`);
|
|
53
|
+
}) }),
|
|
54
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: events.length === 0 ? "Empty timeline." : `${events.length} timeline event${events.length === 1 ? "" : "s"}.` })
|
|
55
|
+
] });
|
|
56
|
+
});
|
|
57
|
+
export {
|
|
58
|
+
Event,
|
|
59
|
+
Timeline
|
|
60
|
+
};
|
|
61
|
+
//# sourceMappingURL=Timeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/docs/figures/Timeline.tsx"],"sourcesContent":["/**\n * Adapted from mdxcn by Keshav Bagaade, MIT licensed.\n * Source: https://github.com/keshav-exe/mdxcn/blob/2928126ba146ebbae9c2351deca27d27bb40e744/registry/default/graph-timeline/graph-timeline.tsx\n * The local port replaces motion and graph variables with deterministic\n * semantic token classes and preserves the Markdown child API.\n */\n\nimport type { ReactNode } from 'react';\nimport * as React from 'react';\nimport {\n childItems,\n defineAsciiItem,\n AsciiFrameBody,\n hasHost,\n itemText,\n listItems,\n splitLabel,\n textOf,\n type FigurePalette,\n} from './FigureFrame';\nimport { cn } from '../../../lib/recipe';\n\nexport type TimelineState = 'done' | 'now' | 'next';\n\nexport interface TimelineEvent {\n /** Date or time label shown in the middle column. */\n date: string;\n /** Falls back to the child text for `<Event date=\"14:02\">p95 crossed</Event>`. */\n label?: string;\n state?: TimelineState;\n}\n\nexport interface TimelineProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Accessible name; the enclosing FigureFrame owns the caption. */\n label?: string;\n /** Data form. If omitted, the component reads Markdown or `<Event>` children. */\n events?: TimelineEvent[];\n /** Markdown list or `<Event>` content used to derive events. */\n children?: ReactNode;\n /** Accent palette used for current and upcoming events. */\n palette?: FigurePalette;\n /** Additional classes for this timeline. */\n className?: string;\n}\n\n/** MDX-only timeline item, for example `<Event date=\"Mar 18\" state=\"now\">Launch</Event>`. */\nexport const Event = defineAsciiItem<TimelineEvent>('Event');\n\nconst MARK: Record<TimelineState, string> = { done: '●', now: '●', next: '○' };\n\nfunction stateClass(palette: FigurePalette | undefined, state: TimelineState): string {\n if (state === 'now') return 'text-accent-primary';\n if (state === 'next') return palette === 'multi' ? 'text-accent-secondary' : 'text-content-muted';\n return 'text-content-primary';\n}\n\nfunction eventsOf(children: ReactNode): TimelineEvent[] {\n const listed = listItems(children).map((item) => {\n const text = itemText(item);\n const time = text.match(/^(\\d{1,2}:\\d{2})\\s*:\\s*(.*)$/);\n const { label: date, rest } = time ? { label: time[1] ?? '', rest: time[2] ?? '' } : splitLabel(text);\n const content = (item.props as { children?: ReactNode }).children;\n const now = hasHost(content, ['strong', 'b']);\n const next = !now && hasHost(content, ['em', 'i']);\n return { date, label: rest || date, state: now ? 'now' : next ? 'next' : 'done' } as TimelineEvent;\n });\n if (listed.length > 0) return listed;\n\n return childItems(children, Event).map((entry) => ({\n ...entry,\n label: entry.label ?? textOf(entry.children),\n }));\n}\n\n/** Renders a dated sequence with explicit done, current, and upcoming states. */\nexport const Timeline = React.forwardRef<HTMLDivElement, TimelineProps>(function Timeline({ label = 'Timeline', events: eventsProp, children, palette, className, ...rest }, ref) {\n const events = eventsProp ?? eventsOf(children);\n\n return (\n <AsciiFrameBody data-slot=\"timeline\" ref={ref} {...rest} className={className}>\n <ol className=\"flex flex-col\" aria-label={label}>\n {events.map((event, index) => {\n const state = event.state ?? 'done';\n const last = index === events.length - 1;\n const label = event.label ?? '';\n return (\n <li className=\"flex flex-col\" key={`${event.date}-${label}-${index}`}>\n <div className=\"grid grid-cols-[1.25rem_7rem_minmax(0,1fr)] items-baseline gap-x-4\" aria-label={`${event.date}: ${label}`}>\n <span aria-hidden=\"true\" className={cn('select-none text-center leading-none', stateClass(palette, state))}>{MARK[state]}</span>\n <span className={cn('tabular-nums', state === 'next' ? 'text-content-muted' : 'text-content-primary')}>{event.date}</span>\n <span className={stateClass(palette, state)}>{label}</span>\n </div>\n {last ? null : <div aria-hidden=\"true\" className=\"grid grid-cols-[1.25rem_7rem_minmax(0,1fr)] gap-x-4 py-1\"><span className=\"select-none text-center text-content-muted\">│</span></div>}\n </li>\n );\n })}\n </ol>\n <span className=\"sr-only\">{events.length === 0 ? 'Empty timeline.' : `${events.length} timeline event${events.length === 1 ? '' : 's'}.`}</span>\n </AsciiFrameBody>\n );\n});\n"],"mappings":";AAQA,YAAY,WAAW;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,UAAU;AAmEH,SACE,KADF;AAzCT,IAAM,QAAQ,gBAA+B,OAAO;AAE3D,IAAM,OAAsC,EAAE,MAAM,UAAK,KAAK,UAAK,MAAM,SAAI;AAE7E,SAAS,WAAW,SAAoC,OAA8B;AACpF,MAAI,UAAU,MAAO,QAAO;AAC5B,MAAI,UAAU,OAAQ,QAAO,YAAY,UAAU,0BAA0B;AAC7E,SAAO;AACT;AAEA,SAAS,SAAS,UAAsC;AACtD,QAAM,SAAS,UAAU,QAAQ,EAAE,IAAI,CAAC,SAAS;AAC/C,UAAM,OAAO,SAAS,IAAI;AAC1B,UAAM,OAAO,KAAK,MAAM,8BAA8B;AACtD,UAAM,EAAE,OAAO,MAAM,KAAK,IAAI,OAAO,EAAE,OAAO,KAAK,CAAC,KAAK,IAAI,MAAM,KAAK,CAAC,KAAK,GAAG,IAAI,WAAW,IAAI;AACpG,UAAM,UAAW,KAAK,MAAmC;AACzD,UAAM,MAAM,QAAQ,SAAS,CAAC,UAAU,GAAG,CAAC;AAC5C,UAAM,OAAO,CAAC,OAAO,QAAQ,SAAS,CAAC,MAAM,GAAG,CAAC;AACjD,WAAO,EAAE,MAAM,OAAO,QAAQ,MAAM,OAAO,MAAM,QAAQ,OAAO,SAAS,OAAO;AAAA,EAClF,CAAC;AACD,MAAI,OAAO,SAAS,EAAG,QAAO;AAE9B,SAAO,WAAW,UAAU,KAAK,EAAE,IAAI,CAAC,WAAW;AAAA,IACjD,GAAG;AAAA,IACH,OAAO,MAAM,SAAS,OAAO,MAAM,QAAQ;AAAA,EAC7C,EAAE;AACJ;AAGO,IAAM,WAAiB,iBAA0C,SAASA,UAAS,EAAE,QAAQ,YAAY,QAAQ,YAAY,UAAU,SAAS,WAAW,GAAG,KAAK,GAAG,KAAK;AAChL,QAAM,SAAS,cAAc,SAAS,QAAQ;AAE9C,SACI,qBAAC,kBAAe,aAAU,YAAW,KAAW,GAAG,MAAM,WACvD;AAAA,wBAAC,QAAG,WAAU,iBAAgB,cAAY,OACvC,iBAAO,IAAI,CAAC,OAAO,UAAU;AAC5B,YAAM,QAAQ,MAAM,SAAS;AAC7B,YAAM,OAAO,UAAU,OAAO,SAAS;AACvC,YAAMC,SAAQ,MAAM,SAAS;AAC7B,aACE,qBAAC,QAAG,WAAU,iBACZ;AAAA,6BAAC,SAAI,WAAU,sEAAqE,cAAY,GAAG,MAAM,IAAI,KAAKA,MAAK,IACrH;AAAA,8BAAC,UAAK,eAAY,QAAO,WAAW,GAAG,wCAAwC,WAAW,SAAS,KAAK,CAAC,GAAI,eAAK,KAAK,GAAE;AAAA,UACzH,oBAAC,UAAK,WAAW,GAAG,gBAAgB,UAAU,SAAS,uBAAuB,sBAAsB,GAAI,gBAAM,MAAK;AAAA,UACnH,oBAAC,UAAK,WAAW,WAAW,SAAS,KAAK,GAAI,UAAAA,QAAM;AAAA,WACtD;AAAA,QACC,OAAO,OAAO,oBAAC,SAAI,eAAY,QAAO,WAAU,4DAA2D,8BAAC,UAAK,WAAU,8CAA6C,oBAAC,GAAO;AAAA,WANhJ,GAAG,MAAM,IAAI,IAAIA,MAAK,IAAI,KAAK,EAOlE;AAAA,IAEJ,CAAC,GACH;AAAA,IACA,oBAAC,UAAK,WAAU,WAAW,iBAAO,WAAW,IAAI,oBAAoB,GAAG,OAAO,MAAM,kBAAkB,OAAO,WAAW,IAAI,KAAK,GAAG,KAAI;AAAA,KAC3I;AAEN,CAAC;","names":["Timeline","label"]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// src/components/docs/figures/TokenTable.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../../../lib/recipe.js";
|
|
4
|
+
import { Swatch } from "../../Swatch.js";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
var CELL = "border-b border-edge-subtle px-3 py-2 align-top";
|
|
7
|
+
var HEAD = "border-b-2 border-edge-strong px-3 pb-2 text-left font-mono text-[0.65rem] font-bold uppercase tracking-[0.1em] text-content-muted";
|
|
8
|
+
function Chip({ value }) {
|
|
9
|
+
if (value === void 0) return null;
|
|
10
|
+
if (value === null) return /* @__PURE__ */ jsx("span", { className: "font-mono text-xs text-content-muted", children: "none" });
|
|
11
|
+
return /* @__PURE__ */ jsx(Swatch, { value, name: value, size: "sm" });
|
|
12
|
+
}
|
|
13
|
+
var TokenTable = React.forwardRef(function TokenTable2({ label = "Tokens", measures = [], rows, className, ...rest }, ref) {
|
|
14
|
+
const hasBefore = rows.some((r) => r.before !== void 0);
|
|
15
|
+
const hasNote = rows.some((r) => r.note);
|
|
16
|
+
return /* @__PURE__ */ jsxs("div", { "data-slot": "token-table", ref, role: "region", tabIndex: 0, "aria-label": `${label} scroll area`, ...rest, className: cn("min-w-0 overflow-x-auto", className), children: [
|
|
17
|
+
/* @__PURE__ */ jsxs("table", { "aria-label": label, className: "w-full min-w-[34rem] border-collapse text-sm", children: [
|
|
18
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
19
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: HEAD, children: "Token" }),
|
|
20
|
+
hasBefore && /* @__PURE__ */ jsx("th", { scope: "col", className: HEAD, children: "Before" }),
|
|
21
|
+
/* @__PURE__ */ jsx("th", { scope: "col", className: HEAD, children: hasBefore ? "After" : "Value" }),
|
|
22
|
+
measures.map((m) => /* @__PURE__ */ jsx("th", { scope: "col", className: HEAD, children: m }, m)),
|
|
23
|
+
hasNote && /* @__PURE__ */ jsx("th", { scope: "col", className: HEAD, children: "Note" })
|
|
24
|
+
] }) }),
|
|
25
|
+
/* @__PURE__ */ jsx("tbody", { children: rows.map((r, ri) => /* @__PURE__ */ jsxs("tr", { children: [
|
|
26
|
+
/* @__PURE__ */ jsx("th", { scope: "row", className: cn(CELL, "text-left font-mono text-xs font-bold text-content-primary"), children: r.token }),
|
|
27
|
+
hasBefore && /* @__PURE__ */ jsx("td", { className: CELL, children: /* @__PURE__ */ jsx(Chip, { value: r.before }) }),
|
|
28
|
+
/* @__PURE__ */ jsx("td", { className: CELL, children: /* @__PURE__ */ jsx(Chip, { value: r.after }) }),
|
|
29
|
+
measures.map((m, i) => /* @__PURE__ */ jsx("td", { className: cn(CELL, "font-mono text-xs tabular-nums text-content-secondary"), children: r.values?.[i] ?? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
30
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: "\u2014" }),
|
|
31
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: "not measured" })
|
|
32
|
+
] }) }, m)),
|
|
33
|
+
hasNote && /* @__PURE__ */ jsx("td", { className: cn(CELL, "text-content-secondary"), children: r.note })
|
|
34
|
+
] }, `${r.token}-${ri}`)) })
|
|
35
|
+
] }),
|
|
36
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: rows.length === 0 ? "No tokens." : `${rows.length} token${rows.length === 1 ? "" : "s"}.` })
|
|
37
|
+
] });
|
|
38
|
+
});
|
|
39
|
+
export {
|
|
40
|
+
TokenTable
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=TokenTable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/docs/figures/TokenTable.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../../lib/recipe';\nimport { Swatch } from '../../Swatch';\n\nexport interface TokenRow {\n /** The token's path, e.g. `text.muted`. */\n token: string;\n /** The value before the change. `null` reads as \"did not exist\". Omit when nothing changed. */\n before?: string | null;\n /** The value now. */\n after: string;\n /** One entry per `measures` heading, already formatted. */\n values?: readonly string[];\n /** Why this value, in a sentence. */\n note?: string;\n}\n\nexport interface TokenTableProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Accessible name for the table. */\n label?: string;\n /** Headings for the measured columns, e.g. `WCAG`, `APCA Lc`. */\n measures?: readonly string[];\n /** One row per token. */\n rows: readonly TokenRow[];\n /** Additional classes for the scroll container. */\n className?: string;\n}\n\nconst CELL = 'border-b border-edge-subtle px-3 py-2 align-top';\nconst HEAD = 'border-b-2 border-edge-strong px-3 pb-2 text-left font-mono text-[0.65rem] font-bold uppercase tracking-[0.1em] text-content-muted';\n\nfunction Chip({ value }: { value: string | null | undefined }) {\n if (value === undefined) return null;\n if (value === null) return <span className=\"font-mono text-xs text-content-muted\">none</span>;\n return <Swatch value={value} name={value} size=\"sm\" />;\n}\n\n/** Tokens with their values and measurements side by side, so a change is read as numbers, not taste. */\nexport const TokenTable = React.forwardRef<HTMLDivElement, TokenTableProps>(function TokenTable(\n { label = 'Tokens', measures = [], rows, className, ...rest },\n ref,\n) {\n const hasBefore = rows.some((r) => r.before !== undefined);\n const hasNote = rows.some((r) => r.note);\n // Focusable and named because it scrolls on a narrow screen; `Table` says why.\n return (\n <div data-slot=\"token-table\" ref={ref} role=\"region\" tabIndex={0} aria-label={`${label} scroll area`} {...rest} className={cn('min-w-0 overflow-x-auto', className)}>\n <table aria-label={label} className=\"w-full min-w-[34rem] border-collapse text-sm\">\n <thead>\n <tr>\n <th scope=\"col\" className={HEAD}>Token</th>\n {hasBefore && <th scope=\"col\" className={HEAD}>Before</th>}\n <th scope=\"col\" className={HEAD}>{hasBefore ? 'After' : 'Value'}</th>\n {measures.map((m) => <th key={m} scope=\"col\" className={HEAD}>{m}</th>)}\n {hasNote && <th scope=\"col\" className={HEAD}>Note</th>}\n </tr>\n </thead>\n <tbody>\n {rows.map((r, ri) => (\n <tr key={`${r.token}-${ri}`}>\n <th scope=\"row\" className={cn(CELL, 'text-left font-mono text-xs font-bold text-content-primary')}>{r.token}</th>\n {hasBefore && <td className={CELL}><Chip value={r.before} /></td>}\n <td className={CELL}><Chip value={r.after} /></td>\n {measures.map((m, i) => <td key={m} className={cn(CELL, 'font-mono text-xs tabular-nums text-content-secondary')}>{r.values?.[i] ?? <><span aria-hidden=\"true\">—</span><span className=\"sr-only\">not measured</span></>}</td>)}\n {hasNote && <td className={cn(CELL, 'text-content-secondary')}>{r.note}</td>}\n </tr>\n ))}\n </tbody>\n </table>\n <span className=\"sr-only\">{rows.length === 0 ? 'No tokens.' : `${rows.length} token${rows.length === 1 ? '' : 's'}.`}</span>\n </div>\n );\n});\n"],"mappings":";AAAA,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,cAAc;AA+BM,SA8BqH,UA9BrH,KAgBnB,YAhBmB;AAL7B,IAAM,OAAO;AACb,IAAM,OAAO;AAEb,SAAS,KAAK,EAAE,MAAM,GAAyC;AAC7D,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,UAAU,KAAM,QAAO,oBAAC,UAAK,WAAU,wCAAuC,kBAAI;AACtF,SAAO,oBAAC,UAAO,OAAc,MAAM,OAAO,MAAK,MAAK;AACtD;AAGO,IAAM,aAAmB,iBAA4C,SAASA,YACnF,EAAE,QAAQ,UAAU,WAAW,CAAC,GAAG,MAAM,WAAW,GAAG,KAAK,GAC5D,KACA;AACA,QAAM,YAAY,KAAK,KAAK,CAAC,MAAM,EAAE,WAAW,MAAS;AACzD,QAAM,UAAU,KAAK,KAAK,CAAC,MAAM,EAAE,IAAI;AAEvC,SACE,qBAAC,SAAI,aAAU,eAAc,KAAU,MAAK,UAAS,UAAU,GAAG,cAAY,GAAG,KAAK,gBAAiB,GAAG,MAAM,WAAW,GAAG,2BAA2B,SAAS,GAChK;AAAA,yBAAC,WAAM,cAAY,OAAO,WAAU,gDAClC;AAAA,0BAAC,WACC,+BAAC,QACC;AAAA,4BAAC,QAAG,OAAM,OAAM,WAAW,MAAM,mBAAK;AAAA,QACrC,aAAa,oBAAC,QAAG,OAAM,OAAM,WAAW,MAAM,oBAAM;AAAA,QACrD,oBAAC,QAAG,OAAM,OAAM,WAAW,MAAO,sBAAY,UAAU,SAAQ;AAAA,QAC/D,SAAS,IAAI,CAAC,MAAM,oBAAC,QAAW,OAAM,OAAM,WAAW,MAAO,eAAjC,CAAmC,CAAK;AAAA,QACrE,WAAW,oBAAC,QAAG,OAAM,OAAM,WAAW,MAAM,kBAAI;AAAA,SACnD,GACF;AAAA,MACA,oBAAC,WACE,eAAK,IAAI,CAAC,GAAG,OACZ,qBAAC,QACC;AAAA,4BAAC,QAAG,OAAM,OAAM,WAAW,GAAG,MAAM,4DAA4D,GAAI,YAAE,OAAM;AAAA,QAC3G,aAAa,oBAAC,QAAG,WAAW,MAAM,8BAAC,QAAK,OAAO,EAAE,QAAQ,GAAE;AAAA,QAC5D,oBAAC,QAAG,WAAW,MAAM,8BAAC,QAAK,OAAO,EAAE,OAAO,GAAE;AAAA,QAC5C,SAAS,IAAI,CAAC,GAAG,MAAM,oBAAC,QAAW,WAAW,GAAG,MAAM,uDAAuD,GAAI,YAAE,SAAS,CAAC,KAAK,iCAAE;AAAA,8BAAC,UAAK,eAAY,QAAO,oBAAC;AAAA,UAAO,oBAAC,UAAK,WAAU,WAAU,0BAAY;AAAA,WAAO,KAAnL,CAAuL,CAAK;AAAA,QAC5N,WAAW,oBAAC,QAAG,WAAW,GAAG,MAAM,wBAAwB,GAAI,YAAE,MAAK;AAAA,WALhE,GAAG,EAAE,KAAK,IAAI,EAAE,EAMzB,CACD,GACH;AAAA,OACF;AAAA,IACA,oBAAC,UAAK,WAAU,WAAW,eAAK,WAAW,IAAI,eAAe,GAAG,KAAK,MAAM,SAAS,KAAK,WAAW,IAAI,KAAK,GAAG,KAAI;AAAA,KACvH;AAEJ,CAAC;","names":["TokenTable"]}
|