Skip to content

Commit f7134b4

Browse files
committedJan 26, 2021
init generic
0 parents  commit f7134b4

26 files changed

+18710
-0
lines changed
 

‎.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
node_modules/
2+
build/
3+
storybook-static/

‎.storybook/main.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
const path = require("path");
2+
3+
module.exports = {
4+
stories: ["../src/**/*.stories.tsx"],
5+
// Add any Storybook addons you want here: https://storybook.js.org/addons/
6+
addons: [],
7+
webpackFinal: async (config) => {
8+
config.module.rules.push({
9+
test: /\.scss$/,
10+
use: ["style-loader", "css-loader", "sass-loader"],
11+
include: path.resolve(__dirname, "../")
12+
});
13+
14+
config.module.rules.push({
15+
test: /\.(ts|tsx)$/,
16+
loader: require.resolve("babel-loader"),
17+
options: {
18+
presets: [["react-app", { flow: false, typescript: true }]]
19+
}
20+
});
21+
config.resolve.extensions.push(".ts", ".tsx");
22+
23+
return config;
24+
}
25+
};

‎.storybook/preview.js

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/**
2+
* Read https://storybook.js.org/docs/react/configure/overview#configure-story-rendering
3+
* for more information about the purpose of this file.
4+
*
5+
* Use preview.js for global code (such as CSS imports or JavaScript mocks)
6+
* that applies to all stories. For example, `import thirdPartyCss.css`.
7+
*
8+
* This file can have three exports:
9+
* - decorators - an array of global decorators
10+
* - parameters - an object of global parameters
11+
* - globalTypes - definition of globalTypes
12+
*/
13+
14+
/**
15+
* Decorators
16+
*
17+
* A decorator is a way to wrap a story in extra “rendering” functionality.
18+
*
19+
* Example:
20+
*
21+
* import React from 'react';
22+
* export const decorators = [(Story) => <div style={{ margin: '3em' }}><Story/></div>];
23+
*
24+
* Each story throughout the library will be wrapped in a div with a margin of 3
25+
*/
26+
27+
/**
28+
* Parameters
29+
*
30+
* Most Storybook addons are configured via a parameter-based API.
31+
* You can set global parameters in this file
32+
*
33+
* export const parameters = {
34+
* backgrounds: {
35+
* values: [
36+
* { name: 'red', value: '#f00' },
37+
* { name: 'green', value: '#0f0' },
38+
* ],
39+
* },
40+
* };
41+
*
42+
* With backgrounds, you configure the list of backgrounds that every story can render in.
43+
*/
44+
45+
/**
46+
* Global Types
47+
*
48+
* Global Types allow you to add your own toolbars by creating
49+
* globalTypes with a toolbar annotation:
50+
*
51+
* For example:
52+
*
53+
* export const globalTypes = {
54+
* theme: {
55+
* name: 'Theme',
56+
* description: 'Global theme for components',
57+
* defaultValue: 'light',
58+
* toolbar: {
59+
* icon: 'circlehollow',
60+
* // array of plain string values or MenuItem shape
61+
* items: ['light', 'dark'],
62+
* },
63+
* },
64+
* };
65+
*
66+
* Will add a new dropdown in your toolbar with options light and dark.
67+
**/

‎README.md

+272
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,272 @@
1+
# Hoare Lea Common Web UI Library
2+
3+
[![Build status](https://badge.buildkite.com/90ff98db996bb137c5be1bdce666c4b1ce68a25b17af0a6a04.svg?branch=master)](https://buildkite.com/harvey/hl-common-auth)
4+
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
5+
6+
React component library using:
7+
8+
- [Rollup](https://github.com/rollup/rollup)
9+
- [Sass](https://sass-lang.com/)
10+
- [TypeScript](https://www.typescriptlang.org/)
11+
12+
Features:
13+
14+
- [Storybook](https://storybook.js.org/) to help you create and show off your components
15+
- [Jest](https://jestjs.io/) and [React Testing Library](https://github.com/testing-library/react-testing-library) enabling testing of the components
16+
17+
18+
19+
## Development
20+
21+
### Testing
22+
23+
```
24+
npm run test
25+
```
26+
27+
### Building
28+
29+
```
30+
npm run build
31+
```
32+
33+
### Storybook
34+
35+
To run a live-reload Storybook server on your local machine:
36+
37+
```
38+
npm run storybook
39+
```
40+
41+
To export your Storybook as static files:
42+
43+
```
44+
npm run storybook:export
45+
```
46+
47+
You can then serve the files under `storybook-static` using S3, GitHub pages, Express etc. I've hosted this library at: https://www.harveydelaney.com/hl-common-auth
48+
49+
### Generating New Components
50+
51+
I've included a handy NodeJS util file under `util` called `create-component.js`. Instead of copy pasting components to create a new component, you can instead run this command to generate all the files you need to start building out a new component. To use it:
52+
53+
```
54+
npm run generate YourComponentName
55+
```
56+
57+
This will generate:
58+
59+
```
60+
/src
61+
/YourComponentName
62+
YourComponentName.tsx
63+
YourComponentName.stories.tsx
64+
YourComponentName.test.tsx
65+
YourComponentName.types.ts
66+
YourComponentName.scss
67+
```
68+
69+
The default templates for each file can be modified under `util/templates`.
70+
71+
Don't forget to add the component to your `index.ts` exports if you want the library to export the component!
72+
73+
### Installing Component Library Locally
74+
75+
Let's say you have another project (`test-app`) on your machine that you want to try installing the component library into without having to first publish the component library. In the `test-app` directory, you can run:
76+
77+
```
78+
npm i --save ../hl-common-auth
79+
```
80+
81+
which will install the local component library as a dependency in `test-app`. It'll then appear as a dependency in `package.json` like:
82+
83+
```JSON
84+
...
85+
"dependencies": {
86+
...
87+
"hl-common-auth": "file:../hl-common-auth",
88+
...
89+
},
90+
...
91+
```
92+
93+
Your components can then be imported and used in that project.
94+
95+
## Publishing
96+
97+
### Hosting via NPM
98+
99+
First, make sure you have an NPM account and are [logged into NPM using the `npm login` command.](https://docs.npmjs.com/creating-a-new-npm-user-account)
100+
101+
Then update the `name` field in `package.json` to reflect your NPM package name in your private or public NPM registry. Then run:
102+
103+
```
104+
npm publish
105+
```
106+
107+
The `"prepublishOnly": "npm run build"` script in `package.json` will execute before publish occurs, ensuring the `build/` directory and the compiled component library exist.
108+
109+
### Hosting via GitHub
110+
111+
I recommend you host the component library using NPM. However, if you don't want to use NPM, you can use GitHub to host it instead.
112+
113+
You'll need to remove `build/` from `.gitignore`, build the component library (`npm run build`), add, commit and push the contents of `build`. [See this branch for an example.](https://github.com/HarveyD/hl-common-auth/tree/host-via-github)
114+
115+
You can then install your library into other projects by running:
116+
117+
```
118+
npm i --save git+https://github.com/HarveyD/hl-common-auth.git#branch-name
119+
```
120+
121+
OR
122+
123+
```
124+
npm i --save github:harveyd/hl-common-auth#branch-name
125+
```
126+
127+
## Usage
128+
129+
Let's say you created a public NPM package called `harvey-component-library` with the `TestComponent` component created in this repository.
130+
131+
Usage of the component (after the library installed as a dependency into another project) will be:
132+
133+
```TSX
134+
import React from "react";
135+
import { TestComponent } from "harvey-component-library";
136+
137+
const App = () => (
138+
<div className="app-container">
139+
<h1>Hello I'm consuming the component library</h1>
140+
<TestComponent theme="primary" />
141+
</div>
142+
);
143+
144+
export default App;
145+
```
146+
147+
[Check out this Code Sandbox for a live example.](https://codesandbox.io/s/harvey-component-library-example-y2b60?file=/src/App.js)
148+
149+
### Using Component Library SASS Variables
150+
151+
I've found that it's helpful to export SASS variables to projects consuming the library. As such, I've added the `rollup-plugin-copy` NPM package and used it to copy the `typography.scss` and `variables.scss` into the `build` directory as part of the Rollup bundle process. This allows you to use these variables in your projects consuming the component library.
152+
153+
For example, let's say you installed `harvey-component-library` into your project. To use the exported variables/mixins, in a SASS file you would do the following:
154+
155+
```Sass
156+
@import '~harvey-component-library/build/typography';
157+
158+
.example-container {
159+
@include heading;
160+
161+
color: $harvey-white;
162+
}
163+
```
164+
165+
## Additional Help
166+
167+
### Using Alternatives to Sass
168+
169+
#### Less or Stylus
170+
171+
The Rollup plugin `rollup-plugin-postcss` supports Sass, Less and Stylus:
172+
173+
- For Stylus, install stylus: `yarn add stylus --dev`
174+
- For Less, install less: `yarn add less --dev`
175+
176+
You can then remove `node-sass` from your dependencies.
177+
178+
#### CSS Modules
179+
180+
If you want to use CSS Modules, update `postcss` in `rollup-config.js` to:
181+
182+
```
183+
postcss({
184+
modules: true
185+
})
186+
```
187+
188+
#### Styled Components
189+
190+
If you want to use [`styled-components`](https://styled-components.com/), the changes required are a bit more involved. As such, I've created a branch where I've got `styled-components` working in this component library, [check it out here](https://github.com/HarveyD/hl-common-auth/tree/styled-components).
191+
192+
### Component Code Splitting
193+
194+
Code splitting of your components is not supported by default.
195+
196+
[Read this section of my blog post](https://blog.harveydelaney.com/creating-your-own-hl-common-auth/#introducing-code-splitting-optional-) to find out how and why you would enable code splitting of your components. In summary, code splitting enables users to import components in isolation like:
197+
198+
```
199+
import TestComponent from 'harvey-component-library/build/TestComponent';
200+
```
201+
202+
This can reduce the bundle size for projects using older (CJS) module formats.
203+
204+
You can check out [this branch](https://github.com/HarveyD/hl-common-auth/tree/code-splitting) or [this commit](https://github.com/HarveyD/hl-common-auth/commit/94631be5a871f3b39dbc3e9bd3e75a8ae5b3b759) to see what changes are neccesary to implement it.
205+
206+
Please note, there's an issue with code splitting and using `rollup-plugin-postcss`. I recommend using `rollup-plugin-sass` instead alongside code splitting.
207+
208+
### Supporting Image Imports
209+
210+
Add the following library to your component library [@rollup/plugin-image](https://github.com/rollup/plugins/tree/master/packages/image):
211+
212+
```
213+
npm i -D @rollup/plugin-image
214+
```
215+
216+
Then add it to `rollup-config.js`:
217+
218+
```
219+
...
220+
plugins:[
221+
...,
222+
image(),
223+
...
224+
]
225+
...
226+
```
227+
228+
You can then import and render images in your components like:
229+
230+
```tsx
231+
import logo from "./rollup.png";
232+
233+
export const ImageComponent = () => (
234+
<div>
235+
<img src={logo} />
236+
</div>
237+
);
238+
```
239+
240+
### Supporting JSON Imports
241+
242+
Add the following library to your component library [@rollup/plugin-json](https://github.com/rollup/plugins/tree/master/packages/json):
243+
244+
```
245+
npm i -D @rollup/plugin-json
246+
```
247+
248+
Then add it to `rollup-config.js`:
249+
250+
```
251+
...
252+
plugins:[
253+
...,
254+
json(),
255+
...
256+
]
257+
...
258+
```
259+
260+
You can then import and use JSON as ES6 Modules:
261+
262+
```tsx
263+
import data from "./some-data.json";
264+
265+
export const JsonDataComponent = () => <div>{data.description}</div>;
266+
```
267+
268+
Checkout the [official Rollup plugin list](https://github.com/rollup/plugins) for additional helpful plugins.
269+
270+
271+
Credit:
272+
[Based on the blog post "Creating a React Component Library using Rollup, Typescript, Sass and Storybook" from Harvey Delaney](https://blog.harveydelaney.com)

‎jest.config.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module.exports = {
2+
roots: ["src"],
3+
setupFilesAfterEnv: ["./jest.setup.ts"],
4+
moduleFileExtensions: ["ts", "tsx", "js"],
5+
testPathIgnorePatterns: ["node_modules/"],
6+
transform: {
7+
"^.+\\.tsx?$": "ts-jest"
8+
},
9+
testMatch: ["**/*.test.(ts|tsx)"],
10+
moduleNameMapper: {
11+
// Mocks out all these file formats when tests are run.
12+
"\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
13+
"identity-obj-proxy",
14+
"\\.(css|less|scss|sass)$": "identity-obj-proxy"
15+
}
16+
};

‎jest.setup.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import "@testing-library/jest-dom";

0 commit comments

Comments
 (0)
Please sign in to comment.