storybook-addon-md 0.7.0 → 0.9.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,5 +1,24 @@
1
1
  # storybook-addon-md
2
2
 
3
+ ## 0.9.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 990c4b9: Rendered links now behave correctly on their own. Docs links keep the absolute manager URL and navigate through the Storybook channel on a plain click, so the preview no longer reloads; modified clicks and non-primary buttons fall through to the browser. External links open in a new tab with `rel="noopener noreferrer"`, both kinds carry a `data-link` attribute, and explicit `target` or `rel` attributes are preserved. `Anchor` is exported from `storybook-addon-md/runtime` for custom renderers.
8
+
9
+ Docs links no longer set `target="_top"`. Stylesheets or tests that relied on that attribute should target `[data-link="docs"]` instead.
10
+
11
+ ## 0.8.0
12
+
13
+ ### Minor Changes
14
+
15
+ - 298284c: Add an opt-in `links` option that rewrites relative Markdown links instead of bundling their targets as assets.
16
+
17
+ - `links.documents` (default `true` when `links` is set) turns links to other discovered documents into ordinary links to their Docs page in the Storybook manager.
18
+ - `links.repository` turns links to other files or folders inside root into `<repository>/<relative path>` links, so source files are no longer copied into the bundle and folder links no longer fail discovery.
19
+
20
+ Images, image reference definitions, manifests, and the default behavior without `links` are unchanged.
21
+
3
22
  ## 0.7.0
4
23
 
5
24
  ### Minor Changes
package/README.md CHANGED
@@ -159,6 +159,7 @@ Invalid frontmatter, missing or ambiguous story references, and missing local as
159
159
  | `manifests` | `false` | Include original Markdown in Storybook documentation manifests. |
160
160
  | `tagFields` | `[]` | Additional frontmatter fields displayed as tags. |
161
161
  | `presentation` | None | Module exporting `Layout` and/or `MarkdownRenderer`. |
162
+ | `links` | None | Rewrite relative links to Docs pages and repository files. |
162
163
 
163
164
  Globs and customization paths start from your project folder (the parent of `.storybook` by default). Keep the config and local files inside that folder. Restart Storybook after changing options.
164
165
 
@@ -186,6 +187,32 @@ const config: StorybookConfig = {
186
187
 
187
188
  `tagFields` adds string values and string array items from those fields to the existing tags. Missing fields, blank strings, and non-string values are ignored. Labels are deduplicated by exact value across documents, tags, configured fields, and status; status takes precedence and retains its original `data-status`. Metadata is not modified. Consumers can remove adapters that only copied these fields into `tags`.
188
189
 
190
+ ### Relative links
191
+
192
+ By default every relative link is bundled as an asset, so a link to another Markdown file opens its raw source. Set `links` to rewrite relative links instead:
193
+
194
+ ```ts
195
+ {
196
+ name: 'storybook-addon-md',
197
+ options: {
198
+ patterns: ['src/**/*.md', 'docs/**/*.md'],
199
+ links: {
200
+ documents: true,
201
+ repository: 'https://github.com/acme/design-system/blob/main',
202
+ },
203
+ },
204
+ }
205
+ ```
206
+
207
+ | Field | Default | Behavior |
208
+ | ------------ | ------- | -------------------------------------------------------------------------------------------------------------- |
209
+ | `documents` | `true` | Links to discovered Markdown documents become ordinary links to their Docs page in the manager. |
210
+ | `repository` | None | Links to other files or folders inside the project folder become `<repository>/<path relative to root>` links. |
211
+
212
+ Rendered links behave correctly without a click handler in your Layout. Docs links keep the absolute manager URL as `href`, so copying, middle-clicking, and opening in a new tab work as usual, and a plain left click asks the manager to navigate without reloading the preview. Modified clicks fall through to the browser. Absolute `http:` and `https:` links, including every `repository` link, open in a new tab with `rel="noopener noreferrer"`. Fragment links are left untouched, and explicit `target` or `rel` attributes from a custom renderer are never overridden.
213
+
214
+ Fragments and query strings are preserved. Attached documents link to their story file's Docs page using the CSF `title`; when the story file has no explicit title, the link falls back to the `story:<path>` key and will not resolve until a title is set. Images and image reference definitions remain bundled assets, and manifests keep the original Markdown. Relative links to files outside root, or to missing files, still fail the build. Without `links`, behavior is unchanged.
215
+
189
216
  ### Node parsing and CI checks
190
217
 
191
218
  Use the Node-only `storybook-addon-md/node` export. It shares discovery's parser and story resolution without loading Storybook or browser code:
@@ -262,7 +289,7 @@ See [Styling](STYLING.md) for all variables, status and callout colors, theme sw
262
289
  ## Links and limitations
263
290
 
264
291
  - Relative links and images resolve from the Markdown source and are included in static builds. Root-relative assets use Storybook’s `staticDirs`.
265
- - Links to `.md` files open the original source, not a rendered Docs page. Use a Storybook URL such as `/?path=/docs/guides-introduction--docs` for page navigation.
292
+ - Without the `links` option, links to `.md` files open the original source, not a rendered Docs page. Set `links` or use a Storybook URL such as `?path=/docs/guides-introduction--docs` for page navigation.
266
293
  - Braces and JSX-like text are treated as content. Raw HTML renders as text by default.
267
294
  - Set Storybook’s `parameters.options.storySort` for explicit sidebar ordering. See the [example preview](https://github.com/ruijdacd/storybook-addon-md/blob/main/example/.storybook/preview.ts).
268
295
  - Multiple development Storybooks sharing one config directory are unsupported.
package/STYLING.md CHANGED
@@ -90,6 +90,8 @@ Five tokens cover most of the page. Element variables fall back to them, so set
90
90
 
91
91
  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.
92
92
 
93
+ Links carry `data-link="docs"` for Storybook Docs pages and `data-link="external"` for absolute `http:` and `https:` URLs, so a stylesheet can mark external links or hide the distinction. Fragment links and other hrefs have no `data-link`.
94
+
93
95
  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. The addon sets `--sbmd-callout-accent` on each callout from its type’s accent variable, and uses it for the default border and the label color. Per-type accent variables default to Storybook theme colors chosen for the light or dark base.
94
96
 
95
97
  Properties without a variable use ordinary CSS. Match the addon’s specificity for properties it sets, for example `.sbdocs-content .storybook-addon-md h2` for heading letter spacing or `.sbdocs-content .storybook-addon-md-tags` for the tag gap.
@@ -204,6 +206,18 @@ export function MarkdownRenderer(document: MarkdownDocument) {
204
206
 
205
207
  `MarkdownRenderer` receives `{ markdown, metadata, source, heading? }`: processed Markdown with resolved asset URLs, preserved frontmatter, and the source path relative to the project folder.
206
208
 
209
+ `Anchor` is the link component used by `DefaultMarkdownRenderer`. It navigates the manager for Docs links, opens external links in a new tab, sets `data-link`, and keeps explicit `target` and `rel` attributes. Reuse it in a custom renderer's `overrides` so links keep the same behavior:
210
+
211
+ ```tsx
212
+ import { Markdown } from '@storybook/addon-docs/blocks';
213
+ import { Anchor } from 'storybook-addon-md/runtime';
214
+ import type { MarkdownDocument } from 'storybook-addon-md/runtime';
215
+
216
+ export function MarkdownRenderer({ markdown }: MarkdownDocument) {
217
+ return <Markdown options={{ overrides: { a: Anchor } }}>{markdown}</Markdown>;
218
+ }
219
+ ```
220
+
207
221
  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`.
208
222
 
209
223
  `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.
@@ -17,12 +17,13 @@ const storyExtensions = [
17
17
  ];
18
18
  const slash = (value) => value.split(path.sep).join("/");
19
19
  const fail = (source, message) => /* @__PURE__ */ new Error(`[storybook-addon-md] ${source}: ${message}`);
20
- async function localFile(file, root, source, kind) {
20
+ async function localFile(file, root, source, kind, directories = false) {
21
21
  try {
22
22
  const actual = await realpath(file);
23
23
  const relative = path.relative(await realpath(root), actual);
24
24
  if (relative.startsWith(`..${path.sep}`) || relative === ".." || path.isAbsolute(relative)) throw fail(source, `${kind} must be inside root: ${file}`);
25
- if (!(await stat(actual)).isFile()) throw new Error("not a file");
25
+ const info = await stat(actual);
26
+ if (!info.isFile() && !(directories && info.isDirectory())) throw new Error("not a file");
26
27
  return file;
27
28
  } catch (error) {
28
29
  if (error instanceof Error && error.message.startsWith("[storybook-addon-md]")) throw error;
@@ -85,12 +86,20 @@ async function resolveStoryAssociations(file, metadata, root) {
85
86
  if (matches.length !== 1) throw Object.assign(fail(file, matches.length ? "ambiguous sibling stories; set stories explicitly" : "missing sibling story for .metadata.md; set stories explicitly or rename the Markdown file"), { dependencies: storyExtensions.map((extension) => `${base}.stories.${extension}`) });
86
87
  return [await localFile(matches[0], root, file, "story reference")];
87
88
  }
88
- async function resolveAssets(body, file, root, standalone = false) {
89
+ const imageDefinitions = (tree) => {
90
+ const identifiers = /* @__PURE__ */ new Set();
91
+ visit(tree, "imageReference", (node) => {
92
+ identifiers.add(node.identifier);
93
+ });
94
+ return identifiers;
95
+ };
96
+ async function resolveAssets(body, file, root, standalone = false, resolveLink) {
89
97
  const tree = markdown.parse(body);
90
98
  const nodes = [];
91
99
  visit(tree, (node) => {
92
100
  if (node.type === "image" || node.type === "link" || node.type === "definition") nodes.push(node);
93
101
  });
102
+ const images = imageDefinitions(tree);
94
103
  const assets = [];
95
104
  for (const node of nodes) {
96
105
  const url = node.url;
@@ -102,7 +111,13 @@ async function resolveAssets(body, file, root, standalone = false) {
102
111
  } catch {
103
112
  throw fail(file, `invalid local URL: ${url}`);
104
113
  }
105
- const asset = await localFile(path.resolve(path.dirname(file), decoded), root, file, "local asset");
114
+ const target = path.resolve(path.dirname(file), decoded);
115
+ const link = node.type === "image" || node.type === "definition" && images.has(node.identifier) || !resolveLink ? void 0 : await resolveLink(target, file);
116
+ if (link) {
117
+ node.url = `${link}${suffix}`;
118
+ continue;
119
+ }
120
+ const asset = await localFile(target, root, file, "local asset");
106
121
  const token = `SBMDASSET${assets.length}END`;
107
122
  if (body.includes(token)) throw fail(file, `reserved asset token in content: ${token}`);
108
123
  assets.push({
@@ -124,7 +139,7 @@ async function resolveAssets(body, file, root, standalone = false) {
124
139
  heading
125
140
  };
126
141
  }
127
- async function discover({ root, patterns, output }) {
142
+ async function discover({ root, patterns, output, links, docsName }) {
128
143
  if (!Array.isArray(patterns) || !patterns.length || patterns.some((item) => typeof item !== "string" || !item || path.isAbsolute(item) || item.split("/").includes(".."))) throw fail(root, "patterns must be a non-empty array of globs relative to root");
129
144
  const files = await glob(patterns, {
130
145
  cwd: root,
@@ -139,9 +154,8 @@ async function discover({ root, patterns, output }) {
139
154
  ...path.relative(root, output).startsWith("..") ? [] : [`${slash(path.relative(root, output))}/**`]
140
155
  ]
141
156
  });
142
- return Promise.all(files.sort().filter((file) => file.endsWith(".md")).map(async (file) => {
157
+ const documents = await Promise.all(files.sort().filter((file) => file.endsWith(".md")).map(async (file) => {
143
158
  const { original, body, metadata, stories } = await readMarkdown(file, root);
144
- const content = await resolveAssets(body, file, root, !stories.length);
145
159
  return {
146
160
  file,
147
161
  original,
@@ -149,10 +163,34 @@ async function discover({ root, patterns, output }) {
149
163
  source: slash(path.relative(root, file)),
150
164
  title: metadata.title ?? `Documentation/${slash(path.relative(root, file)).replace(/\.md$/, "")}`,
151
165
  metadata,
152
- stories,
153
- ...content
166
+ stories
154
167
  };
155
168
  }));
169
+ const resolveLink = links ? await linkResolver(links, documents, root, docsName) : void 0;
170
+ return Promise.all(documents.map(async (document) => ({
171
+ ...document,
172
+ ...await resolveAssets(document.body, document.file, root, !document.stories.length, resolveLink)
173
+ })));
174
+ }
175
+ async function docsId(document, root, docsName, titles) {
176
+ const { toId } = await import("storybook/internal/csf");
177
+ if (!document.stories.length) return toId(document.title, docsName);
178
+ const [story] = document.stories;
179
+ if (!titles.has(story)) titles.set(story, import("storybook/internal/csf-tools").then(({ readCsf }) => readCsf(story, { makeTitle: (title) => title })).then((csf) => csf.parse().meta).catch(() => void 0));
180
+ const meta = await titles.get(story);
181
+ return meta?.title ? toId(meta.id ?? meta.title, docsName) : `story:${slash(path.relative(root, story))}`;
182
+ }
183
+ async function linkResolver(links, documents, root, docsName = "Docs") {
184
+ const paths = /* @__PURE__ */ new Map();
185
+ const titles = /* @__PURE__ */ new Map();
186
+ if (links.documents !== false) for (const document of documents) paths.set(document.file, `?path=/docs/${await docsId(document, root, docsName, titles)}`);
187
+ const repository = links.repository?.replace(/\/+$/, "");
188
+ return async (target, source) => {
189
+ const page = paths.get(target);
190
+ if (page || !repository) return page;
191
+ await localFile(target, root, source, "link target", true);
192
+ return `${repository}/${slash(path.relative(root, target))}`;
193
+ };
156
194
  }
157
195
  async function readMarkdown(file, root) {
158
196
  root = path.resolve(root);
@@ -1,4 +1,4 @@
1
- import { t as MarkdownOptions } from "./index-BzM0tjFM.js";
1
+ import { n as MarkdownOptions } from "./index-D3ynUvxB.js";
2
2
  //#region src/content.d.ts
3
3
  interface ContentOptions extends MarkdownOptions {
4
4
  root: string;
@@ -17,7 +17,7 @@ declare function parseMarkdown(text: string, source: string): {
17
17
  metadata: Frontmatter;
18
18
  };
19
19
  declare function resolveStoryAssociations(file: string, metadata: Frontmatter, root: string): Promise<string[]>;
20
- declare function discover({ root, patterns, output }: ContentOptions): Promise<{
20
+ declare function discover({ root, patterns, output, links, docsName }: ContentOptions): Promise<{
21
21
  markdown: string;
22
22
  assets: {
23
23
  file: string;
@@ -1,4 +1,8 @@
1
1
  //#region src/index.d.ts
2
+ interface LinkOptions {
3
+ documents?: boolean;
4
+ repository?: string;
5
+ }
2
6
  interface MarkdownOptions {
3
7
  tagFields?: string[];
4
8
  manifests?: boolean;
@@ -7,6 +11,7 @@ interface MarkdownOptions {
7
11
  stylesheet?: string;
8
12
  root?: string;
9
13
  presentation?: string;
14
+ links?: LinkOptions;
10
15
  }
11
16
  //#endregion
12
- export { MarkdownOptions as t };
17
+ export { MarkdownOptions as n, LinkOptions as t };
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { t as MarkdownOptions } from "./index-BzM0tjFM.js";
2
- export { MarkdownOptions };
1
+ import { n as MarkdownOptions, t as LinkOptions } from "./index-D3ynUvxB.js";
2
+ export { LinkOptions, MarkdownOptions };
package/dist/node.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as readMarkdown, i as parseMarkdown, o as resolveStoryAssociations, r as Frontmatter } from "./content-CKQsa_HK.js";
1
+ import { a as readMarkdown, i as parseMarkdown, o as resolveStoryAssociations, r as Frontmatter } from "./content-CwjmOiRK.js";
2
2
  export { type Frontmatter, parseMarkdown, readMarkdown, resolveStoryAssociations };
package/dist/node.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as readMarkdown, i as parseMarkdown, o as resolveStoryAssociations } from "./content-CTcZAfoF.js";
1
+ import { a as readMarkdown, i as parseMarkdown, o as resolveStoryAssociations } from "./content-BrghNgvp.js";
2
2
  export { parseMarkdown, readMarkdown, resolveStoryAssociations };
package/dist/preset.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { t as MarkdownOptions } from "./index-BzM0tjFM.js";
2
- import { n as DiscoveredDocument, t as ContentOptions } from "./content-CKQsa_HK.js";
1
+ import { n as MarkdownOptions } from "./index-D3ynUvxB.js";
2
+ import { n as DiscoveredDocument, t as ContentOptions } from "./content-CwjmOiRK.js";
3
3
  import { StorybookConfigRaw } from "storybook/internal/types";
4
4
  import { UserConfig } from "vite";
5
5
  //#region src/preset.d.ts
package/dist/preset.js CHANGED
@@ -1,4 +1,4 @@
1
- import { n as fail, r as localFile, s as slash, t as discover } from "./content-CTcZAfoF.js";
1
+ import { n as fail, r as localFile, s as slash, t as discover } from "./content-BrghNgvp.js";
2
2
  import path from "node:path";
3
3
  import { createHash } from "node:crypto";
4
4
  import { watch } from "chokidar";
@@ -133,6 +133,8 @@ function settings(options) {
133
133
  const root = path.resolve(configDir, options.root ?? "..");
134
134
  const generatedDir = options.generatedDir ?? "storybook-markdown-generated";
135
135
  if (options.tagFields !== void 0 && (!Array.isArray(options.tagFields) || options.tagFields.some((field) => typeof field !== "string" || !/^[a-z][a-z0-9_-]*$/.test(field)))) throw fail(configDir, "tagFields must be an array of lowercase frontmatter field names");
136
+ const { links } = options;
137
+ if (links !== void 0 && (typeof links !== "object" || links === null || Array.isArray(links) || Object.keys(links).some((key) => !["documents", "repository"].includes(key)) || links.documents !== void 0 && typeof links.documents !== "boolean" || links.repository !== void 0 && (typeof links.repository !== "string" || !/^https?:\/\/\S+$/.test(links.repository)))) throw fail(configDir, "links must be an object with an optional documents boolean and an optional repository URL");
136
138
  if ("exclude" in options) throw fail(configDir, "exclude has been removed; use negative globs in patterns, such as !docs/private/**");
137
139
  if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(generatedDir) || ["node_modules", "storybook-static"].includes(generatedDir)) throw fail(configDir, "generatedDir must be a visible folder name containing only letters, digits, hyphens or underscores");
138
140
  return {
@@ -141,7 +143,11 @@ function settings(options) {
141
143
  patterns: options.patterns,
142
144
  tagFields: options.tagFields,
143
145
  stylesheet: options.stylesheet ? path.resolve(root, options.stylesheet) : void 0,
144
- presentation: options.presentation ? path.resolve(root, options.presentation) : void 0
146
+ presentation: options.presentation ? path.resolve(root, options.presentation) : void 0,
147
+ links: links ? {
148
+ documents: links.documents ?? true,
149
+ repository: links.repository?.replace(/\/+$/, "")
150
+ } : void 0
145
151
  };
146
152
  }
147
153
  async function stories(existing = [], options) {
package/dist/runtime.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ComponentType, ReactNode } from "react";
1
+ import { ComponentProps, ComponentType, ReactNode } from "react";
2
2
  //#region src/types.d.ts
3
3
  interface MarkdownDocument {
4
4
  source: string;
@@ -21,6 +21,7 @@ interface Presentation {
21
21
  }
22
22
  //#endregion
23
23
  //#region src/runtime.d.ts
24
+ export declare function Anchor({ href, target, rel, ...props }: ComponentProps<'a'>): import("react").JSX.Element;
24
25
  export declare function DefaultMarkdownRenderer({ markdown }: MarkdownDocument): import("react").JSX.Element;
25
26
  export declare function DefaultLayout({ documents, title, attached, children, examples, heading, tagFields }: LayoutProps): import("react").JSX.Element;
26
27
  export declare function Documentation({ documents, title, attached, presentation, tagFields }: {
package/dist/runtime.js CHANGED
@@ -1,4 +1,6 @@
1
1
  import { Children, cloneElement, isValidElement } from "react";
2
+ import { NAVIGATE_URL } from "storybook/internal/core-events";
3
+ import { addons } from "storybook/preview-api";
2
4
  import { useTheme } from "storybook/theming";
3
5
  import { CodeOrSourceMdx, Controls, HeadersMdx, Markdown, Primary, Stories, Title } from "@storybook/addon-docs/blocks";
4
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -34,6 +36,37 @@ function Blockquote({ children, ...props }) {
34
36
  }), content]
35
37
  });
36
38
  }
39
+ function Anchor({ href, target, rel, ...props }) {
40
+ if (href?.startsWith("?path=")) {
41
+ const navigate = (event) => {
42
+ props.onClick?.(event);
43
+ if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || target && target !== "_self") return;
44
+ event.preventDefault();
45
+ addons.getChannel().emit(NAVIGATE_URL, href);
46
+ };
47
+ return /* @__PURE__ */ jsx("a", {
48
+ ...props,
49
+ href: new URL(href, new URL("./", window.location.href)).href,
50
+ target,
51
+ rel,
52
+ "data-link": "docs",
53
+ onClick: navigate
54
+ });
55
+ }
56
+ if (href && /^https?:\/\//i.test(href)) return /* @__PURE__ */ jsx("a", {
57
+ ...props,
58
+ href,
59
+ target: target ?? "_blank",
60
+ rel: rel ?? "noopener noreferrer",
61
+ "data-link": "external"
62
+ });
63
+ return /* @__PURE__ */ jsx("a", {
64
+ ...props,
65
+ href,
66
+ target,
67
+ rel
68
+ });
69
+ }
37
70
  function DefaultMarkdownRenderer({ markdown }) {
38
71
  return /* @__PURE__ */ jsx(Markdown, {
39
72
  options: {
@@ -41,7 +74,7 @@ function DefaultMarkdownRenderer({ markdown }) {
41
74
  overrides: {
42
75
  code: CodeOrSourceMdx,
43
76
  ...HeadersMdx,
44
- a: "a",
77
+ a: Anchor,
45
78
  blockquote: Blockquote
46
79
  }
47
80
  },
@@ -120,4 +153,4 @@ function Documentation({ documents, title, attached = false, presentation = {},
120
153
  });
121
154
  }
122
155
  //#endregion
123
- export { DefaultLayout, DefaultMarkdownRenderer, Documentation };
156
+ export { Anchor, DefaultLayout, DefaultMarkdownRenderer, Documentation };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storybook-addon-md",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "Discover ordinary Markdown and render it in Storybook Docs.",
5
5
  "keywords": [
6
6
  "docs",