/** * Component Generator */ import { Actions, PlopGenerator } from 'node-plop'; import path from 'path'; import { componentExists } from '../utils'; export enum ComponentProptNames { 'ComponentName' = 'ComponentName', 'wantMemo' = 'wantMemo', 'wantStyledComponents' = 'wantStyledComponents', 'wantTranslations' = 'wantTranslations', 'wantLoadable' = 'wantLoadable', 'wantTests' = 'wantTests', } const componentsPath = path.join(__dirname, '../../../src/app/components'); export const componentGenerator: PlopGenerator = { description: 'Add an unconnected component', prompts: [ { type: 'input', name: ComponentProptNames.ComponentName, message: 'What should it be called?', default: 'Button', validate: value => { if (/.+/.test(value)) { return componentExists(value) ? 'A component with this name already exists' : true; } return 'The name is required'; }, }, { type: 'confirm', name: ComponentProptNames.wantMemo, default: false, message: 'Do you want to wrap your component in React.memo?', }, { type: 'confirm', name: ComponentProptNames.wantStyledComponents, default: true, message: 'Do you want to use styled-components?', }, { type: 'confirm', name: ComponentProptNames.wantTranslations, default: false, message: 'Do you want i18n translations (i.e. will this component use text)?', }, { type: 'confirm', name: ComponentProptNames.wantLoadable, default: false, message: 'Do you want to load the component asynchronously?', }, { type: 'confirm', name: ComponentProptNames.wantTests, default: false, message: 'Do you want to have tests?', }, ], actions: (data: { [P in ComponentProptNames]: string }) => { const containerPath = `${componentsPath}/{{properCase ${ComponentProptNames.ComponentName}}}`; const actions: Actions = [ { type: 'add', path: `${containerPath}/index.tsx`, templateFile: './component/index.tsx.hbs', abortOnFail: true, }, ]; if (data.wantLoadable) { actions.push({ type: 'add', path: `${containerPath}/Loadable.ts`, templateFile: './component/loadable.ts.hbs', abortOnFail: true, }); } if (data.wantTests) { actions.push({ type: 'add', path: `${containerPath}/__tests__/index.test.tsx`, templateFile: './component/index.test.tsx.hbs', abortOnFail: true, }); } actions.push({ type: 'prettify', data: { path: `${componentsPath}/${data.ComponentName}/**` }, }); return actions; }, };