diff --git a/README.md b/README.md index e858342..752bf2c 100644 --- a/README.md +++ b/README.md @@ -7,37 +7,103 @@

CLI Usage

-```sh -$ moris create component Example - -$ moris c c Example - -$ moris create component Example --path src/components - -$ moris c c Example -p src/components -``` - -All the commands provided above do the same action -

Arguments

+ + + + + + + + + + + +

Argument

Alias

Default

Description

create component c c-Command to tell Moris to create a component
--path src/pages -p src/pagessrc/componentsOptional argument that is used to specify a path you want a component to be created at
--size s|m|l|xl-s s|m|l|xlmOptional argument that is used to specify a size of the component. s - index.tsx, styles.ts. m - index.tsx, styles.ts, types.ts. l - index.tsx, styles.ts, types.ts, useExample.ts. xl - index.tsx, styles.ts, types.ts, useExample.ts, constants.ts

+```sh +$ moris create component Example + +$ moris c c Example + +$ moris create component Example --path src/components + +$ moris c c Example -p src/components +``` +All the commands provided above do the same action + +

Default files

+ +After running any of the above commands will be created such folder structure and file contents: + +```bash +src +└─ components + └─ Example + ├── index.tsx + ├── styles.ts + ├── useExample.ts + ├── types.ts + └── constants.ts +``` + +```jsx +// index.tsx + +import { useExample } from './useExample'; +import { ExampleProps } from './types'; +import { ExampleWrapper } from './styles'; + +const Example = ({}: ExampleProps) => { +useExample(); + +return ; +}; + +export default Example; +``` + +```jsx +// styles.ts + +import styled from 'styled-components'; + +export const ExampleWrapper = styled.div``; +``` + +```jsx +// useExample.ts + +import { useState, useEffect } from 'react'; + +export const useExample = () => {}; +``` + +```jsx +// types.ts + +export type ExampleProps = {}; +``` + +
+

Configuration file

@@ -68,6 +134,11 @@ moris.json "useAbsolutePath": "src" "-" path without any suffixes, "anything you want" any suffix you prefer + + defaultComponentSet + "defaultComponentSet": "l" + s m l xl + indexContent "indexContent": "import React from 'react'\n" @@ -99,13 +170,16 @@ moris.json

Variable

Description

+

Usage

${name} Uses a dynamic name that you pass when creating a component instead of a statically generated + export const ${name}Wrapper = styled.div`` ${path} Uses a dynamic path that you pass when creating a component instead of a statically generated + import ${name}Wrapper from '${path}${name}' diff --git a/package.json b/package.json index 4cafd63..3b4b850 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { "name": "moris", - "version": "1.0.0", + "version": "1.0.1", "license": "MIT", "author": "Oleksandr Didyshen", "description": "React CLI to generate components", - "main": "./dist/index.js", + "main": "./build/index.js", "bin": { "moris": "./build/index.js" }, @@ -13,20 +13,24 @@ "url": "git+https://github.com/alex-dishen/moris" }, "files": [ - "dist", + "build", "license", "README.md" ], "keywords": [ "CLI", - "generate", + "make", "create", + "generate", "files", + "folders", "template", "templates", "react", "component", - "components" + "components", + "react-component", + "react-components" ], "bugs": { "url": "https://github.com/alex-dishen/moris/issues" diff --git a/src/helpers.ts b/src/helpers.ts index fd4ffdd..112d988 100644 --- a/src/helpers.ts +++ b/src/helpers.ts @@ -73,17 +73,30 @@ export const returnDefaultContent = ( pathWithoutSrc: string, useAbsolutePath?: string, ): TReturnDefaultContent => { + const displayTypesImport = true; + const displayHookImport = true; + const modifiedPath = returnModifiedPath(pathWithoutSrc, useAbsolutePath); + const hookName = `use${name}`; const propsName = `${name}Props`; const stylesName = `${name}Wrapper`; - const modifiedPath = returnModifiedPath(pathWithoutSrc, useAbsolutePath); - const hookImport = useAbsolutePath + const typesPath = useAbsolutePath ? `${modifiedPath}/types` : './types'; + const stylesPath = useAbsolutePath ? `${modifiedPath}/styles` : './styles'; + const hookPath = useAbsolutePath ? `${modifiedPath}/${hookName}` : `./${hookName}`; - const typesImport = useAbsolutePath ? `${modifiedPath}/types` : './types'; - const stylesImport = useAbsolutePath ? `${modifiedPath}/styles` : './styles'; + const hookImport = displayHookImport + ? `import { ${hookName} } from '${hookPath}';\n` + : ''; + const typesImport = displayTypesImport + ? `import { ${propsName} } from '${typesPath}';\n` + : ''; + const componentProps = displayTypesImport ? `{}: ${propsName}` : ''; + const hookCall = displayHookImport ? `\n ${hookName}();\n` : ''; + + // DEFAULT CONTENTS const defaultTypesContent = `export type ${propsName} = {};\n`; @@ -93,12 +106,9 @@ export const ${stylesName} = styled.div\`\`;\n`; const defaultHookContent = `import { useState, useEffect } from 'react';\n export const ${hookName} = () => {};\n`; - const defaultIndexContent = `import { ${hookName} } from '${hookImport}'; -import { ${propsName} } from '${typesImport}'; -import { ${stylesName} } from '${stylesImport}';\n -const ${name} = ({}: ${propsName}) => { -use${name}();\n -return <${stylesName}>; + const defaultIndexContent = `${hookImport}${typesImport}import { ${stylesName} } from '${stylesPath}';\n +const ${name} = (${componentProps}) => {${hookCall} + return <${stylesName}>; };\n export default ${name};\n`; diff --git a/src/index.ts b/src/index.ts index 1d3ebeb..2a0fbe2 100755 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,11 @@ import { returnMorisSettings, returnDefaultContent, } from './helpers'; +import { TOptions } from './types'; + +const dirname = process.cwd(); +let componentFolder: string; +let pathWithoutSrc: string; program.version('1.0.0').description('Custom CLI for React'); @@ -17,11 +22,9 @@ program .alias('c') .description('Create a new React component') .option('-p, --path ', 'Specify a custom path') - .action((name: string, options) => { - const dirname = process.cwd(); + .option('-s, --size ', 'Set component size') + .action((name: string, options: TOptions) => { const componentPath = options.path || 'src/components'; - let componentFolder: string; - let pathWithoutSrc: string; if (options.path) { componentFolder = path.join(dirname, options.path, name); @@ -38,6 +41,7 @@ program typesContent, constantsContent, useAbsolutePath, + defaultComponentSet, } = returnMorisSettings(dirname, name, pathWithoutSrc); const { @@ -50,7 +54,7 @@ program const typesFileContent = typesContent || defaultTypesContent; const stylesFileContent = stylesContent || defaultStylesContent; const hookFileContent = hookContent || defaultHookContent; - const componentContent = indexContent || defaultIndexContent; + const componentFileContent = indexContent || defaultIndexContent; const constantsFileContent = constantsContent || ''; const componentFile = path.join(componentFolder, 'index.tsx'); @@ -62,12 +66,37 @@ program if (fs.existsSync(componentFolder)) return logCommandStatus(name, componentPath, true); + const configurations = { + s: [componentFile, stylesFile], + m: [componentFile, stylesFile, typesFile], + l: [componentFile, stylesFile, typesFile, hookFile], + xl: [componentFile, stylesFile, typesFile, hookFile, constantsFile], + }; + fs.mkdirSync(componentFolder, { recursive: true }); - fs.writeFileSync(componentFile, componentContent); - fs.writeFileSync(stylesFile, stylesFileContent); - fs.writeFileSync(typesFile, typesFileContent); - fs.writeFileSync(hookFile, hookFileContent); - fs.writeFileSync(constantsFile, constantsFileContent); + + const elements = + (options.size as keyof typeof configurations) || + defaultComponentSet || + 'm'; + + const getFileContent = (file: string): string => { + if (file.includes('index')) return componentFileContent; + + if (file.includes('styles')) return stylesFileContent; + + if (file.includes('types')) return typesFileContent; + + if (file.includes('use')) return hookFileContent; + + if (file.includes('constants')) return constantsFileContent; + + return ''; + }; + + configurations[elements].forEach(file => { + fs.writeFileSync(file, getFileContent(file)); + }); logCommandStatus(name, componentPath); }); diff --git a/src/types.ts b/src/types.ts index c030465..15f876a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -5,6 +5,7 @@ export type TMorisSettings = { typesContent?: string; constantsContent?: string; useAbsolutePath?: string; + defaultComponentSet?: string; }; export type TReturnDefaultContent = { @@ -13,3 +14,8 @@ export type TReturnDefaultContent = { defaultStylesContent: string; defaultTypesContent: string; }; + +export type TOptions = { + path?: string; + size?: string; +};