From 930a4d26a0dafbc82e5828b8c471d95f18536ae0 Mon Sep 17 00:00:00 2001 From: Josh Wooding <12938082+joshwooding@users.noreply.github.com> Date: Tue, 6 Dec 2022 01:01:05 +0000 Subject: [PATCH] Support customization of MDX plugins --- code/addons/docs/README.md | 1 + code/addons/docs/src/preset.ts | 14 +++++++++++--- code/lib/builder-vite/src/plugins/mdx-plugin.ts | 17 +++++++++++++---- code/yarn.lock | 8 +++++--- docs/essentials/introduction.md | 3 ++- 5 files changed, 32 insertions(+), 11 deletions(-) diff --git a/code/addons/docs/README.md b/code/addons/docs/README.md index 2c1076773b69..912702a58f85 100644 --- a/code/addons/docs/README.md +++ b/code/addons/docs/README.md @@ -142,6 +142,7 @@ module.exports = { options: { jsxOptions: {}, csfPluginOptions: null, + mdxPluginOptions: {}, transcludeMarkdown: true, }, }, diff --git a/code/addons/docs/src/preset.ts b/code/addons/docs/src/preset.ts index 5e1ce6146199..d5e494c053c6 100644 --- a/code/addons/docs/src/preset.ts +++ b/code/addons/docs/src/preset.ts @@ -5,7 +5,7 @@ import { dedent } from 'ts-dedent'; import type { IndexerOptions, StoryIndexer, DocsOptions, Options } from '@storybook/types'; import type { CsfPluginOptions } from '@storybook/csf-plugin'; -import type { JSXOptions } from '@storybook/mdx2-csf'; +import type { JSXOptions, CompileOptions } from '@storybook/mdx2-csf'; import { loadCsf } from '@storybook/csf-tools'; async function webpack( @@ -26,6 +26,7 @@ async function webpack( csfPluginOptions: CsfPluginOptions | null; transcludeMarkdown: boolean; jsxOptions?: JSXOptions; + mdxPluginOptions?: CompileOptions; } /* & Parameters< typeof createCompiler >[0] */ @@ -41,13 +42,20 @@ async function webpack( sourceLoaderOptions = null, configureJsx, mdxBabelOptions, + mdxPluginOptions = {}, } = options; - const mdxLoaderOptions = await options.presets.apply('mdxLoaderOptions', { + const mdxLoaderOptions: CompileOptions = await options.presets.apply('mdxLoaderOptions', { skipCsf: true, + ...mdxPluginOptions, mdxCompileOptions: { providerImportSource: '@storybook/addon-docs/mdx-react-shim', - remarkPlugins: [remarkSlug, remarkExternalLinks], + // @ts-expect-error CompileOptions type is wrong + ...mdxPluginOptions.mdxCompileOptions, + remarkPlugins: [remarkSlug, remarkExternalLinks].concat( + // @ts-expect-error CompileOptions type is wrong + mdxPluginOptions?.mdxCompileOptions?.remarkPlugins ?? [] + ), }, jsxOptions, }); diff --git a/code/lib/builder-vite/src/plugins/mdx-plugin.ts b/code/lib/builder-vite/src/plugins/mdx-plugin.ts index deedf25fa822..e96fcbb56a8d 100644 --- a/code/lib/builder-vite/src/plugins/mdx-plugin.ts +++ b/code/lib/builder-vite/src/plugins/mdx-plugin.ts @@ -1,9 +1,18 @@ -import type { Options, StorybookConfig } from '@storybook/types'; +import type { Options, Preset, StorybookConfig } from '@storybook/types'; import type { Plugin } from 'vite'; import { createFilter } from 'vite'; const isStorybookMdx = (id: string) => id.endsWith('stories.mdx') || id.endsWith('story.mdx'); +type AddonWithOptions = Exclude; +function getAddonOptions(addons: StorybookConfig['addons'], name: string): Record { + return ( + addons?.find( + (addon): addon is AddonWithOptions => typeof addon !== 'string' && addon.name === name + )?.options ?? {} + ); +} + /** * Storybook uses two different loaders when dealing with MDX: * @@ -16,9 +25,7 @@ export async function mdxPlugin(options: Options): Promise { const include = /\.mdx?$/; const filter = createFilter(include); const addons = await options.presets.apply('addons', []); - const docsOptions = - // @ts-expect-error - not sure what type to use here - addons.find((a) => [a, a.name].includes('@storybook/addon-docs'))?.options ?? {}; + const { mdxPluginOptions } = getAddonOptions(addons, '@storybook/addon-docs'); return { name: 'storybook:mdx-plugin', @@ -29,8 +36,10 @@ export async function mdxPlugin(options: Options): Promise { const { compile } = await import('@storybook/mdx2-csf'); const mdxLoaderOptions = await options.presets.apply('mdxLoaderOptions', { + ...mdxPluginOptions, mdxCompileOptions: { providerImportSource: '@storybook/addon-docs/mdx-react-shim', + ...mdxPluginOptions?.mdxCompileOptions, }, jsxOptions: docsOptions.jsxOptions, }); diff --git a/code/yarn.lock b/code/yarn.lock index 195ffe33b534..9d70d3662b81 100644 --- a/code/yarn.lock +++ b/code/yarn.lock @@ -6771,9 +6771,11 @@ __metadata: linkType: soft "@storybook/mdx2-csf@npm:next": - version: 1.0.0-next.2 - resolution: "@storybook/mdx2-csf@npm:1.0.0-next.2" - checksum: ebf285ee9bb27912c7e3795ef2d155d555c0f7ade15fa38b2c9e15cd590143299b890663bb2e22438ba806aaba232ead1e025ba566540d6f86047c1c2b2b44ec + version: 0.1.0-next.8 + resolution: "@storybook/mdx2-csf@npm:0.1.0-next.8" + dependencies: + loader-utils: ^2.0.4 + checksum: 7126e80489a3aa59ea14a4262e190ee31bfd2a362b9fd73cad565ca0d1ca41bba7f28ece940df4ba8419290d4a6e21b3d25cd6f69d6bcd0b728d992c93fea103 languageName: node linkType: hard diff --git a/docs/essentials/introduction.md b/docs/essentials/introduction.md index 7fa33515ec50..7f2de187f09d 100644 --- a/docs/essentials/introduction.md +++ b/docs/essentials/introduction.md @@ -82,12 +82,13 @@ Below is an abridged configuration and table with all the available options for | Addon | Configuration element | Description | -| ------------------------------ | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | +| ------------------------------ |-----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------| | `@storybook/addon-actions` | N/A | N/A | | `@storybook/addon-viewport` | N/A | N/A | | `@storybook/addon-docs` | `configureJSX` | Enables JSX support in MDX for projects that aren't configured to handle the format.
`configureJSX: true` | | | `babelOptions` | Provides additional Babel configurations for file transpilation.
`babelOptions: { plugins: [], presets: []}`
Extends `configureJSX`. | | | `csfPluginOptions` | Provides additional configuration for Storybook's CSF plugin. Can be disabled with `null` | +| | `mdxPluginOptions` | Provides additional configuration for Storybook's MDX plugin. | | | `transcludeMarkdown` | Enables Markdown file support into MDX and render them as components.
`transcludeMarkdown: true` | | `@storybook/addon-controls` | N/A | N/A | | `@storybook/addon-backgrounds` | N/A | N/A |