@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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @designtools/docs
|
|
2
2
|
|
|
3
|
+
## 0.2.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- a6d3829: The colour page gives its samples room: no panels round them, one hairline in each sample's own colour, the mode named once over each column, surfaces and utility colours as one row each with their full names and ratios, and the on-the-page table's verdicts as one quiet line (an icon, the ratio, the word) instead of wrapping pills.
|
|
8
|
+
|
|
9
|
+
## 0.2.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- a8e0eee: Editorial pages can be components: `body` takes React, with `markdown` for agents, and `DocsSection`, `Prose` and `Live` are exported for composing them. `Live` marks the project's own components inside the docs, and the docs' CSS never matches inside it: the docs' utilities no longer beat a project's responsive utilities on its components (a hero's `hidden lg:flex`), and a project's utilities no longer beat the docs' on their own elements, whichever stylesheet loads last. A legacy `:before` in the scoped CSS no longer invalidates its rule.
|
|
14
|
+
|
|
15
|
+
The overview explains the system instead of listing every component: each part, why it exists, its count and a glimpse of it, then "Why this is agentic" for client and design leads (`overview` in the config tunes or drops it).
|
|
16
|
+
|
|
17
|
+
Layout: the colour page drops its nested cards for open rows with a panel per mode; rules have an index and a two-column layout with the check beside the statement; pattern pages show the compositions first, status in the header and "Made of" below; variants sit on one stage without grid lines; vocabulary and voice share a calm term row (say, not, why) with a quiet search and a correction callout; navigation links read as links and group headings recede; section numbers align to their titles; the page header loses its rule; previous and next come before where the page came from, which is last; the phone drawer has room above its first item; the props tooltip is ink and opens at once.
|
|
18
|
+
|
|
3
19
|
## 0.1.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -76,13 +76,35 @@ pnpm add -D @designtools/manifest
|
|
|
76
76
|
| `registry` | The generated registry from `designtools-docs map` |
|
|
77
77
|
| `manifest` | The manifest files, as imported JSON |
|
|
78
78
|
| `hero` | A full-bleed introduction across the top of the overview; without it the overview has a plain header and `lead` |
|
|
79
|
-
| `editorial` | Pages people write,
|
|
79
|
+
| `editorial` | Pages people write, each with its author and status, in the brand, foundations or standards group: markdown, or components (below) |
|
|
80
80
|
| `workbench` | Per component: starting `props`, text `children`, richer `content` (a Card's parts), and a `wrap` element for the provider or root it needs |
|
|
81
81
|
| `demonstrations` | Per rule id: an element shown on the rule, for one that needs persuading |
|
|
82
82
|
| `baselines`, `adherence`, `provenance` | The standards page's targets, the adherence report, and the line naming the version and commit |
|
|
83
|
+
| `overview` | `{ agentic: false }` drops the overview's "Why this is agentic"; `agenticLead` rewrites its opening line |
|
|
83
84
|
| `hide` | Built-in pages to leave out |
|
|
84
85
|
| `blocks` | Blocks replaced by the project's own (see Eject) |
|
|
85
86
|
|
|
87
|
+
## Editorial pages with components
|
|
88
|
+
|
|
89
|
+
A page that has to show rather than tell (the brand on two surfaces, the status colours in their real jobs) takes React as its `body`, with `markdown` for agents:
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
import { DocsSection, Live, Prose } from "@designtools/docs/next";
|
|
93
|
+
|
|
94
|
+
editorial: [{
|
|
95
|
+
slug: "foundations/two-surfaces", section: "foundations", title: "One system, two surfaces", by,
|
|
96
|
+
body: (
|
|
97
|
+
<DocsSection title="Side by side">
|
|
98
|
+
<Prose text="The same tokens and components, set for two jobs." />
|
|
99
|
+
<Live><MarketingSlice /><AppSlice /></Live>
|
|
100
|
+
</DocsSection>
|
|
101
|
+
),
|
|
102
|
+
markdown: "## Side by side\n\nThe same tokens and components, set for two jobs.",
|
|
103
|
+
}]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`DocsSection` and `Prose` give the page the docs' own sections and type. Wrap the project's components in `Live`: the docs' styles never reach inside it, so the components look exactly as they do in the product. `markdown` is what the page's `.md` carries.
|
|
107
|
+
|
|
86
108
|
## Theming
|
|
87
109
|
|
|
88
110
|
The docs read the project's own variables, so a project on [`@designtools/tokens`](../tokens) is themed with nothing to set. Any other project sets these on the docs (or anywhere above them):
|
|
@@ -101,7 +123,7 @@ The docs read the project's own variables, so a project on [`@designtools/tokens
|
|
|
101
123
|
|
|
102
124
|
Text sizes, leading, tracking, weights, shadows, control sizes and motion follow the project's `--text-*`, `--leading-*`, `--tracking-*`, `--font-weight-*`, `--shadow-*`, `--size-*`, `--duration-*` and `--ease-*` where it has them. Every value has a fallback, so the docs render on a project with none of it.
|
|
103
125
|
|
|
104
|
-
The CSS is scoped to `[data-designtools]
|
|
126
|
+
The CSS is scoped to `[data-designtools]`, so it styles the docs and nothing else. It never matches inside `Live` (`[data-docs-content]`), which marks everywhere the project's components render: examples, the workbench, variants, anatomy, rule demonstrations, the hero and the logo. There only the project's CSS applies, responsive utilities included. On the docs' own elements its rules carry one attribute more than a project utility of the same name, so neither side's utilities leak into the other, whichever stylesheet loads last.
|
|
105
127
|
|
|
106
128
|
## Eject
|
|
107
129
|
|
package/dist/anatomy.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Live } from "./lib/live.js";
|
|
3
4
|
import { Layers } from "lucide-react";
|
|
4
5
|
import { useEffect, useId, useRef, useState } from "react";
|
|
5
6
|
import { cx, target } from "./lib/cx.js";
|
|
@@ -32,7 +33,7 @@ export function Anatomy({ entry, children, }) {
|
|
|
32
33
|
const Component = lookup.componentFor(entry);
|
|
33
34
|
const module = lookup.examplesFor(entry);
|
|
34
35
|
const first = entry.examples?.canonical?.name ?? entry.examples?.do[0]?.name ?? entry.examples?.other[0]?.name;
|
|
35
|
-
const example = children ?? (module && first ? renderExample(module[first], first) : Component ? _jsx(Component, { children: entry.name }) : null);
|
|
36
|
+
const example = children ?? (module && first ? renderExample(module[first], first) : Component ? (_jsx(Live, { children: _jsx(Component, { children: entry.name }) })) : null);
|
|
36
37
|
const shown = entry.slots.filter((slot) => counts[slot]).length;
|
|
37
38
|
return (_jsxs(Frame, { "data-slot": "anatomy", children: [active && (_jsx("style", { children: `[data-anatomy="${id}"] [data-slot="${active.replace(/"/g, '\\"')}"] { outline: 2px solid var(--ring); outline-offset: 3px; border-radius: var(--radius-sm); background-color: color-mix(in oklch, var(--ring) 10%, transparent); }` })), _jsxs("div", { className: "grid lg:grid-cols-[minmax(0,1fr)_17rem]", children: [_jsxs("div", { className: "flex min-w-0 flex-col", children: [_jsx(Toolbar, { children: _jsxs("span", { className: "flex items-center gap-2 pl-2 text-xs font-medium text-muted-foreground", children: [_jsx(Layers, { "aria-hidden": true, className: "size-(--dt-size-xs)" }), entry.slots.length, " ", entry.slots.length === 1 ? "part" : "parts", shown < entry.slots.length && ` · ${shown} in this example`] }) }), _jsx(Stage, { className: "min-h-64 flex-1", children: _jsx("div", { ref: box, "data-anatomy": id, "data-slot": "anatomy-example", className: "min-w-0", children: example }) })] }), _jsxs("div", { className: "flex flex-col gap-2 border-t border-border p-3 lg:border-t-0 lg:border-l", children: [_jsx("p", { className: "px-2 pt-1 text-xs text-muted-foreground", children: "Point at a part to find it." }), _jsx("ol", { "data-slot": "anatomy-parts", className: "flex flex-col gap-0.5 text-sm", onMouseLeave: () => setActive(null), children: entry.slots.map((slot, i) => (_jsx("li", { children: _jsxs("button", { type: "button", onMouseEnter: () => setActive(slot), onFocus: () => setActive(slot), onBlur: () => setActive(null), onClick: () => setActive(slot), className: cx(target, "group flex w-full items-center gap-3 rounded-lg px-2 text-left hover:bg-muted focus-visible:outline-2 focus-visible:outline-ring", active === slot && "bg-muted", !counts[slot] && "text-muted-foreground"), children: [_jsx("span", { "aria-hidden": true, className: cx("flex size-6 shrink-0 items-center justify-center rounded-full border border-border font-mono text-xs", active === slot && "border-transparent bg-primary text-primary-foreground"), children: i + 1 }), _jsx("code", { className: "min-w-0 flex-1 truncate font-mono text-xs", children: slot }), _jsx("span", { className: "text-xs text-muted-foreground", children: counts[slot] ? `×${counts[slot]}` : "not shown" })] }) }, slot))) }), entry.variants?.parts && (_jsxs("p", { className: "mt-auto px-2 pt-2 text-xs text-muted-foreground", children: ["Styled in ", _jsx("code", { className: "font-mono", children: entry.variants.config }), ": ", entry.variants.parts.join(", ")] }))] })] })] }));
|
|
38
39
|
}
|
package/dist/cli.js
CHANGED
|
@@ -19,7 +19,7 @@ var BLOCKS = [
|
|
|
19
19
|
{ name: "props-table", file: "props-table.tsx", exports: ["PropsTable"], description: "Props as an API reference" },
|
|
20
20
|
{ name: "preview-frame", file: "preview-frame.tsx", exports: ["PreviewFrame"], description: "An example at device widths, in a browser window" },
|
|
21
21
|
{ name: "pattern", file: "pattern.tsx", exports: ["Pattern"], description: "A screen composition, live, with what it is made of" },
|
|
22
|
-
{ name: "rule", file: "rule.tsx", exports: ["Rule"], description: "A rule for people and as an agent reads it, with its check" },
|
|
22
|
+
{ name: "rule", file: "rule.tsx", exports: ["Rule", "RuleIndex"], description: "A rule for people and as an agent reads it, with its check, and the index of every rule" },
|
|
23
23
|
{ name: "swatches", file: "swatches.tsx", exports: ["SemanticSwatches", "PageContrast", "RampSwatches"], description: "Colour: each pair measured, each colour on each background, the ramps" },
|
|
24
24
|
{ name: "type-ramp", file: "type-ramp.tsx", exports: ["TypeRamp"], description: "Type: families, the scale, weights, leading and tracking" },
|
|
25
25
|
{ name: "scale", file: "scale.tsx", exports: ["Scale"], description: "Space, size, radius, elevation and motion" },
|
package/dist/glossary.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { TermEntry } from "./lib/manifest-types.js";
|
|
2
|
-
/** Every name in the system, searchable by its wrong forms too, so a wrong name finds the right one. */
|
|
2
|
+
/** Every name in the system, searchable by its wrong forms too, so a wrong name finds the right one. A to Z. */
|
|
3
3
|
export declare function Glossary({ terms }: {
|
|
4
4
|
terms: TermEntry[];
|
|
5
5
|
}): import("react").JSX.Element;
|
package/dist/glossary.js
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
3
|
-
import { Search } from "lucide-react";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ArrowRight, Search } from "lucide-react";
|
|
4
4
|
import { useId, useState } from "react";
|
|
5
|
-
import {
|
|
6
|
-
/** Every name in the system, searchable by its wrong forms too, so a wrong name finds the right one. */
|
|
5
|
+
import { TermRow } from "./lib/terms.js";
|
|
6
|
+
/** Every name in the system, searchable by its wrong forms too, so a wrong name finds the right one. A to Z. */
|
|
7
7
|
export function Glossary({ terms }) {
|
|
8
8
|
const id = useId();
|
|
9
9
|
const [query, setQuery] = useState("");
|
|
10
10
|
const q = query.trim().toLowerCase();
|
|
11
|
-
const matches = q ? terms.filter((t) => t.name.toLowerCase().includes(q) || t.wrong?.some((w) => w.toLowerCase().includes(q))) : terms
|
|
11
|
+
const matches = (q ? terms.filter((t) => t.name.toLowerCase().includes(q) || t.wrong?.some((w) => w.toLowerCase().includes(q))) : terms)
|
|
12
|
+
.slice()
|
|
13
|
+
.sort((a, b) => a.name.localeCompare(b.name, undefined, { sensitivity: "base" }));
|
|
12
14
|
const corrected = q ? terms.find((t) => t.wrong?.some((w) => w.toLowerCase() === q)) : undefined;
|
|
13
|
-
|
|
15
|
+
const letters = new Map();
|
|
16
|
+
for (const t of matches) {
|
|
17
|
+
const l = /[a-z]/i.test(t.name[0]) ? t.name[0].toUpperCase() : "#";
|
|
18
|
+
letters.set(l, [...(letters.get(l) ?? []), t]);
|
|
19
|
+
}
|
|
20
|
+
return (_jsxs("div", { "data-slot": "glossary", className: "flex flex-col gap-10", children: [_jsxs("div", { className: "flex max-w-3xl flex-col gap-4", children: [_jsx("label", { htmlFor: id, className: "sr-only", children: "Find a term" }), _jsxs("div", { className: "relative", children: [_jsx(Search, { "aria-hidden": true, className: "pointer-events-none absolute top-1/2 left-0 size-(--dt-size-md) -translate-y-1/2 text-muted-foreground" }), _jsx("input", { id: id, type: "search", value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Find a term, or a name you half remember", className: "h-16 w-full border-0 border-b border-border bg-transparent pr-2 pl-10 text-2xl tracking-tight placeholder:text-muted-foreground/70 hover:border-input focus-visible:border-b-2 focus-visible:border-canvas-foreground focus-visible:outline-none" })] }), _jsx("div", { "aria-live": "polite", children: corrected ? (_jsxs("p", { "data-slot": "glossary-correction", className: "flex flex-wrap items-center gap-2 rounded-xl bg-muted/60 px-5 py-4 text-lg", children: ["Say ", _jsx("strong", { className: "font-semibold", children: corrected.name }), _jsx(ArrowRight, { "aria-hidden": true, className: "size-4 text-muted-foreground" }), _jsxs("span", { className: "text-muted-foreground", children: ["not \u201C", query.trim(), "\u201D"] })] })) : (_jsx("p", { className: "text-sm text-muted-foreground", children: q ? `${matches.length} ${matches.length === 1 ? "term" : "terms"}` : `${terms.length} terms, A to Z. Search by the right name or a wrong one.` })) })] }), _jsx("div", { "data-slot": "glossary-list", className: "flex flex-col gap-8", children: [...letters].map(([letter, list]) => (_jsxs("section", { "aria-label": letter, className: "grid gap-x-8 lg:grid-cols-[3rem_minmax(0,1fr)]", children: [_jsx("h3", { className: "pt-5 text-2xl tracking-tight text-muted-foreground lg:sticky lg:top-24 lg:self-start", children: letter }), _jsx("div", { children: _jsx("dl", { children: list.map((t) => (_jsx(TermRow, { term: t, kind: true }, `${t.kind}:${t.name}`))) }) })] }, letter))) })] }));
|
|
14
21
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@ export { Pattern } from "./pattern.js";
|
|
|
17
17
|
export { Playground } from "./playground.js";
|
|
18
18
|
export { PreviewComposition, PreviewExample, PreviewFrame, PreviewSurface } from "./preview-frame.js";
|
|
19
19
|
export { PropsTable } from "./props-table.js";
|
|
20
|
-
export { Rule } from "./rule.js";
|
|
20
|
+
export { Rule, RuleIndex } from "./rule.js";
|
|
21
21
|
export { Scale } from "./scale.js";
|
|
22
22
|
export { DocsSearch } from "./search.js";
|
|
23
23
|
export { type DocsLink, DocsFooter, DocsHeader, DocsSection, DocsShell } from "./shell.js";
|
|
@@ -29,6 +29,7 @@ export { Usage } from "./usage.js";
|
|
|
29
29
|
export { VariantMatrix } from "./variant-matrix.js";
|
|
30
30
|
export { VoiceTerms } from "./voice-terms.js";
|
|
31
31
|
export { Workbench } from "./workbench.js";
|
|
32
|
+
export { Live } from "./lib/live.js";
|
|
32
33
|
export { type Registry, RegistryProvider, useRegistry } from "./lib/registry.js";
|
|
33
34
|
export * from "./lib/manifest-types.js";
|
|
34
35
|
export type { AdherenceReport } from "./lib/adherence-types.js";
|
package/dist/index.js
CHANGED
|
@@ -17,7 +17,7 @@ export { Pattern } from "./pattern.js";
|
|
|
17
17
|
export { Playground } from "./playground.js";
|
|
18
18
|
export { PreviewComposition, PreviewExample, PreviewFrame, PreviewSurface } from "./preview-frame.js";
|
|
19
19
|
export { PropsTable } from "./props-table.js";
|
|
20
|
-
export { Rule } from "./rule.js";
|
|
20
|
+
export { Rule, RuleIndex } from "./rule.js";
|
|
21
21
|
export { Scale } from "./scale.js";
|
|
22
22
|
export { DocsSearch } from "./search.js";
|
|
23
23
|
export { DocsFooter, DocsHeader, DocsSection, DocsShell } from "./shell.js";
|
|
@@ -29,5 +29,6 @@ export { Usage } from "./usage.js";
|
|
|
29
29
|
export { VariantMatrix } from "./variant-matrix.js";
|
|
30
30
|
export { VoiceTerms } from "./voice-terms.js";
|
|
31
31
|
export { Workbench } from "./workbench.js";
|
|
32
|
+
export { Live } from "./lib/live.js";
|
|
32
33
|
export { RegistryProvider, useRegistry } from "./lib/registry.js";
|
|
33
34
|
export * from "./lib/manifest-types.js";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Marks the project's own components inside the docs: an example, a workbench, the hero, a rule's
|
|
4
|
+
* demonstration. The docs' styles never match inside it, so the project's own CSS, its responsive
|
|
5
|
+
* utilities included, is all that styles its components, whichever stylesheet loads last. It draws
|
|
6
|
+
* nothing itself (`display: contents`). Wrap the project's components in it on an editorial page.
|
|
7
|
+
*/
|
|
8
|
+
export declare function Live({ children }: {
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
}): import("react").JSX.Element;
|
package/dist/lib/live.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Marks the project's own components inside the docs: an example, a workbench, the hero, a rule's
|
|
4
|
+
* demonstration. The docs' styles never match inside it, so the project's own CSS, its responsive
|
|
5
|
+
* utilities included, is all that styles its components, whichever stylesheet loads last. It draws
|
|
6
|
+
* nothing itself (`display: contents`). Wrap the project's components in it on an editorial page.
|
|
7
|
+
*/
|
|
8
|
+
export function Live({ children }) {
|
|
9
|
+
return (_jsx("div", { "data-docs-content": "", style: { display: "contents" }, children: children }));
|
|
10
|
+
}
|
package/dist/lib/lookup.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Live } from "./live.js";
|
|
2
3
|
import { createElement, isValidElement } from "react";
|
|
3
4
|
import { componentKey } from "./manifest.js";
|
|
4
5
|
import { useRegistry } from "./registry.js";
|
|
@@ -34,8 +35,8 @@ export function Missing({ name, what = "component" }) {
|
|
|
34
35
|
/** An example export is a component that takes no props, or an element. */
|
|
35
36
|
export function renderExample(value, name) {
|
|
36
37
|
if (isValidElement(value))
|
|
37
|
-
return value;
|
|
38
|
+
return _jsx(Live, { children: value });
|
|
38
39
|
if (typeof value === "function")
|
|
39
|
-
return createElement(value);
|
|
40
|
+
return _jsx(Live, { children: createElement(value) });
|
|
40
41
|
return _jsxs("span", { className: "text-xs text-muted-foreground", children: [name, " is not a component or an element."] });
|
|
41
42
|
}
|
package/dist/lib/status.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
type
|
|
1
|
+
export type Status = "stable" | "emerging" | "deprecated" | "confirmed" | "assumption" | "measured" | "draft" | "published";
|
|
2
2
|
/** A status, everywhere one is shown: components, patterns, rules and editorial pages. Unset says so. */
|
|
3
3
|
export declare function StatusBadge({ status, className }: {
|
|
4
|
-
status?:
|
|
4
|
+
status?: Status;
|
|
5
5
|
className?: string;
|
|
6
6
|
}): import("react").JSX.Element;
|
|
7
|
-
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { TermEntry } from "./manifest-types.js";
|
|
2
|
+
/** The wrong forms of a term: quiet chips, each with a cross, so "not this" reads without shouting. */
|
|
3
|
+
export declare function WrongForms({ wrong }: {
|
|
4
|
+
wrong?: string[];
|
|
5
|
+
}): import("react").JSX.Element;
|
|
6
|
+
/**
|
|
7
|
+
* One term on one row: the word to use, the words not to, and why. Three columns on a wide screen, under
|
|
8
|
+
* the labels `TermHead` draws; stacked on a phone.
|
|
9
|
+
*/
|
|
10
|
+
export declare function TermRow({ term, kind }: {
|
|
11
|
+
term: TermEntry;
|
|
12
|
+
kind?: boolean;
|
|
13
|
+
}): import("react").JSX.Element;
|
|
14
|
+
/** The column labels over a list of `TermRow`s, on a wide screen. */
|
|
15
|
+
export declare function TermHead(): import("react").JSX.Element;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { X } from "lucide-react";
|
|
3
|
+
import { inline } from "./text.js";
|
|
4
|
+
/** The wrong forms of a term: quiet chips, each with a cross, so "not this" reads without shouting. */
|
|
5
|
+
export function WrongForms({ wrong }) {
|
|
6
|
+
if (!wrong?.length)
|
|
7
|
+
return _jsx("span", { className: "text-sm text-muted-foreground", children: "None" });
|
|
8
|
+
return (_jsxs("span", { className: "flex flex-wrap gap-1.5", children: [_jsx("span", { className: "sr-only", children: "Not " }), wrong.map((w) => (_jsxs("span", { "data-slot": "term-wrong", className: "inline-flex min-h-7 items-center gap-1 rounded-md bg-muted px-2 text-sm text-muted-foreground", children: [_jsx(X, { "aria-hidden": true, className: "size-3 shrink-0" }), _jsx("span", { className: "line-through decoration-current/40", children: w })] }, w)))] }));
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* One term on one row: the word to use, the words not to, and why. Three columns on a wide screen, under
|
|
12
|
+
* the labels `TermHead` draws; stacked on a phone.
|
|
13
|
+
*/
|
|
14
|
+
export function TermRow({ term, kind }) {
|
|
15
|
+
return (_jsxs("div", { "data-slot": "term", className: "grid gap-x-8 gap-y-2 border-t border-border py-5 md:grid-cols-[minmax(10rem,14rem)_minmax(0,1fr)_minmax(0,1.3fr)] md:items-baseline", children: [_jsxs("dt", { className: "flex items-baseline gap-2", children: [_jsx("span", { className: "text-xl leading-snug tracking-tight", children: term.name }), kind && _jsx("span", { className: "font-mono text-xs text-muted-foreground", children: term.kind }), _jsx("span", { className: "sr-only", children: ", say this" })] }), _jsx("dd", { children: _jsx(WrongForms, { wrong: term.wrong }) }), _jsxs("dd", { className: "text-sm leading-relaxed text-muted-foreground", children: [term.note ? inline(term.note) : term.kind !== "product" ? `The ${term.kind}'s name in the code.` : null, term.ref && _jsx("code", { className: "ml-1 font-mono text-xs", children: term.ref })] })] }));
|
|
16
|
+
}
|
|
17
|
+
/** The column labels over a list of `TermRow`s, on a wide screen. */
|
|
18
|
+
export function TermHead() {
|
|
19
|
+
return (_jsxs("div", { "aria-hidden": true, className: "hidden gap-x-8 pb-3 text-xs font-medium text-muted-foreground md:grid md:grid-cols-[minmax(10rem,14rem)_minmax(0,1fr)_minmax(0,1.3fr)]", children: [_jsx("span", { children: "Say" }), _jsx("span", { children: "Not" }), _jsx("span", { children: "Why" })] }));
|
|
20
|
+
}
|
package/dist/next/config.d.ts
CHANGED
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
import type { ComponentType, ReactElement, ReactNode } from "react";
|
|
2
2
|
import type { AdherenceReport } from "../lib/adherence-types.js";
|
|
3
|
-
/** A page people write: brand, principles, a design language
|
|
4
|
-
export
|
|
3
|
+
/** A page people write: brand, principles, a design language, with its author and how settled it is. */
|
|
4
|
+
export type EditorialPage = EditorialBase & ({
|
|
5
|
+
/** Markdown: `##` and `###` sections, paragraphs, bullet lists, bold, code and links; a list whose items open in bold is a set of principles. */
|
|
6
|
+
body: string;
|
|
7
|
+
markdown?: undefined;
|
|
8
|
+
} | {
|
|
9
|
+
/**
|
|
10
|
+
* The page as React: real components from the project's system beside the docs' own `DocsSection`
|
|
11
|
+
* and `Prose`, for a page that has to show rather than tell. Rendered as is, under the page header.
|
|
12
|
+
*/
|
|
13
|
+
body: ReactNode;
|
|
14
|
+
/** What agents read instead, at the page's `.md`: the same page, in words. */
|
|
15
|
+
markdown: string;
|
|
16
|
+
});
|
|
17
|
+
interface EditorialBase {
|
|
5
18
|
/** Its path under the docs, e.g. `brand` or `brand/accessibility`. */
|
|
6
19
|
slug: string;
|
|
7
20
|
title: string;
|
|
8
21
|
lead?: string;
|
|
9
|
-
/** Markdown: `##` sections, paragraphs, bullet lists; a list whose items open in bold is a set of principles. */
|
|
10
|
-
body: string;
|
|
11
22
|
by: {
|
|
12
23
|
author: string;
|
|
13
24
|
reviewer?: string;
|
|
@@ -50,6 +61,14 @@ export interface DocsConfig {
|
|
|
50
61
|
hero?: ReactNode;
|
|
51
62
|
/** The overview's lead, when there is no hero. */
|
|
52
63
|
lead?: string;
|
|
64
|
+
/**
|
|
65
|
+
* The overview after its hero or header: `agentic: false` drops "Why this is agentic", and `agenticLead`
|
|
66
|
+
* replaces the line that opens it.
|
|
67
|
+
*/
|
|
68
|
+
overview?: {
|
|
69
|
+
agentic?: boolean;
|
|
70
|
+
agenticLead?: string;
|
|
71
|
+
};
|
|
53
72
|
/** The generated registry (`designtools-docs map`): a provider for the project's components, examples and assets. */
|
|
54
73
|
registry: ComponentType<{
|
|
55
74
|
children: ReactNode;
|
|
@@ -83,3 +102,4 @@ export interface DocsConfig {
|
|
|
83
102
|
*/
|
|
84
103
|
blocks?: Partial<Record<string, ComponentType<any>>>;
|
|
85
104
|
}
|
|
105
|
+
export {};
|
package/dist/next/index.d.ts
CHANGED
|
@@ -2,7 +2,10 @@ import "../styles.css";
|
|
|
2
2
|
import type { Metadata } from "next";
|
|
3
3
|
import type { ReactNode } from "react";
|
|
4
4
|
import type { DocsConfig } from "./config.js";
|
|
5
|
+
export { Live } from "../lib/live.js";
|
|
6
|
+
export { DocsSection } from "../shell.js";
|
|
5
7
|
export type { BuiltInPage, DocsConfig, EditorialPage, WorkbenchSetup } from "./config.js";
|
|
8
|
+
export { Markdown as Prose } from "./prose.js";
|
|
6
9
|
export { markdownFor } from "./markdown.js";
|
|
7
10
|
export { docsMatcher, docsProxy, prefersMarkdown } from "./proxy.js";
|
|
8
11
|
type SlugParams = {
|
package/dist/next/index.js
CHANGED
|
@@ -7,6 +7,9 @@ import { DocsShell } from "../shell.js";
|
|
|
7
7
|
import { manifestFiles, manifestRoute, markdownRoute } from "./markdown.js";
|
|
8
8
|
import { DocsPageView } from "./pages.js";
|
|
9
9
|
import { allSlugs, metaOf, navOf, resolve, siteOf } from "./site.js";
|
|
10
|
+
export { Live } from "../lib/live.js";
|
|
11
|
+
export { DocsSection } from "../shell.js";
|
|
12
|
+
export { Markdown as Prose } from "./prose.js";
|
|
10
13
|
export { markdownFor } from "./markdown.js";
|
|
11
14
|
export { docsMatcher, docsProxy, prefersMarkdown } from "./proxy.js";
|
|
12
15
|
/**
|
package/dist/next/markdown.js
CHANGED
|
@@ -37,7 +37,7 @@ export function markdownFor(site, path) {
|
|
|
37
37
|
].join("\n"));
|
|
38
38
|
}
|
|
39
39
|
case "editorial":
|
|
40
|
-
return `${editorialHeader(page.page.by)}# ${page.page.title}\n\n${page.page.lead ? `${page.page.lead}\n\n` : ""}${page.page.body}\n`;
|
|
40
|
+
return `${editorialHeader(page.page.by)}# ${page.page.title}\n\n${page.page.lead ? `${page.page.lead}\n\n` : ""}${typeof page.page.body === "string" ? page.page.body : page.page.markdown}\n`;
|
|
41
41
|
case "logo":
|
|
42
42
|
return generated(assetsMarkdown(assets.assets.filter((a) => a.kind === "logo")) +
|
|
43
43
|
"\n" +
|
package/dist/next/pages.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { ArrowRight, ArrowUpRight } from "lucide-react";
|
|
3
3
|
import Link from "next/link";
|
|
4
|
+
import { cx, display } from "../lib/cx.js";
|
|
4
5
|
import { AdherenceSummary } from "../adherence-summary.js";
|
|
5
6
|
import { Anatomy } from "../anatomy.js";
|
|
6
7
|
import { Examples } from "../examples.js";
|
|
@@ -13,7 +14,7 @@ import { PageActions } from "../page-actions.js";
|
|
|
13
14
|
import { Pattern } from "../pattern.js";
|
|
14
15
|
import { PreviewFrame } from "../preview-frame.js";
|
|
15
16
|
import { PropsTable } from "../props-table.js";
|
|
16
|
-
import { Rule } from "../rule.js";
|
|
17
|
+
import { Rule, RuleIndex } from "../rule.js";
|
|
17
18
|
import { Scale } from "../scale.js";
|
|
18
19
|
import { DocsFooter, DocsHeader, DocsSection } from "../shell.js";
|
|
19
20
|
import { Standards } from "../standards.js";
|
|
@@ -39,6 +40,7 @@ const DEFAULT_BLOCKS = {
|
|
|
39
40
|
PropsTable,
|
|
40
41
|
RampSwatches,
|
|
41
42
|
Rule,
|
|
43
|
+
RuleIndex,
|
|
42
44
|
Scale,
|
|
43
45
|
SemanticSwatches,
|
|
44
46
|
Standards,
|
|
@@ -61,7 +63,7 @@ export function DocsPageView({ site, page }) {
|
|
|
61
63
|
case "overview":
|
|
62
64
|
return _jsx(Overview, { site: site });
|
|
63
65
|
case "editorial":
|
|
64
|
-
return (_jsxs(_Fragment, { children: [header(page.page.title, page.page.lead), _jsx(Markdown, { text: page.page.body }), _jsx(DocsFooter, { editorial: page.page.by })] }));
|
|
66
|
+
return (_jsxs(_Fragment, { children: [header(page.page.title, page.page.lead), typeof page.page.body === "string" ? _jsx(Markdown, { text: page.page.body }) : page.page.body, _jsx(DocsFooter, { editorial: page.page.by })] }));
|
|
65
67
|
case "logo":
|
|
66
68
|
return (_jsxs(_Fragment, { children: [header(COPY.logo.title, COPY.logo.lead), _jsx(B.LogoUsage, { assets: site.assets.assets, rules: site.rules.rules, rulesHref: `${base}/rules` }), footer] }));
|
|
67
69
|
case "imagery":
|
|
@@ -75,7 +77,7 @@ export function DocsPageView({ site, page }) {
|
|
|
75
77
|
case "scale":
|
|
76
78
|
return (_jsxs(_Fragment, { children: [header(COPY.scale.title, COPY.scale.lead), _jsx(B.Scale, { tokens: site.tokens }), footer] }));
|
|
77
79
|
case "rules":
|
|
78
|
-
return (_jsxs(_Fragment, { children: [header(COPY.rules.title, COPY.rules.lead), ["brand", "interface"].map((kind) => {
|
|
80
|
+
return (_jsxs(_Fragment, { children: [header(COPY.rules.title, COPY.rules.lead), _jsx(DocsSection, { title: "Every rule", lead: "A line each: what it covers, how settled it is, and how it is checked.", children: _jsx(B.RuleIndex, { rules: [...site.rules.rules].sort((a, b) => a.kind.localeCompare(b.kind)) }) }), ["brand", "interface"].map((kind) => {
|
|
79
81
|
const rules = site.rules.rules.filter((r) => r.kind === kind);
|
|
80
82
|
return rules.length ? (_jsx(DocsSection, { title: kind === "brand" ? "Brand" : "Interface", children: rules.map((r) => (_jsx(B.Rule, { rule: r, children: config.demonstrations?.[r.id] }, r.id))) }, kind)) : null;
|
|
81
83
|
}), footer] }));
|
|
@@ -84,7 +86,7 @@ export function DocsPageView({ site, page }) {
|
|
|
84
86
|
case "vocabulary":
|
|
85
87
|
return (_jsxs(_Fragment, { children: [header(COPY.vocabulary.title, COPY.vocabulary.lead), _jsx(B.Glossary, { terms: site.taxonomy.terms }), footer] }));
|
|
86
88
|
case "pattern":
|
|
87
|
-
return (_jsxs(_Fragment, { children: [
|
|
89
|
+
return (_jsxs(_Fragment, { children: [_jsx(DocsHeader, { title: page.pattern.name, lead: page.pattern.description, status: page.pattern.status, children: _jsx(PageActions, { basePath: base }) }), _jsx(B.Pattern, { pattern: page.pattern, manifest: site.components, basePath: base }), _jsx(DocsFooter, { source: page.pattern.source, provenance: config.provenance })] }));
|
|
88
90
|
case "component":
|
|
89
91
|
return _jsx(ComponentPage, { site: site, blocks: B, entry: page.entry });
|
|
90
92
|
}
|
|
@@ -103,20 +105,84 @@ function ComponentPage({ site, blocks: B, entry }) {
|
|
|
103
105
|
const backgrounds = site.tokens.tokens.map((t) => t.name.slice(2)).filter((n) => /^surface-[a-z]/.test(n) && !n.endsWith("-foreground"));
|
|
104
106
|
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
107
|
}
|
|
106
|
-
|
|
107
|
-
/** The overview: where to start, then every component by category. Below the hero when there is one. */
|
|
108
|
+
/** The overview, below the hero when there is one: each part of the system and why it exists, then why it is agentic. */
|
|
108
109
|
function Overview({ site }) {
|
|
109
110
|
const { base, config } = site;
|
|
110
111
|
const families = groupFamilies(site.components);
|
|
111
112
|
const count = families.reduce((n, g) => n + g.families.length, 0);
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
113
|
+
const brandPages = site.editorial.filter((p) => (p.section ?? "brand") === "brand");
|
|
114
|
+
const brandFirst = brandPages[0];
|
|
115
|
+
const products = site.taxonomy.terms.filter((t) => t.kind === "product" && t.wrong?.length);
|
|
116
|
+
const example = products[0] ?? site.taxonomy.terms.find((t) => t.wrong?.length);
|
|
117
|
+
const fills = ["--primary", "--neutral", "--success", "--warning", "--destructive"].filter((n) => site.tokens.tokens.some((t) => t.name === n));
|
|
118
|
+
const share = config.adherence?.summary.share;
|
|
119
|
+
// each section of the system, why it exists, how much is in it, and a glimpse of it, live from the manifest
|
|
120
|
+
const sections = [];
|
|
121
|
+
if (brandFirst || site.shows("logo"))
|
|
122
|
+
sections.push({
|
|
123
|
+
title: "Brand",
|
|
124
|
+
href: `${base}/${brandFirst?.slug ?? "brand/logo"}`,
|
|
125
|
+
why: "What the brand believes, how it sounds and how it looks, so every screen and sentence comes from the same place.",
|
|
126
|
+
count: `${brandPages.length + (site.assets.assets.some((a) => a.kind === "logo") ? 1 : 0)} pages`,
|
|
127
|
+
preview: config.logo ? _jsx("span", { className: "flex h-10 items-center [&_img]:h-8 [&_svg]:h-8", children: config.logo }) : null,
|
|
128
|
+
});
|
|
129
|
+
sections.push({
|
|
130
|
+
title: "Foundations",
|
|
131
|
+
href: `${base}/colour`,
|
|
132
|
+
why: "Colour, type and the scale, generated from the tokens and measured in both modes, so nothing is a guess.",
|
|
133
|
+
count: `${site.tokens.tokens.length} tokens`,
|
|
134
|
+
preview: (_jsxs("span", { className: "flex items-center gap-4", children: [_jsx("span", { className: "flex -space-x-1.5", children: fills.map((n) => (_jsx("span", { "aria-hidden": true, className: "size-8 rounded-full ring-2 ring-canvas", style: { background: `var(${n})` } }, n))) }), _jsx("span", { "aria-hidden": true, className: cx(display, "text-3xl leading-none tracking-tight"), children: "Aa" })] })),
|
|
135
|
+
});
|
|
136
|
+
if (site.rules.rules.length)
|
|
137
|
+
sections.push({
|
|
138
|
+
title: "Rules",
|
|
139
|
+
href: `${base}/rules`,
|
|
140
|
+
why: "The lines the brand and the interface hold, each written for people, with the check that proves it.",
|
|
141
|
+
count: `${site.rules.rules.length} rules, ${site.rules.rules.filter((r) => r.status === "confirmed").length} confirmed`,
|
|
142
|
+
preview: (_jsx("span", { className: "flex flex-col gap-1.5 text-sm", children: site.rules.rules
|
|
143
|
+
.filter((r) => r.kind === "brand")
|
|
144
|
+
.slice(0, 2)
|
|
145
|
+
.map((r) => (_jsxs("span", { className: "flex items-center gap-2", children: [_jsx(StatusBadge, { status: r.status }), _jsx("span", { className: "truncate", children: r.title })] }, r.id))) })),
|
|
146
|
+
});
|
|
147
|
+
if (site.shows("components") && count)
|
|
148
|
+
sections.push({
|
|
149
|
+
title: "Components",
|
|
150
|
+
href: `${base}/components/${slugOf(families[0].families[0].head)}`,
|
|
151
|
+
why: "The real components the product is built from, each with when to use it, a live workbench and an accessibility report.",
|
|
152
|
+
count: `${count} components`,
|
|
153
|
+
preview: (_jsx("span", { className: "flex flex-wrap gap-1.5", children: families.slice(0, 6).map((g) => (_jsxs("span", { className: "inline-flex min-h-7 items-center rounded-md bg-muted px-2 text-xs", children: [g.category, " ", _jsx("span", { className: "ml-1.5 text-muted-foreground tabular-nums", children: g.families.length })] }, g.category))) })),
|
|
154
|
+
});
|
|
155
|
+
if (site.patterns.patterns.length)
|
|
156
|
+
sections.push({
|
|
157
|
+
title: "Patterns",
|
|
158
|
+
href: `${base}/patterns/${site.patterns.patterns[0].id}`,
|
|
159
|
+
why: "The screens the product keeps making, composed of the components, so a recurring problem is solved once.",
|
|
160
|
+
count: `${site.patterns.patterns.length} patterns`,
|
|
161
|
+
preview: _jsx("span", { className: "text-sm text-muted-foreground", children: site.patterns.patterns.slice(0, 3).map((p) => p.name).join(" · ") }),
|
|
162
|
+
});
|
|
163
|
+
if (site.shows("standards") && (config.baselines || config.adherence))
|
|
164
|
+
sections.push({
|
|
165
|
+
title: "Standards",
|
|
166
|
+
href: `${base}/standards`,
|
|
167
|
+
why: "The bar the product is held to, and how closely it follows the system today, reported on every change.",
|
|
168
|
+
count: share == null ? "Baselines agreed" : `${Math.round(share * 100)}% of the product on the system`,
|
|
169
|
+
preview: share == null ? null : (_jsxs("span", { className: "flex w-full max-w-56 items-center gap-3", children: [_jsx("span", { className: "h-1.5 flex-1 overflow-hidden rounded-full bg-muted", children: _jsx("span", { className: "block h-full rounded-full bg-canvas-foreground", style: { width: `${Math.round(share * 100)}%` } }) }), _jsxs("span", { className: "text-sm tabular-nums", children: [Math.round(share * 100), "%"] })] })),
|
|
170
|
+
});
|
|
171
|
+
if (site.shows("vocabulary") && site.taxonomy.terms.length)
|
|
172
|
+
sections.push({
|
|
173
|
+
title: "Vocabulary",
|
|
174
|
+
href: `${base}/vocabulary`,
|
|
175
|
+
why: "One name for each thing, and the names people reach for instead, so people and agents mean the same thing.",
|
|
176
|
+
count: `${site.taxonomy.terms.length} terms`,
|
|
177
|
+
preview: example ? (_jsxs("span", { className: "text-sm", children: ["Say ", _jsx("strong", { className: "font-semibold", children: example.name }), ", ", _jsx("span", { className: "text-muted-foreground line-through decoration-current/40", children: example.wrong?.[0] })] })) : null,
|
|
178
|
+
});
|
|
179
|
+
const loop = [
|
|
180
|
+
["Written once", "The components, tokens and rules live in the product's own code. Nobody keeps a second copy in a slide deck or a wiki."],
|
|
181
|
+
["Generated, never drifting", "This site is built from that code on every change, so it cannot fall out of date."],
|
|
182
|
+
["Read by people and agents", "Every page is also plain markdown, and coding agents are pointed at the same source, so they build with the real components and rules."],
|
|
183
|
+
["Checked", "Each rule names the check that proves it. Stale docs stop a commit; everything else is reported."],
|
|
184
|
+
["Measured", "A report on every change shows how closely the product follows the system. It informs the conversation; it never blocks the work."],
|
|
185
|
+
];
|
|
186
|
+
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: "grid gap-x-12 md:grid-cols-2", children: sections.map((sec) => (_jsx("li", { className: "border-t border-border", children: _jsxs(Link, { href: sec.href, className: "group flex h-full flex-col gap-4 py-7 focus-visible:outline-2 focus-visible:outline-ring", children: [_jsxs("span", { className: "flex items-baseline justify-between gap-4", children: [_jsx("span", { className: "text-2xl leading-tight tracking-tight underline-offset-[6px] group-hover:underline", children: sec.title }), _jsx("span", { className: "shrink-0 text-xs text-muted-foreground tabular-nums", children: sec.count })] }), _jsx("span", { className: "max-w-md text-base leading-relaxed text-muted-foreground", children: sec.why }), sec.preview && _jsx("span", { className: "mt-auto flex min-h-10 items-center pt-2", children: sec.preview })] }) }, sec.title))) }) }), config.overview?.agentic !== false && (_jsxs(DocsSection, { title: "Why this is agentic", lead: config.overview?.agenticLead ??
|
|
187
|
+
"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`, 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" })] })] })] })), _jsx(DocsFooter, { provenance: config.provenance })] }));
|
|
122
188
|
}
|
package/dist/next/prose.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The few markdown shapes editorial pages use: `##` sections, paragraphs and bullet
|
|
3
|
-
* and
|
|
2
|
+
* The few markdown shapes editorial pages use: `##` sections, `###` headings, paragraphs and bullet
|
|
3
|
+
* lists, with bold, code and links. Each `##` is a docs section, so it reads at the same size as a generated page and is
|
|
4
4
|
* listed in "On this page". A list whose every item opens in bold ("**Say it plainly.** …") is a set
|
|
5
5
|
* of principles, numbered, each a heading over its sentence.
|
|
6
6
|
*/
|
package/dist/next/prose.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { DocsSection } from "../shell.js";
|
|
3
3
|
/**
|
|
4
|
-
* The few markdown shapes editorial pages use: `##` sections, paragraphs and bullet
|
|
5
|
-
* and
|
|
4
|
+
* The few markdown shapes editorial pages use: `##` sections, `###` headings, paragraphs and bullet
|
|
5
|
+
* lists, with bold, code and links. Each `##` is a docs section, so it reads at the same size as a generated page and is
|
|
6
6
|
* listed in "On this page". A list whose every item opens in bold ("**Say it plainly.** …") is a set
|
|
7
7
|
* of principles, numbered, each a heading over its sentence.
|
|
8
8
|
*/
|
|
@@ -18,6 +18,8 @@ export function Markdown({ text }) {
|
|
|
18
18
|
}
|
|
19
19
|
function Blocks({ blocks }) {
|
|
20
20
|
return (_jsx("div", { className: "flex flex-col gap-5", children: blocks.map((b, i) => {
|
|
21
|
+
if (b.startsWith("### "))
|
|
22
|
+
return (_jsx("h3", { className: "mt-4 max-w-3xl text-2xl leading-snug tracking-tight first:mt-0", children: inline(b.slice(4)) }, i));
|
|
21
23
|
const lines = b.split("\n");
|
|
22
24
|
if (lines.every((l) => l.startsWith("- "))) {
|
|
23
25
|
const items = lines.map((l) => l.slice(2));
|
|
@@ -25,7 +27,7 @@ function Blocks({ blocks }) {
|
|
|
25
27
|
if (principles)
|
|
26
28
|
return (_jsx("ol", { className: "flex max-w-3xl flex-col gap-12", children: items.map((l, n) => {
|
|
27
29
|
const [, head, rest] = /^\*\*([^*]+)\*\*\s*(.*)$/.exec(l) ?? [];
|
|
28
|
-
return (_jsxs("li", { className: "grid grid-cols-[3rem_minmax(0,1fr)] gap-x-4 gap-y-3 sm:grid-cols-[4rem_minmax(0,1fr)]", children: [_jsx("span", { className: "
|
|
30
|
+
return (_jsxs("li", { className: "grid grid-cols-[3rem_minmax(0,1fr)] items-baseline gap-x-4 gap-y-3 sm:grid-cols-[4rem_minmax(0,1fr)]", children: [_jsx("span", { className: "text-lg text-muted-foreground tabular-nums", children: String(n + 1).padStart(2, "0") }), _jsxs("span", { className: "flex flex-col gap-3", children: [_jsx("span", { className: "text-2xl leading-snug tracking-tight md:text-3xl", children: head.replace(/\.$/, "") }), _jsx("span", { className: "text-lg leading-relaxed text-canvas-foreground/75", children: inline(rest) })] })] }, l));
|
|
29
31
|
}) }, i));
|
|
30
32
|
return (_jsx("ul", { className: "flex max-w-3xl list-disc flex-col gap-2 pl-5 text-lg leading-relaxed", children: items.map((l) => (_jsx("li", { children: inline(l) }, l))) }, i));
|
|
31
33
|
}
|
|
@@ -33,5 +35,5 @@ function Blocks({ blocks }) {
|
|
|
33
35
|
}) }));
|
|
34
36
|
}
|
|
35
37
|
function inline(text) {
|
|
36
|
-
return text.split(/(\*\*[^*]+\*\*|`[^`]
|
|
38
|
+
return text.split(/(\*\*[^*]+\*\*|`[^`]+`|\[[^\]]+\]\([^)\s]+\))/).map((part, i) => part.startsWith("[") ? (_jsx("a", { href: /\(([^)]+)\)$/.exec(part)?.[1], className: "underline decoration-from-font underline-offset-4 hover:decoration-2", children: /^\[([^\]]+)\]/.exec(part)?.[1] }, i)) : part.startsWith("**") ? (_jsx("strong", { className: "font-semibold", children: part.slice(2, -2) }, i)) : part.startsWith("`") ? (_jsx("code", { className: "font-mono text-[0.9em]", children: part.slice(1, -1) }, i)) : (part));
|
|
37
39
|
}
|
package/dist/pattern.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { ComponentsManifest, PatternEntry } from "./lib/manifest-types.js";
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* A recurring screen composition: each composition live in its frame, with its code, then the
|
|
4
|
+
* components it is made of, each linking to its page. Its status sits in the page header.
|
|
5
|
+
*/
|
|
3
6
|
export declare function Pattern({ pattern, manifest, basePath, }: {
|
|
4
7
|
pattern: PatternEntry;
|
|
5
8
|
/** To link the components it uses to their pages. */
|