Skip to content

Instantly share code, notes, and snippets.

@nandanmen
Created August 7, 2022 18:29
Show Gist options
  • Save nandanmen/5a5e44bbd862a92d0e429a340af7d254 to your computer and use it in GitHub Desktop.
Save nandanmen/5a5e44bbd862a92d0e429a340af7d254 to your computer and use it in GitHub Desktop.
/**
* This is what the script outputs given the following two files:
* - content/tokenizer/Tokenizer/Tokenizer.stories.tsx
* - content/framer-magic-motion/LayoutExample/LayoutExample.stories.tsx
*/
import * as LayoutExample from '../_dist-content/framer-magic-motion/components/LayoutExample/LayoutExample.stories'
import * as Tokenizer from '../_dist-content/tokenizer/components/Tokenizer/Tokenizer.stories'
const stories = [
{ name: 'LayoutExample', variants: LayoutExample, postName: 'framer-magic-motion' },
{ name: 'Tokenizer', variants: Tokenizer, postName: 'tokenizer' }
];
import { StoriesPage } from '../layouts/StoriesPage';
export default function Stories() {
return <StoriesPage stories={stories} />;
}
const glob = require("glob");
const fs = require("fs");
const getStories = () => {
return new Promise((resolve, reject) => {
glob("**/*.stories.tsx", (err, files) => {
if (err) {
reject(err);
}
resolve(files);
});
});
};
const parseStoryPath = (storyPath) => {
const parts = storyPath.split("/");
const name = parts[parts.length - 1].replace(".stories.tsx", "");
/**
* My components that are custom for specific posts live in a separate directory from
* shared components and are sometimes generated by Babel. This part changes the import
* to come from the build directory instead of the source.
*/
let postName;
const isContentComponent = parts[0] === "content";
if (isContentComponent) {
parts[0] = "_dist-content";
postName = parts[1];
}
/**
* The source file is a TS file, but sometimes the output is a JS file, so we
* explicitly remove the extension here.
*/
parts[parts.length - 1] = `${name}.stories`;
const path = parts.join("/");
return {
name,
isContentComponent,
path,
postName,
asImport: `import * as ${name} from '../${path}'`,
};
};
const template = `
import { StoriesPage } from '../layouts/StoriesPage';
export default function Stories() {
return <StoriesPage stories={stories} />;
}
`;
const main = async () => {
const files = (await getStories()).map(parseStoryPath);
const imports = files.map(({ asImport }) => asImport).join(`\n`);
const storiesProp = files
.map(
(story) =>
`{ name: '${story.name}', variants: ${story.name}, postName: '${story.postName}' }`
)
.join(`,\n`);
const header = `${imports}\nconst stories = [\n${storiesProp}\n];`;
fs.writeFileSync("./pages/_stories.tsx", header + template);
};
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment