@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 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/docs/figures/Decision.tsx"],"sourcesContent":["import * as React from 'react';\nimport { cn } from '../../../lib/recipe';\nimport { childItems, defineAsciiItem } from './FigureFrame';\n\nexport interface DecisionOption {\n /** The option, as a short heading. */\n title: string;\n /** What it costs, in a line. */\n cost?: string;\n /** Marks the recommended option. */\n picked?: boolean;\n /** One or two sentences on what the option does. */\n children?: React.ReactNode;\n}\n\n/** MDX-only option, for example `<Option title=\"5.5:1\" picked cost=\"…\">…</Option>`. */\nexport const Option = defineAsciiItem<DecisionOption>('Option');\n\nexport interface DecisionProps extends React.HTMLAttributes<HTMLDivElement> {\n /** The question being decided. Also the accessible name. */\n question: string;\n /** One line on why it matters, under the question. */\n context?: string;\n /** Data form. If omitted, the component reads `<Option>` children. */\n options?: readonly DecisionOption[];\n /** The recommendation, under the options. */\n recommendation?: React.ReactNode;\n /** `<Option>` items. */\n children?: React.ReactNode;\n /** Additional classes for the frame. */\n className?: string;\n}\n\n/** A decision laid out as options with costs, with the recommended one marked. */\nexport const Decision = React.forwardRef<HTMLDivElement, DecisionProps>(function Decision(\n { question, context, options: optionsProp, recommendation, children, className, ...rest },\n ref,\n) {\n const options = optionsProp ?? childItems(children, Option);\n const picked = options.find((o) => o.picked);\n return (\n <div data-slot=\"decision\" ref={ref} role=\"group\" aria-label={question} {...rest} className={cn('border-[3px] border-intent-warning bg-surface-raised shadow-hard-md', className)}>\n <div className=\"border-b-2 border-intent-warning px-4 py-3\">\n <p className=\"m-0 font-display text-base font-extrabold text-content-primary\">{question}</p>\n {context && <p className=\"m-0 mt-1 font-mono text-xs text-content-muted\">{context}</p>}\n </div>\n <div className=\"grid sm:grid-cols-2\">\n {options.map((o, i) => (\n <div key={`${o.title}-${i}`} data-slot=\"decision-option\" className={cn('flex flex-col gap-2 border-b border-edge-subtle px-4 py-3 sm:odd:border-r', o.picked && 'bg-surface-sunken')}>\n <p className=\"m-0 flex items-baseline justify-between gap-2 font-display text-sm font-bold text-content-primary\">\n <span>{o.title}</span>\n {o.picked && <span className=\"border-2 border-intent-success px-1 font-mono text-[0.6rem] uppercase text-intent-success\">Recommended</span>}\n </p>\n {o.children && <div className=\"text-sm text-content-secondary [&_p]:m-0\">{o.children}</div>}\n {o.cost && <p className=\"m-0 font-mono text-xs text-content-muted\">cost: <span>{o.cost}</span></p>}\n </div>\n ))}\n </div>\n <span className=\"sr-only\">{options.length === 0 ? 'No options.' : `${options.length} option${options.length === 1 ? '' : 's'}${picked ? `, recommended: ${picked.title}` : ''}.`}</span>\n {recommendation && <div className=\"px-4 py-3 text-sm text-content-primary [&_p]:m-0\">{recommendation}</div>}\n </div>\n );\n});\n"],"mappings":";AAAA,YAAY,WAAW;AACvB,SAAS,UAAU;AACnB,SAAS,YAAY,uBAAuB;AAwCtC,SACE,KADF;AA1BC,IAAM,SAAS,gBAAgC,QAAQ;AAkBvD,IAAM,WAAiB,iBAA0C,SAASA,UAC/E,EAAE,UAAU,SAAS,SAAS,aAAa,gBAAgB,UAAU,WAAW,GAAG,KAAK,GACxF,KACA;AACA,QAAM,UAAU,eAAe,WAAW,UAAU,MAAM;AAC1D,QAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,MAAM;AAC3C,SACE,qBAAC,SAAI,aAAU,YAAW,KAAU,MAAK,SAAQ,cAAY,UAAW,GAAG,MAAM,WAAW,GAAG,uEAAuE,SAAS,GAC7K;AAAA,yBAAC,SAAI,WAAU,8CACb;AAAA,0BAAC,OAAE,WAAU,kEAAkE,oBAAS;AAAA,MACvF,WAAW,oBAAC,OAAE,WAAU,iDAAiD,mBAAQ;AAAA,OACpF;AAAA,IACA,oBAAC,SAAI,WAAU,uBACZ,kBAAQ,IAAI,CAAC,GAAG,MACf,qBAAC,SAA4B,aAAU,mBAAkB,WAAW,GAAG,6EAA6E,EAAE,UAAU,mBAAmB,GACjL;AAAA,2BAAC,OAAE,WAAU,qGACX;AAAA,4BAAC,UAAM,YAAE,OAAM;AAAA,QACd,EAAE,UAAU,oBAAC,UAAK,WAAU,6FAA4F,yBAAW;AAAA,SACtI;AAAA,MACC,EAAE,YAAY,oBAAC,SAAI,WAAU,4CAA4C,YAAE,UAAS;AAAA,MACpF,EAAE,QAAQ,qBAAC,OAAE,WAAU,4CAA2C;AAAA;AAAA,QAAM,oBAAC,UAAM,YAAE,MAAK;AAAA,SAAO;AAAA,SANtF,GAAG,EAAE,KAAK,IAAI,CAAC,EAOzB,CACD,GACH;AAAA,IACA,oBAAC,UAAK,WAAU,WAAW,kBAAQ,WAAW,IAAI,gBAAgB,GAAG,QAAQ,MAAM,UAAU,QAAQ,WAAW,IAAI,KAAK,GAAG,GAAG,SAAS,kBAAkB,OAAO,KAAK,KAAK,EAAE,KAAI;AAAA,IAChL,kBAAkB,oBAAC,SAAI,WAAU,oDAAoD,0BAAe;AAAA,KACvG;AAEJ,CAAC;","names":["Decision"]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// src/components/docs/figures/DrawingSheet.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../../../lib/recipe.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
var LETTERS = "ABCDEFGHJKLMNPQRSTUVWXYZ";
|
|
6
|
+
function sheetRowLabel(index) {
|
|
7
|
+
const letter = LETTERS[index % LETTERS.length] ?? "A";
|
|
8
|
+
return index < LETTERS.length ? letter : `${letter}${Math.floor(index / LETTERS.length) + 1}`;
|
|
9
|
+
}
|
|
10
|
+
var DrawingSheet = React.forwardRef(function DrawingSheet2({ columns = 4, rows = 3, children, className, ...rest }, ref) {
|
|
11
|
+
const top = Math.max(0, Math.floor(columns));
|
|
12
|
+
const side = Math.max(0, Math.floor(rows));
|
|
13
|
+
return /* @__PURE__ */ jsxs(
|
|
14
|
+
"div",
|
|
15
|
+
{
|
|
16
|
+
ref,
|
|
17
|
+
...rest,
|
|
18
|
+
"data-slot": "drawing-sheet",
|
|
19
|
+
className: cn(
|
|
20
|
+
"grid w-full border-2 border-edge-strong bg-surface-base text-content-primary",
|
|
21
|
+
side > 0 ? "grid-cols-[1.75rem_minmax(0,1fr)]" : "grid-cols-[minmax(0,1fr)]",
|
|
22
|
+
top > 0 ? "grid-rows-[auto_1fr]" : "grid-rows-[1fr]",
|
|
23
|
+
className
|
|
24
|
+
),
|
|
25
|
+
children: [
|
|
26
|
+
top > 0 && side > 0 ? /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "border-b-2 border-r-2 border-edge-strong" }) : null,
|
|
27
|
+
top > 0 ? /* @__PURE__ */ jsx("div", { "aria-hidden": "true", "data-slot": "drawing-sheet-columns", className: "flex select-none border-b-2 border-edge-strong font-mono text-xs text-content-muted", children: Array.from({ length: top }, (_, index) => /* @__PURE__ */ jsx("span", { className: cn("flex-1 py-1 text-center", index > 0 && "border-l border-edge-default"), children: index + 1 }, index)) }) : null,
|
|
28
|
+
side > 0 ? /* @__PURE__ */ jsx("div", { "aria-hidden": "true", "data-slot": "drawing-sheet-rows", className: "flex select-none flex-col border-r-2 border-edge-strong font-mono text-xs text-content-muted", children: Array.from({ length: side }, (_, index) => /* @__PURE__ */ jsx("span", { className: cn("flex flex-1 items-center justify-center", index > 0 && "border-t border-edge-default"), children: sheetRowLabel(index) }, index)) }) : null,
|
|
29
|
+
/* @__PURE__ */ jsx("div", { "data-slot": "drawing-sheet-body", className: "flex min-w-0 flex-col gap-6 p-3 sm:p-6", children })
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
export {
|
|
35
|
+
DrawingSheet
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=DrawingSheet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/docs/figures/DrawingSheet.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport * as React from 'react';\nimport { cn } from '../../../lib/recipe';\n\n\n\nconst LETTERS = 'ABCDEFGHJKLMNPQRSTUVWXYZ';\n\n/** Row reference for an index — drawing-sheet convention skips I and O, which read as 1 and 0. */\nfunction sheetRowLabel(index: number): string {\n const letter = LETTERS[index % LETTERS.length] ?? 'A';\n return index < LETTERS.length ? letter : `${letter}${Math.floor(index / LETTERS.length) + 1}`;\n}\n\nexport interface DrawingSheetProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Grid references across the top edge, numbered from 1. `0` hides the top ruler. */\n columns?: number;\n /** Grid references down the left edge, lettered from A. `0` hides the side ruler. */\n rows?: number;\n /** Sheet content, usually one or more `IndexedSection`s. */\n children?: ReactNode;\n /** Additional classes for the root. */\n className?: string;\n}\n\n/**\n * An engineering drawing sheet: a hard border with numbered columns along the top and lettered\n * rows down the side, so a review can point at \"B2\" rather than \"the second box on the left\".\n *\n * The references divide the sheet evenly and are decorative — they are hidden from assistive\n * technology, which navigates by the sections' headings instead.\n */\nexport const DrawingSheet = React.forwardRef<HTMLDivElement, DrawingSheetProps>(function DrawingSheet({ columns = 4, rows = 3, children, className, ...rest }, ref) {\n const top = Math.max(0, Math.floor(columns));\n const side = Math.max(0, Math.floor(rows));\n return (\n <div\n ref={ref}\n {...rest}\n data-slot=\"drawing-sheet\"\n className={cn(\n 'grid w-full border-2 border-edge-strong bg-surface-base text-content-primary',\n side > 0 ? 'grid-cols-[1.75rem_minmax(0,1fr)]' : 'grid-cols-[minmax(0,1fr)]',\n top > 0 ? 'grid-rows-[auto_1fr]' : 'grid-rows-[1fr]',\n className,\n )}\n >\n {top > 0 && side > 0 ? <span aria-hidden=\"true\" className=\"border-b-2 border-r-2 border-edge-strong\" /> : null}\n {top > 0 ? (\n <div aria-hidden=\"true\" data-slot=\"drawing-sheet-columns\" className=\"flex select-none border-b-2 border-edge-strong font-mono text-xs text-content-muted\">\n {Array.from({ length: top }, (_, index) => (\n <span key={index} className={cn('flex-1 py-1 text-center', index > 0 && 'border-l border-edge-default')}>\n {index + 1}\n </span>\n ))}\n </div>\n ) : null}\n {side > 0 ? (\n <div aria-hidden=\"true\" data-slot=\"drawing-sheet-rows\" className=\"flex select-none flex-col border-r-2 border-edge-strong font-mono text-xs text-content-muted\">\n {Array.from({ length: side }, (_, index) => (\n <span key={index} className={cn('flex flex-1 items-center justify-center', index > 0 && 'border-t border-edge-default')}>\n {sheetRowLabel(index)}\n </span>\n ))}\n </div>\n ) : null}\n <div data-slot=\"drawing-sheet-body\" className=\"flex min-w-0 flex-col gap-6 p-3 sm:p-6\">\n {children}\n </div>\n </div>\n );\n});\n"],"mappings":";AACA,YAAY,WAAW;AACvB,SAAS,UAAU;AAkCf,SAWyB,KAXzB;AA9BJ,IAAM,UAAU;AAGhB,SAAS,cAAc,OAAuB;AAC5C,QAAM,SAAS,QAAQ,QAAQ,QAAQ,MAAM,KAAK;AAClD,SAAO,QAAQ,QAAQ,SAAS,SAAS,GAAG,MAAM,GAAG,KAAK,MAAM,QAAQ,QAAQ,MAAM,IAAI,CAAC;AAC7F;AAoBO,IAAM,eAAqB,iBAA8C,SAASA,cAAa,EAAE,UAAU,GAAG,OAAO,GAAG,UAAU,WAAW,GAAG,KAAK,GAAG,KAAK;AAClK,QAAM,MAAM,KAAK,IAAI,GAAG,KAAK,MAAM,OAAO,CAAC;AAC3C,QAAM,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,IAAI,CAAC;AACzC,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACC,GAAG;AAAA,MACJ,aAAU;AAAA,MACV,WAAW;AAAA,QACT;AAAA,QACA,OAAO,IAAI,sCAAsC;AAAA,QACjD,MAAM,IAAI,yBAAyB;AAAA,QACnC;AAAA,MACF;AAAA,MAEC;AAAA,cAAM,KAAK,OAAO,IAAI,oBAAC,UAAK,eAAY,QAAO,WAAU,4CAA2C,IAAK;AAAA,QACzG,MAAM,IACL,oBAAC,SAAI,eAAY,QAAO,aAAU,yBAAwB,WAAU,uFACjE,gBAAM,KAAK,EAAE,QAAQ,IAAI,GAAG,CAAC,GAAG,UAC/B,oBAAC,UAAiB,WAAW,GAAG,2BAA2B,QAAQ,KAAK,8BAA8B,GACnG,kBAAQ,KADA,KAEX,CACD,GACH,IACE;AAAA,QACH,OAAO,IACN,oBAAC,SAAI,eAAY,QAAO,aAAU,sBAAqB,WAAU,gGAC9D,gBAAM,KAAK,EAAE,QAAQ,KAAK,GAAG,CAAC,GAAG,UAChC,oBAAC,UAAiB,WAAW,GAAG,2CAA2C,QAAQ,KAAK,8BAA8B,GACnH,wBAAc,KAAK,KADX,KAEX,CACD,GACH,IACE;AAAA,QACJ,oBAAC,SAAI,aAAU,sBAAqB,WAAU,0CAC3C,UACH;AAAA;AAAA;AAAA,EACF;AAEJ,CAAC;","names":["DrawingSheet"]}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
// src/components/docs/figures/FigureFrame.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { cn } from "../../../lib/recipe.js";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
var DIM_OPACITY = 0.4;
|
|
6
|
+
var GLYPH_SETS = {
|
|
7
|
+
shade: ["\xB7", "\u2591", "\u2592", "\u2593", "\u2588"],
|
|
8
|
+
ascii: [".", "-", "=", "#", "@"],
|
|
9
|
+
hash: [".", ":", "+", "#", "\u2588"],
|
|
10
|
+
bar: ["\u2581", "\u2582", "\u2583", "\u2585", "\u2588"]
|
|
11
|
+
};
|
|
12
|
+
function resolveGlyphs(glyphs) {
|
|
13
|
+
if (glyphs == null) return GLYPH_SETS.shade;
|
|
14
|
+
if (typeof glyphs === "string") return GLYPH_SETS[glyphs] ?? GLYPH_SETS.shade;
|
|
15
|
+
return glyphs.length > 0 ? glyphs : GLYPH_SETS.shade;
|
|
16
|
+
}
|
|
17
|
+
function toneClass(palette, tone) {
|
|
18
|
+
if (tone === "empty") return "text-content-muted";
|
|
19
|
+
if (tone === "idle") return "text-content-secondary";
|
|
20
|
+
if (tone === "primary") return "text-accent-primary";
|
|
21
|
+
if (tone === "secondary") {
|
|
22
|
+
return palette === "mono" || palette == null ? "text-content-secondary" : "text-accent-secondary";
|
|
23
|
+
}
|
|
24
|
+
return palette === "multi" ? "text-accent-tertiary" : "text-accent-secondary";
|
|
25
|
+
}
|
|
26
|
+
function intensityClass(level, palette = "mono") {
|
|
27
|
+
const value = Math.min(4, Math.max(0, Math.round(level)));
|
|
28
|
+
if (value === 0) return toneClass(palette, "empty");
|
|
29
|
+
if (palette === "mono") return value <= 2 ? toneClass(palette, "idle") : "text-content-primary";
|
|
30
|
+
return value === 1 ? toneClass(palette, "secondary") : value === 2 ? toneClass(palette, "tertiary") : toneClass(palette, "primary");
|
|
31
|
+
}
|
|
32
|
+
function intensityLevel(value, max) {
|
|
33
|
+
if (value <= 0 || max <= 0) return 0;
|
|
34
|
+
return Math.max(1, Math.round(Math.min(1, value / max) * 4));
|
|
35
|
+
}
|
|
36
|
+
function intensityGlyph(level, glyphs = GLYPH_SETS.shade) {
|
|
37
|
+
if (glyphs.length === 0) return "\xB7";
|
|
38
|
+
const clamped = Math.min(4, Math.max(0, Math.round(level)));
|
|
39
|
+
return glyphs[Math.round(clamped / 4 * (glyphs.length - 1))] ?? glyphs[0] ?? "\xB7";
|
|
40
|
+
}
|
|
41
|
+
function words(value) {
|
|
42
|
+
return Array.isArray(value) ? value : value.split(/[\s,]+/).filter(Boolean);
|
|
43
|
+
}
|
|
44
|
+
var FigureFrame = React.forwardRef(function FigureFrame2({ title, corner = "+", className, children, ...rest }, ref) {
|
|
45
|
+
return /* @__PURE__ */ jsxs(
|
|
46
|
+
"figure",
|
|
47
|
+
{
|
|
48
|
+
"data-slot": "figure-frame",
|
|
49
|
+
ref,
|
|
50
|
+
"aria-label": title ?? "Document figure",
|
|
51
|
+
className: cn(
|
|
52
|
+
"relative mx-auto my-8 w-full max-w-5xl border-2 border-dashed border-edge-strong bg-surface-base font-mono text-sm text-content-primary",
|
|
53
|
+
className
|
|
54
|
+
),
|
|
55
|
+
...rest,
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "pointer-events-none absolute left-0 top-0 z-10 flex size-4 -translate-x-1/2 -translate-y-1/2 items-center justify-center bg-surface-base font-mono text-xs leading-none text-content-muted", children: corner }),
|
|
58
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "pointer-events-none absolute right-0 top-0 z-10 flex size-4 translate-x-1/2 -translate-y-1/2 items-center justify-center bg-surface-base font-mono text-xs leading-none text-content-muted", children: corner }),
|
|
59
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "pointer-events-none absolute bottom-0 left-0 z-10 flex size-4 -translate-x-1/2 translate-y-1/2 items-center justify-center bg-surface-base font-mono text-xs leading-none text-content-muted", children: corner }),
|
|
60
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "pointer-events-none absolute bottom-0 right-0 z-10 flex size-4 translate-x-1/2 translate-y-1/2 items-center justify-center bg-surface-base font-mono text-xs leading-none text-content-muted", children: corner }),
|
|
61
|
+
title ? /* @__PURE__ */ jsxs("figcaption", { className: "absolute left-1/2 top-0 z-10 -translate-x-1/2 -translate-y-1/2 whitespace-nowrap bg-surface-base px-3 uppercase tracking-wide text-accent-primary", children: [
|
|
62
|
+
"[ ",
|
|
63
|
+
title,
|
|
64
|
+
" ]"
|
|
65
|
+
] }) : null,
|
|
66
|
+
/* @__PURE__ */ jsx("div", { className: "flex min-w-0 flex-col gap-6 px-5 py-7 sm:px-8 sm:py-8", children })
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
var AsciiFrameBody = React.forwardRef(function AsciiFrameBody2({ className, ...props }, ref) {
|
|
72
|
+
return /* @__PURE__ */ jsx("div", { "data-slot": "ascii-frame-body", ref, className: cn("min-w-0", className), ...props });
|
|
73
|
+
});
|
|
74
|
+
function AsciiFrameProse({ className, ...props }) {
|
|
75
|
+
return /* @__PURE__ */ jsx(
|
|
76
|
+
"div",
|
|
77
|
+
{
|
|
78
|
+
"data-slot": "ascii-frame-prose",
|
|
79
|
+
className: cn(
|
|
80
|
+
"flex min-w-0 flex-col gap-3 leading-relaxed",
|
|
81
|
+
"[&_p]:m-0 [&_p]:text-pretty",
|
|
82
|
+
"[&_ul]:m-0 [&_ul]:flex [&_ul]:list-none [&_ul]:flex-col [&_ul]:gap-1 [&_ul]:p-0",
|
|
83
|
+
"[&_ol]:m-0 [&_ol]:flex [&_ol]:list-none [&_ol]:flex-col [&_ol]:gap-1 [&_ol]:p-0",
|
|
84
|
+
"[&_li]:relative [&_li]:pl-4 [&_li]:before:absolute [&_li]:before:left-0 [&_li]:before:text-content-muted [&_li]:before:content-['-']",
|
|
85
|
+
"[&_a]:text-content-primary [&_a]:underline [&_a]:decoration-dashed [&_a]:underline-offset-[0.2em]",
|
|
86
|
+
"[&_code]:font-semibold [&_code]:text-content-primary",
|
|
87
|
+
"[&_pre]:m-0 [&_pre]:whitespace-pre-wrap [&_pre_code]:font-normal [&_pre_code]:text-inherit",
|
|
88
|
+
"[&_strong]:font-semibold [&_strong]:text-content-primary",
|
|
89
|
+
"[&_em]:text-content-secondary [&_em]:not-italic",
|
|
90
|
+
className
|
|
91
|
+
),
|
|
92
|
+
...props
|
|
93
|
+
}
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
function AsciiFrameRule({ className, ...props }) {
|
|
97
|
+
return /* @__PURE__ */ jsx("div", { "data-slot": "ascii-frame-rule", "aria-hidden": "true", className: cn("my-1 h-px w-full border-t border-dashed border-edge-subtle", className), ...props });
|
|
98
|
+
}
|
|
99
|
+
function AsciiFrameRuleY({ className, ...props }) {
|
|
100
|
+
return /* @__PURE__ */ jsx("div", { "data-slot": "ascii-frame-rule-y", "aria-hidden": "true", className: cn("w-px self-stretch border-l border-dashed border-edge-subtle", className), ...props });
|
|
101
|
+
}
|
|
102
|
+
function AsciiFrameTrack({ className, ...props }) {
|
|
103
|
+
return /* @__PURE__ */ jsx("span", { "data-slot": "ascii-frame-track", "aria-hidden": "true", className: cn("flex w-full min-w-0 select-none", className), ...props });
|
|
104
|
+
}
|
|
105
|
+
function AsciiFrameTick({ className, ...props }) {
|
|
106
|
+
return /* @__PURE__ */ jsx("span", { "data-slot": "ascii-frame-tick", className: cn("min-w-0 flex-1 overflow-hidden text-center", className), ...props });
|
|
107
|
+
}
|
|
108
|
+
function AsciiFrameArrow({ accent = false, stretch = false, className }) {
|
|
109
|
+
return /* @__PURE__ */ jsxs("span", { "data-slot": "ascii-frame-arrow", "aria-hidden": "true", className: cn("flex min-w-6 items-center text-content-muted", stretch && "flex-1", className), children: [
|
|
110
|
+
/* @__PURE__ */ jsx("span", { className: cn("w-full border-t border-dashed border-current", accent && "text-accent-primary") }),
|
|
111
|
+
/* @__PURE__ */ jsx("span", { className: cn("-ml-1", accent ? "text-accent-primary" : "text-content-muted"), children: "\u25B6" })
|
|
112
|
+
] });
|
|
113
|
+
}
|
|
114
|
+
function defineAsciiItem(name) {
|
|
115
|
+
const Item = (() => null);
|
|
116
|
+
Item.displayName = name;
|
|
117
|
+
Item.graphItem = name;
|
|
118
|
+
return Item;
|
|
119
|
+
}
|
|
120
|
+
function typeName(type) {
|
|
121
|
+
if (typeof type === "string") return type;
|
|
122
|
+
if (typeof type === "function") {
|
|
123
|
+
const fn = type;
|
|
124
|
+
return fn.graphItem || fn.displayName || fn.name || "";
|
|
125
|
+
}
|
|
126
|
+
if (type && typeof type === "object") {
|
|
127
|
+
const value = type;
|
|
128
|
+
if (value.graphItem) return value.graphItem;
|
|
129
|
+
if (value.displayName) return value.displayName;
|
|
130
|
+
if (typeof value.$$id === "string") return value.$$id.split("#").pop()?.split("@")[0] ?? "";
|
|
131
|
+
return value.name || "";
|
|
132
|
+
}
|
|
133
|
+
return "";
|
|
134
|
+
}
|
|
135
|
+
function isHost(element, tags) {
|
|
136
|
+
const name = typeName(element.type).toLowerCase();
|
|
137
|
+
const list = typeof tags === "string" ? [tags] : tags;
|
|
138
|
+
return list.some((tag) => tag.toLowerCase() === name);
|
|
139
|
+
}
|
|
140
|
+
function elementsOf(children) {
|
|
141
|
+
const result = [];
|
|
142
|
+
for (const child of React.Children.toArray(children)) {
|
|
143
|
+
if (!React.isValidElement(child)) continue;
|
|
144
|
+
if (child.type === React.Fragment) {
|
|
145
|
+
result.push(...elementsOf(child.props.children));
|
|
146
|
+
} else {
|
|
147
|
+
result.push(child);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return result;
|
|
151
|
+
}
|
|
152
|
+
function textOf(children) {
|
|
153
|
+
return React.Children.toArray(children).map((child) => React.isValidElement(child) ? textOf(child.props.children) : String(child)).join("");
|
|
154
|
+
}
|
|
155
|
+
function itemText(item) {
|
|
156
|
+
const children = item.props.children;
|
|
157
|
+
return textOf(children).replace(/\s+/g, " ").trim();
|
|
158
|
+
}
|
|
159
|
+
function listItems(children) {
|
|
160
|
+
const elements = elementsOf(children);
|
|
161
|
+
const lists = elements.filter((element) => isHost(element, ["ul", "ol"]));
|
|
162
|
+
const items = lists.length > 0 ? lists.flatMap((list) => elementsOf(list.props.children)) : elements;
|
|
163
|
+
return items.filter((element) => isHost(element, "li"));
|
|
164
|
+
}
|
|
165
|
+
function nestedList(item) {
|
|
166
|
+
return listItems(item.props.children);
|
|
167
|
+
}
|
|
168
|
+
function paragraphsOf(children) {
|
|
169
|
+
return elementsOf(children).filter((element) => isHost(element, "p"));
|
|
170
|
+
}
|
|
171
|
+
function hasHost(children, tags) {
|
|
172
|
+
return React.Children.toArray(children).some((child) => {
|
|
173
|
+
if (!React.isValidElement(child)) return false;
|
|
174
|
+
return isHost(child, tags) || hasHost(child.props.children, tags);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
function childItems(children, item) {
|
|
178
|
+
return elementsOf(children).filter((element) => typeName(element.type) === item.graphItem).map((element) => element.props);
|
|
179
|
+
}
|
|
180
|
+
function splitLabel(value) {
|
|
181
|
+
const match = value.match(/^([^:—–-]+?)\s*:\s*(.*)$/);
|
|
182
|
+
if (!match) return { label: value.trim(), rest: "" };
|
|
183
|
+
return { label: match[1]?.trim() ?? "", rest: match[2]?.trim() ?? "" };
|
|
184
|
+
}
|
|
185
|
+
function splitDash(value) {
|
|
186
|
+
const match = value.match(/^(.+?)\s+[-—–]\s+(.+)$/);
|
|
187
|
+
if (!match) return { label: value.trim(), rest: "" };
|
|
188
|
+
return { label: match[1]?.trim() ?? "", rest: match[2]?.trim() ?? "" };
|
|
189
|
+
}
|
|
190
|
+
function numberOf(value) {
|
|
191
|
+
if (typeof value === "number") return value;
|
|
192
|
+
const parsed = Number(value.replace(/[^\d.+-]/g, ""));
|
|
193
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
194
|
+
}
|
|
195
|
+
export {
|
|
196
|
+
AsciiFrameArrow,
|
|
197
|
+
AsciiFrameBody,
|
|
198
|
+
AsciiFrameProse,
|
|
199
|
+
AsciiFrameRule,
|
|
200
|
+
AsciiFrameRuleY,
|
|
201
|
+
AsciiFrameTick,
|
|
202
|
+
AsciiFrameTrack,
|
|
203
|
+
DIM_OPACITY,
|
|
204
|
+
FigureFrame,
|
|
205
|
+
GLYPH_SETS,
|
|
206
|
+
childItems,
|
|
207
|
+
defineAsciiItem,
|
|
208
|
+
elementsOf,
|
|
209
|
+
hasHost,
|
|
210
|
+
intensityClass,
|
|
211
|
+
intensityGlyph,
|
|
212
|
+
intensityLevel,
|
|
213
|
+
isHost,
|
|
214
|
+
itemText,
|
|
215
|
+
listItems,
|
|
216
|
+
nestedList,
|
|
217
|
+
numberOf,
|
|
218
|
+
paragraphsOf,
|
|
219
|
+
resolveGlyphs,
|
|
220
|
+
splitDash,
|
|
221
|
+
splitLabel,
|
|
222
|
+
textOf,
|
|
223
|
+
toneClass,
|
|
224
|
+
words
|
|
225
|
+
};
|
|
226
|
+
//# sourceMappingURL=FigureFrame.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/docs/figures/FigureFrame.tsx"],"sourcesContent":["/**\n * Adapted from mdxcn by Keshav Bagaade, MIT licensed.\n * Source: https://github.com/keshav-exe/mdxcn/blob/2928126ba146ebbae9c2351deca27d27bb40e744/registry/default/graph-frame/graph-frame.tsx\n * The port replaces mdxcn's motion runtime and graph variables with this\n * package's deterministic rendering and semantic token contracts.\n */\n\nimport * as React from 'react';\nimport type { ReactElement, ReactNode } from 'react';\nimport { cn } from '../../../lib/recipe';\n\nexport type FigurePalette = 'mono' | 'duo' | 'multi';\nexport type FigureTone = 'primary' | 'secondary' | 'tertiary' | 'idle' | 'empty';\n\nexport const DIM_OPACITY = 0.4;\n\nexport const GLYPH_SETS = {\n shade: ['·', '░', '▒', '▓', '█'],\n ascii: ['.', '-', '=', '#', '@'],\n hash: ['.', ':', '+', '#', '█'],\n bar: ['▁', '▂', '▃', '▅', '█'],\n} as const;\n\nexport type GlyphSetName = keyof typeof GLYPH_SETS;\nexport type Glyphs = GlyphSetName | readonly string[];\n\nexport function resolveGlyphs(glyphs?: Glyphs): readonly string[] {\n if (glyphs == null) return GLYPH_SETS.shade;\n if (typeof glyphs === 'string') return GLYPH_SETS[glyphs] ?? GLYPH_SETS.shade;\n return glyphs.length > 0 ? glyphs : GLYPH_SETS.shade;\n}\n\nexport function toneClass(palette: FigurePalette | undefined, tone: FigureTone): string {\n if (tone === 'empty') return 'text-content-muted';\n if (tone === 'idle') return 'text-content-secondary';\n if (tone === 'primary') return 'text-accent-primary';\n if (tone === 'secondary') {\n return palette === 'mono' || palette == null ? 'text-content-secondary' : 'text-accent-secondary';\n }\n return palette === 'multi' ? 'text-accent-tertiary' : 'text-accent-secondary';\n}\n\nexport function intensityClass(level: number, palette: FigurePalette = 'mono'): string {\n const value = Math.min(4, Math.max(0, Math.round(level)));\n if (value === 0) return toneClass(palette, 'empty');\n if (palette === 'mono') return value <= 2 ? toneClass(palette, 'idle') : 'text-content-primary';\n return value === 1 ? toneClass(palette, 'secondary') : value === 2 ? toneClass(palette, 'tertiary') : toneClass(palette, 'primary');\n}\n\nexport function intensityLevel(value: number, max: number): number {\n if (value <= 0 || max <= 0) return 0;\n return Math.max(1, Math.round(Math.min(1, value / max) * 4));\n}\n\nexport function intensityGlyph(level: number, glyphs: readonly string[] = GLYPH_SETS.shade): string {\n if (glyphs.length === 0) return '·';\n const clamped = Math.min(4, Math.max(0, Math.round(level)));\n return glyphs[Math.round((clamped / 4) * (glyphs.length - 1))] ?? glyphs[0] ?? '·';\n}\n\nexport function words<T extends string>(value: T[] | string): T[] {\n return Array.isArray(value) ? value : value.split(/[\\s,]+/).filter(Boolean) as T[];\n}\n\nexport interface FigureFrameProps extends Omit<React.ComponentProps<'figure'>, 'title'> {\n /** Short uppercase caption drawn across the top edge. */\n title?: string;\n /** Character used at each frame corner. */\n corner?: string;\n}\n\n/**\n * Shared border and caption for one or more documentation renderers.\n * Renderers own their data and can also appear without a frame.\n */\nexport const FigureFrame = React.forwardRef<HTMLElement, FigureFrameProps>(function FigureFrame({ title, corner = '+', className, children, ...rest }, ref) {\n return (\n <figure data-slot=\"figure-frame\"\n ref={ref}\n aria-label={title ?? 'Document figure'}\n className={cn(\n 'relative mx-auto my-8 w-full max-w-5xl border-2 border-dashed border-edge-strong bg-surface-base font-mono text-sm text-content-primary',\n className,\n )}\n {...rest}\n >\n <span aria-hidden=\"true\" className=\"pointer-events-none absolute left-0 top-0 z-10 flex size-4 -translate-x-1/2 -translate-y-1/2 items-center justify-center bg-surface-base font-mono text-xs leading-none text-content-muted\">\n {corner}\n </span>\n <span aria-hidden=\"true\" className=\"pointer-events-none absolute right-0 top-0 z-10 flex size-4 translate-x-1/2 -translate-y-1/2 items-center justify-center bg-surface-base font-mono text-xs leading-none text-content-muted\">\n {corner}\n </span>\n <span aria-hidden=\"true\" className=\"pointer-events-none absolute bottom-0 left-0 z-10 flex size-4 -translate-x-1/2 translate-y-1/2 items-center justify-center bg-surface-base font-mono text-xs leading-none text-content-muted\">\n {corner}\n </span>\n <span aria-hidden=\"true\" className=\"pointer-events-none absolute bottom-0 right-0 z-10 flex size-4 translate-x-1/2 translate-y-1/2 items-center justify-center bg-surface-base font-mono text-xs leading-none text-content-muted\">\n {corner}\n </span>\n {title ? <figcaption className=\"absolute left-1/2 top-0 z-10 -translate-x-1/2 -translate-y-1/2 whitespace-nowrap bg-surface-base px-3 uppercase tracking-wide text-accent-primary\">[ {title} ]</figcaption> : null}\n <div className=\"flex min-w-0 flex-col gap-6 px-5 py-7 sm:px-8 sm:py-8\">{children}</div>\n </figure>\n );\n});\n\n/** Internal root for a renderer. The frame owns the inset. */\nexport const AsciiFrameBody = React.forwardRef<HTMLDivElement, React.ComponentProps<'div'>>(function AsciiFrameBody({ className, ...props }, ref) {\n return <div data-slot=\"ascii-frame-body\" ref={ref} className={cn('min-w-0', className)} {...props} />;\n});\n\n/** Markdown children inside a documentation visual. */\nexport function AsciiFrameProse({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div data-slot=\"ascii-frame-prose\"\n className={cn(\n 'flex min-w-0 flex-col gap-3 leading-relaxed',\n '[&_p]:m-0 [&_p]:text-pretty',\n '[&_ul]:m-0 [&_ul]:flex [&_ul]:list-none [&_ul]:flex-col [&_ul]:gap-1 [&_ul]:p-0',\n '[&_ol]:m-0 [&_ol]:flex [&_ol]:list-none [&_ol]:flex-col [&_ol]:gap-1 [&_ol]:p-0',\n '[&_li]:relative [&_li]:pl-4 [&_li]:before:absolute [&_li]:before:left-0 [&_li]:before:text-content-muted [&_li]:before:content-[\\'-\\']',\n '[&_a]:text-content-primary [&_a]:underline [&_a]:decoration-dashed [&_a]:underline-offset-[0.2em]',\n '[&_code]:font-semibold [&_code]:text-content-primary',\n '[&_pre]:m-0 [&_pre]:whitespace-pre-wrap [&_pre_code]:font-normal [&_pre_code]:text-inherit',\n '[&_strong]:font-semibold [&_strong]:text-content-primary',\n '[&_em]:text-content-secondary [&_em]:not-italic',\n className,\n )}\n {...props}\n />\n );\n}\n\n/** A dashed horizontal rule inside a documentation visual. */\nexport function AsciiFrameRule({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"ascii-frame-rule\" aria-hidden=\"true\" className={cn('my-1 h-px w-full border-t border-dashed border-edge-subtle', className)} {...props} />;\n}\n\n/** A dashed vertical rule inside a documentation visual. */\nexport function AsciiFrameRuleY({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"ascii-frame-rule-y\" aria-hidden=\"true\" className={cn('w-px self-stretch border-l border-dashed border-edge-subtle', className)} {...props} />;\n}\n\n/** A full-width character track used by uptime and related figures. */\nexport function AsciiFrameTrack({ className, ...props }: React.ComponentProps<'span'>) {\n return <span data-slot=\"ascii-frame-track\" aria-hidden=\"true\" className={cn('flex w-full min-w-0 select-none', className)} {...props} />;\n}\n\n/** One flexible cell in a character track. */\nexport function AsciiFrameTick({ className, ...props }: React.ComponentProps<'span'>) {\n return <span data-slot=\"ascii-frame-tick\" className={cn('min-w-0 flex-1 overflow-hidden text-center', className)} {...props} />;\n}\n\n/** ASCII arrow used by flow diagrams. */\nexport function AsciiFrameArrow({ accent = false, stretch = false, className }: { accent?: boolean; stretch?: boolean; className?: string }) {\n return (\n <span data-slot=\"ascii-frame-arrow\" aria-hidden=\"true\" className={cn('flex min-w-6 items-center text-content-muted', stretch && 'flex-1', className)}>\n <span className={cn('w-full border-t border-dashed border-current', accent && 'text-accent-primary')} />\n <span className={cn('-ml-1', accent ? 'text-accent-primary' : 'text-content-muted')}>▶</span>\n </span>\n );\n}\n\ntype WithChildren<P> = P & { children?: ReactNode };\ntype AsciiItemComponent<P extends object> = ((props: WithChildren<P>) => null) & {\n graphItem: string;\n displayName?: string;\n};\n\n/** Defines an MDX-only data child that its parent renderer reads. */\nexport function defineAsciiItem<P extends object>(name: string): AsciiItemComponent<P> {\n const Item = (() => null) as unknown as AsciiItemComponent<P>;\n Item.displayName = name;\n Item.graphItem = name;\n return Item;\n}\n\nfunction typeName(type: unknown): string {\n if (typeof type === 'string') return type;\n if (typeof type === 'function') {\n const fn = type as { graphItem?: string; displayName?: string; name?: string };\n return fn.graphItem || fn.displayName || fn.name || '';\n }\n if (type && typeof type === 'object') {\n const value = type as { graphItem?: string; displayName?: string; name?: string; $$id?: string };\n if (value.graphItem) return value.graphItem;\n if (value.displayName) return value.displayName;\n if (typeof value.$$id === 'string') return value.$$id.split('#').pop()?.split('@')[0] ?? '';\n return value.name || '';\n }\n return '';\n}\n\nexport function isHost(element: ReactElement, tags: string | readonly string[]): boolean {\n const name = typeName(element.type).toLowerCase();\n const list = typeof tags === 'string' ? [tags] : tags;\n return list.some((tag) => tag.toLowerCase() === name);\n}\n\nexport function elementsOf(children: ReactNode): ReactElement[] {\n const result: ReactElement[] = [];\n for (const child of React.Children.toArray(children)) {\n if (!React.isValidElement(child)) continue;\n if (child.type === React.Fragment) {\n result.push(...elementsOf((child.props as { children?: ReactNode }).children));\n } else {\n result.push(child);\n }\n }\n return result;\n}\n\nexport function textOf(children: ReactNode): string {\n return React.Children.toArray(children)\n .map((child) => (React.isValidElement(child) ? textOf((child.props as { children?: ReactNode }).children) : String(child)))\n .join('');\n}\n\nexport function itemText(item: ReactElement): string {\n const children = (item.props as { children?: ReactNode }).children;\n return textOf(children).replace(/\\s+/g, ' ').trim();\n}\n\nexport function listItems(children: ReactNode): ReactElement[] {\n const elements = elementsOf(children);\n const lists = elements.filter((element) => isHost(element, ['ul', 'ol']));\n const items = lists.length > 0\n ? lists.flatMap((list) => elementsOf((list.props as { children?: ReactNode }).children))\n : elements;\n return items.filter((element) => isHost(element, 'li'));\n}\n\nexport function nestedList(item: ReactElement): ReactElement[] {\n return listItems((item.props as { children?: ReactNode }).children);\n}\n\nexport function paragraphsOf(children: ReactNode): ReactElement[] {\n return elementsOf(children).filter((element) => isHost(element, 'p'));\n}\n\nexport function hasHost(children: ReactNode, tags: string | readonly string[]): boolean {\n return React.Children.toArray(children).some((child) => {\n if (!React.isValidElement(child)) return false;\n return isHost(child, tags) || hasHost((child.props as { children?: ReactNode }).children, tags);\n });\n}\n\nexport function childItems<P extends object>(children: ReactNode, item: AsciiItemComponent<P>): (P & { children?: ReactNode })[] {\n return elementsOf(children)\n .filter((element) => typeName(element.type) === item.graphItem)\n .map((element) => element.props as P & { children?: ReactNode });\n}\n\nexport function splitLabel(value: string): { label: string; rest: string } {\n const match = value.match(/^([^:—–-]+?)\\s*:\\s*(.*)$/);\n if (!match) return { label: value.trim(), rest: '' };\n return { label: match[1]?.trim() ?? '', rest: match[2]?.trim() ?? '' };\n}\n\nexport function splitDash(value: string): { label: string; rest: string } {\n const match = value.match(/^(.+?)\\s+[-—–]\\s+(.+)$/);\n if (!match) return { label: value.trim(), rest: '' };\n return { label: match[1]?.trim() ?? '', rest: match[2]?.trim() ?? '' };\n}\n\nexport function numberOf(value: number | string): number {\n if (typeof value === 'number') return value;\n const parsed = Number(value.replace(/[^\\d.+-]/g, ''));\n return Number.isFinite(parsed) ? parsed : 0;\n}\n"],"mappings":"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","names":["FigureFrame","AsciiFrameBody"]}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
// src/components/docs/figures/FileChangeTree.tsx
|
|
4
|
+
import * as React from "react";
|
|
5
|
+
import { AsciiFrameBody } from "./FigureFrame.js";
|
|
6
|
+
import { cn } from "../../../lib/recipe.js";
|
|
7
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
var VIEWS = ["before", "changes", "after"];
|
|
9
|
+
var CHANGES = ["add", "modify", "rename", "remove"];
|
|
10
|
+
var DEFAULT_VIEW_LABELS = { before: "Before", changes: "Changes", after: "After" };
|
|
11
|
+
var DEFAULT_CHANGE_LABELS = { add: "added", modify: "modified", rename: "renamed", remove: "removed" };
|
|
12
|
+
var GLYPH = { add: "+", modify: "~", rename: "\u2192", remove: "\u2212" };
|
|
13
|
+
var TONE = {
|
|
14
|
+
add: { text: "text-intent-success", fill: "bg-intent-success" },
|
|
15
|
+
modify: { text: "text-intent-warning", fill: "bg-intent-warning" },
|
|
16
|
+
rename: { text: "text-intent-info", fill: "bg-intent-info" },
|
|
17
|
+
remove: { text: "text-intent-danger", fill: "bg-intent-danger" }
|
|
18
|
+
};
|
|
19
|
+
function isDirectory(node) {
|
|
20
|
+
return node.children != null;
|
|
21
|
+
}
|
|
22
|
+
function visible(nodes, view) {
|
|
23
|
+
return nodes.flatMap((node) => {
|
|
24
|
+
if (view === "before" && node.change === "add") return [];
|
|
25
|
+
if (view === "after" && node.change === "remove") return [];
|
|
26
|
+
if (!isDirectory(node)) return [node];
|
|
27
|
+
const children = visible(node.children ?? [], view);
|
|
28
|
+
return children.length > 0 || view === "changes" ? [{ ...node, children }] : [];
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function tally(nodes, counts = { add: 0, modify: 0, rename: 0, remove: 0 }) {
|
|
32
|
+
for (const node of nodes) {
|
|
33
|
+
if (node.change) counts[node.change] += 1;
|
|
34
|
+
if (node.children) tally(node.children, counts);
|
|
35
|
+
}
|
|
36
|
+
return counts;
|
|
37
|
+
}
|
|
38
|
+
function ChangeMark({ change }) {
|
|
39
|
+
return /* @__PURE__ */ jsx(
|
|
40
|
+
"span",
|
|
41
|
+
{
|
|
42
|
+
"aria-hidden": "true",
|
|
43
|
+
"data-slot": "file-change-tree-mark",
|
|
44
|
+
className: cn("inline-flex size-4 shrink-0 select-none items-center justify-center text-[0.7rem] font-bold leading-none text-content-inverse", TONE[change].fill),
|
|
45
|
+
children: GLYPH[change]
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
function Entries({ nodes, view, changeLabels }) {
|
|
50
|
+
return /* @__PURE__ */ jsx("ul", { className: "flex flex-col gap-3", "data-slot": "file-change-tree-list", children: nodes.map((node, index) => {
|
|
51
|
+
const last = index === nodes.length - 1;
|
|
52
|
+
const marked = view === "changes" && node.change != null;
|
|
53
|
+
const change = marked ? node.change : void 0;
|
|
54
|
+
return /* @__PURE__ */ jsxs("li", { className: "relative pl-6", "data-slot": "file-change-tree-entry", children: [
|
|
55
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: cn("absolute left-0 top-0 border-l-2 border-edge-subtle", last ? "h-[0.8em]" : "-bottom-3") }),
|
|
56
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "absolute left-0 top-[0.8em] w-4 border-t-2 border-edge-subtle" }),
|
|
57
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
58
|
+
change ? /* @__PURE__ */ jsx(ChangeMark, { change }) : null,
|
|
59
|
+
/* @__PURE__ */ jsx("span", { "data-slot": "file-change-tree-name", className: cn("min-w-0 break-all font-mono", change ? TONE[change].text : "text-content-primary", change === "remove" && "line-through"), children: node.name }),
|
|
60
|
+
change ? /* @__PURE__ */ jsxs("span", { className: "sr-only", children: [
|
|
61
|
+
"(",
|
|
62
|
+
changeLabels[change],
|
|
63
|
+
")"
|
|
64
|
+
] }) : null
|
|
65
|
+
] }),
|
|
66
|
+
node.note != null && !isDirectory(node) ? /* @__PURE__ */ jsx("p", { "data-slot": "file-change-tree-note", className: "m-0 mt-1 text-pretty text-content-secondary", children: node.note }) : null,
|
|
67
|
+
isDirectory(node) && (node.children?.length ?? 0) > 0 ? /* @__PURE__ */ jsx("div", { className: "mt-3", children: /* @__PURE__ */ jsx(Entries, { nodes: node.children ?? [], view, changeLabels }) }) : null
|
|
68
|
+
] }, `${node.name}-${index}`);
|
|
69
|
+
}) });
|
|
70
|
+
}
|
|
71
|
+
var FileChangeTree = React.forwardRef(function FileChangeTree2({ label = "File changes", nodes, view: viewProp, defaultView = "changes", onViewChange, hideFooter = false, viewGroupLabel, viewLabels, changeLabels, className, ...rest }, ref) {
|
|
72
|
+
const [uncontrolled, setUncontrolled] = React.useState(defaultView);
|
|
73
|
+
const view = viewProp ?? uncontrolled;
|
|
74
|
+
const views = { ...DEFAULT_VIEW_LABELS, ...viewLabels };
|
|
75
|
+
const changes = { ...DEFAULT_CHANGE_LABELS, ...changeLabels };
|
|
76
|
+
const columns = visible(nodes, view);
|
|
77
|
+
const counts = tally(nodes);
|
|
78
|
+
const connected = columns.length > 1;
|
|
79
|
+
const pick = (next) => {
|
|
80
|
+
if (viewProp == null) setUncontrolled(next);
|
|
81
|
+
onViewChange?.(next);
|
|
82
|
+
};
|
|
83
|
+
return /* @__PURE__ */ jsxs(AsciiFrameBody, { ref, ...rest, "data-slot": "file-change-tree", className: cn("flex flex-col gap-6 font-mono text-sm", className), children: [
|
|
84
|
+
/* @__PURE__ */ jsx("div", { role: "list", "aria-label": label, className: "flex flex-col gap-8 sm:flex-row sm:gap-6", children: columns.map((column, index) => {
|
|
85
|
+
const first = index === 0;
|
|
86
|
+
const last = index === columns.length - 1;
|
|
87
|
+
const marked = view === "changes" && column.change != null;
|
|
88
|
+
return /* @__PURE__ */ jsxs("div", { role: "listitem", className: "relative flex min-w-0 flex-1 flex-col", "data-slot": "file-change-tree-column", children: [
|
|
89
|
+
connected ? /* @__PURE__ */ jsxs("span", { "aria-hidden": "true", className: "relative hidden h-6 sm:block", children: [
|
|
90
|
+
/* @__PURE__ */ jsx("span", { className: cn("absolute top-0 border-t-2 border-edge-strong", first ? "left-1/2" : "-left-3", last ? "right-1/2" : "-right-3") }),
|
|
91
|
+
/* @__PURE__ */ jsx("span", { className: "absolute left-1/2 top-0 h-full border-l-2 border-edge-strong" })
|
|
92
|
+
] }) : null,
|
|
93
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-center gap-2 border-2 border-edge-strong bg-surface-base px-3 py-3 font-semibold text-content-primary", "data-slot": "file-change-tree-root", children: [
|
|
94
|
+
marked && column.change ? /* @__PURE__ */ jsx(ChangeMark, { change: column.change }) : null,
|
|
95
|
+
/* @__PURE__ */ jsx("span", { className: cn("break-all", marked && column.change ? TONE[column.change].text : void 0), children: column.name }),
|
|
96
|
+
marked && column.change ? /* @__PURE__ */ jsxs("span", { className: "sr-only", children: [
|
|
97
|
+
"(",
|
|
98
|
+
changes[column.change],
|
|
99
|
+
")"
|
|
100
|
+
] }) : null
|
|
101
|
+
] }),
|
|
102
|
+
column.note != null ? /* @__PURE__ */ jsx("p", { "data-slot": "file-change-tree-note", className: "m-0 mt-2 text-pretty text-content-secondary", children: column.note }) : null,
|
|
103
|
+
(column.children?.length ?? 0) > 0 ? /* @__PURE__ */ jsx("div", { className: "ml-4 mt-4", children: /* @__PURE__ */ jsx(Entries, { nodes: column.children ?? [], view, changeLabels: changes }) }) : null
|
|
104
|
+
] }, `${column.name}-${index}`);
|
|
105
|
+
}) }),
|
|
106
|
+
hideFooter ? null : /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4", "data-slot": "file-change-tree-footer", children: [
|
|
107
|
+
/* @__PURE__ */ jsx("p", { className: "m-0 flex flex-wrap gap-x-5 gap-y-1 font-mono tabular-nums", "data-slot": "file-change-tree-tally", children: CHANGES.filter((change) => counts[change] > 0).map((change) => /* @__PURE__ */ jsxs("span", { className: TONE[change].text, children: [
|
|
108
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: GLYPH[change] }),
|
|
109
|
+
counts[change],
|
|
110
|
+
" ",
|
|
111
|
+
changes[change]
|
|
112
|
+
] }, change)) }),
|
|
113
|
+
/* @__PURE__ */ jsx("div", { role: "group", "aria-label": viewGroupLabel ?? "View", className: "flex border-2 border-edge-default", "data-slot": "file-change-tree-views", children: VIEWS.map((option, index) => /* @__PURE__ */ jsx(
|
|
114
|
+
"button",
|
|
115
|
+
{
|
|
116
|
+
type: "button",
|
|
117
|
+
"aria-pressed": view === option,
|
|
118
|
+
onClick: () => pick(option),
|
|
119
|
+
className: cn(
|
|
120
|
+
"px-4 py-1.5 text-content-secondary hover:bg-surface-raised",
|
|
121
|
+
index > 0 && "border-l-2 border-edge-default",
|
|
122
|
+
view === option && "bg-content-primary font-semibold text-content-inverse hover:bg-content-primary"
|
|
123
|
+
),
|
|
124
|
+
children: views[option]
|
|
125
|
+
},
|
|
126
|
+
option
|
|
127
|
+
)) })
|
|
128
|
+
] })
|
|
129
|
+
] });
|
|
130
|
+
});
|
|
131
|
+
export {
|
|
132
|
+
FileChangeTree
|
|
133
|
+
};
|
|
134
|
+
//# sourceMappingURL=FileChangeTree.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/docs/figures/FileChangeTree.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\nimport * as React from 'react';\nimport { AsciiFrameBody } from './FigureFrame';\nimport { cn } from '../../../lib/recipe';\n\nexport type FileChange = 'add' | 'modify' | 'remove' | 'rename';\nexport type FileChangeView = 'before' | 'changes' | 'after';\n\nexport interface FileChangeNode {\n /** File or directory name. A node with `children` is drawn as a directory. */\n name: string;\n /** How the file changed. Omit for an unchanged file or a directory. */\n change?: FileChange;\n /** One line on what changed, drawn under the name. */\n note?: ReactNode;\n /** Entries inside a directory. */\n children?: FileChangeNode[];\n}\n\nexport interface FileChangeTreeProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'children'> {\n /** Accessible name; the enclosing frame owns the caption. */\n label?: string;\n /** Top-level entries. Each one becomes a column under the shared connector. */\n nodes: FileChangeNode[];\n /** Controlled view. `changes` marks every entry; `before` and `after` show the tree on one side of the change. */\n view?: FileChangeView;\n /** Initial view when uncontrolled. */\n defaultView?: FileChangeView;\n /** Called when the reader picks a view. */\n onViewChange?: (view: FileChangeView) => void;\n /** Hide the before / changes / after switch and the tallies. */\n hideFooter?: boolean;\n /** Accessible label for the view selection button group. */\n viewGroupLabel?: string;\n /** Replaces the switch's button text, for translated pages. */\n viewLabels?: Partial<Record<FileChangeView, string>>;\n /** Replaces the tally words, for translated pages. */\n changeLabels?: Partial<Record<FileChange, string>>;\n /** Additional classes for the root. */\n className?: string;\n}\n\nconst VIEWS: readonly FileChangeView[] = ['before', 'changes', 'after'];\nconst CHANGES: readonly FileChange[] = ['add', 'modify', 'rename', 'remove'];\n\nconst DEFAULT_VIEW_LABELS: Record<FileChangeView, string> = { before: 'Before', changes: 'Changes', after: 'After' };\nconst DEFAULT_CHANGE_LABELS: Record<FileChange, string> = { add: 'added', modify: 'modified', rename: 'renamed', remove: 'removed' };\n\nconst GLYPH: Record<FileChange, string> = { add: '+', modify: '~', rename: '→', remove: '−' };\n\n/** A change is meaning, so it is addressed through intent roles, never accents. */\nconst TONE: Record<FileChange, { text: string; fill: string }> = {\n add: { text: 'text-intent-success', fill: 'bg-intent-success' },\n modify: { text: 'text-intent-warning', fill: 'bg-intent-warning' },\n rename: { text: 'text-intent-info', fill: 'bg-intent-info' },\n remove: { text: 'text-intent-danger', fill: 'bg-intent-danger' },\n};\n\nfunction isDirectory(node: FileChangeNode): boolean {\n return node.children != null;\n}\n\n/** Drops what does not exist on one side of the change, and empty directories with it. */\nfunction visible(nodes: FileChangeNode[], view: FileChangeView): FileChangeNode[] {\n return nodes.flatMap((node) => {\n if (view === 'before' && node.change === 'add') return [];\n if (view === 'after' && node.change === 'remove') return [];\n if (!isDirectory(node)) return [node];\n const children = visible(node.children ?? [], view);\n return children.length > 0 || view === 'changes' ? [{ ...node, children }] : [];\n });\n}\n\nfunction tally(nodes: FileChangeNode[], counts: Record<FileChange, number> = { add: 0, modify: 0, rename: 0, remove: 0 }): Record<FileChange, number> {\n for (const node of nodes) {\n if (node.change) counts[node.change] += 1;\n if (node.children) tally(node.children, counts);\n }\n return counts;\n}\n\nfunction ChangeMark({ change }: { change: FileChange }) {\n return (\n <span\n aria-hidden=\"true\"\n data-slot=\"file-change-tree-mark\"\n className={cn('inline-flex size-4 shrink-0 select-none items-center justify-center text-[0.7rem] font-bold leading-none text-content-inverse', TONE[change].fill)}\n >\n {GLYPH[change]}\n </span>\n );\n}\n\nfunction Entries({ nodes, view, changeLabels }: { nodes: FileChangeNode[]; view: FileChangeView; changeLabels: Record<FileChange, string> }) {\n return (\n <ul className=\"flex flex-col gap-3\" data-slot=\"file-change-tree-list\">\n {nodes.map((node, index) => {\n const last = index === nodes.length - 1;\n const marked = view === 'changes' && node.change != null;\n const change = marked ? node.change : undefined;\n return (\n <li key={`${node.name}-${index}`} className=\"relative pl-6\" data-slot=\"file-change-tree-entry\">\n {/* The elbow: a stem down to this row, then a tick across to it. The last row's stem stops at its tick. */}\n <span aria-hidden=\"true\" className={cn('absolute left-0 top-0 border-l-2 border-edge-subtle', last ? 'h-[0.8em]' : '-bottom-3')} />\n <span aria-hidden=\"true\" className=\"absolute left-0 top-[0.8em] w-4 border-t-2 border-edge-subtle\" />\n <div className=\"flex items-center gap-2\">\n {change ? <ChangeMark change={change} /> : null}\n <span data-slot=\"file-change-tree-name\" className={cn('min-w-0 break-all font-mono', change ? TONE[change].text : 'text-content-primary', change === 'remove' && 'line-through')}>\n {node.name}\n </span>\n {change ? <span className=\"sr-only\">({changeLabels[change]})</span> : null}\n </div>\n {node.note != null && !isDirectory(node) ? <p data-slot=\"file-change-tree-note\" className=\"m-0 mt-1 text-pretty text-content-secondary\">{node.note}</p> : null}\n {isDirectory(node) && (node.children?.length ?? 0) > 0 ? (\n <div className=\"mt-3\">\n <Entries nodes={node.children ?? []} view={view} changeLabels={changeLabels} />\n </div>\n ) : null}\n </li>\n );\n })}\n </ul>\n );\n}\n\n/**\n * A changeset drawn as its directory layout: each top-level directory is a boxed column under\n * one connector, its files hang from a ruled tree with a change mark and a one-line note, and a\n * footer tallies the change and switches between the tree before, the change itself, and after.\n *\n * Stacks into one column below the `sm` breakpoint, where the connector is dropped.\n */\nexport const FileChangeTree = React.forwardRef<HTMLDivElement, FileChangeTreeProps>(function FileChangeTree(\n { label = 'File changes', nodes, view: viewProp, defaultView = 'changes', onViewChange, hideFooter = false, viewGroupLabel, viewLabels, changeLabels, className, ...rest },\n ref,\n) {\n const [uncontrolled, setUncontrolled] = React.useState<FileChangeView>(defaultView);\n const view = viewProp ?? uncontrolled;\n const views = { ...DEFAULT_VIEW_LABELS, ...viewLabels };\n const changes = { ...DEFAULT_CHANGE_LABELS, ...changeLabels };\n const columns = visible(nodes, view);\n const counts = tally(nodes);\n const connected = columns.length > 1;\n\n const pick = (next: FileChangeView) => {\n if (viewProp == null) setUncontrolled(next);\n onViewChange?.(next);\n };\n\n return (\n <AsciiFrameBody ref={ref} {...rest} data-slot=\"file-change-tree\" className={cn('flex flex-col gap-6 font-mono text-sm', className)}>\n <div role=\"list\" aria-label={label} className=\"flex flex-col gap-8 sm:flex-row sm:gap-6\">\n {columns.map((column, index) => {\n const first = index === 0;\n const last = index === columns.length - 1;\n const marked = view === 'changes' && column.change != null;\n return (\n <div role=\"listitem\" key={`${column.name}-${index}`} className=\"relative flex min-w-0 flex-1 flex-col\" data-slot=\"file-change-tree-column\">\n {connected ? (\n <span aria-hidden=\"true\" className=\"relative hidden h-6 sm:block\">\n {/* The shared bar, carried half a gap past each side so neighbours meet; the ends stop at the drop. */}\n <span className={cn('absolute top-0 border-t-2 border-edge-strong', first ? 'left-1/2' : '-left-3', last ? 'right-1/2' : '-right-3')} />\n <span className=\"absolute left-1/2 top-0 h-full border-l-2 border-edge-strong\" />\n </span>\n ) : null}\n <div className=\"flex items-center justify-center gap-2 border-2 border-edge-strong bg-surface-base px-3 py-3 font-semibold text-content-primary\" data-slot=\"file-change-tree-root\">\n {marked && column.change ? <ChangeMark change={column.change} /> : null}\n <span className={cn('break-all', marked && column.change ? TONE[column.change].text : undefined)}>{column.name}</span>\n {marked && column.change ? <span className=\"sr-only\">({changes[column.change]})</span> : null}\n </div>\n {column.note != null ? <p data-slot=\"file-change-tree-note\" className=\"m-0 mt-2 text-pretty text-content-secondary\">{column.note}</p> : null}\n {(column.children?.length ?? 0) > 0 ? (\n <div className=\"ml-4 mt-4\">\n <Entries nodes={column.children ?? []} view={view} changeLabels={changes} />\n </div>\n ) : null}\n </div>\n );\n })}\n </div>\n {hideFooter ? null : (\n <div className=\"flex flex-wrap items-center justify-between gap-4\" data-slot=\"file-change-tree-footer\">\n <p className=\"m-0 flex flex-wrap gap-x-5 gap-y-1 font-mono tabular-nums\" data-slot=\"file-change-tree-tally\">\n {CHANGES.filter((change) => counts[change] > 0).map((change) => (\n <span key={change} className={TONE[change].text}>\n <span aria-hidden=\"true\">{GLYPH[change]}</span>\n {counts[change]} {changes[change]}\n </span>\n ))}\n </p>\n <div role=\"group\" aria-label={viewGroupLabel ?? 'View'} className=\"flex border-2 border-edge-default\" data-slot=\"file-change-tree-views\">\n {VIEWS.map((option, index) => (\n <button\n key={option}\n type=\"button\"\n aria-pressed={view === option}\n onClick={() => pick(option)}\n className={cn(\n 'px-4 py-1.5 text-content-secondary hover:bg-surface-raised',\n index > 0 && 'border-l-2 border-edge-default',\n view === option && 'bg-content-primary font-semibold text-content-inverse hover:bg-content-primary',\n )}\n >\n {views[option]}\n </button>\n ))}\n </div>\n </div>\n )}\n </AsciiFrameBody>\n );\n});\n"],"mappings":"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","names":["FileChangeTree"]}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
// src/components/docs/figures/FlowDiagram.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import {
|
|
4
|
+
childItems,
|
|
5
|
+
defineAsciiItem,
|
|
6
|
+
AsciiFrameArrow,
|
|
7
|
+
AsciiFrameBody,
|
|
8
|
+
isHost,
|
|
9
|
+
listItems,
|
|
10
|
+
paragraphsOf,
|
|
11
|
+
textOf
|
|
12
|
+
} from "./FigureFrame.js";
|
|
13
|
+
import { cn } from "../../../lib/recipe.js";
|
|
14
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
15
|
+
var Path = defineAsciiItem("Path");
|
|
16
|
+
var ARROW = /\s*(?:→|->|—>|=>)\s*/;
|
|
17
|
+
function nodesOf(children) {
|
|
18
|
+
const nodes = [];
|
|
19
|
+
for (const child of React.Children.toArray(children)) {
|
|
20
|
+
if (typeof child === "string" || typeof child === "number") {
|
|
21
|
+
for (const part of String(child).split(ARROW)) {
|
|
22
|
+
const label = part.trim();
|
|
23
|
+
if (label) nodes.push({ label });
|
|
24
|
+
}
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (!React.isValidElement(child)) continue;
|
|
28
|
+
if (isHost(child, ["strong", "b"])) {
|
|
29
|
+
nodes.push({ label: textOf(child).trim(), tone: "accent" });
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
if (isHost(child, ["em", "i"])) {
|
|
33
|
+
nodes.push({ label: textOf(child).trim(), tone: "muted" });
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
nodes.push(...nodesOf(child.props.children));
|
|
37
|
+
}
|
|
38
|
+
return nodes;
|
|
39
|
+
}
|
|
40
|
+
function rowsOf(children) {
|
|
41
|
+
const tagged = childItems(children, Path).map((path) => ({ nodes: nodesOf(path.children) }));
|
|
42
|
+
if (tagged.length > 0) return tagged;
|
|
43
|
+
const listed = listItems(children);
|
|
44
|
+
if (listed.length > 0) {
|
|
45
|
+
return listed.map((item) => ({ nodes: nodesOf(item.props.children) }));
|
|
46
|
+
}
|
|
47
|
+
const paragraphs = paragraphsOf(children);
|
|
48
|
+
if (paragraphs.length > 0) {
|
|
49
|
+
return paragraphs.map((paragraph) => ({ nodes: nodesOf(paragraph.props.children) }));
|
|
50
|
+
}
|
|
51
|
+
const text = textOf(children).trim();
|
|
52
|
+
return text ? text.split(/\n+/).map((line) => ({ nodes: nodesOf(line) })) : [];
|
|
53
|
+
}
|
|
54
|
+
function toneClass(palette, tone) {
|
|
55
|
+
if (tone === "accent") return "text-accent-primary";
|
|
56
|
+
if (tone === "muted") return palette === "multi" ? "text-accent-secondary" : "text-content-muted";
|
|
57
|
+
return "text-content-primary";
|
|
58
|
+
}
|
|
59
|
+
var FlowDiagram = React.forwardRef(function FlowDiagram2({ label = "Flow diagram", rows: rowsProp, children, palette, className, ...rest }, ref) {
|
|
60
|
+
const rows = rowsProp ?? rowsOf(children);
|
|
61
|
+
return /* @__PURE__ */ jsxs(AsciiFrameBody, { "data-slot": "flow-diagram", ref, ...rest, className: cn("flex flex-col gap-7", className), children: [
|
|
62
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col gap-7", role: "list", "aria-label": `${label} paths`, children: rows.map((row, rowIndex) => /* @__PURE__ */ jsx(
|
|
63
|
+
"div",
|
|
64
|
+
{
|
|
65
|
+
className: "flex min-w-0 flex-wrap items-center gap-x-3 gap-y-2 sm:flex-nowrap",
|
|
66
|
+
"aria-label": row.nodes.map((node) => node.label).join(" then "),
|
|
67
|
+
role: "listitem",
|
|
68
|
+
children: row.nodes.map((node, nodeIndex) => /* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 items-center gap-3", node.stretch && "min-w-16 flex-1"), children: [
|
|
69
|
+
nodeIndex > 0 ? /* @__PURE__ */ jsx(AsciiFrameArrow, { accent: node.tone === "accent", stretch: node.stretch }) : null,
|
|
70
|
+
/* @__PURE__ */ jsx("span", { className: cn("shrink-0 whitespace-nowrap", toneClass(palette, node.tone ?? "default")), children: node.label })
|
|
71
|
+
] }, `${node.label}-${nodeIndex}`))
|
|
72
|
+
},
|
|
73
|
+
`row-${rowIndex}`
|
|
74
|
+
)) }),
|
|
75
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: rows.length === 0 ? "Empty flow." : `Flow with ${rows.length} path${rows.length === 1 ? "" : "s"}: ${rows.map((row) => row.nodes.map((node) => node.label).join(" then ")).join("; ")}.` })
|
|
76
|
+
] });
|
|
77
|
+
});
|
|
78
|
+
export {
|
|
79
|
+
FlowDiagram,
|
|
80
|
+
Path
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=FlowDiagram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/components/docs/figures/FlowDiagram.tsx"],"sourcesContent":["/**\n * Adapted from mdxcn by Keshav Bagaade, MIT licensed.\n * Source: https://github.com/keshav-exe/mdxcn/blob/2928126ba146ebbae9c2351deca27d27bb40e744/registry/default/graph-flow/graph-flow.tsx\n * The local port keeps the MDX data API while replacing motion and graph\n * variables with deterministic rendering and semantic design-system tokens.\n */\n\nimport type { ReactNode } from 'react';\nimport * as React from 'react';\nimport {\n childItems,\n defineAsciiItem,\n AsciiFrameArrow,\n AsciiFrameBody,\n isHost,\n listItems,\n paragraphsOf,\n textOf,\n type FigurePalette,\n} from './FigureFrame';\nimport { cn } from '../../../lib/recipe';\n\nexport type FlowTone = 'default' | 'accent' | 'muted';\n\nexport interface FlowNode {\n /** Text shown in the node. */\n label: string;\n /** Visual emphasis for the node. */\n tone?: FlowTone;\n /** Let this node absorb available row width. */\n stretch?: boolean;\n}\n\nexport interface FlowRow {\n /** Nodes rendered from left to right. */\n nodes: FlowNode[];\n}\n\nexport interface FlowPathProps {\n /** Flow nodes can also be written as Markdown children. */\n children?: ReactNode;\n}\n\nexport interface FlowDiagramProps extends React.HTMLAttributes<HTMLDivElement> {\n /** Accessible name for the paths; the enclosing FigureFrame owns the caption. */\n label?: string;\n /** Data form. If omitted, the component reads Markdown or `<Path>` children. */\n rows?: FlowRow[];\n /** Markdown list or `<Path>` content used to derive rows. */\n children?: ReactNode;\n /** Accent palette used for emphasized nodes. */\n palette?: FigurePalette;\n /** Additional classes for this diagram. */\n className?: string;\n}\n\n/** MDX-only item for a flow row, for example `<Path>write → ship</Path>`. */\nexport const Path = defineAsciiItem<FlowPathProps>('Path');\n\nconst ARROW = /\\s*(?:→|->|—>|=>)\\s*/;\n\nfunction nodesOf(children: ReactNode): FlowNode[] {\n const nodes: FlowNode[] = [];\n\n for (const child of React.Children.toArray(children)) {\n if (typeof child === 'string' || typeof child === 'number') {\n for (const part of String(child).split(ARROW)) {\n const label = part.trim();\n if (label) nodes.push({ label });\n }\n continue;\n }\n\n if (!React.isValidElement<{ children?: ReactNode }>(child)) continue;\n if (isHost(child, ['strong', 'b'])) {\n nodes.push({ label: textOf(child).trim(), tone: 'accent' });\n continue;\n }\n if (isHost(child, ['em', 'i'])) {\n nodes.push({ label: textOf(child).trim(), tone: 'muted' });\n continue;\n }\n nodes.push(...nodesOf(child.props.children));\n }\n\n return nodes;\n}\n\nfunction rowsOf(children: ReactNode): FlowRow[] {\n const tagged = childItems(children, Path).map((path) => ({ nodes: nodesOf(path.children) }));\n if (tagged.length > 0) return tagged;\n\n const listed = listItems(children);\n if (listed.length > 0) {\n return listed.map((item) => ({ nodes: nodesOf((item.props as { children?: ReactNode }).children) }));\n }\n\n const paragraphs = paragraphsOf(children);\n if (paragraphs.length > 0) {\n return paragraphs.map((paragraph) => ({ nodes: nodesOf((paragraph.props as { children?: ReactNode }).children) }));\n }\n\n const text = textOf(children).trim();\n return text ? text.split(/\\n+/).map((line) => ({ nodes: nodesOf(line) })) : [];\n}\n\nfunction toneClass(palette: FigurePalette | undefined, tone: FlowTone): string {\n if (tone === 'accent') return 'text-accent-primary';\n if (tone === 'muted') return palette === 'multi' ? 'text-accent-secondary' : 'text-content-muted';\n return 'text-content-primary';\n}\n\n/**\n * Renders an MDX-friendly sequence of nodes connected by ASCII arrows.\n * Bold nodes are emphasized and italic nodes recede without relying on animation.\n */\nexport const FlowDiagram = React.forwardRef<HTMLDivElement, FlowDiagramProps>(function FlowDiagram({ label = 'Flow diagram', rows: rowsProp, children, palette, className, ...rest }, ref) {\n const rows = rowsProp ?? rowsOf(children);\n\n return (\n <AsciiFrameBody data-slot=\"flow-diagram\" ref={ref} {...rest} className={cn('flex flex-col gap-7', className)}>\n <div className=\"flex flex-col gap-7\" role=\"list\" aria-label={`${label} paths`}>\n {rows.map((row, rowIndex) => (\n <div\n className=\"flex min-w-0 flex-wrap items-center gap-x-3 gap-y-2 sm:flex-nowrap\"\n key={`row-${rowIndex}`}\n aria-label={row.nodes.map((node) => node.label).join(' then ')}\n role=\"listitem\"\n >\n {row.nodes.map((node, nodeIndex) => (\n <div className={cn('flex min-w-0 items-center gap-3', node.stretch && 'min-w-16 flex-1')} key={`${node.label}-${nodeIndex}`}>\n {nodeIndex > 0 ? <AsciiFrameArrow accent={node.tone === 'accent'} stretch={node.stretch} /> : null}\n <span className={cn('shrink-0 whitespace-nowrap', toneClass(palette, node.tone ?? 'default'))}>{node.label}</span>\n </div>\n ))}\n </div>\n ))}\n </div>\n <span className=\"sr-only\">\n {rows.length === 0 ? 'Empty flow.' : `Flow with ${rows.length} path${rows.length === 1 ? '' : 's'}: ${rows.map((row) => row.nodes.map((node) => node.label).join(' then ')).join('; ')}.`}\n </span>\n </AsciiFrameBody>\n );\n});\n"],"mappings":"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","names":["FlowDiagram"]}
|