@balazs31/new-component
v0.5.1
Published
CLI for creating new React components
Downloads
6
Readme
Create a new React component
Forked from https://github.com/joshwcomeau/new-component. Added Storybook and basic testing.
Usage
Install via NPM:
Globally for all projects
# Using Yarn:
$ yarn global add @balazs31/new-component
# or, using NPM
$ npm i -g @balazs31/new-component
Locally for a specific project
# Using Yarn:
$ yarn add @balazs31/new-component
# or, using NPM
$ npm i @balazs31/new-component
Then run:
$ cd PROJECT_DIRECTORY
$ new-component Button
Packages included
clsx
for better class names
See https://www.npmjs.com/package/clsx for details.
i18next
for multi-language support
Will support the following languages / locales:
- Romanian (default):
ro-RO
- Hungarian:
hu-HU
- German:
de-DE
- English:
en-US
The locales / short codes were chosen from this list.
See https://github.com/i18next/react-i18next for details.
Setup
You must have a i18n.js
config file next to the index.js
file in a CRA app.
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
/**
* Sets up translations
*
* - Every component manages it's own translations via namespaces
* - Every component adds it's own translation items to `resources`
*
* @see https://github.com/i18next/react-i18next/issues/299
* @see https://react.i18next.com/latest/usetranslation-hook#loading-namespaces
*
*/
const resources = {};
/**
* Sets up i18next
*
* @see https://react.i18next.com/latest/using-with-hooks
*/
i18n
/**
* Detects user language
*
* @see https://github.com/i18next/i18next-browser-languageDetector
*/
.use(LanguageDetector)
/**
* Passes the i18n instance to react-i18next.
*/
.use(initReactI18next)
/**
* Inits i18next
*
* @see https://www.i18next.com/overview/configuration-options
*/
.init({
resources,
lng: "en-EN",
keySeparator: false, // we do not use keys in form messages.welcome
interpolation: {
escapeValue: false, // react already safes from xss
},
});
export default i18n;
In index.js
you'll have to add this import statement:
import "./i18n"; // See https://react.i18next.com/latest/using-with-hooks
What you'll get
In src/components/Button
:
// `Button/Button.js`
/**
* Component short description
*
* @see Button.md for details
*/
/**
* Imports React and third party packages
*/
import React from "react";
import clsx from "clsx";
/**
* Imports project specific components and hooks
*/
/**
* Imports propTypes / component data requirements
*/
import { propTypes, defaultProps } from "./Button.data";
/**
* Imports Material UI components
*/
import { makeStyles } from "@material-ui/core";
import Grid from "@material-ui/core/Grid";
/**
* Imports translations
*/
import i18n from "../../i18n";
import { useTranslation } from "react-i18next";
import { ro_ro } from "./Button.lang.ro-ro";
import { hu_hu } from "./Button.lang.hu-hu";
import { en_us } from "./Button.lang.en-us";
import { de_de } from "./Button.lang.de-de";
i18n.addResourceBundle("ro-RO", "Button", ro_ro);
i18n.addResourceBundle("hu-HU", "Button", hu_hu);
i18n.addResourceBundle("en-US", "Button", en_us);
i18n.addResourceBundle("de-DE", "Button", de_de);
/**
* Styles the component
*/
const useStyles = makeStyles(theme => ({
container: {
padding: theme.spacing(1),
margin: theme.spacing(1),
border: "1px solid"
}
}));
/**
* Displays the component
*/
const Button = props => {
const { container } = useStyles(props);
const { t } = useTranslation("Button");
return (
<Grid container>
<Grid item xs={12} className={clsx(container, "Button")}>
{t("Button")}
</Grid>
</Grid>
);
};
Button.propTypes = propTypes;
Button.defaultProps = defaultProps;
export default Button;
export { propTypes as ButtonPropTypes, defaultProps as ButtonDefaultProps };
// `Button/Button.data.js`
/**
* Defines the data requirements for the company
*/
import PropTypes from "prop-types";
/**
* Defines the prop types
*/
const propTypes = {};
/**
* Defines the default props
*/
const defaultProps = {};
export { propTypes, defaultProps };
// `Button/Button.native.js`
/**
* React Native specific code
*
* @see https://reactnative.dev/docs/platform-specific-code#platform-specific-extensions
*/
// `Button/Button.md`
## Button
// `Button/Button.test.js`
import React from "react";
import { render } from "@testing-library/react";
import Button from "./Button";
it("has a Button component", () => {
const { getByText } = render(<Button />);
expect(getByText("Button")).toBeInTheDocument();
});
// `Button/index.js`
export { default, ButtonPropTypes, ButtonDefaultProps } from "./Button";
// `Button/Button.lang.en-us.js`
const en_us = {
Button: "Button"
};
export { en_us };
// `Button/Button.lang.de-de.js`
const de_de = {
Button: "Button (de_de)"
};
export { de_de };
// `Button/Button.lang.ro-ro.js`
const ro_ro = {
Button: "Button (ro_ro)"
};
export { ro_ro };
// `Button/Button.lang.hu-hu.js`
const hu_hu = {
Button: "Button (hu_hu)"
};
export { hu_hu };
Modify & test locally
You can easily fork this repo, modify, test, and publish on npm.
NOTE: Always start with changing the version number in package.json
!!
Test locally
In this current repo:
npm pack
This will create a file like [email protected]
.
In another folder:
npx create-react-app new-component-test
cd new-component-test
mkdir src/components
yarn add <path_to_new_component_repo>/[email protected]
./node_modules/.bin/new-component Button
# create the i18n.j file
# import and render <Button> in App.js
yarn start # run server and check the result
Update the changelog
NOTE: Always update the changelog
Publish
First push changes to Github. Then:
npm publish
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.4.3] - 2020-05-27
Changed
- The copy on some comments
import i18n from "../../../i18n";
- that 3 levels of nesting (changed from two) means in this project new components will mostly be added under a page subfolder. Ex:src/components/pagename/Component
[0.4.2] - 2020-05-25
Added
clsx
, for better class names- Material UI, as the default Design System
Removed
styled-components
, replaced with Material UI- Storybook, never used in the previous few projects
[0.3.0] - 2020-01-14
Added
styled-components
, re-added, because when a new component is added it's first purpose is to mockup. Also every new component has a border and padding added to serve mockuping.react-i18next
withaddResourceBundle
loading translations from language files co-located to the component
[0.2.0] - 2019-11-6
Added
- Default tests
Changed
- Storybook stories to follow the Component Story Format: https://storybook.js.org/docs/formats/component-story-format/
Removed
styled-components
, because many times components use another library, likematerial-ui
[0.1.2] - 2018-08-17
Fixed
- Exporting default props
[0.1.1] - 2018-08-17
Changed
- How default props are exported
[0.1.0] - 2018-07-03
Added
- New templates for function components
[0.0.4] - 2018-12-11
Fixed
- Markdown is not run through
prettify()
.
[0.0.3] - 2018-12-11
Added
- Markdown documentation support.
[0.0.2] - 2018-12-11
Added
- A CHANGELOG section in README.
Changed
- The install instructions in README.
0.0.1 - 2018-12-11
Added
- Initial release