import { Task, TaskRunner } from './task'; import fs from 'fs'; import { template as _template } from 'lodash'; import { prompt } from 'inquirer'; import { pascalCase } from '../utils/pascalCase'; import { promptConfirm, promptInput, promptList } from '../utils/prompt'; import { componentTpl, docsTpl, storyTpl, testTpl } from '../templates'; interface Details { name?: string; hasStory: boolean; group?: string; isStoryPublic: boolean; hasTests: boolean; } interface GeneratorOptions { details: Details; path: string; } type ComponentGenerator = (options: GeneratorOptions) => Promise; const componentGroups = [ { name: 'General', value: 'General' }, { name: 'Forms', value: 'Forms' }, { name: 'Panel', value: 'Panel' }, { name: 'Visualizations', value: 'Visualizations' }, { name: 'Others', value: 'Others' }, ]; export const promptDetails = () => { return prompt
([ promptInput('name', 'Component name', true), promptConfirm('hasTests', "Generate component's test file?"), promptConfirm('hasStory', "Generate component's story file?"), promptConfirm( 'isStoryPublic', 'Generate public story? (Selecting "No" will create an internal story)', true, ({ hasStory }) => hasStory ), promptList( 'group', 'Select component group for the story (e.g. Forms, Layout)', () => componentGroups, 0, ({ hasStory }) => hasStory ), ]); }; export const generateComponents: ComponentGenerator = async ({ details, path }) => { const name = pascalCase(details.name); const getCompiled = (template: string) => { return _template(template)({ ...details, name }); }; const filePath = `${path}/${name}`; let paths = []; fs.writeFileSync(`${filePath}.tsx`, getCompiled(componentTpl)); paths.push(`${filePath}.tsx`); if (details.hasTests) { fs.writeFileSync(`${filePath}.test.tsx`, getCompiled(testTpl)); paths.push(`${filePath}.test.tsx`); } if (details.hasStory) { const storyExt = details.isStoryPublic ? '.story.tsx' : '.story.internal.tsx'; fs.writeFileSync(`${filePath}${storyExt}`, getCompiled(storyTpl)); fs.writeFileSync(`${filePath}.mdx`, getCompiled(docsTpl)); paths.push(`${filePath}${storyExt}`, `${filePath}.mdx`); } console.log('Generated files:'); console.log(paths.join('\n')); }; const componentCreateRunner: TaskRunner = async () => { const destPath = process.cwd(); const details = await promptDetails(); await generateComponents({ details, path: destPath }); }; export const componentCreateTask = new Task('component:create', componentCreateRunner);