Liquid Component React UI Library is a node package for the UI components for the liquid cloud initiative.
npm run rollup
npm run tailwind
npm publish
npm run test
npm run storybook
npm run build-storybook
Setup is very simple. Just install the dependencies:
npm i
When creating a new component, make sure to follow the same patterns. Since we are creating a library, we are going to create index files for each tier, and export our components from each one to make it as easy as possible for the people using our library to import them.
The project structure is as follows:
.
├── src
│ ├── components
| │ ├── Button
| | │ ├── Button.tsx
| | │ └── index.ts
| │ └── index.ts
│ └── index.ts
├── package.json
└── package-lock.json
Here's an example of what a simple Button component should look like:
src/components/Button/Button.tsx
import React from 'react'
export interface ButtonProps {
label: string
}
const Button = (props: ButtonProps) => {
return <button>{props.label}</button>
}
export default Button
src/components/Button/index.ts
export { default } from './Button'
src/components/index.ts
export { default as Button } from './Button'
And finally, we will export all of our components from the base src directory:
src/index.ts
export * from './components'
Note that the props Button
receives has an acompanying interface. Make sure that every property that can be used by the component is properly typed. Also determine whether that property has a default level and whether it is required.
Before publishing be sure to bump the version on package.json
. You can then publish it using:
npm publish
To run this package locally start by building the bundle with npm run rollup
and then package it all with npm pack
.
That will generate a file like 'liquidcloud-liquid-component-0.6.2.tgz'.
Now head over to the project you want to use this package with and type:
npm i path/to/file/liquidcloud-liquid-component-0.6.2.tgz
Now you can use the package in any project locally.
We will use React Testing Library for tests.
Be sure to include test cases for every component added. Here's what a test would look like for our Button
component:
Inside of our Button directory, create a new file called Button.test.tsx
src/components/Button/Button.test.tsx
import React from 'react'
import { render } from '@testing-library/react'
import Button from './Button'
describe('Button', () => {
test('renders the Button component', () => {
render(<Button label="Hello world!" />)
})
})
What this will do is render our button on a non-browser DOM implementation and make sure that it mounts properly. This is a very simple test, but it serves as a good example of the syntax you can use to get started. To go deeper in depth read further in the React Testing Library documentation.
You can run the tests at any time with:
npm run test
Storybook is a a tool for visualizing UI components outside of your site / application. It's fantastic for prototyping and testing different visual states of components to ensure they work the way they are designed to without the extra overhead of having other unrelated components on the screen.
It also gives you an easy way to see and use your components while working on them in your library project, without having to build an unnecessary testing page just to display them.
Let's create a simple story for our button. Create a new file in the Button
directory called Button.stories.tsx
:
src/components/Button/Button.stories.tsx
import React from 'react'
import { ComponentStory, ComponentMeta } from '@storybook/react'
import Button from './Button'
// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
export default {
title: 'LiquidComponent/Button',
component: Button,
} as ComponentMeta<typeof Button>
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
const Template: ComponentStory<typeof Button> = (args) => <Button {...args} />
export const HelloWorld = Template.bind({})
// More on args: https://storybook.js.org/docs/react/writing-stories/args
HelloWorld.args = {
label: 'Hello world!',
}
export const ClickMe = Template.bind({})
ClickMe.args = {
label: 'Click me!',
}
This might be a little overwhelming at first, but when you go through it piece by piece you should see it's fairly straightforward.
-
The default export defines where the button will appear in the Storybook. I've chosen LiquidComponent as a simple name to group our custom components together.
-
The Template determines which component is actually being rendered, and which default args/props to apply to it.
-
The Template.bind objects are instances or example states of the component. So in a real project you might have something like "LargeButton" and "SmallButton". Since our button is always big I've just used an example of testing the button with two different labels.
You can run storybook at any time with:
npm run storybook
There is plenty more to learn about Storybook, make sure to read through the documentation.
Any React project can use this library simply by installing the package:
npm install @liquidcloud/liquid-component
Then importing and using the component:
import Button from '@liquidcloud/liquid-component'
const MyApp = () => {
return <Button>Click me</Button>
}