Create styled-components library

Part 1— setup, styled components and storybook

Kacper Brezdeń
3 min readJan 26, 2019

Recently at my work I’ve had a pleasure to start using Typescript and experiment with styled-components. It changed my frontend perspective completely. As a side project I’ve decided to create my first component library with static types and styled-components included.

Setup

npx create-react-app components-library --typescript

I’ve started from simple create react app template with support for typescript. We don’t really need webpack but if we’d like to create example app which uses our components it might come in handy. Since I’ve learned not to fear webpack configurations but to understand it I always eject my projects. This gives you better understanding of how your app is configured and how it works without hidden magic.

npm run eject 

After ejection we can add storybook to our project that will allow as to showcase and document our library.

npx -p @storybook/cli sb init && npm run storybook
Empty storybook in the browser and project structure

My good practice is to have everything concerning single entity such as component I like to keep tests storybook stories and component itself in the same directory. In order to configure storybook to look for the stories in all of src/components directory we have to configure it as follows

//.storybook/config.js
import
{ configure } from '@storybook/react';

// automatically import all files ending in *.stories.js
const req = require.context('../src/components', true, /.stories.js$/);
function loadStories() {
req.keys().forEach(filename => req(filename));
}

configure(loadStories, module);

To enable typescript support we have to edit storybooks webpack config and replace it’s content with the code below. This will allow to use typescript modules in the javascript stories.

//.storybook/webpack.config.js
const
path = require('path');
module.exports = (baseConfig, env, config) => {
config.resolve.modules = [
...(config.resolve.modules || []),
path.resolve(__dirname, '../src')
];
config.module.rules.push({
test: /\.(ts|tsx)$/,
loader: require.resolve("babel-loader"),
options: {
presets: [["react-app", { flow: false, typescript: true }]]
}
});
config.resolve.extensions.push(".ts", ".tsx");

return config;
};

💅 Styled components 💅

The big reason why I’m thinking that now is a great time to create a component library are styled components. There’s been projects alike before but this one shook the industry. After release of v3.1 which gave ~10x performance improvement and then another v4.0 with another 25% and many improvements. It became almost as performant as css modules with much better API. To add styled-components to our project simply run

npm i @types/styled-componentsnpm i -D styled-components

We’re adding styled-components to devDependencies to avoid conflict when installing your library in another project.

Make sure that you add styled-components as peerDependency so that your future users wouldn’t be angry for missing styled-components 😭.

//package.json
...,
"peerDependencies": {
"styled-components": "^4.1.3"
},
...

First component

Our first component should be fairly easy so as always we’ll go for the button 😅.

//src/components/button/index.tsximport styled from "styled-components";const StyledButton = styled.button`
padding-bottom: 10px;
padding-left: 20px;
padding-right: 20px;
padding-top: 15px;
background-color: red;
&:active {
outline: 0;
color: #fff;
top: 1px;
}
`;
export const Button = StyledButton;

And story for this button

//src/components/button/button.stories.jsimport React from "react";

import { storiesOf } from "@storybook/react";
import {Button} from './';

storiesOf("Button", module)
.add("with text", () => (
<Button>Hello Button</Button>
));
Yaaay, it works 🎉

To learn how to statically type your styled-components head over to the second part of this tutorial 😎

--

--

Kacper Brezdeń

Full stack web developer, struggling for motivation to create something useful as a side project