@designtools/docs 0.1.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +24 -2
- package/dist/anatomy.js +2 -1
- package/dist/cli.js +1 -1
- package/dist/glossary.d.ts +1 -1
- package/dist/glossary.js +13 -6
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/lib/live.d.ts +10 -0
- package/dist/lib/live.js +10 -0
- package/dist/lib/lookup.js +3 -2
- package/dist/lib/status.d.ts +2 -3
- package/dist/lib/terms.d.ts +15 -0
- package/dist/lib/terms.js +20 -0
- package/dist/next/config.d.ts +24 -4
- package/dist/next/index.d.ts +3 -0
- package/dist/next/index.js +3 -0
- package/dist/next/markdown.js +1 -1
- package/dist/next/pages.js +82 -16
- package/dist/next/prose.d.ts +2 -2
- package/dist/next/prose.js +6 -4
- package/dist/pattern.d.ts +4 -1
- package/dist/pattern.js +11 -8
- package/dist/playground.js +1 -1
- package/dist/rule.d.ts +9 -5
- package/dist/rule.js +14 -9
- package/dist/shell.d.ts +4 -1
- package/dist/shell.js +13 -11
- package/dist/styles.css +961 -754
- package/dist/swatches.d.ts +7 -6
- package/dist/swatches.js +50 -16
- package/dist/variant-matrix.js +11 -6
- package/dist/voice-terms.js +6 -5
- package/dist/workbench.js +2 -1
- package/package.json +1 -1
- package/src/anatomy.tsx +6 -1
- package/src/glossary.tsx +39 -40
- package/src/index.ts +2 -1
- package/src/lib/live.tsx +15 -0
- package/src/lib/lookup.tsx +3 -2
- package/src/lib/status.tsx +3 -3
- package/src/lib/terms.tsx +53 -0
- package/src/next/config.ts +25 -4
- package/src/next/index.tsx +3 -0
- package/src/next/markdown.ts +1 -1
- package/src/next/pages.tsx +172 -59
- package/src/next/prose.tsx +16 -6
- package/src/pattern.tsx +42 -37
- package/src/playground.tsx +7 -2
- package/src/rule.tsx +108 -59
- package/src/shell.tsx +30 -16
- package/src/styles.css +4 -2
- package/src/swatches.tsx +189 -120
- package/src/variant-matrix.tsx +63 -80
- package/src/voice-terms.tsx +20 -29
- package/src/workbench.tsx +6 -3
package/dist/pattern.js
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { ArrowUpRight } from "lucide-react";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
4
3
|
import Link from "next/link";
|
|
5
4
|
import { ExampleFrame } from "./examples.js";
|
|
6
5
|
import { Missing, renderExample, useLookup } from "./lib/lookup.js";
|
|
7
6
|
import { slugOf } from "./lib/manifest.js";
|
|
8
7
|
import { StatusBadge } from "./lib/status.js";
|
|
9
|
-
|
|
8
|
+
import { DocsSection } from "./shell.js";
|
|
9
|
+
/**
|
|
10
|
+
* A recurring screen composition: each composition live in its frame, with its code, then the
|
|
11
|
+
* components it is made of, each linking to its page. Its status sits in the page header.
|
|
12
|
+
*/
|
|
10
13
|
export function Pattern({ pattern, manifest, basePath = "/design/system", }) {
|
|
11
14
|
const lookup = useLookup();
|
|
12
15
|
const module = lookup.compositionsFor(pattern);
|
|
13
16
|
const known = new Map((manifest?.components ?? []).map((c) => [c.name, c]));
|
|
14
|
-
return (_jsxs("div", { "data-slot": "pattern", className: "flex flex-col gap-10", children:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { "data-slot": "pattern", className: "flex flex-col gap-10", children: !module ? (_jsx(Missing, { name: pattern.name, what: "compositions" })) : (pattern.examples.map((ex, i) => (_jsx(ExampleFrame, { name: ex.name, kind: i === 0 ? "canonical" : "other", description: ex.description, code: ex.code, children: renderExample(module[ex.name], ex.name) }, ex.name)))) }), pattern.components.length > 0 && (_jsx(DocsSection, { title: "Made of", lead: "The system's own components, so the pattern changes when they do.", children: _jsx("ul", { "data-slot": "pattern-parts", className: "grid gap-x-10 sm:grid-cols-2", children: pattern.components.map((name) => {
|
|
18
|
+
const c = known.get(name);
|
|
19
|
+
const body = (_jsxs(_Fragment, { children: [_jsxs("span", { className: "flex items-center justify-between gap-3", children: [_jsx("span", { className: "text-lg tracking-tight underline-offset-4 group-hover:underline", children: name }), c && _jsx(StatusBadge, { status: c.status })] }), c?.description && _jsx("span", { className: "line-clamp-2 text-sm text-muted-foreground", children: c.description })] }));
|
|
20
|
+
return (_jsx("li", { className: "border-t border-border", children: c ? (_jsx(Link, { href: `${basePath}/components/${slugOf(c)}`, className: "group flex flex-col gap-1.5 py-4 focus-visible:outline-2 focus-visible:outline-ring", children: body })) : (_jsx("span", { className: "flex flex-col gap-1.5 py-4", children: body })) }, name));
|
|
21
|
+
}) }) }))] }));
|
|
19
22
|
}
|
package/dist/playground.js
CHANGED
|
@@ -55,7 +55,7 @@ const fitsSegments = (axis) => axis.options.length <= 4 && axis.options.reduce((
|
|
|
55
55
|
/** A control's label, with the prop it sets and what its options mean behind an info button. */
|
|
56
56
|
export function Label({ id, name, info, htmlFor }) {
|
|
57
57
|
const text = (_jsx("span", { className: "text-sm font-medium", children: title(name) }));
|
|
58
|
-
return (_jsxs("div", { className: "flex items-center justify-between gap-2", children: [htmlFor ? (_jsx("label", { id: id, htmlFor: htmlFor, children: text })) : (_jsx("span", { id: id, children: text })), _jsxs(Tooltip.Root, { children: [_jsx(Tooltip.Trigger, { "aria-label": `About ${title(name)}`, className: "relative inline-flex size-6 cursor-pointer items-center justify-center rounded-full text-muted-foreground hover:text-canvas-foreground focus-visible:outline-2 focus-visible:outline-ring after:absolute after:-inset-2.5 after:content-['']", children: _jsx(Info, { "aria-hidden": true, className: "size-4" }) }), _jsx(Tooltip.Portal, { children: _jsx(Tooltip.Positioner, { "data-designtools": "", side: "left", sideOffset: 8, className: "z-50", children: _jsxs(Tooltip.Popup, { className: "flex max-w-64 flex-col gap-1
|
|
58
|
+
return (_jsxs("div", { className: "flex items-center justify-between gap-2", children: [htmlFor ? (_jsx("label", { id: id, htmlFor: htmlFor, children: text })) : (_jsx("span", { id: id, children: text })), _jsxs(Tooltip.Root, { children: [_jsx(Tooltip.Trigger, { delay: 0, closeDelay: 0, "aria-label": `About ${title(name)}`, className: "relative inline-flex size-6 cursor-pointer items-center justify-center rounded-full text-muted-foreground hover:text-canvas-foreground focus-visible:outline-2 focus-visible:outline-ring after:absolute after:-inset-2.5 after:content-['']", children: _jsx(Info, { "aria-hidden": true, className: "size-4" }) }), _jsx(Tooltip.Portal, { children: _jsx(Tooltip.Positioner, { "data-designtools": "", side: "left", sideOffset: 8, className: "z-50", children: _jsxs(Tooltip.Popup, { "data-slot": "docs-tooltip", className: "flex max-w-64 flex-col gap-1 rounded-md bg-canvas-foreground px-2.5 py-2 text-xs leading-snug text-canvas shadow-md transition-opacity duration-(--dt-duration-fast) data-ending-style:opacity-0 data-starting-style:opacity-0 [&_*]:text-canvas/80", children: [_jsx("code", { className: "font-mono font-medium text-canvas!", children: name }), info] }) }) })] })] }));
|
|
59
59
|
}
|
|
60
60
|
function AxisInfo({ axis }) {
|
|
61
61
|
const described = axis.options.filter((o) => o.description);
|
package/dist/rule.d.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
2
|
import type { RuleEntry } from "./lib/manifest-types.js";
|
|
3
3
|
/**
|
|
4
|
-
* One rule, brand or interface, written for people
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* One rule, brand or interface, written for people. On a wide screen, its name, status and the check
|
|
5
|
+
* that proves it hold the left column while the right reads: the statement set large, the
|
|
6
|
+
* demonstration (pass it as children, for a rule that needs persuading), the facts, then why. A small
|
|
7
|
+
* switch shows the same rule as an agent reads it.
|
|
8
8
|
*/
|
|
9
9
|
export declare function Rule({ rule, children }: {
|
|
10
10
|
rule: RuleEntry;
|
|
11
11
|
children?: ReactNode;
|
|
12
12
|
}): import("react").JSX.Element;
|
|
13
|
+
/** Every rule on one screen, a line each, linking to the rule: what it is, how settled, how it is checked. */
|
|
14
|
+
export declare function RuleIndex({ rules }: {
|
|
15
|
+
rules: RuleEntry[];
|
|
16
|
+
}): import("react").JSX.Element;
|
package/dist/rule.js
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Live } from "./lib/live.js";
|
|
3
4
|
import { Bot, Eye, Hash, ShieldCheck } from "lucide-react";
|
|
5
|
+
import { useState } from "react";
|
|
4
6
|
import { CodeView } from "./code-view.js";
|
|
5
7
|
import { cx } from "./lib/cx.js";
|
|
6
8
|
import { ruleMarkdown } from "./lib/markdown.js";
|
|
7
9
|
import { StatusBadge } from "./lib/status.js";
|
|
8
10
|
import { inline, Prose } from "./lib/text.js";
|
|
9
|
-
import { Eyebrow
|
|
11
|
+
import { Eyebrow } from "./lib/ui.js";
|
|
10
12
|
const CHECK = { test: "Tested", lint: "Linted", audit: "Audited", manual: "Checked by a person" };
|
|
11
13
|
/**
|
|
12
|
-
* One rule, brand or interface, written for people
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
14
|
+
* One rule, brand or interface, written for people. On a wide screen, its name, status and the check
|
|
15
|
+
* that proves it hold the left column while the right reads: the statement set large, the
|
|
16
|
+
* demonstration (pass it as children, for a rule that needs persuading), the facts, then why. A small
|
|
17
|
+
* switch shows the same rule as an agent reads it.
|
|
16
18
|
*/
|
|
17
19
|
export function Rule({ rule, children }) {
|
|
20
|
+
const [view, setView] = useState("people");
|
|
18
21
|
const chips = (items, mono = false) => (_jsx("span", { className: "flex flex-wrap gap-1.5", children: items.map((t) => (_jsx("span", { className: cx("inline-flex min-h-6 items-center rounded-sm bg-muted px-1.5 text-xs", mono && "font-mono"), children: t }, t))) }));
|
|
19
22
|
const facts = [];
|
|
20
23
|
if (rule.threshold)
|
|
@@ -25,8 +28,10 @@ export function Rule({ rule, children }) {
|
|
|
25
28
|
facts.push(["Exceptions", _jsx("span", { children: rule.exceptions.join("; ") }, "e")]);
|
|
26
29
|
if (rule.tokens?.length)
|
|
27
30
|
facts.push(["Tokens", chips(rule.tokens, true)]);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
const toggle = (value, label, Icon) => (_jsxs("button", { type: "button", "aria-pressed": view === value, onClick: () => setView(value), className: cx("inline-flex min-h-8 cursor-pointer items-center gap-1.5 rounded-md px-2 text-xs font-medium transition-colors duration-(--dt-duration-fast) focus-visible:outline-2 focus-visible:outline-ring", view === value ? "bg-muted text-canvas-foreground" : "text-muted-foreground hover:text-canvas-foreground"), children: [_jsx(Icon, { "aria-hidden": true, className: "size-3.5" }), label] }));
|
|
32
|
+
return (_jsxs("article", { id: rule.id, "data-slot": "rule", className: "grid scroll-mt-24 gap-x-12 gap-y-6 border-t border-border pt-10 xl:grid-cols-[15rem_minmax(0,1fr)]", children: [_jsxs("header", { "data-slot": "rule-header", className: "flex flex-col gap-4 xl:sticky xl:top-24 xl:self-start", children: [_jsxs("div", { className: "flex flex-col gap-2.5", children: [_jsx("span", { className: "text-xs font-medium text-muted-foreground", children: rule.kind === "brand" ? "Brand rule" : "Interface rule" }), _jsxs("h3", { className: "group flex items-start gap-1 text-2xl leading-tight tracking-tight", children: [rule.title, _jsx("a", { href: `#${rule.id}`, "aria-label": `Link to ${rule.title}`, className: "relative mt-0.5 inline-flex size-7 shrink-0 items-center justify-center rounded-md text-muted-foreground opacity-0 group-hover:opacity-100 hover:bg-muted focus-visible:opacity-100 focus-visible:outline-2 focus-visible:outline-ring after:absolute after:-inset-2 after:content-['']", children: _jsx(Hash, { "aria-hidden": true, className: "size-4" }) })] }), _jsx("span", { children: _jsx(StatusBadge, { status: rule.status }) })] }), rule.check && (_jsxs("p", { "data-slot": "rule-check", className: "flex items-start gap-2 text-sm", children: [_jsx(ShieldCheck, { "aria-hidden": true, className: "mt-0.5 size-(--dt-size-xs) shrink-0 text-muted-foreground" }), _jsxs("span", { className: "flex flex-col gap-0.5", children: [_jsxs("span", { className: "font-medium", children: [CHECK[rule.check.kind] ?? rule.check.kind, rule.check.ref && (_jsxs(_Fragment, { children: [" ", "by ", _jsx("code", { className: "font-mono text-xs", children: rule.check.ref })] }))] }), rule.check.description && _jsx("span", { className: "text-muted-foreground", children: inline(rule.check.description) })] })] })), _jsxs("div", { role: "group", "aria-label": `Read ${rule.title}`, className: "-ml-2 flex gap-1", children: [toggle("people", "For people", Eye), toggle("agents", "For agents", Bot)] })] }), view === "people" ? (_jsxs("div", { "data-slot": "rule-body", className: "flex min-w-0 flex-col gap-8", children: [_jsx("p", { "data-slot": "rule-statement", className: "max-w-3xl text-2xl leading-snug tracking-tight", children: inline(rule.statement) }), children && (_jsx("div", { "data-slot": "rule-demonstration", "data-docs-stage": "", className: "flex min-h-40 items-center justify-center rounded-2xl bg-muted/60 p-8 sm:p-10", children: _jsx(Live, { children: children }) })), facts.length > 0 && (_jsx("dl", { className: "grid max-w-3xl gap-x-10 gap-y-4 sm:grid-cols-2", 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))) })), rule.rationale && (_jsxs("div", { className: "flex max-w-3xl flex-col gap-2", children: [_jsx(Eyebrow, { children: "Why" }), _jsx("div", { className: "flex flex-col gap-2 text-base leading-relaxed text-muted-foreground", children: _jsx(Prose, { text: rule.rationale }) })] }))] })) : (_jsx("div", { className: "min-w-0", children: _jsx(CodeView, { code: ruleMarkdown(rule), lang: "markdown", label: `${rule.id}.md`, wrap: true }) }))] }));
|
|
33
|
+
}
|
|
34
|
+
/** Every rule on one screen, a line each, linking to the rule: what it is, how settled, how it is checked. */
|
|
35
|
+
export function RuleIndex({ rules }) {
|
|
36
|
+
return (_jsx("div", { "data-slot": "rule-index", className: "-mx-1 overflow-x-auto px-1", children: _jsxs("table", { className: "w-full min-w-[34rem] border-collapse text-left text-sm", children: [_jsx("thead", { children: _jsxs("tr", { className: "text-xs text-muted-foreground", children: [_jsx("th", { scope: "col", className: "pr-4 pb-3 font-medium", children: "Rule" }), _jsx("th", { scope: "col", className: "px-4 pb-3 font-medium", children: "Kind" }), _jsx("th", { scope: "col", className: "px-4 pb-3 font-medium", children: "Status" }), _jsx("th", { scope: "col", className: "pb-3 pl-4 font-medium", children: "Checked" })] }) }), _jsx("tbody", { children: rules.map((r) => (_jsxs("tr", { className: "border-t border-border", children: [_jsx("th", { scope: "row", className: "py-3 pr-4 font-normal", children: _jsx("a", { href: `#${r.id}`, className: "font-medium underline-offset-4 hover:underline focus-visible:outline-2 focus-visible:outline-ring", children: r.title }) }), _jsx("td", { className: "px-4 py-3 text-muted-foreground capitalize", children: r.kind }), _jsx("td", { className: "px-4 py-3", children: _jsx(StatusBadge, { status: r.status }) }), _jsx("td", { className: "py-3 pl-4 text-muted-foreground", children: r.check ? (CHECK[r.check.kind] ?? r.check.kind) : "Not yet" })] }, r.id))) })] }) }));
|
|
32
37
|
}
|
package/dist/shell.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type ReactNode } from "react";
|
|
2
|
+
import { type Status } from "./lib/status.js";
|
|
2
3
|
import type { ComponentsManifest, PatternsManifest, RulesManifest, TaxonomyManifest } from "./lib/manifest-types.js";
|
|
3
4
|
export interface DocsLink {
|
|
4
5
|
label: string;
|
|
@@ -52,11 +53,13 @@ export declare function DocsShell({ manifest, rules, patterns, terms, search, th
|
|
|
52
53
|
* lead, and the page's actions as children. Where the page comes from goes at the
|
|
53
54
|
* foot, in `DocsFooter`.
|
|
54
55
|
*/
|
|
55
|
-
export declare function DocsHeader({ title, lead, eyebrow, children, }: {
|
|
56
|
+
export declare function DocsHeader({ title, lead, eyebrow, status, children, }: {
|
|
56
57
|
title: string;
|
|
57
58
|
lead?: string;
|
|
58
59
|
/** Above the title. Defaults to the section the page sits in. */
|
|
59
60
|
eyebrow?: string;
|
|
61
|
+
/** How settled the thing the page documents is, beside the eyebrow: a pattern's status. */
|
|
62
|
+
status?: Status;
|
|
60
63
|
/** The page's actions, beside the title: `PageActions`. */
|
|
61
64
|
children?: ReactNode;
|
|
62
65
|
}): import("react").JSX.Element;
|
package/dist/shell.js
CHANGED
|
@@ -6,7 +6,9 @@ import { ArrowLeft, ArrowRight, BookOpen, ChevronRight, Component, Gauge, House,
|
|
|
6
6
|
import Link from "next/link";
|
|
7
7
|
import { usePathname } from "next/navigation";
|
|
8
8
|
import { createContext, useContext, useEffect, useMemo, useState } from "react";
|
|
9
|
+
import { Live } from "./lib/live.js";
|
|
9
10
|
import { accent, cx, display, target } from "./lib/cx.js";
|
|
11
|
+
import { StatusBadge } from "./lib/status.js";
|
|
10
12
|
import { groupFamilies, slugOf } from "./lib/manifest.js";
|
|
11
13
|
import { searchIndex } from "./lib/search.js";
|
|
12
14
|
import { Prose } from "./lib/text.js";
|
|
@@ -85,12 +87,12 @@ export function DocsShell({ manifest, rules, patterns, terms, search = true, the
|
|
|
85
87
|
useThemeScript();
|
|
86
88
|
const [menu, setMenu] = useState(false);
|
|
87
89
|
useEffect(() => setMenu(false), [current]);
|
|
88
|
-
const brandLink = (_jsxs(Link, { href: basePath, "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: logo })), _jsx("span", { className: cx(logo ? "sr-only" : "truncate text-base font-semibold tracking-tight"), children: title })] }));
|
|
89
|
-
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 }), 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 === basePath && (_jsx("div", { "data-slot": "docs-hero", className: "w-full", 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 })] })] })] }) }));
|
|
90
|
+
const brandLink = (_jsxs(Link, { href: basePath, "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 })] }));
|
|
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 === basePath && (_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 })] })] })] }) }));
|
|
90
92
|
}
|
|
91
93
|
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";
|
|
92
94
|
/** The sections, each a link or a fold that opens where the current page is. */
|
|
93
|
-
function Nav({ sections, current, title }) {
|
|
95
|
+
function Nav({ sections, current, title, className }) {
|
|
94
96
|
const holds = (s) => s.groups.some((g) => g.links.some((l) => l.href === current || l.children?.some((c) => c.href === current)));
|
|
95
97
|
const [open, setOpen] = useState(() => Object.fromEntries(sections.map((s) => [s.id, holds(s)])));
|
|
96
98
|
// moving to a page opens its section; nothing closes on its own
|
|
@@ -100,7 +102,7 @@ function Nav({ sections, current, title }) {
|
|
|
100
102
|
setOpen((o) => (o[here.id] ? o : { ...o, [here.id]: true }));
|
|
101
103
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
102
104
|
}, [current, sections]);
|
|
103
|
-
return (_jsx("nav", { "aria-label": title, "data-slot": "docs-nav", className: "min-h-0 flex-1 overflow-y-auto px-3 pb-4 text-sm", children: _jsx("ul", { className: "flex flex-col gap-0.5", children: sections.map((s) => {
|
|
105
|
+
return (_jsx("nav", { "aria-label": title, "data-slot": "docs-nav", className: cx("min-h-0 flex-1 overflow-y-auto px-3 pb-4 text-sm", className), children: _jsx("ul", { className: "flex flex-col gap-0.5", children: sections.map((s) => {
|
|
104
106
|
const Icon = s.icon;
|
|
105
107
|
const row = cx(target, "group flex w-full items-center gap-3 rounded-md px-2.5 font-medium text-canvas-foreground hover:bg-muted focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring");
|
|
106
108
|
const icon = _jsx(Icon, { "aria-hidden": true, className: "size-(--dt-size-xs) shrink-0 text-muted-foreground group-hover:text-canvas-foreground" });
|
|
@@ -108,7 +110,7 @@ function Nav({ sections, current, title }) {
|
|
|
108
110
|
const active = current === s.href;
|
|
109
111
|
return (_jsx("li", { children: _jsxs(Link, { href: s.href, "aria-current": active ? "page" : undefined, "data-slot": "docs-nav-section", className: cx(row, active && "bg-muted"), children: [icon, s.label] }) }, s.id));
|
|
110
112
|
}
|
|
111
|
-
return (_jsx("li", { children: _jsxs(Collapsible.Root, { open: open[s.id] ?? false, onOpenChange: (next) => setOpen((o) => ({ ...o, [s.id]: next })), children: [_jsxs(Collapsible.Trigger, { "data-slot": "docs-nav-section", className: row, children: [icon, _jsx("span", { className: "flex-1 text-left", children: s.label }), _jsx(ChevronRight, { "aria-hidden": true, className: "size-(--dt-size-xs) text-muted-foreground transition-transform duration-(--dt-duration-fast) group-data-panel-open:rotate-90" })] }), _jsx(Collapsible.Panel, { "data-slot": "docs-nav-panel", className: "h-(--collapsible-panel-height) overflow-hidden transition-[height] duration-(--dt-duration-base) ease-(--dt-ease-out) data-ending-style:h-0 data-starting-style:h-0", children: _jsx("div", { className: "ml-[1.1875rem] flex flex-col gap-3 border-l border-border py-1 pl-3", children: s.groups.map((g, i) => (_jsxs("div", { className: "flex flex-col", children: [g.heading && (_jsx("p", { "data-slot": "docs-nav-heading", className: "px-2.5 pt-
|
|
113
|
+
return (_jsx("li", { children: _jsxs(Collapsible.Root, { open: open[s.id] ?? false, onOpenChange: (next) => setOpen((o) => ({ ...o, [s.id]: next })), children: [_jsxs(Collapsible.Trigger, { "data-slot": "docs-nav-section", className: row, children: [icon, _jsx("span", { className: "flex-1 text-left", children: s.label }), _jsx(ChevronRight, { "aria-hidden": true, className: "size-(--dt-size-xs) text-muted-foreground transition-transform duration-(--dt-duration-fast) group-data-panel-open:rotate-90" })] }), _jsx(Collapsible.Panel, { "data-slot": "docs-nav-panel", className: "h-(--collapsible-panel-height) overflow-hidden transition-[height] duration-(--dt-duration-base) ease-(--dt-ease-out) data-ending-style:h-0 data-starting-style:h-0", children: _jsx("div", { className: "ml-[1.1875rem] flex flex-col gap-3 border-l border-border py-1 pl-3", children: s.groups.map((g, i) => (_jsxs("div", { className: "flex flex-col", children: [g.heading && (_jsx("p", { "data-slot": "docs-nav-heading", className: "px-2.5 pt-3 pb-1.5 text-[0.6875rem] font-semibold tracking-[0.08em] text-muted-foreground uppercase first:pt-1", children: g.heading })), _jsx("ul", { className: "flex flex-col", children: g.links.map((link) => {
|
|
112
114
|
const here = current === link.href || link.children?.some((c) => c.href === current);
|
|
113
115
|
return (_jsxs("li", { children: [_jsx(NavLink, { link: link, current: current }), here && link.children?.length ? (_jsx("ul", { "data-slot": "docs-nav-parts", "aria-label": `${link.label} parts`, className: "ml-3 flex flex-col border-l border-border pl-2", children: link.children.map((child) => (_jsx("li", { children: _jsx(NavLink, { link: child, current: current }) }, child.href))) })) : null] }, link.href));
|
|
114
116
|
}) })] }, g.heading ?? i))) }) })] }) }, s.id));
|
|
@@ -116,7 +118,7 @@ function Nav({ sections, current, title }) {
|
|
|
116
118
|
}
|
|
117
119
|
function NavLink({ link, current }) {
|
|
118
120
|
const active = current === link.href;
|
|
119
|
-
return (_jsxs(Link, { href: link.href, "aria-current": active ? "page" : undefined, "data-slot": "docs-nav-link", className: cx(target, "relative flex items-center rounded-md px-2.5 text-
|
|
121
|
+
return (_jsxs(Link, { href: link.href, "aria-current": active ? "page" : undefined, "data-slot": "docs-nav-link", className: cx(target, "relative flex items-center rounded-md px-2.5 text-canvas-foreground/80 hover:bg-muted hover:text-canvas-foreground focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-ring", active && "bg-muted font-medium text-canvas-foreground"), children: [active && _jsx("span", { "aria-hidden": true, "data-slot": "docs-nav-marker", className: cx(accent, "absolute inset-y-2.5 -left-[0.8125rem] w-0.5 rounded-full") }), link.label] }));
|
|
120
122
|
}
|
|
121
123
|
/** The page's sections, beside it on a wide screen, marking the one being read. */
|
|
122
124
|
function OnThisPage({ current }) {
|
|
@@ -164,17 +166,17 @@ function Pager({ prev, next }) {
|
|
|
164
166
|
if (!prev && !next)
|
|
165
167
|
return null;
|
|
166
168
|
const card = cx(target, "group flex flex-col gap-1 rounded-lg border border-border p-5 transition-colors duration-(--dt-duration-fast) hover:bg-muted focus-visible:outline-2 focus-visible:outline-ring");
|
|
167
|
-
return (_jsxs("nav", { "aria-label": "Previous and next", "data-slot": "docs-pager", className: "grid gap-3
|
|
169
|
+
return (_jsxs("nav", { "aria-label": "Previous and next", "data-slot": "docs-pager", className: "-mt-4 grid gap-3 sm:grid-cols-2 lg:-mt-8", children: [prev ? (_jsxs(Link, { href: prev.href, className: card, children: [_jsxs("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: [_jsx(ArrowLeft, { "aria-hidden": true, className: "size-(--dt-size-xs) transition-transform group-hover:-translate-x-0.5" }), " Previous"] }), _jsx("span", { className: "text-base font-medium", children: prev.label })] })) : (_jsx("span", {})), next && (_jsxs(Link, { href: next.href, className: cx(card, "sm:items-end sm:text-right"), children: [_jsxs("span", { className: "flex items-center gap-1.5 text-xs text-muted-foreground", children: ["Next ", _jsx(ArrowRight, { "aria-hidden": true, className: "size-(--dt-size-xs) transition-transform group-hover:translate-x-0.5" })] }), _jsx("span", { className: "text-base font-medium", children: next.label })] }))] }));
|
|
168
170
|
}
|
|
169
171
|
/**
|
|
170
172
|
* A page's heading: the section it sits in (from the navigation), the title, the
|
|
171
173
|
* lead, and the page's actions as children. Where the page comes from goes at the
|
|
172
174
|
* foot, in `DocsFooter`.
|
|
173
175
|
*/
|
|
174
|
-
export function DocsHeader({ title, lead, eyebrow, children, }) {
|
|
176
|
+
export function DocsHeader({ title, lead, eyebrow, status, children, }) {
|
|
175
177
|
const { section } = useContext(DocsPage);
|
|
176
178
|
const over = eyebrow ?? (section && section !== title ? section : undefined);
|
|
177
|
-
return (_jsxs("header", { "data-slot": "docs-header", className: "flex flex-col gap-6
|
|
179
|
+
return (_jsxs("header", { "data-slot": "docs-header", className: "flex flex-col gap-6", children: [_jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4", children: [over || status ? (_jsxs("span", { className: "flex flex-wrap items-center gap-3", children: [over && (_jsx("p", { "data-slot": "docs-eyebrow", className: "text-xs font-medium tracking-[var(--tracking-widest,0.16em)] text-muted-foreground uppercase", children: over })), status && _jsx(StatusBadge, { status: status })] })) : (_jsx("span", {})), children && (_jsx("div", { "data-slot": "docs-header-actions", className: "flex flex-wrap items-center gap-2", children: children }))] }), _jsx("h1", { className: cx(display, "text-5xl leading-[1.05] tracking-tight md:text-7xl"), children: title }), lead && (_jsx("div", { "data-slot": "docs-lead", className: "flex max-w-3xl flex-col gap-3 text-xl leading-snug font-light text-muted-foreground md:text-2xl md:leading-snug [&_code]:bg-transparent [&_code]:p-0", children: _jsx(Prose, { text: lead }) }))] }));
|
|
178
180
|
}
|
|
179
181
|
/**
|
|
180
182
|
* Where a page comes from, at its foot: a generated page names the version and
|
|
@@ -185,7 +187,7 @@ export function DocsHeader({ title, lead, eyebrow, children, }) {
|
|
|
185
187
|
export function DocsFooter({ provenance, editorial, source, }) {
|
|
186
188
|
if (!provenance && !editorial && !source)
|
|
187
189
|
return null;
|
|
188
|
-
return (_jsxs("footer", { "data-slot": "docs-footer", className: "flex flex-wrap items-center gap-x-6 gap-y-2 text-xs text-muted-foreground", children: [(provenance || editorial) && (_jsxs("p", { "data-slot": "docs-provenance", className: "flex items-center gap-2", children: [_jsx("span", { "aria-hidden": true, className: cx("size-1.5 shrink-0 rounded-full", editorial ? (editorial.status === "published" ? "bg-success" : "bg-warning") : "bg-primary") }), editorial
|
|
190
|
+
return (_jsxs("footer", { "data-slot": "docs-footer", className: "order-last -mt-8 flex flex-wrap items-center gap-x-6 gap-y-2 border-t border-border pt-6 text-xs text-muted-foreground lg:-mt-14", children: [(provenance || editorial) && (_jsxs("p", { "data-slot": "docs-provenance", className: "flex items-center gap-2", children: [_jsx("span", { "aria-hidden": true, className: cx("size-1.5 shrink-0 rounded-full", editorial ? (editorial.status === "published" ? "bg-success" : "bg-warning") : "bg-primary") }), editorial
|
|
189
191
|
? `Written by ${editorial.author} · ${editorial.reviewer ? `reviewed by ${editorial.reviewer}, ` : "last reviewed "}${editorial.reviewed} · ${editorial.status}`
|
|
190
192
|
: `${provenance} · generated from the code`] })), source && (_jsx("p", { "data-slot": "docs-source", className: "font-mono", children: source }))] }));
|
|
191
193
|
}
|
|
@@ -195,5 +197,5 @@ export function DocsFooter({ provenance, editorial, source, }) {
|
|
|
195
197
|
*/
|
|
196
198
|
export function DocsSection({ title, lead, children }) {
|
|
197
199
|
const id = title.toLowerCase().replace(/[^a-z0-9]+/g, "-");
|
|
198
|
-
return (_jsxs("section", { "data-slot": "docs-section", "aria-labelledby": id, className: "grid gap-x-10 gap-y-8 [counter-increment:docs-section] xl:grid-cols-[5rem_minmax(0,1fr)]", children: [_jsx("span", { "aria-hidden": true, className: "
|
|
200
|
+
return (_jsxs("section", { "data-slot": "docs-section", "aria-labelledby": id, className: "grid gap-x-10 gap-y-8 [counter-increment:docs-section] xl:grid-cols-[5rem_minmax(0,1fr)]", children: [_jsx("span", { "aria-hidden": true, className: "font-mono text-xs tracking-[var(--tracking-widest,0.16em)] text-muted-foreground [text-box:trim-both_cap_alphabetic] before:content-[counter(docs-section,decimal-leading-zero)]" }), _jsxs("div", { className: "flex min-w-0 flex-col gap-10", children: [_jsxs("div", { className: "flex flex-col gap-4", children: [_jsx("h2", { id: id, "data-slot": "docs-section-title", className: cx(display, "scroll-mt-24 text-4xl leading-[1.1] tracking-tight [text-box:trim-both_cap_alphabetic] md:text-5xl"), children: title }), lead && _jsx("p", { className: "max-w-2xl text-lg leading-relaxed text-muted-foreground", children: lead })] }), children] })] }));
|
|
199
201
|
}
|