@designtools/docs 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +27 -3
- package/dist/adherence-summary.js +2 -2
- package/dist/anatomy.d.ts +6 -2
- package/dist/anatomy.js +3 -2
- package/dist/glossary.d.ts +1 -1
- package/dist/glossary.js +3 -8
- package/dist/lib/adherence-types.d.ts +2 -0
- package/dist/lib/colour.d.ts +16 -0
- package/dist/lib/colour.js +99 -0
- package/dist/lib/contrast.js +1 -7
- package/dist/lib/design-md.d.ts +27 -0
- package/dist/lib/design-md.js +176 -0
- package/dist/lib/markdown.js +1 -0
- package/dist/lib/terms.d.ts +1 -1
- package/dist/lib/terms.js +1 -1
- package/dist/lib/wrap.d.ts +5 -0
- package/dist/lib/wrap.js +5 -0
- package/dist/logo-usage.js +3 -3
- package/dist/next/config.d.ts +9 -0
- package/dist/next/markdown.d.ts +1 -1
- package/dist/next/markdown.js +15 -1
- package/dist/next/pages.js +2 -2
- package/dist/next/proxy.js +3 -2
- package/dist/page-actions.d.ts +2 -1
- package/dist/page-actions.js +4 -3
- package/dist/playground.js +1 -1
- package/dist/shell.js +6 -4
- package/dist/standards.js +1 -1
- package/dist/styles.css +28 -35
- package/dist/type-ramp.js +1 -1
- package/dist/variant-matrix.d.ts +6 -2
- package/dist/variant-matrix.js +3 -2
- package/dist/workbench.js +3 -2
- package/package.json +1 -1
- package/src/adherence-summary.tsx +7 -2
- package/src/anatomy.tsx +6 -4
- package/src/glossary.tsx +10 -22
- package/src/lib/adherence-types.ts +2 -0
- package/src/lib/colour.ts +104 -0
- package/src/lib/contrast.ts +2 -8
- package/src/lib/design-md.ts +193 -0
- package/src/lib/markdown.ts +1 -0
- package/src/lib/terms.tsx +1 -1
- package/src/lib/wrap.tsx +6 -0
- package/src/logo-usage.tsx +20 -12
- package/src/next/config.ts +7 -0
- package/src/next/markdown.ts +16 -1
- package/src/next/pages.tsx +7 -3
- package/src/next/proxy.ts +3 -2
- package/src/page-actions.tsx +10 -2
- package/src/playground.tsx +2 -2
- package/src/shell.tsx +6 -4
- package/src/standards.tsx +2 -2
- package/src/styles.css +9 -8
- package/src/type-ramp.tsx +3 -6
- package/src/variant-matrix.tsx +11 -4
- package/src/workbench.tsx +2 -1
package/dist/logo-usage.js
CHANGED
|
@@ -20,7 +20,7 @@ export function LogoUsage({ assets, rules = [], rulesHref }) {
|
|
|
20
20
|
return _jsx("p", { className: "text-sm text-muted-foreground", children: "No logos in the brand folder yet." });
|
|
21
21
|
const brand = rules.filter((r) => r.kind === "brand");
|
|
22
22
|
const general = brand.filter((r) => (r.appliesTo ?? []).some((x) => ["logo", "logos"].includes(x.toLowerCase())));
|
|
23
|
-
return (_jsxs("div", { "data-slot": "logo-usage", className: "flex flex-col gap-16", children: [
|
|
23
|
+
return (_jsxs("div", { "data-slot": "logo-usage", className: "flex flex-col gap-16 lg:gap-24", children: [logos.map((logo) => {
|
|
24
24
|
const src = lookup.assetUrl(logo);
|
|
25
25
|
const names = new Set([logo.name.toLowerCase(), logo.file.toLowerCase()]);
|
|
26
26
|
const own = brand.filter((r) => !general.includes(r) && (r.appliesTo ?? []).some((x) => names.has(x.toLowerCase())));
|
|
@@ -38,8 +38,8 @@ export function LogoUsage({ assets, rules = [], rulesHref }) {
|
|
|
38
38
|
if (logo.width && logo.height)
|
|
39
39
|
facts.push(["Proportions", _jsxs("span", { className: "font-mono text-xs", children: [logo.width, " \u00D7 ", logo.height] }, "p")]);
|
|
40
40
|
return (_jsxs("section", { "data-slot": "logo", className: "flex flex-col gap-5", children: [_jsxs("header", { className: "flex flex-col gap-1.5", children: [_jsx("h3", { className: "text-3xl tracking-tight", children: logo.name }), logo.usage && _jsx("p", { className: "max-w-2xl text-base text-muted-foreground", children: inline(logo.usage) })] }), _jsxs("div", { className: "grid gap-3 lg:grid-cols-[minmax(0,2fr)_minmax(0,1fr)]", children: [_jsxs("div", { "data-slot": "logo-surface", "data-theme": "light", className: "relative flex min-h-72 items-center justify-center overflow-hidden rounded-2xl border border-border p-10", style: paint(surfaces[0]), children: [_jsx("span", { className: "absolute top-4 left-4 font-mono text-xs opacity-70", children: surfaces[0] }), _jsxs("span", { className: "relative inline-flex", children: [_jsx("span", { "data-slot": "logo-clear-space", className: "inline-flex border border-dashed", style: { padding: clear ? `calc(${clear[1]}${clear[2]} * 2)` : "1.5rem", borderColor: "color-mix(in oklch, currentColor 45%, transparent)" }, title: `Clear space: ${logo.clearSpace ?? "not set"}`, children: src ? _jsx("img", { src: src, alt: logo.alt ?? logo.name, className: "block h-16 w-auto sm:h-20" }) : _jsx("span", { className: "text-xs", children: logo.file }) }), clear && (_jsx("span", { className: "absolute -bottom-6 left-1/2 -translate-x-1/2 font-mono text-xs whitespace-nowrap opacity-70", children: "clear space, shown at 2\u00D7" }))] })] }), _jsxs("ul", { className: "grid grid-cols-2 gap-3 lg:grid-cols-1 lg:grid-rows-3", children: [surfaces.slice(1).map((surface) => (_jsxs("li", { "data-slot": "logo-surface", "data-theme": "light", className: "relative flex min-h-28 items-center justify-center rounded-2xl border border-border p-6", style: paint(surface), children: [_jsx("span", { className: "absolute top-3 left-3 font-mono text-xs opacity-70", children: surface }), src && _jsx("img", { src: src, alt: "", "aria-hidden": true, className: "block h-9 w-auto" })] }, surface))), surfaces.length === 1 && (_jsxs("li", { className: "col-span-2 flex items-center rounded-2xl border border-dashed border-border p-6 text-sm text-muted-foreground lg:col-span-1 lg:row-span-3", children: ["Only on ", surfaces[0], "."] }))] })] }), _jsx("dl", { className: "grid gap-x-10 gap-y-5 sm:grid-cols-3", children: facts.map(([term, detail]) => (_jsxs("div", { className: "flex flex-col gap-1.5", children: [_jsx("dt", { className: "text-xs font-medium text-muted-foreground", children: term }), _jsx("dd", { className: "text-sm", children: detail })] }, term))) }), own.length > 0 && _jsx(RuleList, { rules: own, rulesHref: rulesHref })] }, logo.file));
|
|
41
|
-
})] }));
|
|
41
|
+
}), general.length > 0 && (_jsxs("section", { "data-slot": "logo-rules", "aria-labelledby": "logo-rules", className: "flex flex-col gap-5", children: [_jsxs("header", { className: "flex flex-col gap-1.5", children: [_jsx("h3", { id: "logo-rules", className: "text-3xl tracking-tight", children: "Rules for the logo" }), _jsx("p", { className: "max-w-2xl text-base text-muted-foreground", children: "What holds for every logo above, each with how it is checked." })] }), _jsx(RuleList, { rules: general, rulesHref: rulesHref })] }))] }));
|
|
42
42
|
}
|
|
43
43
|
function RuleList({ rules, rulesHref }) {
|
|
44
|
-
return (_jsx("ul", { "data-slot": "logo-rules", className: "
|
|
44
|
+
return (_jsx("ul", { "data-slot": "logo-rules", className: "flex flex-col divide-y divide-border border-y border-border", children: rules.map((r) => (_jsx("li", { children: _jsxs("a", { href: rulesHref ? `${rulesHref}#${r.id}` : `#${r.id}`, className: "group grid items-baseline gap-x-8 gap-y-1.5 py-5 focus-visible:outline-2 focus-visible:outline-ring md:grid-cols-[14rem_minmax(0,1fr)_auto]", children: [_jsxs("span", { className: "flex items-center gap-2 text-base font-medium underline-offset-4 group-hover:underline", children: [_jsx(Scale, { "aria-hidden": true, className: "size-(--dt-size-xs) shrink-0 text-muted-foreground" }), r.title] }), _jsx("span", { className: "text-sm leading-relaxed text-muted-foreground", children: inline(r.statement) }), _jsx(StatusBadge, { status: r.status })] }) }, r.id))) }));
|
|
45
45
|
}
|
package/dist/next/config.d.ts
CHANGED
|
@@ -88,6 +88,15 @@ export interface DocsConfig {
|
|
|
88
88
|
provenance?: string;
|
|
89
89
|
/** `designtools-adherence --json`, for the standards page. */
|
|
90
90
|
adherence?: AdherenceReport;
|
|
91
|
+
/**
|
|
92
|
+
* design.md, served at `<base>/design.md`: the brand in one file for anything made outside the repo's
|
|
93
|
+
* components (a page built elsewhere, a slide, a document). `body` is its hand-written half, in markdown
|
|
94
|
+
* `##` sections: what comes first when guidance conflicts, how to work, the reflexes to avoid, a review
|
|
95
|
+
* list. The values after it are generated. Without a body the file still serves, with the values alone.
|
|
96
|
+
*/
|
|
97
|
+
designMd?: {
|
|
98
|
+
body: string;
|
|
99
|
+
};
|
|
91
100
|
/** Pages people write, in the order they appear. */
|
|
92
101
|
editorial?: EditorialPage[];
|
|
93
102
|
/** Built-in pages to leave out. */
|
package/dist/next/markdown.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { type Site } from "./site.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* The markdown form of a docs page, generated from the manifest rather than
|
|
4
4
|
* converted from HTML, or nothing when there is no such page. `context` is the
|
|
5
|
-
* whole system in one file.
|
|
5
|
+
* whole system in one file; `design` is design.md, the brand for work outside the repo.
|
|
6
6
|
*/
|
|
7
7
|
export declare function markdownFor(site: Site, path: string): string | undefined;
|
|
8
8
|
/** The route handler for `md/[[...path]]`: the page's markdown with `Vary: Accept` and its canonical link, or a markdown 404. */
|
package/dist/next/markdown.js
CHANGED
|
@@ -1,16 +1,29 @@
|
|
|
1
1
|
import { groupByCategory, slugOf } from "../lib/manifest.js";
|
|
2
2
|
import { adherenceMarkdown, assetsMarkdown, coloursMarkdown, componentMarkdown, editorialHeader, generatedHeader, glossaryMarkdown, manifestLinks, patternMarkdown, ruleMarkdown, scaleMarkdown, standardsMarkdown, systemMarkdown, typeMarkdown, } from "../lib/markdown.js";
|
|
3
|
+
import { designMarkdown } from "../lib/design-md.js";
|
|
3
4
|
import { navOf, resolve } from "./site.js";
|
|
4
5
|
/**
|
|
5
6
|
* The markdown form of a docs page, generated from the manifest rather than
|
|
6
7
|
* converted from HTML, or nothing when there is no such page. `context` is the
|
|
7
|
-
* whole system in one file.
|
|
8
|
+
* whole system in one file; `design` is design.md, the brand for work outside the repo.
|
|
8
9
|
*/
|
|
9
10
|
export function markdownFor(site, path) {
|
|
10
11
|
const { base, title, components, tokens, rules, patterns, taxonomy, assets, config } = site;
|
|
11
12
|
const generated = (md) => generatedHeader(config.provenance ?? "") + md;
|
|
12
13
|
if (path === "context")
|
|
13
14
|
return systemMarkdown({ components, tokens, rules: rules.rules, patterns: patterns.patterns, terms: taxonomy.terms }, title, config.provenance ?? "");
|
|
15
|
+
if (path === "design")
|
|
16
|
+
return designMarkdown({
|
|
17
|
+
title,
|
|
18
|
+
base,
|
|
19
|
+
provenance: config.provenance,
|
|
20
|
+
components,
|
|
21
|
+
tokens,
|
|
22
|
+
rules: rules.rules,
|
|
23
|
+
assets: assets.assets,
|
|
24
|
+
terms: taxonomy.terms,
|
|
25
|
+
body: config.designMd?.body,
|
|
26
|
+
});
|
|
14
27
|
const page = resolve(site, path ? path.split("/") : []);
|
|
15
28
|
if (!page)
|
|
16
29
|
return undefined;
|
|
@@ -32,6 +45,7 @@ export function markdownFor(site, path) {
|
|
|
32
45
|
...groupByCategory(components).flatMap((g) => g.components.map((c) => `- ${g.category}: [${c.name}](${base}/components/${slugOf(c)}.md), ${c.status ?? "status not set"}`)),
|
|
33
46
|
...(nav.standards.length ? [`- Standards: ${links(nav.standards)}`] : []),
|
|
34
47
|
`- Everything in [one file](${base}/context.md)`,
|
|
48
|
+
`- The brand for work outside the repo, a page, a slide or a document: [design.md](${base}/design.md)`,
|
|
35
49
|
"",
|
|
36
50
|
manifestLinks(`${base}/manifest`),
|
|
37
51
|
].join("\n"));
|
package/dist/next/pages.js
CHANGED
|
@@ -102,7 +102,7 @@ function ComponentPage({ site, blocks: B, entry }) {
|
|
|
102
102
|
const first = entry.examples?.canonical?.name;
|
|
103
103
|
// the brand's named backgrounds (--surface-<name>), offered on the workbench's stage
|
|
104
104
|
const backgrounds = site.tokens.tokens.map((t) => t.name.slice(2)).filter((n) => /^surface-[a-z]/.test(n) && !n.endsWith("-foreground"));
|
|
105
|
-
return (_jsxs(_Fragment, { children: [_jsx(DocsHeader, { title: entry.name, lead: entry.description, children: _jsx(PageActions, { basePath: base }) }), _jsx(DocsSection, { title: "Usage", children: _jsx(B.Usage, { entry: entry, manifest: site.components, basePath: base }) }), _jsx(B.Workbench, { entry: entry, props: setup.props, content: setup.content, wrap: setup.wrap, backgrounds: backgrounds, previewHref: first && `${preview}/${first}`, children: setup.children }), _jsx(DocsSection, { title: "Anatomy", children: _jsx(B.Anatomy, { entry: entry }) }), _jsx(DocsSection, { title: "Examples", lead: "The usual use first, then each do beside its don't. Every one is the real component.", children: _jsx(B.Examples, { entry: entry, previewHref: preview }) }), !!entry.variants?.axes.length && (_jsx(DocsSection, { title: "Variants", lead: `Every combination, from the ${entry.variants.from === "props" ? "props' types" : `${entry.variants.from}() config`}, then each state.`, children: _jsx(B.VariantMatrix, { entry: entry, props: setup.props, children: setup.children === "" ? undefined : (setup.content ?? entry.name) }) })), first && (_jsx(DocsSection, { title: "At each width", children: _jsx(B.PreviewFrame, { src: `${preview}/${first}`, title: `${entry.name}: ${first}` }) })), _jsx(DocsFooter, { source: entry.source, provenance: config.provenance })] }));
|
|
105
|
+
return (_jsxs(_Fragment, { children: [_jsx(DocsHeader, { title: entry.name, lead: entry.description, children: _jsx(PageActions, { basePath: base }) }), _jsx(DocsSection, { title: "Usage", children: _jsx(B.Usage, { entry: entry, manifest: site.components, basePath: base }) }), _jsx(B.Workbench, { entry: entry, props: setup.props, content: setup.content, wrap: setup.wrap, backgrounds: backgrounds, previewHref: first && `${preview}/${first}`, children: setup.children }), _jsx(DocsSection, { title: "Anatomy", children: _jsx(B.Anatomy, { entry: entry, wrap: setup.wrap }) }), _jsx(DocsSection, { title: "Examples", lead: "The usual use first, then each do beside its don't. Every one is the real component.", children: _jsx(B.Examples, { entry: entry, previewHref: preview }) }), !!entry.variants?.axes.length && (_jsx(DocsSection, { title: "Variants", lead: `Every combination, from the ${entry.variants.from === "props" ? "props' types" : `${entry.variants.from}() config`}, then each state.`, children: _jsx(B.VariantMatrix, { entry: entry, props: setup.props, wrap: setup.wrap, children: setup.children === "" ? undefined : (setup.content ?? entry.name) }) })), first && (_jsx(DocsSection, { title: "At each width", children: _jsx(B.PreviewFrame, { src: `${preview}/${first}`, title: `${entry.name}: ${first}` }) })), _jsx(DocsFooter, { source: entry.source, provenance: config.provenance })] }));
|
|
106
106
|
}
|
|
107
107
|
/** The overview, below the hero when there is one: each part of the system and why it exists, then why it is agentic. */
|
|
108
108
|
function Overview({ site }) {
|
|
@@ -162,5 +162,5 @@ function Overview({ site }) {
|
|
|
162
162
|
["Measured", "A report on every change shows how closely the product follows the system. It informs the conversation; it never blocks the work."],
|
|
163
163
|
];
|
|
164
164
|
return (_jsxs(_Fragment, { children: [!config.hero && (_jsx(DocsHeader, { title: site.title, lead: config.lead ?? "The brand and the design system in one place, for the people who make the product and the agents that build it with them.", children: _jsx(PageActions, { basePath: base }) })), _jsx(DocsSection, { title: "What's here, and why", lead: "Each part of the system has one job. Together they mean the product, its people and its agents work from the same source.", children: _jsx("ul", { "data-slot": "overview-sections", className: "flex flex-col border-b border-border", children: sections.map((sec) => (_jsx("li", { className: "border-t border-border", children: _jsxs(Link, { href: sec.href, className: "group grid items-baseline gap-x-10 gap-y-2 py-6 focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-ring md:grid-cols-[13rem_minmax(0,1fr)_auto]", children: [_jsx("span", { className: cx(display, "text-2xl leading-snug tracking-tight underline-offset-4 group-hover:underline"), children: sec.title }), _jsx("span", { className: "max-w-2xl text-base leading-relaxed text-muted-foreground", children: sec.why }), _jsx(ArrowUpRight, { "aria-hidden": true, className: "hidden size-(--dt-size-sm) translate-y-0.5 self-start text-muted-foreground transition duration-(--dt-duration-base) ease-(--dt-ease-out) group-hover:translate-x-1 group-hover:-translate-y-0.5 group-hover:text-canvas-foreground md:mt-1.5 md:block" })] }) }, sec.title))) }) }), config.overview?.agentic !== false && (_jsxs(DocsSection, { title: "Why this is agentic", lead: config.overview?.agenticLead ??
|
|
165
|
-
"A design system used to be a document people were asked to follow. This one is the source the product, its people and its AI agents all work from, and it checks itself.", children: [_jsx("ol", { "data-slot": "overview-loop", className: "grid gap-x-6 gap-y-8 sm:grid-cols-2 xl:grid-cols-5", children: loop.map(([title, body], i) => (_jsxs("li", { className: "relative flex flex-col gap-3 xl:pr-2", children: [_jsxs("span", { className: "flex items-center gap-3", children: [_jsx("span", { className: "grid size-8 shrink-0 place-items-center rounded-full bg-canvas-foreground text-sm font-medium text-canvas tabular-nums", children: i + 1 }), i < loop.length - 1 && _jsx("span", { "aria-hidden": true, className: "hidden h-px flex-1 bg-border xl:block" })] }), _jsx("span", { className: "text-lg leading-snug tracking-tight", children: title }), _jsx("span", { className: "text-sm leading-relaxed text-muted-foreground", children: body })] }, title))) }), _jsxs("p", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-sm text-muted-foreground", children: ["See it the way an agent does:", _jsxs("a", { href: `${base}.md
|
|
165
|
+
"A design system used to be a document people were asked to follow. This one is the source the product, its people and its AI agents all work from, and it checks itself.", children: [_jsx("ol", { "data-slot": "overview-loop", className: "grid gap-x-6 gap-y-8 sm:grid-cols-2 xl:grid-cols-5", children: loop.map(([title, body], i) => (_jsxs("li", { className: "relative flex flex-col gap-3 xl:pr-2", children: [_jsxs("span", { className: "flex items-center gap-3", children: [_jsx("span", { className: "grid size-8 shrink-0 place-items-center rounded-full bg-canvas-foreground text-sm font-medium text-canvas tabular-nums", children: i + 1 }), i < loop.length - 1 && _jsx("span", { "aria-hidden": true, className: "hidden h-px flex-1 bg-border xl:block" })] }), _jsx("span", { className: "text-lg leading-snug tracking-tight", children: title }), _jsx("span", { className: "text-sm leading-relaxed text-muted-foreground", children: body })] }, title))) }), _jsxs("p", { className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-sm text-muted-foreground", children: ["See it the way an agent does:", _jsxs("a", { href: base ? `${base}.md` : "/.md", className: "inline-flex items-center gap-1 font-medium text-canvas-foreground underline underline-offset-4 hover:decoration-2", children: ["this page as markdown ", _jsx(ArrowUpRight, { "aria-hidden": true, className: "size-3.5" })] }), "or, for a page, slide or document made outside the repo,", _jsxs("a", { href: `${base}/design.md`, className: "inline-flex items-center gap-1 font-medium text-canvas-foreground underline underline-offset-4 hover:decoration-2", children: ["design.md ", _jsx(ArrowUpRight, { "aria-hidden": true, className: "size-3.5" })] })] })] })), _jsx(DocsFooter, { provenance: config.provenance })] }));
|
|
166
166
|
}
|
package/dist/next/proxy.js
CHANGED
|
@@ -28,7 +28,7 @@ export function docsProxy({ basePath = "/design/system", production } = {}) {
|
|
|
28
28
|
// the markdown responses keep theirs.
|
|
29
29
|
const res = NextResponse.next();
|
|
30
30
|
res.headers.set("vary", "Accept");
|
|
31
|
-
res.headers.set("link", `<${page}.md>; rel="alternate"; type="text/markdown"`);
|
|
31
|
+
res.headers.set("link", `<${page ? `${page}.md` : "/.md"}>; rel="alternate"; type="text/markdown"`);
|
|
32
32
|
res.headers.set("x-robots-tag", "noindex");
|
|
33
33
|
return res;
|
|
34
34
|
};
|
|
@@ -36,7 +36,8 @@ export function docsProxy({ basePath = "/design/system", production } = {}) {
|
|
|
36
36
|
/** The proxy's matcher for a base path. Next reads `config.matcher` statically, so write the result out where it must be a literal. */
|
|
37
37
|
export function docsMatcher(basePath = "/design/system") {
|
|
38
38
|
const base = basePath.replace(/\/$/, "");
|
|
39
|
-
|
|
39
|
+
// served at the site root, every path is a docs path
|
|
40
|
+
return base ? [base, `${base}.md`, `${base}/:path*`] : ["/", "/:path*"];
|
|
40
41
|
}
|
|
41
42
|
/** text/markdown ranked above text/html in the Accept header. */
|
|
42
43
|
export function prefersMarkdown(accept) {
|
package/dist/page-actions.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* What a reader can take from a page, as one split button: copy the page as
|
|
3
3
|
* markdown, the same markdown any agent gets at `.md`, with a menu beside it to
|
|
4
|
-
* view that markdown, copy the whole system as one file,
|
|
4
|
+
* view that markdown, copy the whole system as one file, copy design.md (the
|
|
5
|
+
* brand for work outside the repo), or open the manifest.
|
|
5
6
|
* Put it in a `DocsHeader`.
|
|
6
7
|
*/
|
|
7
8
|
export declare function PageActions({ basePath }: {
|
package/dist/page-actions.js
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Menu } from "@base-ui/react/menu";
|
|
4
|
-
import { Braces, Check, ChevronDown, Copy, FileText, Files } from "lucide-react";
|
|
4
|
+
import { Braces, Check, ChevronDown, Copy, FileText, Files, Palette } from "lucide-react";
|
|
5
5
|
import { usePathname } from "next/navigation";
|
|
6
6
|
import { useState } from "react";
|
|
7
7
|
/**
|
|
8
8
|
* What a reader can take from a page, as one split button: copy the page as
|
|
9
9
|
* markdown, the same markdown any agent gets at `.md`, with a menu beside it to
|
|
10
|
-
* view that markdown, copy the whole system as one file,
|
|
10
|
+
* view that markdown, copy the whole system as one file, copy design.md (the
|
|
11
|
+
* brand for work outside the repo), or open the manifest.
|
|
11
12
|
* Put it in a `DocsHeader`.
|
|
12
13
|
*/
|
|
13
14
|
export function PageActions({ basePath = "/design/system" }) {
|
|
@@ -28,5 +29,5 @@ export function PageActions({ basePath = "/design/system" }) {
|
|
|
28
29
|
};
|
|
29
30
|
const item = "flex min-h-(--docs-target,2.75rem) cursor-pointer items-center gap-3 rounded-md px-3 text-sm outline-none select-none data-highlighted:bg-muted";
|
|
30
31
|
const icon = "size-4 shrink-0 text-muted-foreground";
|
|
31
|
-
return (_jsxs("div", { "data-slot": "page-actions", className: "inline-flex items-stretch rounded-lg border border-border bg-canvas text-sm shadow-xs", children: [_jsxs("button", { type: "button", onClick: () => copyFrom(`${path}.md`, "Page copied"), className: "inline-flex min-h-9 cursor-pointer items-center gap-2 rounded-l-lg py-1.5 pr-3 pl-3 font-medium hover:bg-muted focus-visible:outline-2 focus-visible:outline-ring", children: [done === "Page copied" ? _jsx(Check, { "aria-hidden": true, className: "size-4" }) : _jsx(Copy, { "aria-hidden": true, className: icon }), done === "Page copied" ? "Copied" : "Copy page"] }), _jsxs(Menu.Root, { children: [_jsx(Menu.Trigger, { "aria-label": "More ways to take this page", className: "inline-flex min-h-9 w-9 cursor-pointer items-center justify-center rounded-r-lg border-l border-border text-muted-foreground hover:bg-muted hover:text-canvas-foreground focus-visible:outline-2 focus-visible:outline-ring data-popup-open:bg-muted", children: _jsx(ChevronDown, { "aria-hidden": true, className: "size-4" }) }), _jsx(Menu.Portal, { children: _jsx(Menu.Positioner, { "data-designtools": "", align: "end", sideOffset: 6, className: "z-50", children: _jsxs(Menu.Popup, { className: "w-72 rounded-xl border border-border bg-overlay p-1.5 text-overlay-foreground shadow-lg transition-[opacity,scale] duration-(--dt-duration-fast) data-ending-style:scale-95 data-ending-style:opacity-0 data-starting-style:scale-95 data-starting-style:opacity-0", children: [_jsxs(Menu.Item, { className: item, onClick: () => copyFrom(`${path}.md`, "Page copied"), children: [_jsx(Copy, { "aria-hidden": true, className: icon }), _jsxs("span", { className: "flex flex-col", children: ["Copy page", _jsx("span", { className: "text-xs text-muted-foreground", children: "As markdown, for an assistant" })] })] }), _jsxs(Menu.LinkItem, { className: item, href: `${path}.md`, target: "_blank", rel: "noreferrer", children: [_jsx(FileText, { "aria-hidden": true, className: icon }), _jsxs("span", { className: "flex flex-col", children: ["View as markdown", _jsx("span", { className: "text-xs text-muted-foreground", children: "What an agent reads at this address" })] })] }), _jsx(Menu.Separator, { className: "my-1.5 h-px bg-border" }), _jsxs(Menu.Item, { className: item, onClick: () => copyFrom(`${basePath}/context.md`, "System copied"), children: [_jsx(Files, { "aria-hidden": true, className: icon }), _jsxs("span", { className: "flex flex-col", children: ["Copy the whole system", _jsx("span", { className: "text-xs text-muted-foreground", children: "Every page in one markdown file" })] })] }), _jsxs(Menu.LinkItem, { className: item, href: `${basePath}/manifest/components.json`, target: "_blank", rel: "noreferrer", children: [_jsx(Braces, { "aria-hidden": true, className: icon }), _jsxs("span", { className: "flex flex-col", children: ["Open the manifest", _jsx("span", { className: "text-xs text-muted-foreground", children: "Components, tokens and rules as JSON" })] })] })] }) }) })] }), _jsx("span", { className: "sr-only", "aria-live": "polite", children: done ?? "" })] }));
|
|
32
|
+
return (_jsxs("div", { "data-slot": "page-actions", className: "inline-flex items-stretch rounded-lg border border-border bg-canvas text-sm shadow-xs", children: [_jsxs("button", { type: "button", onClick: () => copyFrom(`${path}.md`, "Page copied"), className: "inline-flex min-h-9 cursor-pointer items-center gap-2 rounded-l-lg py-1.5 pr-3 pl-3 font-medium hover:bg-muted focus-visible:outline-2 focus-visible:outline-ring", children: [done === "Page copied" ? _jsx(Check, { "aria-hidden": true, className: "size-4" }) : _jsx(Copy, { "aria-hidden": true, className: icon }), done === "Page copied" ? "Copied" : "Copy page"] }), _jsxs(Menu.Root, { children: [_jsx(Menu.Trigger, { "aria-label": "More ways to take this page", className: "inline-flex min-h-9 w-9 cursor-pointer items-center justify-center rounded-r-lg border-l border-border text-muted-foreground hover:bg-muted hover:text-canvas-foreground focus-visible:outline-2 focus-visible:outline-ring data-popup-open:bg-muted", children: _jsx(ChevronDown, { "aria-hidden": true, className: "size-4" }) }), _jsx(Menu.Portal, { children: _jsx(Menu.Positioner, { "data-designtools": "", align: "end", sideOffset: 6, className: "z-50", children: _jsxs(Menu.Popup, { className: "w-72 rounded-xl border border-border bg-overlay p-1.5 text-overlay-foreground shadow-lg transition-[opacity,scale] duration-(--dt-duration-fast) data-ending-style:scale-95 data-ending-style:opacity-0 data-starting-style:scale-95 data-starting-style:opacity-0", children: [_jsxs(Menu.Item, { className: item, onClick: () => copyFrom(`${path}.md`, "Page copied"), children: [_jsx(Copy, { "aria-hidden": true, className: icon }), _jsxs("span", { className: "flex flex-col", children: ["Copy page", _jsx("span", { className: "text-xs text-muted-foreground", children: "As markdown, for an assistant" })] })] }), _jsxs(Menu.LinkItem, { className: item, href: `${path}.md`, target: "_blank", rel: "noreferrer", children: [_jsx(FileText, { "aria-hidden": true, className: icon }), _jsxs("span", { className: "flex flex-col", children: ["View as markdown", _jsx("span", { className: "text-xs text-muted-foreground", children: "What an agent reads at this address" })] })] }), _jsx(Menu.Separator, { className: "my-1.5 h-px bg-border" }), _jsxs(Menu.Item, { className: item, onClick: () => copyFrom(`${basePath}/context.md`, "System copied"), children: [_jsx(Files, { "aria-hidden": true, className: icon }), _jsxs("span", { className: "flex flex-col", children: ["Copy the whole system", _jsx("span", { className: "text-xs text-muted-foreground", children: "Every page in one markdown file" })] })] }), _jsxs(Menu.Item, { className: item, onClick: () => copyFrom(`${basePath}/design.md`, "design.md copied"), children: [_jsx(Palette, { "aria-hidden": true, className: icon }), _jsxs("span", { className: "flex flex-col", children: ["Copy design.md", _jsx("span", { className: "text-xs text-muted-foreground", children: "The brand for a page, slide or document made elsewhere" })] })] }), _jsxs(Menu.LinkItem, { className: item, href: `${basePath}/manifest/components.json`, target: "_blank", rel: "noreferrer", children: [_jsx(Braces, { "aria-hidden": true, className: icon }), _jsxs("span", { className: "flex flex-col", children: ["Open the manifest", _jsx("span", { className: "text-xs text-muted-foreground", children: "Components, tokens and rules as JSON" })] })] })] }) }) })] }), _jsx("span", { className: "sr-only", "aria-live": "polite", children: done ?? "" })] }));
|
|
32
33
|
}
|
package/dist/playground.js
CHANGED
|
@@ -72,7 +72,7 @@ export function FlagControl({ name, checked, onChange }) {
|
|
|
72
72
|
const id = useId();
|
|
73
73
|
return (_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx("label", { htmlFor: id, className: "text-sm font-medium", children: title(name) }), _jsx(Switch.Root, { id: id, checked: checked, onCheckedChange: onChange,
|
|
74
74
|
// drawn small, pressed large: the hit area reaches the docs' target without the switch growing
|
|
75
|
-
className: "relative h-6 w-10 shrink-0 cursor-pointer rounded-full bg-input p-0.5 transition-colors duration-(--dt-duration-fast) after:absolute after:-inset-2.5 after:content-[''] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring data-[checked]:bg-primary", children: _jsx(Switch.Thumb, { className: "block size-5 rounded-full bg-
|
|
75
|
+
className: "relative h-6 w-10 shrink-0 cursor-pointer rounded-full bg-input p-0.5 transition-colors duration-(--dt-duration-fast) after:absolute after:-inset-2.5 after:content-[''] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring data-[checked]:bg-[var(--docs-accent,var(--primary))]", children: _jsx(Switch.Thumb, { className: "block size-5 rounded-full bg-canvas shadow-xs ring-1 ring-border transition-transform duration-(--dt-duration-fast) data-[checked]:translate-x-4" }) })] }));
|
|
76
76
|
}
|
|
77
77
|
export function TextControl({ value, onChange }) {
|
|
78
78
|
const id = useId();
|
package/dist/shell.js
CHANGED
|
@@ -29,6 +29,8 @@ const DocsPage = createContext({});
|
|
|
29
29
|
*/
|
|
30
30
|
export function DocsShell({ manifest, rules, patterns, terms, search = true, themeSwitch = true, title = "Design system", logo, basePath = "/design/system", brand = [], foundations = [], standards = [], hero, children, }) {
|
|
31
31
|
const current = usePathname();
|
|
32
|
+
// the overview's own address: the base path, or the site root when the docs are served there (basePath "")
|
|
33
|
+
const home = basePath || "/";
|
|
32
34
|
const searchItems = useMemo(() => searchIndex({
|
|
33
35
|
manifest,
|
|
34
36
|
rules: rules?.rules,
|
|
@@ -40,7 +42,7 @@ export function DocsShell({ manifest, rules, patterns, terms, search = true, the
|
|
|
40
42
|
const sections = useMemo(() => {
|
|
41
43
|
const families = groupFamilies(manifest);
|
|
42
44
|
const all = [
|
|
43
|
-
{ id: "overview", label: "Overview", icon: House, href:
|
|
45
|
+
{ id: "overview", label: "Overview", icon: House, href: home, groups: [] },
|
|
44
46
|
{ id: "brand", label: "Brand", icon: BookOpen, groups: [{ links: brand }] },
|
|
45
47
|
{ id: "foundations", label: "Foundations", icon: Palette, groups: [{ links: foundations }] },
|
|
46
48
|
...(rules?.rules.length ? [{ id: "rules", label: "Rules", icon: Scale, href: `${basePath}/rules`, groups: [] }] : []),
|
|
@@ -66,7 +68,7 @@ export function DocsShell({ manifest, rules, patterns, terms, search = true, the
|
|
|
66
68
|
{ id: "standards", label: "Standards", icon: Gauge, groups: [{ links: standards }] },
|
|
67
69
|
];
|
|
68
70
|
return all.filter((s) => s.href || s.groups.some((g) => g.links.length));
|
|
69
|
-
}, [manifest, rules, patterns, brand, foundations, standards, basePath]);
|
|
71
|
+
}, [manifest, rules, patterns, brand, foundations, standards, basePath, home]);
|
|
70
72
|
// every page in navigation order, for the section a page sits in and its neighbours
|
|
71
73
|
const page = useMemo(() => {
|
|
72
74
|
// a section of one page has no section above it: the page is the section
|
|
@@ -87,8 +89,8 @@ export function DocsShell({ manifest, rules, patterns, terms, search = true, the
|
|
|
87
89
|
useThemeScript();
|
|
88
90
|
const [menu, setMenu] = useState(false);
|
|
89
91
|
useEffect(() => setMenu(false), [current]);
|
|
90
|
-
const brandLink = (_jsxs(Link, { href:
|
|
91
|
-
return (_jsx(DocsPage.Provider, { value: page, children: _jsxs("div", { "data-designtools": "", "data-slot": "docs-shell", className: "min-h-dvh bg-canvas text-canvas-foreground lg:grid lg:grid-cols-[19rem_minmax(0,1fr)]", children: [_jsx("aside", { "data-slot": "docs-sidebar", className: "sticky top-0 hidden h-dvh p-3 lg:block", children: _jsxs("div", { className: "flex h-full flex-col overflow-hidden rounded-xl border border-border bg-surface text-surface-foreground shadow-xs", children: [_jsxs("div", { className: "flex flex-col gap-3 p-4 pb-3", children: [brandLink, search && _jsx(DocsSearch, { items: searchItems })] }), _jsx(Nav, { sections: sections, current: current, title: title }), themeSwitch && (_jsxs("div", { "data-slot": "docs-sidebar-foot", className: "flex items-center justify-between gap-3 border-t border-border px-4 py-3", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Appearance" }), _jsx(ThemeSwitch, {})] }))] }) }), _jsxs("div", { className: "min-w-0", children: [_jsxs("header", { "data-slot": "docs-topbar", className: "sticky top-0 z-20 flex h-16 items-center gap-2 border-b border-border bg-canvas/85 px-3 backdrop-blur-md lg:hidden", children: [_jsxs(Dialog.Root, { open: menu, onOpenChange: setMenu, children: [_jsx(Dialog.Trigger, { "aria-label": "Open the navigation", className: iconButton, children: _jsx(Menu, { "aria-hidden": true, className: "size-(--dt-size-sm)" }) }), _jsxs(Dialog.Portal, { children: [_jsx(Dialog.Backdrop, { "data-designtools": "", className: "fixed inset-0 z-40 bg-canvas-foreground/30 transition-opacity duration-(--dt-duration-base) data-ending-style:opacity-0 data-starting-style:opacity-0" }), _jsxs(Dialog.Popup, { "data-designtools": "", "data-slot": "docs-drawer", "aria-label": title, className: "fixed inset-y-0 left-0 z-50 flex w-[min(21rem,88vw)] flex-col bg-surface text-surface-foreground shadow-xl transition-transform duration-(--dt-duration-slow) ease-(--dt-ease-out) data-ending-style:-translate-x-full data-starting-style:-translate-x-full", children: [_jsxs("div", { className: "flex items-center justify-between gap-2 border-b border-border p-3 pl-4", children: [brandLink, _jsx(Dialog.Close, { "aria-label": "Close the navigation", className: iconButton, children: _jsx(X, { "aria-hidden": true, className: "size-(--dt-size-sm)" }) })] }), _jsx(Nav, { sections: sections, current: current, title: title, className: "pt-4" }), themeSwitch && (_jsxs("div", { className: "flex items-center justify-between gap-3 border-t border-border px-4 py-3", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Appearance" }), _jsx(ThemeSwitch, {})] }))] })] })] }), _jsx("div", { className: "min-w-0 flex-1", children: brandLink }), search && _jsx(DocsSearch, { items: searchItems, shortcuts: false, variant: "icon" })] }), hero && current ===
|
|
92
|
+
const brandLink = (_jsxs(Link, { href: home, "data-slot": "docs-title", className: cx(target, "flex min-w-0 items-center gap-3 rounded-md focus-visible:outline-2 focus-visible:outline-ring"), children: [logo && (_jsx("span", { "data-slot": "docs-logo", className: "shrink-0", children: _jsx(Live, { children: logo }) })), _jsx("span", { className: cx(logo ? "sr-only" : "truncate text-base font-semibold tracking-tight"), children: title })] }));
|
|
93
|
+
return (_jsx(DocsPage.Provider, { value: page, children: _jsxs("div", { "data-designtools": "", "data-slot": "docs-shell", className: "min-h-dvh bg-canvas text-canvas-foreground lg:grid lg:grid-cols-[19rem_minmax(0,1fr)]", children: [_jsx("aside", { "data-slot": "docs-sidebar", className: "sticky top-0 hidden h-dvh p-3 lg:block", children: _jsxs("div", { className: "flex h-full flex-col overflow-hidden rounded-xl border border-border bg-surface text-surface-foreground shadow-xs", children: [_jsxs("div", { className: "flex flex-col gap-3 p-4 pb-3", children: [brandLink, search && _jsx(DocsSearch, { items: searchItems })] }), _jsx(Nav, { sections: sections, current: current, title: title }), themeSwitch && (_jsxs("div", { "data-slot": "docs-sidebar-foot", className: "flex items-center justify-between gap-3 border-t border-border px-4 py-3", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Appearance" }), _jsx(ThemeSwitch, {})] }))] }) }), _jsxs("div", { className: "min-w-0", children: [_jsxs("header", { "data-slot": "docs-topbar", className: "sticky top-0 z-20 flex h-16 items-center gap-2 border-b border-border bg-canvas/85 px-3 backdrop-blur-md lg:hidden", children: [_jsxs(Dialog.Root, { open: menu, onOpenChange: setMenu, children: [_jsx(Dialog.Trigger, { "aria-label": "Open the navigation", className: iconButton, children: _jsx(Menu, { "aria-hidden": true, className: "size-(--dt-size-sm)" }) }), _jsxs(Dialog.Portal, { children: [_jsx(Dialog.Backdrop, { "data-designtools": "", className: "fixed inset-0 z-40 bg-canvas-foreground/30 transition-opacity duration-(--dt-duration-base) data-ending-style:opacity-0 data-starting-style:opacity-0" }), _jsxs(Dialog.Popup, { "data-designtools": "", "data-slot": "docs-drawer", "aria-label": title, className: "fixed inset-y-0 left-0 z-50 flex w-[min(21rem,88vw)] flex-col bg-surface text-surface-foreground shadow-xl transition-transform duration-(--dt-duration-slow) ease-(--dt-ease-out) data-ending-style:-translate-x-full data-starting-style:-translate-x-full", children: [_jsxs("div", { className: "flex items-center justify-between gap-2 border-b border-border p-3 pl-4", children: [brandLink, _jsx(Dialog.Close, { "aria-label": "Close the navigation", className: iconButton, children: _jsx(X, { "aria-hidden": true, className: "size-(--dt-size-sm)" }) })] }), _jsx(Nav, { sections: sections, current: current, title: title, className: "pt-4" }), themeSwitch && (_jsxs("div", { className: "flex items-center justify-between gap-3 border-t border-border px-4 py-3", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: "Appearance" }), _jsx(ThemeSwitch, {})] }))] })] })] }), _jsx("div", { className: "min-w-0 flex-1", children: brandLink }), search && _jsx(DocsSearch, { items: searchItems, shortcuts: false, variant: "icon" })] }), hero && current === home && (_jsx("div", { "data-slot": "docs-hero", className: "w-full", children: _jsx(Live, { children: hero }) })), _jsxs("div", { className: "mx-auto flex w-full max-w-[90rem] gap-16 px-5 pt-12 pb-20 sm:px-8 lg:px-12 lg:pt-20 xl:px-20", children: [_jsxs("main", { "data-slot": "docs-main", className: "flex min-w-0 flex-1 flex-col gap-16 [counter-reset:docs-section] lg:gap-24", children: [children, _jsx(Pager, { prev: page.prev, next: page.next })] }), _jsx(OnThisPage, { current: current })] })] })] }) }));
|
|
92
94
|
}
|
|
93
95
|
const iconButton = "inline-flex size-(--docs-target,2.75rem) shrink-0 cursor-pointer items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-canvas-foreground focus-visible:outline-2 focus-visible:outline-ring";
|
|
94
96
|
/** The sections, each a link or a fold that opens where the current page is. */
|
package/dist/standards.js
CHANGED
|
@@ -14,6 +14,6 @@ export function Standards({ baselines, children }) {
|
|
|
14
14
|
return (_jsxs("div", { "data-slot": "standards", className: "flex flex-col gap-6", children: [_jsx("div", { className: "grid gap-x-12 gap-y-10 md:grid-cols-2 xl:grid-cols-3", children: standardsSections(baselines).map((section) => {
|
|
15
15
|
const Icon = ICON[section.key] ?? Ruler;
|
|
16
16
|
const single = section.rows.length === 1 && !section.rows[0].label;
|
|
17
|
-
return (_jsxs("section", { "data-slot": "standard", className: "flex flex-col gap-4 border-t border-border pt-5", children: [_jsxs("h3", { className: "flex items-center gap-2 text-sm font-medium text-muted-foreground", children: [_jsx(Icon, { "aria-hidden": true, className: "size-(--dt-size-xs)" }), section.title] }), single ? (_jsx("p", { className: "text-
|
|
17
|
+
return (_jsxs("section", { "data-slot": "standard", className: "flex flex-col gap-4 border-t border-border pt-5", children: [_jsxs("h3", { className: "flex items-center gap-2 text-sm font-medium text-muted-foreground", children: [_jsx(Icon, { "aria-hidden": true, className: "size-(--dt-size-xs)" }), section.title] }), single ? (_jsx("p", { className: "text-xl leading-snug tracking-tight text-pretty", children: section.rows[0].value })) : section.rows.length ? (_jsx("dl", { className: "flex flex-col gap-3", children: section.rows.map((row) => (_jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("dt", { className: "text-xs text-muted-foreground", children: row.label }), _jsx("dd", { className: "text-lg leading-snug tracking-tight tabular-nums", children: row.value })] }, row.label))) })) : null, section.notes.map((note) => (_jsx("p", { className: "text-sm text-muted-foreground", children: note }, note)))] }, section.key));
|
|
18
18
|
}) }), typeof baselines.$note === "string" && (_jsxs("p", { className: "flex items-start gap-2 text-sm text-muted-foreground", children: [_jsx(Info, { "aria-hidden": true, className: "mt-0.5 size-(--dt-size-xs) shrink-0" }), baselines.$note] })), children] }));
|
|
19
19
|
}
|
package/dist/styles.css
CHANGED
|
@@ -1428,7 +1428,7 @@
|
|
|
1428
1428
|
}
|
|
1429
1429
|
|
|
1430
1430
|
:where([data-designtools]) .rounded-2xl:not([data-docs-content] *), .rounded-2xl:where([data-designtools]):not([data-docs-content] *) {
|
|
1431
|
-
border-radius: var(--docs-radius-2xl,
|
|
1431
|
+
border-radius: var(--docs-radius-2xl, 1rem);
|
|
1432
1432
|
}
|
|
1433
1433
|
|
|
1434
1434
|
:where([data-designtools]) .rounded-full:not([data-docs-content] *), .rounded-full:where([data-designtools]):not([data-docs-content] *) {
|
|
@@ -1436,29 +1436,29 @@
|
|
|
1436
1436
|
}
|
|
1437
1437
|
|
|
1438
1438
|
:where([data-designtools]) .rounded-lg:not([data-docs-content] *), .rounded-lg:where([data-designtools]):not([data-docs-content] *) {
|
|
1439
|
-
border-radius: var(--docs-radius-lg,
|
|
1439
|
+
border-radius: var(--docs-radius-lg, .5rem);
|
|
1440
1440
|
}
|
|
1441
1441
|
|
|
1442
1442
|
:where([data-designtools]) .rounded-md:not([data-docs-content] *), .rounded-md:where([data-designtools]):not([data-docs-content] *) {
|
|
1443
|
-
border-radius: var(--docs-radius-md,
|
|
1443
|
+
border-radius: var(--docs-radius-md, .375rem);
|
|
1444
1444
|
}
|
|
1445
1445
|
|
|
1446
1446
|
:where([data-designtools]) .rounded-sm:not([data-docs-content] *), .rounded-sm:where([data-designtools]):not([data-docs-content] *) {
|
|
1447
|
-
border-radius: var(--docs-radius-sm,
|
|
1447
|
+
border-radius: var(--docs-radius-sm, .25rem);
|
|
1448
1448
|
}
|
|
1449
1449
|
|
|
1450
1450
|
:where([data-designtools]) .rounded-xl:not([data-docs-content] *), .rounded-xl:where([data-designtools]):not([data-docs-content] *) {
|
|
1451
|
-
border-radius: var(--docs-radius-xl,
|
|
1451
|
+
border-radius: var(--docs-radius-xl, .75rem);
|
|
1452
1452
|
}
|
|
1453
1453
|
|
|
1454
1454
|
:where([data-designtools]) .rounded-l-lg:not([data-docs-content] *), .rounded-l-lg:where([data-designtools]):not([data-docs-content] *) {
|
|
1455
|
-
border-top-left-radius: var(--docs-radius-lg,
|
|
1456
|
-
border-bottom-left-radius: var(--docs-radius-lg,
|
|
1455
|
+
border-top-left-radius: var(--docs-radius-lg, .5rem);
|
|
1456
|
+
border-bottom-left-radius: var(--docs-radius-lg, .5rem);
|
|
1457
1457
|
}
|
|
1458
1458
|
|
|
1459
1459
|
:where([data-designtools]) .rounded-r-lg:not([data-docs-content] *), .rounded-r-lg:where([data-designtools]):not([data-docs-content] *) {
|
|
1460
|
-
border-top-right-radius: var(--docs-radius-lg,
|
|
1461
|
-
border-bottom-right-radius: var(--docs-radius-lg,
|
|
1460
|
+
border-top-right-radius: var(--docs-radius-lg, .5rem);
|
|
1461
|
+
border-bottom-right-radius: var(--docs-radius-lg, .5rem);
|
|
1462
1462
|
}
|
|
1463
1463
|
|
|
1464
1464
|
:where([data-designtools]) .border:not([data-docs-content] *), .border:where([data-designtools]):not([data-docs-content] *) {
|
|
@@ -1496,6 +1496,11 @@
|
|
|
1496
1496
|
border-left-width: 1px;
|
|
1497
1497
|
}
|
|
1498
1498
|
|
|
1499
|
+
:where([data-designtools]) .border-l-2:not([data-docs-content] *), .border-l-2:where([data-designtools]):not([data-docs-content] *) {
|
|
1500
|
+
border-left-style: var(--tw-border-style);
|
|
1501
|
+
border-left-width: 2px;
|
|
1502
|
+
}
|
|
1503
|
+
|
|
1499
1504
|
:where([data-designtools]) .border-dashed:not([data-docs-content] *), .border-dashed:where([data-designtools]):not([data-docs-content] *) {
|
|
1500
1505
|
--tw-border-style: dashed;
|
|
1501
1506
|
border-style: dashed;
|
|
@@ -1552,6 +1557,10 @@
|
|
|
1552
1557
|
border-color: #0000;
|
|
1553
1558
|
}
|
|
1554
1559
|
|
|
1560
|
+
:where([data-designtools]) .border-warning:not([data-docs-content] *), .border-warning:where([data-designtools]):not([data-docs-content] *) {
|
|
1561
|
+
border-color: var(--warning, #ed8a3c);
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1555
1564
|
:where([data-designtools]) .bg-\[var\(--docs-accent\,var\(--primary\)\)\]:not([data-docs-content] *), .bg-\[var\(--docs-accent\,var\(--primary\)\)\]:where([data-designtools]):not([data-docs-content] *) {
|
|
1556
1565
|
background-color: var(--docs-accent, var(--primary));
|
|
1557
1566
|
}
|
|
@@ -1646,10 +1655,6 @@
|
|
|
1646
1655
|
background-color: var(--primary, #2b5ce6);
|
|
1647
1656
|
}
|
|
1648
1657
|
|
|
1649
|
-
:where([data-designtools]) .bg-primary-foreground:not([data-docs-content] *), .bg-primary-foreground:where([data-designtools]):not([data-docs-content] *) {
|
|
1650
|
-
background-color: var(--primary-foreground, #fff);
|
|
1651
|
-
}
|
|
1652
|
-
|
|
1653
1658
|
:where([data-designtools]) .bg-primary-subdued:not([data-docs-content] *), .bg-primary-subdued:where([data-designtools]):not([data-docs-content] *) {
|
|
1654
1659
|
background-color: var(--primary-subdued, #eef2fd);
|
|
1655
1660
|
}
|
|
@@ -2160,6 +2165,10 @@
|
|
|
2160
2165
|
letter-spacing: var(--tracking-wide, .04em);
|
|
2161
2166
|
}
|
|
2162
2167
|
|
|
2168
|
+
:where([data-designtools]) .text-pretty:not([data-docs-content] *), .text-pretty:where([data-designtools]):not([data-docs-content] *) {
|
|
2169
|
+
text-wrap: pretty;
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2163
2172
|
:where([data-designtools]) .break-words:not([data-docs-content] *), .break-words:where([data-designtools]):not([data-docs-content] *) {
|
|
2164
2173
|
overflow-wrap: break-word;
|
|
2165
2174
|
}
|
|
@@ -2594,10 +2603,6 @@
|
|
|
2594
2603
|
text-decoration-line: underline;
|
|
2595
2604
|
}
|
|
2596
2605
|
|
|
2597
|
-
:where([data-designtools]) .group-hover\:underline-offset-4:is(:where(.group):hover *):not([data-docs-content] *), .group-hover\:underline-offset-4:is(:where(.group):hover *):where([data-designtools]):not([data-docs-content] *) {
|
|
2598
|
-
text-underline-offset: 4px;
|
|
2599
|
-
}
|
|
2600
|
-
|
|
2601
2606
|
:where([data-designtools]) .group-hover\:opacity-100:is(:where(.group):hover *):not([data-docs-content] *), .group-hover\:opacity-100:is(:where(.group):hover *):where([data-designtools]):not([data-docs-content] *) {
|
|
2602
2607
|
opacity: 1;
|
|
2603
2608
|
}
|
|
@@ -2939,8 +2944,8 @@
|
|
|
2939
2944
|
translate: var(--tw-translate-x) var(--tw-translate-y);
|
|
2940
2945
|
}
|
|
2941
2946
|
|
|
2942
|
-
:where([data-designtools]) .data-\[checked\]\:bg-primary[data-checked]:not([data-docs-content] *), .data-\[checked\]\:bg-primary[data-checked]:where([data-designtools]):not([data-docs-content] *) {
|
|
2943
|
-
background-color: var(--
|
|
2947
|
+
:where([data-designtools]) .data-\[checked\]\:bg-\[var\(--docs-accent\,var\(--primary\)\)\][data-checked]:not([data-docs-content] *), .data-\[checked\]\:bg-\[var\(--docs-accent\,var\(--primary\)\)\][data-checked]:where([data-designtools]):not([data-docs-content] *) {
|
|
2948
|
+
background-color: var(--docs-accent, var(--primary));
|
|
2944
2949
|
}
|
|
2945
2950
|
|
|
2946
2951
|
:where([data-designtools]) .data-\[highlighted\]\:bg-muted[data-highlighted]:not([data-docs-content] *), .data-\[highlighted\]\:bg-muted[data-highlighted]:where([data-designtools]):not([data-docs-content] *) {
|
|
@@ -3067,6 +3072,10 @@
|
|
|
3067
3072
|
grid-template-columns: 13rem minmax(0, 1fr) auto;
|
|
3068
3073
|
}
|
|
3069
3074
|
|
|
3075
|
+
:where([data-designtools]) .md\:grid-cols-\[14rem_minmax\(0\,1fr\)_auto\]:not([data-docs-content] *), .md\:grid-cols-\[14rem_minmax\(0\,1fr\)_auto\]:where([data-designtools]):not([data-docs-content] *) {
|
|
3076
|
+
grid-template-columns: 14rem minmax(0, 1fr) auto;
|
|
3077
|
+
}
|
|
3078
|
+
|
|
3070
3079
|
:where([data-designtools]) .md\:grid-cols-\[minmax\(9rem\,0\.9fr\)_minmax\(0\,1\.6fr\)_minmax\(5rem\,0\.6fr\)_1\.25rem\]:not([data-docs-content] *), .md\:grid-cols-\[minmax\(9rem\,0\.9fr\)_minmax\(0\,1\.6fr\)_minmax\(5rem\,0\.6fr\)_1\.25rem\]:where([data-designtools]):not([data-docs-content] *) {
|
|
3071
3080
|
grid-template-columns: minmax(9rem, .9fr) minmax(0, 1.6fr) minmax(5rem, .6fr) 1.25rem;
|
|
3072
3081
|
}
|
|
@@ -3118,14 +3127,6 @@
|
|
|
3118
3127
|
}
|
|
3119
3128
|
|
|
3120
3129
|
@media (min-width: 64rem) {
|
|
3121
|
-
:where([data-designtools]) .lg\:sticky:not([data-docs-content] *), .lg\:sticky:where([data-designtools]):not([data-docs-content] *) {
|
|
3122
|
-
position: sticky;
|
|
3123
|
-
}
|
|
3124
|
-
|
|
3125
|
-
:where([data-designtools]) .lg\:top-24:not([data-docs-content] *), .lg\:top-24:where([data-designtools]):not([data-docs-content] *) {
|
|
3126
|
-
top: 6rem;
|
|
3127
|
-
}
|
|
3128
|
-
|
|
3129
3130
|
:where([data-designtools]) .lg\:col-span-1:not([data-docs-content] *), .lg\:col-span-1:where([data-designtools]):not([data-docs-content] *) {
|
|
3130
3131
|
grid-column: span 1 / span 1;
|
|
3131
3132
|
}
|
|
@@ -3174,10 +3175,6 @@
|
|
|
3174
3175
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|
3175
3176
|
}
|
|
3176
3177
|
|
|
3177
|
-
:where([data-designtools]) .lg\:grid-cols-\[3rem_minmax\(0\,1fr\)\]:not([data-docs-content] *), .lg\:grid-cols-\[3rem_minmax\(0\,1fr\)\]:where([data-designtools]):not([data-docs-content] *) {
|
|
3178
|
-
grid-template-columns: 3rem minmax(0, 1fr);
|
|
3179
|
-
}
|
|
3180
|
-
|
|
3181
3178
|
:where([data-designtools]) .lg\:grid-cols-\[19rem_minmax\(0\,1fr\)\]:not([data-docs-content] *), .lg\:grid-cols-\[19rem_minmax\(0\,1fr\)\]:where([data-designtools]):not([data-docs-content] *) {
|
|
3182
3179
|
grid-template-columns: 19rem minmax(0, 1fr);
|
|
3183
3180
|
}
|
|
@@ -3206,10 +3203,6 @@
|
|
|
3206
3203
|
gap: 6rem;
|
|
3207
3204
|
}
|
|
3208
3205
|
|
|
3209
|
-
:where([data-designtools]) .lg\:self-start:not([data-docs-content] *), .lg\:self-start:where([data-designtools]):not([data-docs-content] *) {
|
|
3210
|
-
align-self: flex-start;
|
|
3211
|
-
}
|
|
3212
|
-
|
|
3213
3206
|
:where([data-designtools]) .lg\:overflow-y-auto:not([data-docs-content] *), .lg\:overflow-y-auto:where([data-designtools]):not([data-docs-content] *) {
|
|
3214
3207
|
overflow-y: auto;
|
|
3215
3208
|
}
|
package/dist/type-ramp.js
CHANGED
|
@@ -16,7 +16,7 @@ export function TypeRamp({ tokens, sample = "The quick brown fox jumps over the
|
|
|
16
16
|
const weights = tokensOfTier(tokens, "font-weight");
|
|
17
17
|
const leading = tokensOfTier(tokens, "leading");
|
|
18
18
|
const tracking = tokensOfTier(tokens, "tracking");
|
|
19
|
-
return (_jsxs("div", { "data-slot": "type-ramp", className: "flex flex-col gap-14", children: [families.length > 0 && (_jsx("div", { className: "grid gap-x-12 gap-y-10 md:grid-cols-2", children: families.map((f) => (_jsxs("figure", { "data-slot": "type-family", className: "flex flex-col gap-5 border-t border-border pt-6", children: [
|
|
19
|
+
return (_jsxs("div", { "data-slot": "type-ramp", className: "flex flex-col gap-14", children: [families.length > 0 && (_jsx("div", { className: "grid gap-x-12 gap-y-10 md:grid-cols-2", children: families.map((f) => (_jsxs("figure", { "data-slot": "type-family", className: "flex flex-col gap-5 border-t border-border pt-6", children: [_jsx("span", { className: "text-8xl leading-none font-light tracking-tighter", style: { fontFamily: `var(${f.name})` }, children: "Aa" }), _jsxs("figcaption", { className: "flex flex-col gap-0.5", children: [_jsx("code", { className: "font-mono text-xs font-medium", children: shortName(f, "font") }), _jsx("span", { className: "truncate font-mono text-xs text-muted-foreground", title: f.values.default, children: f.description ?? f.values.default })] })] }, f.name))) })), _jsx("ol", { "data-slot": "type-scale", className: "flex flex-col", children: steps.map((step) => (_jsxs("li", { "data-slot": "type-step", className: "grid grid-cols-1 gap-3 border-t border-border py-5 md:grid-cols-[11rem_minmax(0,1fr)] md:items-center md:gap-6", children: [_jsxs("div", { className: "flex flex-col gap-1", children: [_jsxs("span", { className: "flex items-baseline gap-2", children: [_jsx("code", { className: "font-mono text-xs font-semibold", children: shortName(step.size, "text") }), _jsx("span", { className: "font-mono text-xs text-muted-foreground", children: px(step.size.values.default) ?? step.size.values.default })] }), _jsx("span", { className: "font-mono text-xs text-muted-foreground", children: [step.lineHeight && `lh ${step.lineHeight.values.default}`, step.letterSpacing && `tr ${step.letterSpacing.values.default}`].filter(Boolean).join(" · ") }), step.description && _jsx("span", { className: "text-xs text-muted-foreground", children: step.description })] }), _jsx("p", { className: "min-w-0 truncate", style: {
|
|
20
20
|
fontSize: `var(${step.name})`,
|
|
21
21
|
lineHeight: step.lineHeight ? `var(${step.lineHeight.name})` : undefined,
|
|
22
22
|
letterSpacing: step.letterSpacing ? `var(${step.letterSpacing.name})` : undefined,
|
package/dist/variant-matrix.d.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
import { type ReactNode } from "react";
|
|
1
|
+
import { type ReactElement, type ReactNode } from "react";
|
|
2
2
|
import type { ComponentEntry } from "./lib/manifest-types.js";
|
|
3
3
|
/**
|
|
4
4
|
* Every variant, rendered live. The first two axes form a grid; each further
|
|
5
5
|
* axis gets its own row, with the others at their defaults. Pass `props` for
|
|
6
6
|
* anything the component needs to render (an `options` list, a `value`).
|
|
7
7
|
*/
|
|
8
|
-
export declare function VariantMatrix({ entry, props, children, axes: only, }: {
|
|
8
|
+
export declare function VariantMatrix({ entry, props, children, axes: only, wrap, }: {
|
|
9
9
|
entry: ComponentEntry;
|
|
10
10
|
props?: Record<string, unknown>;
|
|
11
|
+
/** What each instance must sit in to work: a provider, its root. */
|
|
12
|
+
wrap?: ReactElement<{
|
|
13
|
+
children?: ReactNode;
|
|
14
|
+
}>;
|
|
11
15
|
/** What to render inside each instance. Defaults to the component's name. */
|
|
12
16
|
children?: ReactNode;
|
|
13
17
|
/** Limit and order the axes shown. */
|
package/dist/variant-matrix.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { Live } from "./lib/live.js";
|
|
4
|
+
import { wrapIn } from "./lib/wrap.js";
|
|
4
5
|
import { Grid3x3, Moon, Sun } from "lucide-react";
|
|
5
6
|
import { useEffect, useState } from "react";
|
|
6
7
|
import { cx } from "./lib/cx.js";
|
|
@@ -12,7 +13,7 @@ import { Frame, IconButton, Toolbar } from "./lib/ui.js";
|
|
|
12
13
|
* axis gets its own row, with the others at their defaults. Pass `props` for
|
|
13
14
|
* anything the component needs to render (an `options` list, a `value`).
|
|
14
15
|
*/
|
|
15
|
-
export function VariantMatrix({ entry, props = {}, children, axes: only, }) {
|
|
16
|
+
export function VariantMatrix({ entry, props = {}, children, axes: only, wrap, }) {
|
|
16
17
|
const lookup = useLookup();
|
|
17
18
|
const Component = lookup.componentFor(entry);
|
|
18
19
|
const [theme, setTheme] = useState();
|
|
@@ -23,7 +24,7 @@ export function VariantMatrix({ entry, props = {}, children, axes: only, }) {
|
|
|
23
24
|
if (axes.length === 0)
|
|
24
25
|
return _jsxs("p", { className: "text-sm text-muted-foreground", children: [entry.name, " has no variants."] });
|
|
25
26
|
const content = children ?? entry.name;
|
|
26
|
-
const render = (extra) => (_jsx(Live, { children: _jsx(Component, { ...props, ...coerce(extra), children: content }) }));
|
|
27
|
+
const render = (extra) => (_jsx(Live, { children: wrapIn(wrap, _jsx(Component, { ...props, ...coerce(extra), children: content })) }));
|
|
27
28
|
const [rows, cols, ...rest] = axes;
|
|
28
29
|
const toggle = (_jsx(IconButton, { icon: theme === "dark" ? Sun : Moon, label: theme === "dark" ? "Show in light mode" : "Show in dark mode", pressed: theme !== undefined, onClick: () => setTheme(theme === "dark" ? "light" : "dark") }));
|
|
29
30
|
return (_jsxs(Frame, { "data-slot": "variant-matrix", children: [_jsxs(Toolbar, { children: [_jsxs("span", { className: "flex items-center gap-2 pl-2 font-mono text-xs text-muted-foreground", children: [_jsx(Grid3x3, { "aria-hidden": true, className: "size-(--dt-size-xs)" }), cols ? `${rows.name} × ${cols.name}` : rows.name, rest.length > 0 && `, ${rest.map((a) => a.name).join(", ")}`] }), toggle] }), _jsxs("div", { "data-docs-stage": "", "data-theme": theme, className: "flex flex-col gap-12 bg-canvas px-6 py-8 text-canvas-foreground sm:px-8", children: [cols ? (_jsx("div", { className: "overflow-x-auto", tabIndex: 0, role: "region", "aria-label": "Variants", children: _jsxs("table", { className: "w-full border-collapse text-sm", children: [_jsxs("caption", { className: "sr-only", children: [entry.name, ": ", rows.name, " by ", cols.name] }), _jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", className: "w-0 p-0" }), cols.options.map((c) => (_jsx("th", { scope: "col", title: c.description, className: "px-4 pb-4 text-center font-mono text-xs font-normal text-muted-foreground", children: _jsx(OptionName, { axis: cols, option: c.name }) }, c.name)))] }) }), _jsx("tbody", { children: rows.options.map((r) => (_jsxs("tr", { children: [_jsx("th", { scope: "row", title: r.description, className: "py-4 pr-6 text-left font-mono text-xs font-normal whitespace-nowrap text-muted-foreground", children: _jsx(OptionName, { axis: rows, option: r.name }) }), cols.options.map((c) => (_jsx("td", { "data-slot": "variant-cell", className: "px-4 py-4 text-center align-middle", children: _jsx("span", { className: "inline-flex justify-center", children: render({ [rows.name]: r.name, [cols.name]: c.name }) }) }, c.name)))] }, r.name))) })] }) })) : (_jsx(AxisRow, { axis: rows, render: render })), rest.map((axis) => (_jsx(AxisRow, { axis: axis, render: render }, axis.name))), _jsx(States, { render: render, canDisable: "disabled" in entry.props })] })] }));
|
package/dist/workbench.js
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { handlerNames } from "./lib/handlers.js";
|
|
4
4
|
import { Live } from "./lib/live.js";
|
|
5
|
+
import { wrapIn } from "./lib/wrap.js";
|
|
5
6
|
import { Tabs } from "@base-ui/react/tabs";
|
|
6
7
|
import { Toggle } from "@base-ui/react/toggle";
|
|
7
8
|
import { ToggleGroup } from "@base-ui/react/toggle-group";
|
|
8
9
|
import { Bot, Braces, Check, Code, Eye, ExternalLink, Link2, Maximize2, Minimize2, Minus, Monitor, Moon, PaintBucket, PersonStanding, Plus, RotateCcw, Ruler, SquareDashed, Sun, Trash2, Zap, } from "lucide-react";
|
|
9
|
-
import {
|
|
10
|
+
import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
10
11
|
import { AxeReport, useAxe } from "./a11y-panel.js";
|
|
11
12
|
import { CodeView } from "./code-view.js";
|
|
12
13
|
import { Boundary } from "./lib/boundary.js";
|
|
@@ -231,7 +232,7 @@ export function Workbench({ entry, props: base = {}, children: initialText = ent
|
|
|
231
232
|
width: view.viewport === "fill" ? undefined : Number(view.viewport),
|
|
232
233
|
zoom: view.zoom === 100 ? undefined : view.zoom / 100,
|
|
233
234
|
filter: filterFor(view.vision, filterId),
|
|
234
|
-
}, children: _jsx("div", { ref: target, "data-slot": "workbench-target", className: "flex max-w-full items-center justify-center", children: _jsx(Boundary, { label: entry.name, children:
|
|
235
|
+
}, children: _jsx("div", { ref: target, "data-slot": "workbench-target", className: "flex max-w-full items-center justify-center", children: _jsx(Boundary, { label: entry.name, children: wrapIn(wrap, node) }) }) }) }), view.measure && _jsx(Measure, { area: area, target: target })] }), _jsxs("div", { "data-slot": "workbench-controls", className: cx("flex flex-col gap-7 border-t border-border p-5 lg:border-t-0 lg:border-l", full ? "overflow-y-auto" : "lg:max-h-[44rem] lg:overflow-y-auto"), children: [_jsxs("div", { className: "-mt-1.5 -mb-2 flex min-h-9 items-center justify-between", children: [_jsx("p", { className: "text-sm font-medium", children: "Properties" }), _jsx(IconButton, { icon: RotateCcw, label: "Reset everything", onClick: reset, disabled: !changed, className: "disabled:pointer-events-none disabled:opacity-40" })] }), _jsx(StateControl, { value: state, onChange: setState, canDisable: canDisable }), axes.length > 0 && (_jsx(Section, { title: "Variants", children: axes.map((axis) => (_jsx(AxisControl, { axis: axis, value: variants[axis.name] ?? axis.default ?? "", onChange: (v) => setVariants((s) => ({ ...s, [axis.name]: v })) }, axis.name))) })), settable.length > 0 && (_jsx(Section, { title: "Props", children: settable.map(([name, p]) => {
|
|
235
236
|
const current = name in values ? values[name] : base[name];
|
|
236
237
|
const put = (v) => setValues((s) => ({ ...s, [name]: v }));
|
|
237
238
|
const info = _jsx(PropInfo, { prop: p });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@designtools/docs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Design system docs as a package: pages, navigation, search, a workbench per component, rules, patterns, brand pages and markdown for agents, generated from the @designtools/manifest and themed by your tokens. One Next adapter serves them inside your app or as a standalone site.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AdherenceReport, Counts } from "./lib/adherence-types";
|
|
2
2
|
import { ChevronDown } from "lucide-react";
|
|
3
|
-
import { cx } from "./lib/cx";
|
|
3
|
+
import { accent, cx } from "./lib/cx";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* The latest adherence report: how much of what the system could render comes
|
|
@@ -32,7 +32,7 @@ export function AdherenceSummary({ report }: { report: AdherenceReport }) {
|
|
|
32
32
|
aria-valuemax={100}
|
|
33
33
|
className="block h-2 overflow-hidden rounded-full bg-muted"
|
|
34
34
|
>
|
|
35
|
-
<span className="block h-full rounded-full
|
|
35
|
+
<span className={cx("block h-full rounded-full", accent)} style={{ width: `${pct}%` }} />
|
|
36
36
|
</span>
|
|
37
37
|
)}
|
|
38
38
|
</span>
|
|
@@ -46,6 +46,11 @@ export function AdherenceSummary({ report }: { report: AdherenceReport }) {
|
|
|
46
46
|
))}
|
|
47
47
|
</dl>
|
|
48
48
|
</div>
|
|
49
|
+
{report.unchecked?.map((note) => (
|
|
50
|
+
<p key={note} data-slot="adherence-unchecked" className="border-l-2 border-warning pl-4 text-sm">
|
|
51
|
+
{note}
|
|
52
|
+
</p>
|
|
53
|
+
))}
|
|
49
54
|
{s.replaceable.length === 0 && (
|
|
50
55
|
<p className="text-sm text-muted-foreground">
|
|
51
56
|
No component declares <code className="font-mono text-xs">@replaces</code>, so raw elements are not counted and the share is
|