storybook-addon-md 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/README.md +338 -0
- package/STYLING.md +105 -0
- package/dist/content.d.ts +40 -0
- package/dist/content.js +188 -0
- package/dist/generator.d.ts +16 -0
- package/dist/generator.js +98 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +1 -0
- package/dist/preset.d.ts +22 -0
- package/dist/preset.js +137 -0
- package/dist/runtime.d.ts +10 -0
- package/dist/runtime.js +32 -0
- package/dist/styles.css +201 -0
- package/dist/types.d.ts +17 -0
- package/dist/types.js +1 -0
- package/package.json +123 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# storybook-addon-md
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
Initial release.
|
|
6
|
+
|
|
7
|
+
- Discover ordinary Markdown through configurable include and exclude patterns.
|
|
8
|
+
- Render standalone pages or attach shared documentation to component stories.
|
|
9
|
+
- Support frontmatter, sibling-story associations, and status and tag chips.
|
|
10
|
+
- Bundle relative assets and update documentation during development.
|
|
11
|
+
- Customize Markdown rendering, layouts, stylesheets, and CSS variables.
|
|
12
|
+
- Include a GitHub-inspired example with system light and dark themes.
|
|
13
|
+
|
|
14
|
+
Tested with Storybook 10.6.0, React 19.2.4, and Vite 7.3.6.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rui Duarte
|
|
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
ADDED
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
# Storybook Markdown
|
|
2
|
+
|
|
3
|
+
A Storybook addon for **ordinary Markdown documentation**. Write `.md` files beside your components or in a docs folder, and browse them inside Storybook.
|
|
4
|
+
|
|
5
|
+
- **Automatic discovery.** Configure file patterns once. Additions, edits, and deletions update during development.
|
|
6
|
+
- **Component and standalone docs.** Attach guidance to existing stories, share it across components, or publish a page on its own.
|
|
7
|
+
- **Native Docs.** Keep Storybook’s examples, generated props, and documentation styling.
|
|
8
|
+
- **Your theme.** Customize content through CSS variables, a stylesheet, or your own layout and Markdown renderer.
|
|
9
|
+
- **Static builds.** Relative images and downloads are bundled with your documentation.
|
|
10
|
+
|
|
11
|
+
Write `Button.metadata.md` beside `Button.stories.tsx`:
|
|
12
|
+
|
|
13
|
+
```md
|
|
14
|
+
---
|
|
15
|
+
status: Stable
|
|
16
|
+
tags: [Actions]
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Overview
|
|
20
|
+
|
|
21
|
+
Use buttons to trigger actions.
|
|
22
|
+
|
|
23
|
+
## When to use
|
|
24
|
+
|
|
25
|
+
- Submit a form.
|
|
26
|
+
- Confirm a choice.
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
The component gets a **Markdown** Docs entry with your guidance, status and tag chips, examples, and props. Authors manage Markdown files; the addon manages disposable MDX wrappers.
|
|
30
|
+
|
|
31
|
+
## Table of Contents
|
|
32
|
+
|
|
33
|
+
- [Install](#install)
|
|
34
|
+
- [Guide](#guide)
|
|
35
|
+
- [Configuration](#configuration)
|
|
36
|
+
- [Styling](#styling)
|
|
37
|
+
- [Example](#example)
|
|
38
|
+
- [Development](#development)
|
|
39
|
+
- [Releasing](#releasing)
|
|
40
|
+
- [Limitations](#limitations)
|
|
41
|
+
|
|
42
|
+
## Install
|
|
43
|
+
|
|
44
|
+
The tested setup is **Storybook 10.6.0**, **@storybook/react-vite 10.6.0**, **@storybook/addon-docs 10.6.0**, **Vite 7.3.6**, and **React 19.2.4**. Node 22.13+ is required; local verification uses Node 24.21.0 and CI uses Node 24 on Linux.
|
|
45
|
+
|
|
46
|
+
This repository uses [Nub](https://nubjs.com/docs) 0.7.5. The checked-in `nub.lock` pins dependencies, and `.npmrc` selects the hoisted layout for Storybook and Vitest. `nub.jsonc` keeps scripts on standard Node without Nub runtime hooks. CI installs with `nub install --frozen-lockfile`.
|
|
47
|
+
|
|
48
|
+
To build an installable tarball from this repository:
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
nub install
|
|
52
|
+
nub pack
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Install it in your Storybook project:
|
|
56
|
+
|
|
57
|
+
```sh
|
|
58
|
+
nub add -D /path/to/storybook-addon-md-0.1.0.tgz @storybook/addon-docs@10.6.0
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The package ships compiled JavaScript and TypeScript declarations. Consumers do not need to compile the addon.
|
|
62
|
+
|
|
63
|
+
Register it after addon-docs in `.storybook/main.ts`:
|
|
64
|
+
|
|
65
|
+
```ts
|
|
66
|
+
import type { StorybookConfig } from '@storybook/react-vite';
|
|
67
|
+
import type { MarkdownOptions } from 'storybook-addon-md';
|
|
68
|
+
|
|
69
|
+
const config: StorybookConfig = {
|
|
70
|
+
framework: '@storybook/react-vite',
|
|
71
|
+
stories: ['../src/**/*.stories.@(ts|tsx|js|jsx)'],
|
|
72
|
+
addons: [
|
|
73
|
+
'@storybook/addon-docs',
|
|
74
|
+
{
|
|
75
|
+
name: 'storybook-addon-md',
|
|
76
|
+
options: {
|
|
77
|
+
patterns: ['src/**/*.md', 'docs/**/*.md'],
|
|
78
|
+
exclude: ['docs/private/**'],
|
|
79
|
+
} satisfies MarkdownOptions,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export default config;
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Keep your normal story patterns: referenced story files must match them. Markdown files belong in the addon’s `patterns`, not Storybook’s `stories` list.
|
|
88
|
+
|
|
89
|
+
Add `storybook-markdown-generated/` to `.gitignore`.
|
|
90
|
+
|
|
91
|
+
## Guide
|
|
92
|
+
|
|
93
|
+
### Standalone Pages
|
|
94
|
+
|
|
95
|
+
A plain `docs/Introduction.md` appears at `Documentation/docs/Introduction`. No frontmatter, component, or story file is required.
|
|
96
|
+
|
|
97
|
+
Use `title` to choose its sidebar location:
|
|
98
|
+
|
|
99
|
+
```md
|
|
100
|
+
---
|
|
101
|
+
title: Guides/Introduction
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Getting started
|
|
105
|
+
|
|
106
|
+
Write ordinary Markdown here.
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Component Documentation
|
|
110
|
+
|
|
111
|
+
Name a document `Button.metadata.md` beside `Button.stories.tsx` to associate it automatically. The convention also checks `.stories.ts`, `.stories.jsx`, and `.stories.js`. Missing or ambiguous siblings produce an error.
|
|
112
|
+
|
|
113
|
+
For a different location or filename, set `stories` relative to the Markdown file:
|
|
114
|
+
|
|
115
|
+
```yaml
|
|
116
|
+
stories: ../components/Button.stories.tsx
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
An explicit `stories` field takes precedence over the filename convention. Existing stories and Autodocs pages remain available. Each component’s **Markdown** entry combines its attached documents in source-path order, followed by its primary example, controls/props, and remaining examples.
|
|
120
|
+
|
|
121
|
+
### Shared Documentation
|
|
122
|
+
|
|
123
|
+
Use an array to attach one document to several story files:
|
|
124
|
+
|
|
125
|
+
```yaml
|
|
126
|
+
stories:
|
|
127
|
+
- ../components/Button.stories.tsx
|
|
128
|
+
- ../components/Toggle.stories.tsx
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Each referenced component displays the shared content alongside its own documentation and examples.
|
|
132
|
+
|
|
133
|
+
### Frontmatter
|
|
134
|
+
|
|
135
|
+
Frontmatter is optional YAML with lowercase top-level keys.
|
|
136
|
+
|
|
137
|
+
| Field | Value | Behavior |
|
|
138
|
+
| ------------ | ----------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
139
|
+
| `title` | Non-empty string | Sidebar location for a standalone page. Does not relocate attached docs. |
|
|
140
|
+
| `stories` | Relative path or non-empty array of paths | Associates the document with story files. |
|
|
141
|
+
| `tags` | Array of non-empty strings | Renders chips below the title. These are content labels, not Storybook indexing tags. |
|
|
142
|
+
| `status` | Non-empty string | Renders a chip after the tags, preserving the value in `data-status`. |
|
|
143
|
+
| Other fields | YAML values | Preserved as metadata for custom layouts and renderers. |
|
|
144
|
+
|
|
145
|
+
Shared pages deduplicate tags and statuses separately in document order. A tag and status with the same label remain separate chips. Fields such as `component` and `category` have no built-in meaning.
|
|
146
|
+
|
|
147
|
+
Invalid frontmatter, duplicate standalone sidebar titles, and missing references produce errors with source paths. Development errors appear in the terminal and Vite overlay or Storybook error view, then recover when corrected.
|
|
148
|
+
|
|
149
|
+
### Links and Assets
|
|
150
|
+
|
|
151
|
+
Use Markdown links and images, including reference-style syntax:
|
|
152
|
+
|
|
153
|
+
```md
|
|
154
|
+

|
|
155
|
+
|
|
156
|
+
[Download the checklist](./checklist.pdf)
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Local paths resolve from the source `.md` file. URL-encoded filenames and fragments are supported. Files are validated and bundled as hashed assets in static builds. Filenames containing URL-reserved characters use safe disposable copies in the generated folder.
|
|
160
|
+
|
|
161
|
+
**Links to `.md` files open their original source**, including frontmatter. They do not navigate to the rendered Storybook page or recursively bundle the linked document’s assets. For page navigation, use a Storybook URL such as `/?path=/docs/guides-introduction--docs`, adjusted for your deployment prefix.
|
|
162
|
+
|
|
163
|
+
External, fragment-only, query-only, and root-relative URLs are unchanged. Supply root-relative assets through Storybook’s `staticDirs`. Source files and local references must stay inside `root`; referenced files become part of the static build.
|
|
164
|
+
|
|
165
|
+
## Configuration
|
|
166
|
+
|
|
167
|
+
| Option | Default | Description |
|
|
168
|
+
| -------------- | ------------------------------ | ------------------------------------------------------------------------ |
|
|
169
|
+
| `patterns` | Required | Array of Markdown globs relative to `root`. Supports negative globs. |
|
|
170
|
+
| `exclude` | `[]` | Excluded globs relative to `root`. Exclusions take precedence. |
|
|
171
|
+
| `root` | `..` | Content root relative to the Storybook config directory. |
|
|
172
|
+
| `generatedDir` | `storybook-markdown-generated` | Visible folder name under the working directory. |
|
|
173
|
+
| `stylesheet` | None | CSS file relative to `root`, loaded for documentation pages. |
|
|
174
|
+
| `presentation` | None | Module relative to `root`, exporting `Layout` and/or `MarkdownRenderer`. |
|
|
175
|
+
|
|
176
|
+
Keep the Storybook config directory inside `root`. Restart Storybook after changing addon options.
|
|
177
|
+
|
|
178
|
+
### Generated Files
|
|
179
|
+
|
|
180
|
+
The addon creates a disposable subdirectory per configuration, registers its MDX glob before indexing, and removes obsolete files. Ignore your configured `generatedDir` in Git and leave its contents to the addon.
|
|
181
|
+
|
|
182
|
+
The folder must be a visible name containing letters, digits, hyphens, or underscores. Leading-dot paths and `node_modules` interfere with Storybook 10.6’s watcher; nested paths and `storybook-static` are also rejected.
|
|
183
|
+
|
|
184
|
+
### Sidebar Order
|
|
185
|
+
|
|
186
|
+
Generated filenames are opaque identifiers. Set Storybook’s `parameters.options.storySort` when sidebar order matters. The [example preview] puts Guides first and sorts component titles alphabetically.
|
|
187
|
+
|
|
188
|
+
## Styling
|
|
189
|
+
|
|
190
|
+
The default presentation uses native Storybook Docs blocks and one shared stylesheet. Existing `parameters.docs.container` and `parameters.docs.theme` still apply.
|
|
191
|
+
|
|
192
|
+
### CSS Variables
|
|
193
|
+
|
|
194
|
+
Set `stylesheet: '.storybook/markdown.css'` in the addon options, then define your overrides:
|
|
195
|
+
|
|
196
|
+
```css
|
|
197
|
+
.storybook-addon-md-page {
|
|
198
|
+
--sbmd-font-size: 16px;
|
|
199
|
+
--sbmd-line-height: 1.8;
|
|
200
|
+
--sbmd-heading-color: currentColor;
|
|
201
|
+
--sbmd-tag-radius: 6px;
|
|
202
|
+
--sbmd-tag-border: 1px solid currentColor;
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Variables cover typography, spacing, links, code, tables, images, and chips. They inherit from your theme container, and default text and link colors follow the active Docs theme. See the [CSS variable reference](STYLING.md) for the complete list.
|
|
207
|
+
|
|
208
|
+
Use ordinary CSS for other properties. `.storybook-addon-md` wraps Markdown content, including custom renderer output; titles, props, and examples sit outside it. Other stable selectors are `.storybook-addon-md-page`, `.storybook-addon-md-title`, `.storybook-addon-md-tags`, and `.storybook-addon-md-tag`.
|
|
209
|
+
|
|
210
|
+
The stylesheet is global to the preview, so scope selectors and account for Storybook’s specificity. For example, use `.sbdocs-content .storybook-addon-md h2` when overriding its heading rules. Vite handles CSS edits, imports, and relative `url()` assets.
|
|
211
|
+
|
|
212
|
+
### Status Chips
|
|
213
|
+
|
|
214
|
+
Status chips share the tag variables. Use `data-status` to map values to your theme:
|
|
215
|
+
|
|
216
|
+
```css
|
|
217
|
+
.storybook-addon-md-tag[data-status='stable' i] {
|
|
218
|
+
--sbmd-tag-color: light-dark(#1a7f37, #3fb950);
|
|
219
|
+
--sbmd-tag-background: light-dark(#dafbe1, #12261e);
|
|
220
|
+
--sbmd-tag-border: 1px solid currentColor;
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
The `i` flag matches both `Stable` and `stable`. The addon accepts any status; your stylesheet decides its colors. Set `color-scheme: light dark` on the theme container when using `light-dark()`.
|
|
225
|
+
|
|
226
|
+
### Light and Dark Themes
|
|
227
|
+
|
|
228
|
+
Use Storybook’s standard Docs theme configuration for a fixed theme:
|
|
229
|
+
|
|
230
|
+
```ts
|
|
231
|
+
import { themes } from 'storybook/theming';
|
|
232
|
+
|
|
233
|
+
export default {
|
|
234
|
+
parameters: { docs: { theme: themes.dark } },
|
|
235
|
+
};
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
For live system-preference switching, follow the example’s [Docs container] and [manager configuration]. They subscribe to preference changes so Storybook’s interface and documentation update together without reloading.
|
|
239
|
+
|
|
240
|
+
### Custom Layouts and Renderers
|
|
241
|
+
|
|
242
|
+
Set `presentation: '.storybook/markdown-presentation.tsx'` and export either or both components:
|
|
243
|
+
|
|
244
|
+
```tsx
|
|
245
|
+
import { DefaultLayout, DefaultMarkdownRenderer } from 'storybook-addon-md/runtime';
|
|
246
|
+
import type { LayoutProps, MarkdownDocument } from 'storybook-addon-md/runtime';
|
|
247
|
+
|
|
248
|
+
export function Layout(props: LayoutProps) {
|
|
249
|
+
return <DefaultLayout {...props} />;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export function MarkdownRenderer(document: MarkdownDocument) {
|
|
253
|
+
return <DefaultMarkdownRenderer {...document} />;
|
|
254
|
+
}
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
`MarkdownRenderer` receives `{ markdown, metadata, source }`: processed Markdown with resolved asset URLs, preserved frontmatter, and the source path relative to `root`.
|
|
258
|
+
|
|
259
|
+
`Layout` receives `{ documents, title, attached, children, examples }`. Render `children` and `examples` to keep documentation and native example/props blocks. `examples` is `null` for standalone pages. `title` contains the standalone sidebar title and is empty for attached pages; `DefaultLayout` uses Storybook’s `Title` block for those.
|
|
260
|
+
|
|
261
|
+
Both customization files must stay inside `root`. Missing files produce source-specific errors. Styling and presentation are independent options.
|
|
262
|
+
|
|
263
|
+
## Example
|
|
264
|
+
|
|
265
|
+
Run the included Storybook:
|
|
266
|
+
|
|
267
|
+
```sh
|
|
268
|
+
nub install
|
|
269
|
+
nub run storybook
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Open **Guides → Introduction**, **Components → Button**, or **Components → Toggle** for standalone, attached, and shared documentation.
|
|
273
|
+
|
|
274
|
+
The theme takes its direction from [GitHub Primer]. [Markdown styles] reference [Tailwind theme variables] for shared colors, typography, spacing, and radii. The example uses Tailwind v4, `clsx`, and `class-variance-authority`; these are development dependencies, not addon requirements. Tailwind Preflight is omitted to preserve native Docs styles.
|
|
275
|
+
|
|
276
|
+
Components use `light-dark()` and `color-scheme: light dark` on `:root`. The manager and Docs container also follow system-preference changes live.
|
|
277
|
+
|
|
278
|
+
## Development
|
|
279
|
+
|
|
280
|
+
Install Chromium for the browser suites:
|
|
281
|
+
|
|
282
|
+
```sh
|
|
283
|
+
nub exec playwright install chromium
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
| Command | Purpose |
|
|
287
|
+
| ------------------------- | ------------------------------------------------------------- |
|
|
288
|
+
| `nub run build` | Compile the addon and its declarations. |
|
|
289
|
+
| `nub run check` | Build the addon, then type-check source, examples, and tests. |
|
|
290
|
+
| `nub run lint` | Run Oxlint. Use `lint:fix` for automatic fixes. |
|
|
291
|
+
| `nub run format:check` | Check Oxfmt formatting. Use `format` to write changes. |
|
|
292
|
+
| `nub run test` | Run Vitest unit tests. |
|
|
293
|
+
| `nub run test:browser` | Run Vitest Browser Mode with Playwright/Chromium. |
|
|
294
|
+
| `nub run test:e2e` | Verify development and static Storybooks in Chromium. |
|
|
295
|
+
| `nub run test:package` | Install and verify a packed addon in an isolated consumer. |
|
|
296
|
+
| `nub run build-storybook` | Build the example as a static site. |
|
|
297
|
+
| `nub pack` | Build and package the addon. |
|
|
298
|
+
|
|
299
|
+
Use `test:watch` or `test:browser:watch` while developing. End-to-end tests use ports 16006/16007, and the package smoke check uses 16008. Browser screenshots and failure traces go to `test-results/`.
|
|
300
|
+
|
|
301
|
+
[CI] runs the checks on Node 24 and Linux, including a dependency audit. Tests cover discovery, associations, watcher recovery, assets, customization, keyboard interaction, and live theme switching. The package smoke check supplies its own image fixture.
|
|
302
|
+
|
|
303
|
+
Content parsing lives in `src/content.ts`, disposable generation in `src/generator.ts`, Storybook integration in `src/preset.ts`, and presentation in `src/runtime.tsx`. The addon uses Storybook’s MDX compilation and indexing; it does not install a custom indexer.
|
|
304
|
+
|
|
305
|
+
Report reproducible bugs in the [issue tracker].
|
|
306
|
+
|
|
307
|
+
## Releasing
|
|
308
|
+
|
|
309
|
+
Releases use [Changesets](https://changesets.dev/guide/automating). For a user-facing change, run `nub run changeset`, choose a patch/minor/major bump, and include the generated release note in your PR. Tooling-only changes do not need a release note.
|
|
310
|
+
|
|
311
|
+
After CI passes for a push to `main`, `release.yml` opens or updates a release PR with the version and changelog. Merge that PR to publish after CI passes again. Nub manages dependencies and scripts; Changesets invokes npm for publishing.
|
|
312
|
+
|
|
313
|
+
One-time setup:
|
|
314
|
+
|
|
315
|
+
1. If the package does not exist on npm yet, publish the initial version from a clean checkout: `nub run build`, `npm login`, then `npm publish --access public`.
|
|
316
|
+
2. In the npm package’s **Settings → Trusted publishing**, select GitHub Actions, owner `ruijdacd`, repository `storybook-addon-md`, workflow `release.yml`, and allow publishing. Leave the environment empty.
|
|
317
|
+
3. In GitHub’s **Settings → Actions → General**, enable **Allow GitHub Actions to create and approve pull requests**.
|
|
318
|
+
|
|
319
|
+
No `NPM_TOKEN` secret is needed. The workflow uses GitHub’s automatic token for release PRs and OIDC for [npm trusted publishing](https://docs.npmjs.com/trusted-publishers/). It installs npm 11 with Node 24 to support OIDC.
|
|
320
|
+
|
|
321
|
+
Release PRs created with the automatic GitHub token do not trigger PR workflows. If branch protection requires those checks, close and reopen the release PR yourself to trigger CI before merging. The release workflow always waits for CI on the merged commit.
|
|
322
|
+
|
|
323
|
+
## Limitations
|
|
324
|
+
|
|
325
|
+
- Only the Storybook, React, and Vite setup listed under [Install](#install) has been tested. Other renderers and builders are unsupported.
|
|
326
|
+
- Markdown supports tables, lists, fenced code, and reference links. Braces and JSX-like text are content, never evaluated. The default renderer displays raw HTML as text; use Markdown syntax for links and images.
|
|
327
|
+
- The **Markdown** page name is reserved under attached components. Avoid giving a hand-written MDX page the same name there.
|
|
328
|
+
- The watcher observes `root` and rescans matching Markdown when documentation or its dependencies change. Interactive story state may reset. Keep `root` focused on your project.
|
|
329
|
+
- Large monorepos, simultaneous Storybooks sharing one config directory, symlinked content directories, and MDX authoring are outside the initial scope.
|
|
330
|
+
|
|
331
|
+
[example preview]: https://github.com/ruijdacd/storybook-addon-md/blob/main/example/.storybook/preview.ts
|
|
332
|
+
[Docs container]: https://github.com/ruijdacd/storybook-addon-md/blob/main/example/.storybook/SystemDocsContainer.tsx
|
|
333
|
+
[manager configuration]: https://github.com/ruijdacd/storybook-addon-md/blob/main/example/.storybook/manager.ts
|
|
334
|
+
[GitHub Primer]: https://primer.style/product/
|
|
335
|
+
[Markdown styles]: https://github.com/ruijdacd/storybook-addon-md/blob/main/example/.storybook/markdown.css
|
|
336
|
+
[Tailwind theme variables]: https://github.com/ruijdacd/storybook-addon-md/blob/main/example/.storybook/tailwind.css
|
|
337
|
+
[CI]: https://github.com/ruijdacd/storybook-addon-md/actions/workflows/ci.yml
|
|
338
|
+
[issue tracker]: https://github.com/ruijdacd/storybook-addon-md/issues
|
package/STYLING.md
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# CSS variable reference
|
|
2
|
+
|
|
3
|
+
Set these variables on `.storybook-addon-md-page` in the file configured by `stylesheet`. All are optional. The shared addon stylesheet supplies defaults, with text, links, borders, and inline-code backgrounds taken from the active Storybook Docs theme.
|
|
4
|
+
|
|
5
|
+
```css
|
|
6
|
+
.storybook-addon-md-page {
|
|
7
|
+
--sbmd-font-size: 16px;
|
|
8
|
+
--sbmd-h2-size: 26px;
|
|
9
|
+
--sbmd-paragraph-spacing: 20px;
|
|
10
|
+
--sbmd-quote-border: 3px solid currentColor;
|
|
11
|
+
--sbmd-quote-radius: 8px;
|
|
12
|
+
--sbmd-table-cell-padding: 12px 16px;
|
|
13
|
+
--sbmd-tag-radius: 6px;
|
|
14
|
+
}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Variables accept normal CSS values for the property listed below, including `clamp()`, `calc()`, and references to your own theme variables. Border variables accept full border shorthands. Heading margins set space above the heading; title margin sets space below it. Paragraph spacing also applies to lists. Tag margin sets space below the chip list.
|
|
18
|
+
|
|
19
|
+
Use your theme selector to override colors in dark mode. The [complete example](https://github.com/ruijdacd/storybook-addon-md/blob/main/example/.storybook/markdown.css) maps the addon variables to Tailwind v4 theme variables. Its `light-dark()` colors follow the system preference.
|
|
20
|
+
|
|
21
|
+
| Variable | CSS property |
|
|
22
|
+
| --------------------------------- | --------------------------- |
|
|
23
|
+
| `--sbmd-background` | `background` |
|
|
24
|
+
| `--sbmd-checkbox-color` | `accent-color` |
|
|
25
|
+
| `--sbmd-checkbox-gap` | `margin-inline-end` |
|
|
26
|
+
| `--sbmd-code-border` | `border` |
|
|
27
|
+
| `--sbmd-code-padding` | `padding` |
|
|
28
|
+
| `--sbmd-code-radius` | `border-radius` |
|
|
29
|
+
| `--sbmd-color` | `color` |
|
|
30
|
+
| `--sbmd-font-family` | `font-family` |
|
|
31
|
+
| `--sbmd-font-size` | `font-size` |
|
|
32
|
+
| `--sbmd-h1-size` | `font-size` |
|
|
33
|
+
| `--sbmd-h2-border` | `border-bottom` |
|
|
34
|
+
| `--sbmd-h2-letter-spacing` | `letter-spacing` |
|
|
35
|
+
| `--sbmd-h2-margin` | `margin-top` |
|
|
36
|
+
| `--sbmd-h2-padding` | `padding-bottom` |
|
|
37
|
+
| `--sbmd-h2-size` | `font-size` |
|
|
38
|
+
| `--sbmd-h3-letter-spacing` | `letter-spacing` |
|
|
39
|
+
| `--sbmd-h3-margin` | `margin-top` |
|
|
40
|
+
| `--sbmd-h3-size` | `font-size` |
|
|
41
|
+
| `--sbmd-h4-size` | `font-size` |
|
|
42
|
+
| `--sbmd-h5-size` | `font-size` |
|
|
43
|
+
| `--sbmd-h6-size` | `font-size` |
|
|
44
|
+
| `--sbmd-heading-color` | `color` |
|
|
45
|
+
| `--sbmd-heading-font-family` | `font-family` |
|
|
46
|
+
| `--sbmd-heading-line-height` | `line-height` |
|
|
47
|
+
| `--sbmd-heading-weight` | `font-weight` |
|
|
48
|
+
| `--sbmd-image-border` | `border` |
|
|
49
|
+
| `--sbmd-image-margin` | `margin-block` |
|
|
50
|
+
| `--sbmd-image-radius` | `border-radius` |
|
|
51
|
+
| `--sbmd-inline-code-background` | `background` |
|
|
52
|
+
| `--sbmd-inline-code-border` | `border` |
|
|
53
|
+
| `--sbmd-inline-code-color` | `color` |
|
|
54
|
+
| `--sbmd-inline-code-padding` | `padding` |
|
|
55
|
+
| `--sbmd-inline-code-radius` | `border-radius` |
|
|
56
|
+
| `--sbmd-inline-code-size` | `font-size` |
|
|
57
|
+
| `--sbmd-line-height` | `line-height` |
|
|
58
|
+
| `--sbmd-link-color` | `color` |
|
|
59
|
+
| `--sbmd-link-decoration` | `text-decoration` |
|
|
60
|
+
| `--sbmd-link-focus-offset` | `outline-offset` |
|
|
61
|
+
| `--sbmd-link-focus-outline` | `outline` |
|
|
62
|
+
| `--sbmd-link-hover-thickness` | `text-decoration-thickness` |
|
|
63
|
+
| `--sbmd-link-radius` | `border-radius` |
|
|
64
|
+
| `--sbmd-link-thickness` | `text-decoration-thickness` |
|
|
65
|
+
| `--sbmd-link-underline-offset` | `text-underline-offset` |
|
|
66
|
+
| `--sbmd-list-item-spacing` | `margin-top` |
|
|
67
|
+
| `--sbmd-list-marker-color` | `color` |
|
|
68
|
+
| `--sbmd-max-width` | `max-width` |
|
|
69
|
+
| `--sbmd-page-border` | `border` |
|
|
70
|
+
| `--sbmd-page-padding` | `padding` |
|
|
71
|
+
| `--sbmd-page-radius` | `border-radius` |
|
|
72
|
+
| `--sbmd-paragraph-spacing` | `margin-block` |
|
|
73
|
+
| `--sbmd-quote-background` | `background` |
|
|
74
|
+
| `--sbmd-quote-border` | `border-inline-start` |
|
|
75
|
+
| `--sbmd-quote-margin` | `margin` |
|
|
76
|
+
| `--sbmd-quote-padding` | `padding` |
|
|
77
|
+
| `--sbmd-quote-radius` | `border-radius` |
|
|
78
|
+
| `--sbmd-rule-color` | `background` |
|
|
79
|
+
| `--sbmd-rule-height` | `height` |
|
|
80
|
+
| `--sbmd-rule-margin` | `margin-block` |
|
|
81
|
+
| `--sbmd-table-align` | `text-align` |
|
|
82
|
+
| `--sbmd-table-background` | `background` |
|
|
83
|
+
| `--sbmd-table-border` | `border` |
|
|
84
|
+
| `--sbmd-table-cell-padding` | `padding` |
|
|
85
|
+
| `--sbmd-table-heading-background` | `background` |
|
|
86
|
+
| `--sbmd-table-heading-weight` | `font-weight` |
|
|
87
|
+
| `--sbmd-table-margin` | `margin-block` |
|
|
88
|
+
| `--sbmd-table-stripe-background` | `background` |
|
|
89
|
+
| `--sbmd-tag-background` | `background` |
|
|
90
|
+
| `--sbmd-tag-border` | `border` |
|
|
91
|
+
| `--sbmd-tag-color` | `color` |
|
|
92
|
+
| `--sbmd-tag-font-size` | `font-size` |
|
|
93
|
+
| `--sbmd-tag-font-weight` | `font-weight` |
|
|
94
|
+
| `--sbmd-tag-gap` | `gap` |
|
|
95
|
+
| `--sbmd-tag-line-height` | `line-height` |
|
|
96
|
+
| `--sbmd-tag-padding` | `padding` |
|
|
97
|
+
| `--sbmd-tag-radius` | `border-radius` |
|
|
98
|
+
| `--sbmd-title-letter-spacing` | `letter-spacing` |
|
|
99
|
+
| `--sbmd-title-line-height` | `line-height` |
|
|
100
|
+
| `--sbmd-title-margin` | `margin-bottom` |
|
|
101
|
+
| `--sbmd-title-size` | `font-size` |
|
|
102
|
+
|
|
103
|
+
Status chips have `data-status` set to the original frontmatter value. Override `--sbmd-tag-*` on selectors such as `.storybook-addon-md-tag[data-status="stable" i]` to assign a status-specific appearance.
|
|
104
|
+
|
|
105
|
+
These styles target Markdown content and its title/chips. Story canvases, props controls, and syntax highlighting still use Storybook’s theme. Custom renderers can use the shared styles when they produce matching HTML elements; custom layouts own any additional structure. Internal `--sbmd-native-*` variables carry Storybook theme values and are not customization hooks.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { MarkdownOptions } from './index.js';
|
|
2
|
+
export interface ContentOptions extends MarkdownOptions {
|
|
3
|
+
root: string;
|
|
4
|
+
output: string;
|
|
5
|
+
}
|
|
6
|
+
export interface Frontmatter extends Record<string, unknown> {
|
|
7
|
+
title?: string;
|
|
8
|
+
stories?: string | string[];
|
|
9
|
+
tags?: string[];
|
|
10
|
+
status?: string;
|
|
11
|
+
}
|
|
12
|
+
export type DiscoveredDocument = Awaited<ReturnType<typeof discover>>[number];
|
|
13
|
+
export declare const slash: (value: string) => string;
|
|
14
|
+
export declare const fail: (source: string, message: string) => Error;
|
|
15
|
+
export declare function localFile(file: string, root: string, source: string, kind: string): Promise<string>;
|
|
16
|
+
export declare function parseMarkdown(text: string, source: string): {
|
|
17
|
+
body: string;
|
|
18
|
+
metadata: Frontmatter;
|
|
19
|
+
};
|
|
20
|
+
export declare function resolveAssets(body: string, file: string, root: string): Promise<{
|
|
21
|
+
markdown: string;
|
|
22
|
+
assets: {
|
|
23
|
+
file: string;
|
|
24
|
+
suffix: string;
|
|
25
|
+
token: string;
|
|
26
|
+
}[];
|
|
27
|
+
}>;
|
|
28
|
+
export declare function discover({ root, patterns, exclude, output }: ContentOptions): Promise<{
|
|
29
|
+
markdown: string;
|
|
30
|
+
assets: {
|
|
31
|
+
file: string;
|
|
32
|
+
suffix: string;
|
|
33
|
+
token: string;
|
|
34
|
+
}[];
|
|
35
|
+
file: string;
|
|
36
|
+
source: string;
|
|
37
|
+
title: string;
|
|
38
|
+
metadata: Frontmatter;
|
|
39
|
+
stories: string[];
|
|
40
|
+
}[]>;
|