@jfrader/storybook-docs 0.0.0-stage → 0.4.4
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/LICENSE +21 -0
- package/README.md +138 -2
- package/dist/app.d.ts +1 -0
- package/dist/base.d.ts +3 -0
- package/dist/build/catalog.d.ts +20 -0
- package/dist/build/code.d.ts +2 -0
- package/dist/build/global-styles.d.ts +1 -0
- package/dist/build/guidance.d.ts +4 -0
- package/dist/build/module-ids.d.ts +2 -0
- package/dist/build/props.d.ts +10 -0
- package/dist/build/releases.d.ts +7 -0
- package/dist/build/site.d.ts +2 -0
- package/dist/build/storybook-test.d.ts +2 -0
- package/dist/build/tokens.d.ts +2 -0
- package/dist/code.d.ts +16 -0
- package/dist/component-demo.d.ts +23 -0
- package/dist/config.d.ts +98 -0
- package/dist/controls.d.ts +49 -0
- package/dist/css.d.ts +1 -0
- package/dist/guidance-model.d.ts +74 -0
- package/dist/guidance.d.ts +9 -0
- package/dist/index.css +420 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +1971 -0
- package/dist/pages/component-page.d.ts +4 -0
- package/dist/pages/foundations-color.d.ts +3 -0
- package/dist/pages/foundations-effects.d.ts +3 -0
- package/dist/pages/foundations-spacing.d.ts +3 -0
- package/dist/pages/foundations-type.d.ts +3 -0
- package/dist/pages/overview.d.ts +3 -0
- package/dist/pages/releases.d.ts +3 -0
- package/dist/prop-docs.d.ts +20 -0
- package/dist/props.d.ts +4 -0
- package/dist/scan.d.ts +19 -0
- package/dist/search-match.d.ts +21 -0
- package/dist/search.d.ts +5 -0
- package/dist/sections.d.ts +52 -0
- package/dist/skeleton.d.ts +11 -0
- package/dist/start.d.ts +4 -0
- package/dist/story-view.d.ts +20 -0
- package/dist/styles.css +685 -0
- package/dist/toc.d.ts +19 -0
- package/dist/virtual.d.ts +42 -0
- package/dist/vite-plugin.d.ts +10 -0
- package/dist/vite-plugin.js +697 -0
- package/docs/CONFIG.md +287 -0
- package/docs/RELEASING.md +153 -0
- package/package.json +75 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Fran
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,139 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @jfrader/storybook-docs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A documentation front for **any design system that has Storybook**. Point it at a set of
|
|
4
|
+
story files; it generates the navigation, renders every story in place, and builds API
|
|
5
|
+
tables from the stories' own `argTypes`. There is no second component list anywhere.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
example/ # a consumer you can copy
|
|
9
|
+
docs.config.mjs # ← the only place the design system is described
|
|
10
|
+
vite.config.ts # registers the plugin
|
|
11
|
+
index.html
|
|
12
|
+
src/main.tsx # six lines
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## What it does with your stories
|
|
16
|
+
|
|
17
|
+
| Piece | Source of truth |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| Sidebar, groups, slugs | each story module's `title` (scoped to the `meta` object, so fixtures never leak in) |
|
|
20
|
+
| Search (⌘K) | the catalog, scored over component, group and story names |
|
|
21
|
+
| Examples (all of them, inline, in sections) | the story module itself — meta `component` + merged `args`, or the story's `render` |
|
|
22
|
+
| Sections (Overview / Variants & sizes / States / Interaction & keyboard / Content & layout / Environments / Edge cases) | the story names, bucketed by convention |
|
|
23
|
+
| Props tables (one per component and part, with native-element notes) | the component sources — `react-docgen-typescript` for components, the TypeScript compiler API for exported `*Props` types (where compound parts live) |
|
|
24
|
+
| Usage snippet | the default story's own arguments |
|
|
25
|
+
| Per-example Code disclosures | the story's merged args (hidden when the story uses a custom render, so a snippet never lies) |
|
|
26
|
+
| Authored guidance per component | Markdown files in the configured guidance directories, with `> Do —` / `> Don't —` blockquotes rendered as do/don't cards — the part stories cannot generate |
|
|
27
|
+
| Foundations: Color, Typography, Spacing & shape, Elevation & motion | your token module (optional) |
|
|
28
|
+
| Docs chrome theme | your CSS custom properties (optional) |
|
|
29
|
+
|
|
30
|
+
Known limits: compound parts declared as property assignments (`Dialog.Content = …`) are picked up
|
|
31
|
+
through their exported `*Props` types; parts with no exported props type stay invisible. Stories that
|
|
32
|
+
need project-level Storybook decorators fail soft (an error boundary per story frame). Play functions,
|
|
33
|
+
controls and a11y checks stay in Storybook — this front is for reading and browsing.
|
|
34
|
+
|
|
35
|
+
## What it looks like
|
|
36
|
+
|
|
37
|
+
| | |
|
|
38
|
+
| --- | --- |
|
|
39
|
+
|  |  |
|
|
40
|
+
| The overview: stat tiles, then a card per area with counts and links into every component. | ⌘K search: matches highlighted, story hits listed as `Component › Story`. |
|
|
41
|
+
|  |  |
|
|
42
|
+
| Every story renders in place, bucketed into sections, with live controls and a Code disclosure per frame. | Authored Markdown becomes typed React blocks: Do/Don't cards, tables, code with language. |
|
|
43
|
+
|  |  |
|
|
44
|
+
| Releases: the changelog rendered in place, with the current version read from the package. | Foundations: colour, type, spacing/shape and elevation/motion, all from the token module. |
|
|
45
|
+
|
|
46
|
+
## The reference consumer
|
|
47
|
+
|
|
48
|
+
`examples/fixtures/` is a second, synthetic design system (Acme UI) used by the scanner tests and by CI
|
|
49
|
+
as the build gate that needs no credentials — it proves the engine is not shaped around jfrader/ui.
|
|
50
|
+
`examples/jfrader-ui/` is the real one; its `link:` paths resolve against the main clone layout, so a
|
|
51
|
+
git worktree copy needs those symlinks repointed locally (see its `node_modules/@jfrader` entries).
|
|
52
|
+
|
|
53
|
+
## Development
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pnpm install
|
|
57
|
+
pnpm test # engine unit tests (glob, title extraction, sections, snippets)
|
|
58
|
+
pnpm --dir examples/fixtures install
|
|
59
|
+
pnpm --dir examples/fixtures dev # the synthetic consumer (port 4334)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
To check what a running docs site actually renders, point the frame check at it. It visits every
|
|
63
|
+
component page, mounts the lazy frames, and reports stories that fail to render, content painted
|
|
64
|
+
outside its frame, zero-size controls and components that collapsed to nothing — the check that
|
|
65
|
+
caught a component rendering at 0×0 with its own tests green. It needs Playwright, so run it from a
|
|
66
|
+
directory where that resolves (normally your Storybook app):
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
node scripts/check-example-frames.mjs http://localhost:4320 [--json report.json]
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
It exits non-zero when a component has a real finding, so it can gate CI. Zero-size component roots
|
|
73
|
+
are reported as notes: an empty group or a progress bar at zero is legitimate.
|
|
74
|
+
|
|
75
|
+
## Use it
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
pnpm add react@^19 react-dom@^19
|
|
79
|
+
pnpm add -D @jfrader/storybook-docs vite @vitejs/plugin-react @types/node @types/react @types/react-dom
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Use Node 22.12 or newer (maintainer tests need Node 22.18 or newer). React 19 and Vite 6, 7 or 8
|
|
83
|
+
are peers supplied by the consumer. Published packages and linked checkouts both expose built
|
|
84
|
+
JavaScript and types (`dist/`); run `pnpm build:package` after editing a linked engine checkout.
|
|
85
|
+
The browser entry imports its CSS automatically; no stylesheet subpath or manual `virtual.d.ts`
|
|
86
|
+
reference is needed. Importing the root entry also loads the virtual-module declarations.
|
|
87
|
+
|
|
88
|
+
Maintainers can run `pnpm smoke:package` to pack, install and typecheck/build an isolated minimal
|
|
89
|
+
consumer without links or private dependencies. See [release instructions](docs/RELEASING.md).
|
|
90
|
+
|
|
91
|
+
The consumer contract is four files:
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
// docs.config.mjs
|
|
95
|
+
export default {
|
|
96
|
+
site: { title: 'acme/ui', mark: 'a', links: [{ label: 'GitHub', href: '…' }] },
|
|
97
|
+
stories: { from: '@acme/ui', pattern: 'src/components/*/*.stories.tsx' },
|
|
98
|
+
groups: { rename: { Data: 'Data display' }, order: ['Foundations', 'Inputs', 'Components'] },
|
|
99
|
+
theme: {
|
|
100
|
+
attribute: 'data-theme',
|
|
101
|
+
values: ['dark', 'light'],
|
|
102
|
+
vars: { bg: 'var(--acme-bg)', text: 'var(--acme-text)', accent: 'var(--acme-accent)' },
|
|
103
|
+
},
|
|
104
|
+
tokens: { varsModule: '@acme/tokens/vars', varsExport: 'vars', css: ['@acme/tokens/tokens.css'] },
|
|
105
|
+
};
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
// vite.config.ts
|
|
110
|
+
import react from '@vitejs/plugin-react';
|
|
111
|
+
import { defineConfig } from 'vite';
|
|
112
|
+
import { storybookDocs } from '@jfrader/storybook-docs/vite';
|
|
113
|
+
import config from './docs.config.mjs';
|
|
114
|
+
|
|
115
|
+
export default defineConfig({ plugins: [storybookDocs({ config }), react()] });
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
```html
|
|
119
|
+
<!-- index.html -->
|
|
120
|
+
<div id="root"></div><script type="module" src="/src/main.tsx"></script>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
// src/main.tsx
|
|
125
|
+
import { start } from '@jfrader/storybook-docs';
|
|
126
|
+
start();
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Notes and limits
|
|
130
|
+
|
|
131
|
+
- The plugin scans the resolved package directory and imports story files by absolute
|
|
132
|
+
path, so it works with workspace links and does not require the design system to publish
|
|
133
|
+
its stories or expose extra package exports.
|
|
134
|
+
- If the design system is consumed from a published tarball that only ships built files,
|
|
135
|
+
point `stories.from` at a checkout (or publish the story sources) — the tool reads
|
|
136
|
+
source modules by design, because that is what Storybook renders.
|
|
137
|
+
- Mounting under a sub-path: set `window.__STORYBOOK_DOCS_BASE__ = '/docs'` before `start()`.
|
|
138
|
+
- Not included yet: search, versioned docs, prose authoring, adoption analytics. All of
|
|
139
|
+
them are free/OSS additions once the shape earns them.
|
package/dist/app.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function DocsApp(): import("react").JSX.Element;
|
package/dist/base.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { readStoryFile } from '../scan.ts';
|
|
2
|
+
import type { CatalogEntry, StorybookDocsConfig } from '../config.js';
|
|
3
|
+
export interface StoryFile {
|
|
4
|
+
file: string;
|
|
5
|
+
facts: NonNullable<ReturnType<typeof readStoryFile>>;
|
|
6
|
+
}
|
|
7
|
+
export interface Catalog {
|
|
8
|
+
entries: CatalogEntry[];
|
|
9
|
+
groups: string[];
|
|
10
|
+
stats: {
|
|
11
|
+
components: number;
|
|
12
|
+
stories: number;
|
|
13
|
+
groups: number;
|
|
14
|
+
};
|
|
15
|
+
files: Map<string, string>;
|
|
16
|
+
}
|
|
17
|
+
export declare function resolveStoryRoot(from: string, root: string): string;
|
|
18
|
+
export declare function scanStories(config: StorybookDocsConfig['stories'], root: string): StoryFile[];
|
|
19
|
+
export declare function buildCatalog(stories: StoryFile[], groupsConfig: StorybookDocsConfig['groups']): Catalog;
|
|
20
|
+
export declare function catalogCode(catalog: Catalog): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function globalStylesCode(engineStyles: string, css?: string[]): string;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { StorybookDocsConfig } from '../config.js';
|
|
2
|
+
export declare function indexGuidance(guidance: StorybookDocsConfig['guidance'], root: string): Map<string, string>;
|
|
3
|
+
export declare function guidanceIndexCode(slugs: Iterable<string>): string;
|
|
4
|
+
export declare function guidanceCode(markdown: string): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ComponentPropsDoc, PropDoc } from '../prop-docs.js';
|
|
2
|
+
export declare function toPropDoc(prop: unknown): PropDoc;
|
|
3
|
+
export declare function createPropsCollector(): {
|
|
4
|
+
collect: (storyFile: string | undefined, entryName: string, slug: string) => ComponentPropsDoc[];
|
|
5
|
+
setBuildMode(value: boolean): void;
|
|
6
|
+
clearPrograms(): void;
|
|
7
|
+
};
|
|
8
|
+
export declare function mergePropsTables(tables: ComponentPropsDoc[]): ComponentPropsDoc[];
|
|
9
|
+
export declare function propsCode(components: ComponentPropsDoc[]): string;
|
|
10
|
+
export declare function propsIndexCode(slugs: Iterable<string>): string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { StorybookDocsConfig } from '../config.js';
|
|
2
|
+
export interface Releases {
|
|
3
|
+
version: string | null;
|
|
4
|
+
changelog: string | null;
|
|
5
|
+
}
|
|
6
|
+
export declare function readReleases(config: StorybookDocsConfig, root: string): Releases;
|
|
7
|
+
export declare function releasesCode(releases: Releases): string;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/** A permissive stand-in for `storybook/test`: play functions never run in the docs front. */
|
|
2
|
+
export declare const STORYBOOK_TEST_STUB = "\nconst chainable = (impl) => {\n const callable = (...args) => (typeof impl === 'function' ? impl(...args) : undefined);\n const chain = () => callable;\n for (const name of [\n 'mockName', 'mockImplementation', 'mockImplementationOnce', 'mockResolvedValue',\n 'mockResolvedValueOnce', 'mockRejectedValue', 'mockReturnValue', 'mockReturnThis',\n 'mockReset', 'mockClear', 'mockRestore',\n ]) callable[name] = chain;\n callable.mock = { calls: [], results: [] };\n return callable;\n};\nexport const fn = (impl) => chainable(impl);\nexport const spyOn = () => chainable();\nexport const mocked = (value) => value;\nexport const expect = () => new Proxy({}, { get: () => () => undefined });\nexport const within = () => new Proxy({}, { get: () => () => ({}) });\nexport const waitFor = (callback) => Promise.resolve(typeof callback === 'function' ? callback() : undefined);\nexport const userEvent = new Proxy({}, { get: () => () => Promise.resolve() });\nexport const fireEvent = () => true;\nexport const cleanup = () => {};\n";
|
package/dist/code.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type CodeBlockProps = {
|
|
2
|
+
code: string;
|
|
3
|
+
/** Language hint for the consumer's highlighter, as an id (`tsx`, `bash`, `json`). */
|
|
4
|
+
language?: string;
|
|
5
|
+
/**
|
|
6
|
+
* What this code is, for a screen reader. Each example on a page needs its own, or every
|
|
7
|
+
* renderer's landmark carries the same name and the page has duplicate landmarks.
|
|
8
|
+
*/
|
|
9
|
+
label?: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* One code block for every place the docs show code: the page snippet, each example's Code panel
|
|
13
|
+
* and every fenced block in authored Markdown. Renders the design system's own code block when the
|
|
14
|
+
* consumer provides one, so code looks exactly as it does in the system it documents.
|
|
15
|
+
*/
|
|
16
|
+
export declare function CodeBlock({ code, language, label }: CodeBlockProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** @jsxImportSource react */
|
|
2
|
+
import { type ReactNode } from 'react';
|
|
3
|
+
import type { StoryControl } from './controls';
|
|
4
|
+
import './controls.css';
|
|
5
|
+
import './component-demo.css';
|
|
6
|
+
export interface ComponentDemoProps {
|
|
7
|
+
story: string;
|
|
8
|
+
storyName: string;
|
|
9
|
+
authoredStory?: string;
|
|
10
|
+
skipped: string[];
|
|
11
|
+
controls: StoryControl[];
|
|
12
|
+
args: Record<string, unknown>;
|
|
13
|
+
unavailable: string | null;
|
|
14
|
+
changed: boolean;
|
|
15
|
+
onControlChange: (name: string, value: unknown) => void;
|
|
16
|
+
onReset: () => void;
|
|
17
|
+
storyLayout: 'centered' | 'fullscreen' | 'padded';
|
|
18
|
+
snippet: string | null;
|
|
19
|
+
codeLanguage: string;
|
|
20
|
+
children: ReactNode;
|
|
21
|
+
}
|
|
22
|
+
export declare function hasHorizontalOverflow({ scrollWidth, clientWidth }: Pick<HTMLElement, 'scrollWidth' | 'clientWidth'>): boolean;
|
|
23
|
+
export declare function ComponentDemo({ story, storyName, authoredStory, skipped, controls, args, unavailable, changed, onControlChange, onReset, storyLayout, snippet, codeLanguage, children, }: ComponentDemoProps): import("react").JSX.Element;
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The consumer-facing configuration. Nothing in the engine is bound to a specific
|
|
3
|
+
* design system: every path, package name, theme variable and label comes from here.
|
|
4
|
+
*/
|
|
5
|
+
export interface StorybookDocsConfig {
|
|
6
|
+
/** Branding and header content. */
|
|
7
|
+
site: {
|
|
8
|
+
title: string;
|
|
9
|
+
mark?: string;
|
|
10
|
+
tagline?: string;
|
|
11
|
+
links?: Array<{
|
|
12
|
+
label: string;
|
|
13
|
+
href: string;
|
|
14
|
+
}>;
|
|
15
|
+
/** Shown as a chip in the header; leave unset to read it from `releases.versionFrom`. */
|
|
16
|
+
version?: string;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Optional release information. Point `changelog` at the design system's changelog file
|
|
20
|
+
* (rendered as a Releases page) and `versionFrom` at the package whose `version` field is
|
|
21
|
+
* the current release.
|
|
22
|
+
*/
|
|
23
|
+
releases?: {
|
|
24
|
+
changelog?: string;
|
|
25
|
+
versionFrom?: string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Where the story files live. `from` is either a package name (`@acme/ui`) or a path
|
|
29
|
+
* relative to the config file (`../packages/ui`); `pattern` is a glob relative to that
|
|
30
|
+
* root — the files it matches are the source of truth for navigation, examples and
|
|
31
|
+
* API tables.
|
|
32
|
+
*/
|
|
33
|
+
stories: {
|
|
34
|
+
from: string;
|
|
35
|
+
pattern: string;
|
|
36
|
+
};
|
|
37
|
+
/** Optional information architecture: explicit group order and renames. */
|
|
38
|
+
groups?: {
|
|
39
|
+
order?: string[];
|
|
40
|
+
rename?: Record<string, string>;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Optional theme bridge. `vars` maps the engine's semantic roles to the design
|
|
44
|
+
* system's own CSS custom properties, so the docs chrome is themed by the system it
|
|
45
|
+
* documents (and the toggle works through the system's own theme attribute).
|
|
46
|
+
*/
|
|
47
|
+
theme?: {
|
|
48
|
+
attribute?: string;
|
|
49
|
+
values?: [string, string];
|
|
50
|
+
vars?: Partial<Record<ThemeRole, string>>;
|
|
51
|
+
};
|
|
52
|
+
/** Optional token source that enables the Foundations pages. */
|
|
53
|
+
tokens?: {
|
|
54
|
+
varsModule: string;
|
|
55
|
+
/** Named export in `varsModule` holding the token object. Defaults to `vars`. */
|
|
56
|
+
varsExport?: string;
|
|
57
|
+
/** CSS files to load for the consumer's tokens (bare specifiers). */
|
|
58
|
+
css?: string[];
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Optional authored prose. A directory of Markdown files named after component slugs
|
|
62
|
+
* (`button.md`) plus optionally `index.md` for the overview; each is rendered on that
|
|
63
|
+
* component's page. This is the part stories cannot generate. Several directories may be
|
|
64
|
+
* listed; for the same slug, a later directory wins.
|
|
65
|
+
*/
|
|
66
|
+
guidance?: {
|
|
67
|
+
dir: string | string[];
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* Optional code renderer. `module` is a path to a module in the consumer app (relative to the
|
|
71
|
+
* config) whose default export renders `{ code, language }` — normally the design system's own
|
|
72
|
+
* code block, wired to its highlighter, so examples look exactly as they do in the system.
|
|
73
|
+
* Without it, code renders in the engine's plain block.
|
|
74
|
+
*/
|
|
75
|
+
code?: {
|
|
76
|
+
module: string;
|
|
77
|
+
};
|
|
78
|
+
/** Optional page switches. Foundations pages require `tokens`. */
|
|
79
|
+
pages?: {
|
|
80
|
+
overview?: boolean;
|
|
81
|
+
color?: boolean;
|
|
82
|
+
typography?: boolean;
|
|
83
|
+
spacing?: boolean;
|
|
84
|
+
effects?: boolean;
|
|
85
|
+
api?: boolean;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export declare const THEME_ROLES: readonly ["bg", "surface", "surfaceRaised", "surfaceHover", "border", "borderSubtle", "text", "textMuted", "textSubtle", "accent", "accentText", "accentSoft", "accentContrast", "danger", "dangerText", "success", "focusRing"];
|
|
89
|
+
export type ThemeRole = (typeof THEME_ROLES)[number];
|
|
90
|
+
export interface CatalogEntry {
|
|
91
|
+
slug: string;
|
|
92
|
+
name: string;
|
|
93
|
+
group: string;
|
|
94
|
+
storybookTitle: string;
|
|
95
|
+
stories: string[];
|
|
96
|
+
hasComponent: boolean;
|
|
97
|
+
load: () => Promise<Record<string, unknown>>;
|
|
98
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
export { hasHorizontalOverflow } from './component-demo';
|
|
2
|
+
import { type DocsParameters } from './sections';
|
|
3
|
+
interface StoryShape {
|
|
4
|
+
name?: string;
|
|
5
|
+
args?: Record<string, unknown>;
|
|
6
|
+
argTypes?: Record<string, Record<string, unknown>>;
|
|
7
|
+
render?: unknown;
|
|
8
|
+
loaders?: unknown;
|
|
9
|
+
beforeEach?: unknown;
|
|
10
|
+
parameters?: {
|
|
11
|
+
docs?: DocsParameters;
|
|
12
|
+
layout?: string;
|
|
13
|
+
viewport?: unknown;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export interface StoryControl {
|
|
17
|
+
name: string;
|
|
18
|
+
type: 'boolean' | 'select' | 'number' | 'text' | 'range' | 'object';
|
|
19
|
+
options?: unknown[];
|
|
20
|
+
min?: number;
|
|
21
|
+
max?: number;
|
|
22
|
+
step?: number;
|
|
23
|
+
}
|
|
24
|
+
/** Storybook's argTypes can declare a default; the component's own default comes from docgen as a
|
|
25
|
+
* source snippet, so it is parsed back into a value the controls can show. */
|
|
26
|
+
export declare function parseDefault(value: string): unknown;
|
|
27
|
+
/** Every prop docgen gave a default for. Declared before the component's own default so an
|
|
28
|
+
* argType default still wins. */
|
|
29
|
+
/** Docgen reports the default either as a source snippet or as `{ value }`; accept both. */
|
|
30
|
+
export declare function defaultsFromProps(props?: Array<{
|
|
31
|
+
defaultValue?: string | {
|
|
32
|
+
value?: string;
|
|
33
|
+
} | null;
|
|
34
|
+
name: string;
|
|
35
|
+
}>): Record<string, unknown>;
|
|
36
|
+
export declare function getStoryControls(meta: StoryShape, story: StoryShape, componentDefaults?: Record<string, unknown>): {
|
|
37
|
+
args: {
|
|
38
|
+
[x: string]: unknown;
|
|
39
|
+
};
|
|
40
|
+
controls: StoryControl[];
|
|
41
|
+
unavailable: string | null;
|
|
42
|
+
};
|
|
43
|
+
export declare function ControlledStoryFrame({ module, story, componentName, componentDefaults }: {
|
|
44
|
+
module: Record<string, unknown>;
|
|
45
|
+
story: string;
|
|
46
|
+
componentName: string;
|
|
47
|
+
/** Defaults read from the component source, shown until the reader changes them. */
|
|
48
|
+
componentDefaults?: Record<string, unknown>;
|
|
49
|
+
}): import("react").JSX.Element;
|
package/dist/css.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
declare module '*.css';
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authored guidance Markdown → a small block model the docs render as React nodes.
|
|
3
|
+
* Blockquotes that open with a do/don't marker (`✅ **Do** —`, `Don't:`, `⛔`) become
|
|
4
|
+
* do/don't cards; every other blockquote is a neutral callout. Pure: no DOM, no React.
|
|
5
|
+
*/
|
|
6
|
+
import { type Token } from 'marked';
|
|
7
|
+
export type CalloutTone = 'do' | 'dont' | 'note';
|
|
8
|
+
export type Align = 'left' | 'center' | 'right' | null;
|
|
9
|
+
export type Inline = {
|
|
10
|
+
kind: 'text';
|
|
11
|
+
text: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: 'strong' | 'em' | 'del';
|
|
14
|
+
children: Inline[];
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'code';
|
|
17
|
+
text: string;
|
|
18
|
+
} | {
|
|
19
|
+
kind: 'link';
|
|
20
|
+
href: string;
|
|
21
|
+
external: boolean;
|
|
22
|
+
children: Inline[];
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'image';
|
|
25
|
+
src: string;
|
|
26
|
+
alt: string;
|
|
27
|
+
} | {
|
|
28
|
+
kind: 'br';
|
|
29
|
+
};
|
|
30
|
+
export type Block = {
|
|
31
|
+
kind: 'heading';
|
|
32
|
+
depth: number;
|
|
33
|
+
children: Inline[];
|
|
34
|
+
} | {
|
|
35
|
+
kind: 'paragraph';
|
|
36
|
+
children: Inline[];
|
|
37
|
+
}
|
|
38
|
+
/** Tight list-item content: inline nodes without a paragraph around them. */
|
|
39
|
+
| {
|
|
40
|
+
kind: 'text';
|
|
41
|
+
children: Inline[];
|
|
42
|
+
} | {
|
|
43
|
+
kind: 'list';
|
|
44
|
+
ordered: boolean;
|
|
45
|
+
start: number;
|
|
46
|
+
items: Block[][];
|
|
47
|
+
} | {
|
|
48
|
+
kind: 'code';
|
|
49
|
+
lang: string;
|
|
50
|
+
text: string;
|
|
51
|
+
} | {
|
|
52
|
+
kind: 'table';
|
|
53
|
+
align: Align[];
|
|
54
|
+
header: Inline[][];
|
|
55
|
+
rows: Inline[][][];
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'callout';
|
|
58
|
+
tone: CalloutTone;
|
|
59
|
+
children: Block[];
|
|
60
|
+
} | {
|
|
61
|
+
kind: 'rule';
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Reads a blockquote's leading do/don't marker. A symbol is a marker on its own; a bare
|
|
65
|
+
* word counts only when emphasised (`**Do**`) or followed by a separator or line end, so
|
|
66
|
+
* "Do you need…" stays a neutral callout. The marker is removed from the returned body.
|
|
67
|
+
*/
|
|
68
|
+
export declare function readCallout(text: string): {
|
|
69
|
+
tone: CalloutTone;
|
|
70
|
+
body: string;
|
|
71
|
+
};
|
|
72
|
+
/** Converts `marked.lexer()` tokens into the guidance block model. */
|
|
73
|
+
export declare function toBlocks(tokens: Token[]): Block[];
|
|
74
|
+
export declare function parseGuidance(markdown: string): Block[];
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import './guidance.css';
|
|
2
|
+
/** Renders parsed guidance Markdown — reused by the Releases page for the changelog. */
|
|
3
|
+
export declare function MarkdownView({ markdown, className }: {
|
|
4
|
+
markdown: string;
|
|
5
|
+
className?: string;
|
|
6
|
+
}): import("react").JSX.Element;
|
|
7
|
+
export declare function Guidance({ slug }: {
|
|
8
|
+
slug: string;
|
|
9
|
+
}): import("react").JSX.Element | null;
|