diff options
Diffstat (limited to 'browser/components/storybook/.storybook/markdown-story-loader.js')
-rw-r--r-- | browser/components/storybook/.storybook/markdown-story-loader.js | 123 |
1 files changed, 3 insertions, 120 deletions
diff --git a/browser/components/storybook/.storybook/markdown-story-loader.js b/browser/components/storybook/.storybook/markdown-story-loader.js index b11036af74..f1848d0e82 100644 --- a/browser/components/storybook/.storybook/markdown-story-loader.js +++ b/browser/components/storybook/.storybook/markdown-story-loader.js @@ -15,71 +15,7 @@ * Storybook usually uses to transform MDX files. */ -const path = require("path"); -const fs = require("fs"); - -const projectRoot = path.resolve(__dirname, "../../../../"); - -/** - * Takes a file path and returns a string to use as the story title, capitalized - * and split into multiple words. The file name gets transformed into the story - * name, which will be visible in the Storybook sidebar. For example, either: - * - * /stories/hello-world.stories.md or /stories/helloWorld.md - * - * will result in a story named "Hello World". - * - * @param {string} filePath - path of the file being processed. - * @returns {string} The title of the story. - */ -function getStoryTitle(filePath) { - let fileName = path.basename(filePath, ".stories.md"); - if (fileName != "README") { - try { - let relatedFilePath = path.resolve( - "../../../", - filePath.replace(".md", ".mjs") - ); - let relatedFile = fs.readFileSync(relatedFilePath).toString(); - let relatedTitle = relatedFile.match(/title: "(.*)"/)[1]; - if (relatedTitle) { - return relatedTitle + "/README"; - } - } catch {} - } - return separateWords(fileName); -} - -/** - * Splits a string into multiple capitalized words e.g. hello-world, helloWorld, - * and hello.world all become "Hello World." - * @param {string} str - String in any case. - * @returns {string} The string split into multiple words. - */ -function separateWords(str) { - return ( - str - .match(/[A-Z]?[a-z0-9]+/g) - ?.map(text => text[0].toUpperCase() + text.substring(1)) - .join(" ") || str - ); -} - -/** - * Enables rendering code in our markdown docs by parsing the source for - * annotated code blocks and replacing them with Storybook's Canvas component. - * @param {string} source - Stringified markdown source code. - * @returns {string} Source with code blocks replaced by Canvas components. - */ -function parseStoriesFromMarkdown(source) { - let storiesRegex = /```(?:js|html) story\n(?<code>[\s\S]*?)```/g; - // $code comes from the <code> capture group in the regex above. It consists - // of any code in between backticks and gets run when used in a Canvas component. - return source.replace( - storiesRegex, - "<Canvas withSource='none'><with-common-styles>\n$<code></with-common-styles></Canvas>" - ); -} +const { getStoryTitle, getMDXSource } = require("./markdown-story-utils.js"); /** * The WebpackLoader export. Takes markdown as its source and returns a docs @@ -89,61 +25,8 @@ function parseStoriesFromMarkdown(source) { * @param {string} source - The markdown source to rewrite to MDX. */ module.exports = function markdownStoryLoader(source) { - // Currently we sort docs only stories under "Docs" by default. - let storyPath = "Docs"; - // `this.resourcePath` is the path of the file being processed. - let relativePath = path - .relative(projectRoot, this.resourcePath) - .replaceAll(path.sep, "/"); - let componentName; - - if (relativePath.includes("toolkit/content/widgets")) { - let storyNameRegex = /(?<=\/widgets\/)(?<name>.*?)(?=\/)/g; - componentName = storyNameRegex.exec(relativePath)?.groups?.name; - if (componentName) { - // Get the common name for a component e.g. Toggle for moz-toggle - storyPath = - "UI Widgets/" + separateWords(componentName).replace(/^Moz/g, ""); - } - } - - let storyTitle = getStoryTitle(relativePath); - let title = storyTitle.includes("/") - ? storyTitle - : `${storyPath}/${storyTitle}`; - - let componentStories; - if (componentName) { - componentStories = this.resourcePath - .replace("README", componentName) - .replace(".md", ".mjs"); - try { - fs.statSync(componentStories); - componentStories = "./" + path.basename(componentStories); - } catch { - componentStories = null; - } - } - - // Unfortunately the indentation/spacing here seems to be important for the - // MDX parser to know what to do in the next step of the Webpack process. - let mdxSource = ` -import { Meta, Description, Canvas, Story } from "@storybook/addon-docs"; -${componentStories ? `import * as Stories from "${componentStories}";` : ""} - -<Meta - title="${title}" - ${componentStories ? `of={Stories}` : ""} - parameters={{ - previewTabs: { - canvas: { hidden: true }, - }, - viewMode: "docs", - }} -/> - -${parseStoriesFromMarkdown(source)}`; - + let title = getStoryTitle(this.resourcePath); + let mdxSource = getMDXSource(source, title, this.resourcePath); return mdxSource; }; |