storybook-addon-md 0.4.0 → 0.5.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 CHANGED
@@ -1,10 +1,18 @@
1
1
  # storybook-addon-md
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 76c1a71: Render GitHub-style alerts (`> [!NOTE]`, `[!TIP]`, `[!IMPORTANT]`, `[!WARNING]`, and `[!CAUTION]`) as labelled callouts in Docs. Ordinary blockquotes and unrecognized markers are unchanged, Markdown and relative assets inside callouts keep working, and manifests keep the original source.
8
+
9
+ Style callouts with the new `--sbmd-callout-*` variables, including per-type accent colors, or target `.storybook-addon-md-callout[data-callout]`. Custom `MarkdownRenderer` implementations receive the original blockquote syntax and must render callouts themselves. See the [callout syntax](https://github.com/ruijdacd/storybook-addon-md#callouts) and [styling reference](https://github.com/ruijdacd/storybook-addon-md/blob/main/STYLING.md#callouts).
10
+
3
11
  ## 0.4.0
4
12
 
5
13
  ### Minor Changes
6
14
 
7
- - df081eb: Respect `docs.defaultName`, use leading H1s as standalone titles, and add `tagFields` and the `storybook-addon-md/node` parsing API. Markdown pages retain props, examples, and original manifest source.
15
+ - 8bf5398: Respect `docs.defaultName`, use leading H1s as standalone titles, and add `tagFields` and the `storybook-addon-md/node` parsing API. Markdown pages retain props, examples, and original manifest source.
8
16
 
9
17
  Migration: update attached links from `--markdown` to `--docs` (or the configured name), enable Autodocs in preview-level tags, and render the supplied `heading` in custom layouts. MCP component IDs are unchanged.
10
18
 
@@ -12,19 +20,19 @@
12
20
 
13
21
  ### Minor Changes
14
22
 
15
- - 209fe53: Add opt-in documentation manifests with original Markdown, frontmatter summaries, and live updates for standalone and attached docs. Enable `manifests: true` to use [Storybook 10.6.0 manifests](https://storybook.js.org/docs/ai/manifests) and [@storybook/addon-mcp](https://storybook.js.org/docs/ai/mcp/overview) without a custom preset.
23
+ - 2052cb5: Add opt-in documentation manifests with original Markdown, frontmatter summaries, and live updates for standalone and attached docs. Enable `manifests: true` to use [Storybook 10.6.0 manifests](https://storybook.js.org/docs/ai/manifests) and [@storybook/addon-mcp](https://storybook.js.org/docs/ai/mcp/overview) without a custom preset.
16
24
 
17
25
  See the [setup guide](https://github.com/ruijdacd/storybook-addon-md#documentation-manifests-and-mcp) and [examples with and without MCP](https://github.com/ruijdacd/storybook-addon-md#examples-and-contributing).
18
26
 
19
27
  ### Patch Changes
20
28
 
21
- - a94853e: Use rem values for default Markdown styles so they scale with the root font size. Add `--sbmd-monospace-font-family` to customize inline code and code blocks, with Storybook’s monospace theme font as the default. See the [CSS variable reference](https://github.com/ruijdacd/storybook-addon-md/blob/main/STYLING.md).
29
+ - d3c7300: Use rem values for default Markdown styles so they scale with the root font size. Add `--sbmd-monospace-font-family` to customize inline code and code blocks, with Storybook’s monospace theme font as the default. See the [CSS variable reference](https://github.com/ruijdacd/storybook-addon-md/blob/main/STYLING.md).
22
30
 
23
31
  ## 0.2.0
24
32
 
25
33
  ### Minor Changes
26
34
 
27
- - 58f8a64: Remove the `exclude` option. Move exclusions into `patterns` with a leading `!`:
35
+ - dc93b21: Remove the `exclude` option. Move exclusions into `patterns` with a leading `!`:
28
36
 
29
37
  ```ts
30
38
  patterns: ['docs/**/*.md', '!docs/private/**'];
@@ -34,7 +42,7 @@
34
42
 
35
43
  ### Patch Changes
36
44
 
37
- - 58f8a64: Upgrade Chokidar to v5 and replace fast-glob with tinyglobby. Keep explicit glob matching, negative-pattern exclusions, and live Markdown updates.
45
+ - dc93b21: Upgrade Chokidar to v5 and replace fast-glob with tinyglobby. Keep explicit glob matching, negative-pattern exclusions, and live Markdown updates.
38
46
 
39
47
  ## 0.1.0
40
48
 
package/README.md CHANGED
@@ -1,7 +1,12 @@
1
1
  # Storybook Markdown
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/storybook-addon-md)](https://www.npmjs.com/package/storybook-addon-md)
4
+ [![CI](https://github.com/ruijdacd/storybook-addon-md/actions/workflows/ci.yml/badge.svg)](https://github.com/ruijdacd/storybook-addon-md/actions/workflows/ci.yml)
5
+
3
6
  Write ordinary `.md` files and browse them inside Storybook. Attach documentation to component stories or create standalone pages, with no JSX, imports, or MDX wrappers to maintain.
4
7
 
8
+ [Try the live example](https://storybook-addon-md.netlify.app/?path=/docs/guides-introduction--docs).
9
+
5
10
  - Discover Markdown automatically, including live additions, edits, and deletions.
6
11
  - Show component docs alongside existing examples and generated props.
7
12
  - Bundle relative images and downloads in static builds.
@@ -9,8 +14,10 @@ Write ordinary `.md` files and browse them inside Storybook. Attach documentatio
9
14
 
10
15
  ## Install
11
16
 
17
+ We recommend [ni](https://github.com/antfu-collective/ni#readme) to install dependencies with your project's package manager. Install it first with `npm install -g @antfu/ni`, then run:
18
+
12
19
  ```sh
13
- nub add -D storybook-addon-md @storybook/addon-docs@10.6.0
20
+ ni -D storybook-addon-md @storybook/addon-docs@10.6.0
14
21
  ```
15
22
 
16
23
  Tested with **Storybook 10.6.0**, **React Vite 10.6.0**, **Vite 7.3.6**, and **React 19.2.4**. Requires Node 22.13+. Other builders and renderers are not tested.
@@ -103,6 +110,29 @@ Without a title, `docs/Introduction.md` appears at `Documentation/docs/Introduct
103
110
 
104
111
  A leading Markdown H1 supplies the visible title, including inline formatting. Otherwise the final segment of `title` is shown. Both `# Heading` and Setext H1 syntax work; a later H1 is ordinary content. Sidebar placement and IDs always use the configured or inferred sidebar title. The original file and manifest content remain unchanged.
105
112
 
113
+ ### Callouts
114
+
115
+ GitHub-style alerts render as labelled callouts:
116
+
117
+ ```md
118
+ > [!NOTE]
119
+ > Additional context.
120
+
121
+ > [!TIP]
122
+ > Recommended approach.
123
+
124
+ > [!IMPORTANT]
125
+ > Information readers need to succeed.
126
+
127
+ > [!WARNING]
128
+ > Something that requires care.
129
+
130
+ > [!CAUTION]
131
+ > A risk or destructive consequence.
132
+ ```
133
+
134
+ The marker must be the first line of a blockquote, on its own, and is case-insensitive. Callouts keep ordinary Markdown, including paragraphs, emphasis, links, lists, and code blocks, and relative links and images inside them resolve as usual. Blockquotes without a marker, unrecognized markers, and markers followed by text on the same line render as ordinary blockquotes. Custom titles and collapsible callouts are not supported. Source files and manifests keep the original syntax.
135
+
106
136
  ### Frontmatter
107
137
 
108
138
  YAML frontmatter is optional. Use lowercase field names.
@@ -225,9 +255,9 @@ Set `stylesheet: '.storybook/markdown.css'` to override the defaults:
225
255
  }
226
256
  ```
227
257
 
228
- Variables cover typography, spacing, links, code, tables, images, and chips. Defaults follow Storybook’s Docs theme in light and dark mode.
258
+ Variables cover typography, spacing, links, code, tables, images, chips, and callouts. Defaults follow Storybook’s Docs theme in light and dark mode.
229
259
 
230
- See [Styling](STYLING.md) for all variables, status colors, theme switching, and custom layouts or Markdown renderers. The [example stylesheet](https://github.com/ruijdacd/storybook-addon-md/blob/main/example/.storybook/markdown.css) provides a complete GitHub-inspired theme.
260
+ See [Styling](STYLING.md) for all variables, status and callout colors, theme switching, and custom layouts or Markdown renderers. The [example stylesheet](https://github.com/ruijdacd/storybook-addon-md/blob/main/example/.storybook/markdown.css) provides a complete GitHub-inspired theme.
231
261
 
232
262
  ## Links and limitations
233
263
 
@@ -254,6 +284,6 @@ Choose either example. They share stories, Markdown, and styling, with separate
254
284
 
255
285
  The MCP example enables `manifests: true` and `@storybook/addon-mcp`. Connect your MCP client to `http://localhost:6007/mcp`. Static builds write to `storybook-static/` and `storybook-static-mcp/`, respectively. MCP is a development dependency for the example only; normal addon usage does not require it.
256
286
 
257
- Browse **Guides → Introduction**, **Components → Button**, and **Components → Toggle** for standalone, attached, and shared docs with system light/dark styling.
287
+ Browse **Guides → Introduction**, **Guides → Callouts**, **Components → Button**, and **Components → Toggle** for standalone, attached, and shared docs with system light/dark styling.
258
288
 
259
289
  See [Contributing](CONTRIBUTING.md) for tests and releases, or [open an issue](https://github.com/ruijdacd/storybook-addon-md/issues).
package/STYLING.md CHANGED
@@ -24,6 +24,21 @@ Use your theme selector to override colors in dark mode. The [complete example](
24
24
  | Variable | CSS property |
25
25
  | --------------------------------- | ----------------------------- |
26
26
  | `--sbmd-background` | `background` |
27
+ | `--sbmd-callout-background` | `background` |
28
+ | `--sbmd-callout-border` | `border-inline-start` |
29
+ | `--sbmd-callout-caution-color` | Caution accent color |
30
+ | `--sbmd-callout-color` | `color` |
31
+ | `--sbmd-callout-important-color` | Important accent color |
32
+ | `--sbmd-callout-label-color` | `color` |
33
+ | `--sbmd-callout-label-margin` | `margin-bottom` |
34
+ | `--sbmd-callout-label-size` | `font-size` |
35
+ | `--sbmd-callout-label-weight` | `font-weight` |
36
+ | `--sbmd-callout-margin` | `margin` |
37
+ | `--sbmd-callout-note-color` | Note accent color |
38
+ | `--sbmd-callout-padding` | `padding` |
39
+ | `--sbmd-callout-radius` | `border-radius` |
40
+ | `--sbmd-callout-tip-color` | Tip accent color |
41
+ | `--sbmd-callout-warning-color` | Warning accent color |
27
42
  | `--sbmd-checkbox-color` | `accent-color` |
28
43
  | `--sbmd-checkbox-gap` | `margin-inline-end` |
29
44
  | `--sbmd-code-border` | `border` |
@@ -106,6 +121,8 @@ Use your theme selector to override colors in dark mode. The [complete example](
106
121
 
107
122
  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.
108
123
 
124
+ Callouts are `.storybook-addon-md-callout` elements with `data-callout` set to `note`, `tip`, `important`, `warning`, or `caution`, and a `.storybook-addon-md-callout-label` paragraph. Each type’s accent color sets the default border color and label color. Per-type accent variables default to Storybook theme colors chosen for the light or dark base. `--sbmd-callout-color` applies to text inside callouts; `--sbmd-callout-border` and `--sbmd-callout-label-color` replace the accent for every type.
125
+
109
126
  These styles target Markdown content and its title/chips. Story canvases, props controls, and syntax-highlighting colors 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.
110
127
 
111
128
  ## Customization
@@ -147,6 +164,34 @@ Status chips share the tag variables. Use `data-status` to map values to your th
147
164
 
148
165
  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()`.
149
166
 
167
+ ### Callouts
168
+
169
+ Map the accent colors to your design tokens, and adjust the shared box and label styles:
170
+
171
+ ```css
172
+ .storybook-addon-md-page {
173
+ --sbmd-callout-note-color: light-dark(#0969da, #4493f8);
174
+ --sbmd-callout-tip-color: light-dark(#1a7f37, #3fb950);
175
+ --sbmd-callout-important-color: light-dark(#8250df, #ab7df8);
176
+ --sbmd-callout-warning-color: light-dark(#9a6700, #d29922);
177
+ --sbmd-callout-caution-color: light-dark(#d1242f, #f85149);
178
+ --sbmd-callout-padding: 0.5rem 1rem;
179
+ --sbmd-callout-radius: 0.375rem;
180
+ --sbmd-callout-label-weight: 500;
181
+ }
182
+ ```
183
+
184
+ Use `data-callout` for anything that differs per type beyond the accent color, such as a tinted background or a different border width:
185
+
186
+ ```css
187
+ .storybook-addon-md-callout[data-callout='caution'] {
188
+ --sbmd-callout-background: light-dark(#ffebe9, #2d1214);
189
+ --sbmd-callout-border: 0.375rem solid var(--sbmd-callout-caution-color);
190
+ }
191
+ ```
192
+
193
+ The label is visible text, so callouts remain distinguishable without color. The markup is static: no `role="alert"` or live region is used.
194
+
150
195
  ### Light and Dark Themes
151
196
 
152
197
  Use Storybook’s standard Docs theme configuration for a fixed theme:
@@ -180,6 +225,8 @@ export function MarkdownRenderer(document: MarkdownDocument) {
180
225
 
181
226
  `MarkdownRenderer` receives `{ markdown, metadata, source, heading? }`: processed Markdown with resolved asset URLs, preserved frontmatter, and the source path relative to the project folder.
182
227
 
228
+ Callouts are rendered by `DefaultMarkdownRenderer`. A custom `MarkdownRenderer` receives them as ordinary blockquotes whose first line is the `[!NOTE]` marker, serialized as `\[!NOTE]` so that renderers treat the brackets as text. Render callouts yourself or delegate to `DefaultMarkdownRenderer`. Custom layouts are unaffected because callouts are part of `children`.
229
+
183
230
  `Layout` receives `{ documents, title, attached, children, examples, heading, tagFields }`. A standalone leading H1 is extracted in the default pipeline and supplied as the rendered `heading` node; render it instead of your fallback title. The remaining Markdown is supplied through `children`, while source files and manifests stay intact. `tagFields` lists configured metadata fields for tag display. 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.
184
231
 
185
232
  Customization paths are relative to the project folder and must stay inside it. Missing files produce source-specific errors. Styling and presentation are independent options.
package/dist/runtime.js CHANGED
@@ -1,7 +1,39 @@
1
+ import { Children, cloneElement, isValidElement } from "react";
1
2
  import { useTheme } from "storybook/theming";
2
3
  import { CodeOrSourceMdx, Controls, HeadersMdx, Markdown, Primary, Stories, Title } from "@storybook/addon-docs/blocks";
3
4
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
5
  //#region src/runtime.tsx
6
+ const calloutLabels = {
7
+ note: "Note",
8
+ tip: "Tip",
9
+ important: "Important",
10
+ warning: "Warning",
11
+ caution: "Caution"
12
+ };
13
+ function Blockquote({ children, ...props }) {
14
+ const [first, ...rest] = Children.toArray(children);
15
+ const paragraph = isValidElement(first) && first.type === "p" ? first : void 0;
16
+ const items = Children.toArray(paragraph?.props.children);
17
+ const split = items.findIndex((item) => typeof item !== "string");
18
+ const leading = items.slice(0, split === -1 ? items.length : split).join("");
19
+ const marker = /^\[!(note|tip|important|warning|caution)\](\n|$)/i.exec(leading);
20
+ if (!paragraph || !marker || !marker[2] && split !== -1) return /* @__PURE__ */ jsx("blockquote", {
21
+ ...props,
22
+ children
23
+ });
24
+ const type = marker[1].toLowerCase();
25
+ const remainder = leading.slice(marker[0].length);
26
+ const trailing = split === -1 ? [] : items.slice(split);
27
+ const content = remainder || trailing.length ? [cloneElement(paragraph, void 0, ...remainder ? [remainder] : [], ...trailing), ...rest] : rest;
28
+ return /* @__PURE__ */ jsxs("div", {
29
+ className: "storybook-addon-md-callout",
30
+ "data-callout": type,
31
+ children: [/* @__PURE__ */ jsx("p", {
32
+ className: "storybook-addon-md-callout-label",
33
+ children: calloutLabels[type]
34
+ }), content]
35
+ });
36
+ }
5
37
  function DefaultMarkdownRenderer({ markdown }) {
6
38
  return /* @__PURE__ */ jsx(Markdown, {
7
39
  options: {
@@ -9,7 +41,8 @@ function DefaultMarkdownRenderer({ markdown }) {
9
41
  overrides: {
10
42
  code: CodeOrSourceMdx,
11
43
  ...HeadersMdx,
12
- a: "a"
44
+ a: "a",
45
+ blockquote: Blockquote
13
46
  }
14
47
  },
15
48
  children: markdown
@@ -44,13 +77,19 @@ function DefaultLayout({ documents, title, attached, children, examples, heading
44
77
  }
45
78
  function Documentation({ documents, title, attached = false, presentation = {}, tagFields = [] }) {
46
79
  const theme = useTheme();
80
+ const dark = theme.base === "dark";
47
81
  const defaults = {
48
82
  "--sbmd-native-color": theme.color.defaultText,
49
83
  "--sbmd-native-link-color": theme.color.secondary,
50
84
  "--sbmd-native-font-family": theme.typography.fonts.base,
51
85
  "--sbmd-native-monospace-font-family": theme.typography.fonts.mono,
52
86
  "--sbmd-native-border-color": theme.appBorderColor,
53
- "--sbmd-native-code-background": theme.background.content
87
+ "--sbmd-native-code-background": theme.background.content,
88
+ "--sbmd-native-callout-note-color": theme.color.secondary,
89
+ "--sbmd-native-callout-tip-color": dark ? theme.color.positive : theme.color.positiveText,
90
+ "--sbmd-native-callout-important-color": dark ? `color-mix(in srgb, ${theme.color.purple}, white 45%)` : theme.color.purple,
91
+ "--sbmd-native-callout-warning-color": dark ? theme.color.warning : theme.color.warningText,
92
+ "--sbmd-native-callout-caution-color": dark ? theme.color.negative : theme.color.negativeText
54
93
  };
55
94
  const Layout = presentation.Layout ?? DefaultLayout;
56
95
  const Renderer = presentation.MarkdownRenderer ?? DefaultMarkdownRenderer;
package/dist/styles.css CHANGED
@@ -109,6 +109,65 @@
109
109
  background: var(--sbmd-quote-background, transparent);
110
110
  }
111
111
 
112
+ .sbdocs-content .storybook-addon-md-callout {
113
+ margin: var(--sbmd-callout-margin, 1rem 0);
114
+ padding: var(--sbmd-callout-padding, 0.5rem 1rem);
115
+ border-inline-start: var(--sbmd-callout-border, 0.25rem solid var(--sbmd-native-callout-color));
116
+ border-radius: var(--sbmd-callout-radius, 0);
117
+ background: var(--sbmd-callout-background, transparent);
118
+ }
119
+
120
+ .sbdocs-content .storybook-addon-md-callout[data-callout='note'] {
121
+ --sbmd-native-callout-color: var(
122
+ --sbmd-callout-note-color,
123
+ var(--sbmd-native-callout-note-color)
124
+ );
125
+ }
126
+
127
+ .sbdocs-content .storybook-addon-md-callout[data-callout='tip'] {
128
+ --sbmd-native-callout-color: var(--sbmd-callout-tip-color, var(--sbmd-native-callout-tip-color));
129
+ }
130
+
131
+ .sbdocs-content .storybook-addon-md-callout[data-callout='important'] {
132
+ --sbmd-native-callout-color: var(
133
+ --sbmd-callout-important-color,
134
+ var(--sbmd-native-callout-important-color)
135
+ );
136
+ }
137
+
138
+ .sbdocs-content .storybook-addon-md-callout[data-callout='warning'] {
139
+ --sbmd-native-callout-color: var(
140
+ --sbmd-callout-warning-color,
141
+ var(--sbmd-native-callout-warning-color)
142
+ );
143
+ }
144
+
145
+ .sbdocs-content .storybook-addon-md-callout[data-callout='caution'] {
146
+ --sbmd-native-callout-color: var(
147
+ --sbmd-callout-caution-color,
148
+ var(--sbmd-native-callout-caution-color)
149
+ );
150
+ }
151
+
152
+ .sbdocs-content .storybook-addon-md-callout :is(p, li, td, th) {
153
+ color: var(--sbmd-callout-color, var(--sbmd-color, var(--sbmd-native-color)));
154
+ }
155
+
156
+ .sbdocs-content .storybook-addon-md .storybook-addon-md-callout-label {
157
+ margin: 0 0 var(--sbmd-callout-label-margin, 0.25rem);
158
+ color: var(--sbmd-callout-label-color, var(--sbmd-native-callout-color));
159
+ font-size: var(--sbmd-callout-label-size, var(--sbmd-font-size, 0.875rem));
160
+ font-weight: var(--sbmd-callout-label-weight, 600);
161
+ }
162
+
163
+ .sbdocs-content .storybook-addon-md-callout > .storybook-addon-md-callout-label + * {
164
+ margin-top: 0;
165
+ }
166
+
167
+ .sbdocs-content .storybook-addon-md-callout > :last-child {
168
+ margin-bottom: 0;
169
+ }
170
+
112
171
  .sbdocs-content .storybook-addon-md :not(pre) > code {
113
172
  padding: var(--sbmd-inline-code-padding, 0.1875rem 0.3125rem);
114
173
  border: var(--sbmd-inline-code-border, 0.0625rem solid var(--sbmd-native-border-color));
@@ -174,7 +233,8 @@
174
233
  margin-inline-end: var(--sbmd-checkbox-gap, 0.25rem);
175
234
  }
176
235
 
177
- .sbdocs-content .storybook-addon-md > pre {
236
+ .sbdocs-content .storybook-addon-md > pre,
237
+ .sbdocs-content .storybook-addon-md-callout > pre {
178
238
  padding: 0;
179
239
  border: 0;
180
240
  white-space: normal;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storybook-addon-md",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Discover ordinary Markdown and render it in Storybook Docs.",
5
5
  "keywords": [
6
6
  "docs",
@@ -14,6 +14,7 @@
14
14
  "url": "https://github.com/ruijdacd/storybook-addon-md/issues"
15
15
  },
16
16
  "license": "MIT",
17
+ "author": "Rui Duarte (https://github.com/ruijdacd)",
17
18
  "repository": {
18
19
  "type": "git",
19
20
  "url": "git+https://github.com/ruijdacd/storybook-addon-md.git"