Skip to content

Instantly share code, notes, and snippets.

@jgdev
Created March 4, 2023 17:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jgdev/5be8b23a5be6ad737132f9e579a3063f to your computer and use it in GitHub Desktop.
Save jgdev/5be8b23a5be6ad737132f9e579a3063f to your computer and use it in GitHub Desktop.
Generate react components using Plop
import React from 'react';
import { Props as ComponentProps, {{pascalCase name}} } from './{{pascalCase name}}'
export type Props = ComponentProps & {};
export const {{pascalCase name}}Container = (props: Props) => {
return (
<{{pascalCase name}} {...props} />
);
};
export default {{pascalCase name}}Container;
{{#if container}}
export { default, type Props as ContainerProps } from './{{pascalCase name}}Container';
export { type Props, {{pascalCase name}} } from './{{pascalCase name}}';
{{else}}
export { type Props, default } from './{{pascalCase name}}';
{{/if}}
.{{camelCase name}} {}
// import React from "react";
import Storybook from "@storybook/react";
import { {{pascalCase name}} } from "./{{pascalCase name}}";
// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
export default {
title: "Example/{{pascalCase name}}",
component: {{pascalCase name}},
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
argTypes: {},
} as Storybook.ComponentMeta<typeof {{pascalCase name}}>;
// const Template: Storybook.ComponentStory<typeof {{pascalCase name}}> = (args) => (
// <{{pascalCase name}} {...args} />
// );
// export const Primary = Template.bind({});
import { render } from "@testing-library/react";
import Component from "./{{pascalCase name}}";
{{#if container}}
import Container from "./{{pascalCase name}}Container";
{{/if}}
describe("{{pascalCase name}} - Component", () => {
it("should render properly", () => {
const { container } = render(<Component />);
expect(container.firstChild).toMatchSnapshot();
});
});
{{#if container}}
describe("{{pascalCase name}} - Container", () => {
it("should render properly", () => {
const { container } = render(<Container />);
expect(container.firstChild).toMatchSnapshot();
});
});
{{/if}}
import React from 'react';
{{#if container}}
import styles from "./{{pascalCase name}}.module.scss";
{{/if}}
export type Props = {};
export const {{pascalCase name}} = (props: Props) => {
return (
<div {{#if scss}}className={{concat '{styles.' (camelCase name) '}'}}{{/if}} {...props}/>
);
};
export default {{pascalCase name}};
/**
* @typedef {import('plop').NodePlopAPI} NodePlopAPI
*/
/**
@param plop {NodePlopAPI}
*/
module.exports = (plop) => {
plop.setHelper("concat", function (...args) {
return args.reduce(
(result, arg) => (typeof arg === "string" && result + arg) || result,
""
);
});
plop.setGenerator("component", {
description: "Create a component",
prompts: [
{
type: "input",
name: "name",
message: "What is your component name?",
},
{
type: "confirm",
name: "container",
message: "Generate container?",
},
{
type: "confirm",
name: "scss",
message: "Generate sass module?",
},
{
type: "confirm",
name: "storybook",
message: "Generate storybook?",
},
{
type: "confirm",
name: "test",
message: "Generate tests?",
},
],
actions: [
// Create component file
{
type: "add",
path: "components/{{pascalCase name}}/{{pascalCase name}}.tsx",
templateFile: "Component.tsx.hbs",
},
// Create container file
{
type: "add",
path: "components/{{pascalCase name}}/{{pascalCase name}}Container.tsx",
templateFile: "Component.container.tsx.hbs",
skip: ({ container }) => !container && "No container file needed",
},
// Create storybook file
{
type: "add",
path: "components/{{pascalCase name}}/{{pascalCase name}}.storybook.tsx",
templateFile: "Component.storybook.tsx.hbs",
skip: ({ storybook }) => !storybook && "No storybook file needed",
},
// Create test file
{
type: "add",
path: "components/{{pascalCase name}}/{{pascalCase name}}.test.tsx",
templateFile: "Component.test.tsx.hbs",
skip: ({ test }) => !test && "No test file needed",
},
// Create test file
{
type: "add",
path: "components/{{pascalCase name}}/{{pascalCase name}}.module.scss",
templateFile: "Component.module.scss.hbs",
skip: ({ scss }) => !scss && "No sass module needed",
},
// Create index file
{
type: "add",
path: "components/{{pascalCase name}}/index.tsx",
templateFile: "Component.index.tsx.hbs",
},
],
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment