From 3a2a8a9a9552cf83b67d0e1259ce5db3b88cc31c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vagner=20Jos=C3=A9=20Nicolodi?= <31249471+VagnerNico@users.noreply.github.com> Date: Wed, 9 Feb 2022 12:49:29 -0300 Subject: [PATCH] chore: Added plop generator for new components STC-699 (#183) --- plop-templates/component.hbs | 21 +++++ plop-templates/docs/api.hbs | 2 +- plop-templates/docs/component.hbs | 17 ++++ plop-templates/entryPoint.hbs | 2 + plop-templates/story.hbs | 13 +++ plop-templates/styleguidist.hbs | 15 ++++ plopfile.mjs | 136 ++++++++++++++++++++++++++++-- 7 files changed, 196 insertions(+), 10 deletions(-) create mode 100644 plop-templates/component.hbs create mode 100644 plop-templates/docs/component.hbs create mode 100644 plop-templates/entryPoint.hbs create mode 100644 plop-templates/story.hbs create mode 100644 plop-templates/styleguidist.hbs diff --git a/plop-templates/component.hbs b/plop-templates/component.hbs new file mode 100644 index 00000000..06ce4d2f --- /dev/null +++ b/plop-templates/component.hbs @@ -0,0 +1,21 @@ +/** @jsxImportSource theme-ui */ +import { forwardRef } from "react" + +export interface {{pascalCase componentName}}Props { + children?: string | React.ReactNode +} + +const {{pascalCase componentName}} = forwardRef(function {{pascalCase componentName}}( + { + children, + }: {{pascalCase componentName}}Props, + ref +): JSX.Element { + return ( +
+ {children} +
+ ) +}) + +export default {{pascalCase componentName}} diff --git a/plop-templates/docs/api.hbs b/plop-templates/docs/api.hbs index 137392bd..e6033672 100644 --- a/plop-templates/docs/api.hbs +++ b/plop-templates/docs/api.hbs @@ -6,4 +6,4 @@ import { PropTable } from '@site/src/components/PropTable' ## Examples -- [{{pascalCase componentName}}](/docs/components/{{pascalCase componentName}}) +- [{{pascalCase componentName}}](/docs/components/{{lowerCase componentName}}) diff --git a/plop-templates/docs/component.hbs b/plop-templates/docs/component.hbs new file mode 100644 index 00000000..f1651cf7 --- /dev/null +++ b/plop-templates/docs/component.hbs @@ -0,0 +1,17 @@ +# {{pascalCase componentName}} + +## Component + +Here goes the {{pascalCase componentName}} description. + +## First level Category + +### Second level Category +```jsx live +<{{pascalCase componentName}}>Component children +``` + +## API + +- [{{pascalCase componentName}}](/docs/apis/{{lowerCase componentName}}) + diff --git a/plop-templates/entryPoint.hbs b/plop-templates/entryPoint.hbs new file mode 100644 index 00000000..c63d8168 --- /dev/null +++ b/plop-templates/entryPoint.hbs @@ -0,0 +1,2 @@ +export { default as {{pascalCase componentName}} } from "./{{pascalCase componentName}}/{{pascalCase componentName}}" +export type { {{pascalCase componentName}}Props } from "./{{pascalCase componentName}}/{{pascalCase componentName}}" diff --git a/plop-templates/story.hbs b/plop-templates/story.hbs new file mode 100644 index 00000000..59c54e3c --- /dev/null +++ b/plop-templates/story.hbs @@ -0,0 +1,13 @@ +/** @jsxImportSource theme-ui */ +import { ComponentMeta } from "@storybook/react" + +import {{pascalCase componentName}} from "./{{pascalCase componentName}}" + +type StoryMeta = ComponentMeta + +export default { + title: "Design System/{{pascalCase componentName}}", + component: {{pascalCase componentName}}, +} as StoryMeta + +export const Default = {} as StoryMeta diff --git a/plop-templates/styleguidist.hbs b/plop-templates/styleguidist.hbs new file mode 100644 index 00000000..6f71b907 --- /dev/null +++ b/plop-templates/styleguidist.hbs @@ -0,0 +1,15 @@ +#### First component variant: + +```js +<{{pascalCase componentName}}> + Children + +``` + +#### Second component variant: + +```js +<{{pascalCase componentName}}> + Children + +``` diff --git a/plopfile.mjs b/plopfile.mjs index bae58f06..0c629125 100644 --- a/plopfile.mjs +++ b/plopfile.mjs @@ -1,7 +1,66 @@ +import { exec } from "child_process" +import fs from "fs" + +const APPEND_STRING = "// appendHere" + export default function (plop) { + plop.setActionType("runPrettier", function (answers, config, plop) { + try { + config.paths.forEach((path) => { + exec(`yarn prettier --write ${plop.renderString(path, answers)}`) + }) + return "Prettier ran successfully" + } catch (error) { + return error + } + }) + + // This action must be reviewed as soon as we have an export that use multiple lines + // because it will break for that kind of export + plop.setActionType("prepareToAppend", function (answers, _config, plop) { + try { + const indexData = fs.readFileSync("src/components/index.ts", "utf8") + const componentExport = plop.renderString( + 'export { default as {{pascalCase componentName}} } from "./{{pascalCase componentName}}/{{pascalCase componentName}}"', + answers + ) + const linesArray = indexData.toString().split("\n") + + const indexToPrepend = linesArray.findIndex((line) => { + return line.startsWith("export { default as ") && line > componentExport + }) + + if (indexToPrepend === -1) { + linesArray.push(APPEND_STRING) + } else if (indexToPrepend === 0) { + linesArray.unshift(APPEND_STRING) + } else { + linesArray[indexToPrepend - 1] = `\n${APPEND_STRING}` + } + fs.writeFileSync("src/components/index.ts", linesArray.join("\n")) + return "Prepare to append ran successfully" + } catch (error) { + return error + } + }) + + plop.setActionType("cleanUp", function () { + try { + const indexData = fs.readFileSync("src/components/index.ts", "utf8") + const linesArray = indexData + .toString() + .split("\n") + .filter((line) => !line.includes(APPEND_STRING)) + fs.writeFileSync("src/components/index.ts", linesArray.join("\n")) + return "Clean up ran successfully" + } catch (error) { + return error + } + }) + // create your generators here - plop.setGenerator('createAPIDoc', { - description: 'create API doc page for a component', + plop.setGenerator("createAPIDoc", { + description: "create API doc page for a component", prompts: [ { type: "input", @@ -9,10 +68,69 @@ export default function (plop) { message: "What is the component name?", }, ], - actions: [{ - type: 'add', - path: 'website/docs/apis/{{pascalCase componentName}}.mdx', - templateFile: 'plop-templates/docs/api.hbs' - }] - }); -}; + actions: () => { + const componentPath = + "src/components/{{pascalCase componentName}}/{{pascalCase componentName}}.tsx" + const storyPath = + "src/components/{{pascalCase componentName}}/{{pascalCase componentName}}.stories.tsx" + const styleguidistPath = + "src/components/{{pascalCase componentName}}/{{pascalCase componentName}}.md" + + const docusaurusApiPath = + "website/docs/apis/{{pascalCase componentName}}.mdx" + const docusaurusComponentPath = + "website/docs/components/{{pascalCase componentName}}.mdx" + + return [ + { + type: "add", + path: componentPath, + templateFile: "plop-templates/component.hbs", + }, + { + type: "add", + path: storyPath, + templateFile: "plop-templates/story.hbs", + }, + { + type: "add", + path: styleguidistPath, + templateFile: "plop-templates/styleguidist.hbs", + }, + { + type: "add", + path: docusaurusApiPath, + templateFile: "plop-templates/docs/api.hbs", + }, + { + type: "add", + path: docusaurusComponentPath, + templateFile: "plop-templates/docs/component.hbs", + }, + { + type: "prepareToAppend", + }, + { + type: "append", + pattern: APPEND_STRING, + path: "src/components/index.ts", + templateFile: "plop-templates/entryPoint.hbs", + }, + { + paths: [ + componentPath, + storyPath, + styleguidistPath, + docusaurusApiPath, + docusaurusComponentPath, + "src/components/index.ts", + ], + type: "runPrettier", + }, + { + type: "cleanUp", + }, + ] + }, + }) +}