Image by: Image by rawpixel.com on Freepik

React, MUI Reusable components using Storybooks.

Fredrick Mbugua
4 min readFeb 16, 2023

React and Material UI are powerful tools for building beautiful and functional user interfaces. However, as applications become more complex, managing styles across multiple components can quickly become a headache. That’s where reusable styled-components come in. By creating a library of reusable components, you can keep your styles consistent and reduce duplication of code.

One popular tool for documenting and testing reusable components is Storybook. In this article, we’ll explore how to write reusable styled-components for React and Material UI on Storybook.

First, let’s take a look at how to create a simple Material UI button component in React:

import React from 'react';
import Button from '@material-ui/core/Button';

const CustomButton = ({ children, ...props }) => (
<Button variant="contained" color="primary" {...props}>
{children}
</Button>
);

export default CustomButton;

In this example, we’re using the Button component from Material UI and passing in the variant and color props to customize the appearance of the button. We're also using the spread operator (...props) to pass any additional props through to the Button component.

Now let’s add some custom styles to our button. We can do this using the makeStyles hook from Material UI:

import React from 'react';
import Button from '@material-ui/core/Button';
import { makeStyles } from '@material-ui/core/styles';

const useStyles = makeStyles({
root: {
borderRadius: 0,
boxShadow: 'none',
textTransform: 'none',
fontSize: 16,
padding: '6px 12px',
border: '1px solid',
lineHeight: 1.5,
backgroundColor: '#007bff',
borderColor: '#007bff',
'&:hover': {
backgroundColor: '#0069d9',
borderColor: '#0062cc',
boxShadow: 'none',
},
'&:active': {
boxShadow: 'none',
backgroundColor: '#0062cc',
borderColor: '#005cbf',
},
'&:focus': {
boxShadow: '0 0 0 0.2rem rgba(0,123,255,.5)',
},
},
});

const CustomButton = ({ children, ...props }) => {
const classes = useStyles();
return (
<Button
variant="contained"
color="primary"
className={classes.root}
{...props}
>
{children}
</Button>
);
};

export default CustomButton;

In this example, we’re using the makeStyles hook to define a custom-style object for our button. We're then using the className prop to apply these styles to our Button component.

Now that we have our reusable styled button component, we can document it and test it using Storybook. Here’s an example of how to do that:

import React from 'react';
import { storiesOf } from '@storybook/react';
import CustomButton from './CustomButton';

storiesOf('CustomButton', module).add('default', () => (
<CustomButton>Hello, world!</CustomButton>
));

In this example, we’re using the storiesOf function from Storybook to create a new story for our CustomButton component. We're then using the add function to add a new story to our component. In this case, we're just rendering our CustomButton component with the text "Hello, world!".

By following this pattern, you can easily create a library of reusable styled-components for your React and Material UI applications. And with Storybook, you can document and test these components with ease.

To demonstrate how you can build on this pattern to create more complex components, let’s create a reusable alert component.

import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Alert from '@material-ui/lab/Alert';

const useStyles = makeStyles((theme) => ({
alert: {
borderRadius: theme.shape.borderRadius,
padding: theme.spacing(1),
marginBottom: theme.spacing(2),
display: 'flex',
alignItems: 'center',
},
icon: {
marginRight: theme.spacing(1),
},
}));

const CustomAlert = ({ type, message }) => {
const classes = useStyles();

return (
<Alert
severity={type}
className={classes.alert}
icon={false}
>
<div className={classes.icon}>
{type === 'success' && <CheckCircleOutlineIcon />}
{type === 'error' && <HighlightOffIcon />}
{type === 'warning' && <WarningIcon />}
{type === 'info' && <InfoIcon />}
</div>
{message}
</Alert>
);
};

export default CustomAlert;

In this example, we’re using the Alert component from Material UI to create an alert with a customizable type and message prop. We're also using the makeStyles hook to define a custom style object for our alert, including some additional styles for the icon and message.

We’re then rendering the Alert component with the severity, className, and icon props, and using conditional rendering to determine which icon to show based on the type prop.

Finally, we’re exporting our CustomAlert component so it can be used in other parts of our application.

Here’s how you can document and test our CustomAlert component using Storybook:

import React from 'react';
import { storiesOf } from '@storybook/react';
import CustomAlert from './CustomAlert';

storiesOf('CustomAlert', module)
.add('success', () => (
<CustomAlert type="success" message="Success message" />
))
.add('error', () => (
<CustomAlert type="error" message="Error message" />
))
.add('warning', () => (
<CustomAlert type="warning" message="Warning message" />
))
.add('info', () => (
<CustomAlert type="info" message="Info message" />
));

In this example, we’re using the storiesOf function to create a new story for our CustomAlert component. We're then using the add function to add a new story for each type of alert.

By following these patterns, you can create a library of reusable styled-components for your React and Material UI applications, and use Storybook to document and test them with ease.

Once you have built your library of reusable styled-components and documented them in Storybook, you can easily reuse these components in your React applications.

To use a component, simply import it into your React component and render it with the desired props. For example:

import React from 'react';
import CustomButton from './CustomButton';

const MyComponent = () => {
return (
<div>
<CustomButton color="primary" variant="contained">
Click me!
</CustomButton>
</div>
);
};

export default MyComponent;

In this example, we’re importing the CustomButton component that we built earlier, and rendering it with the color and variant props.

By building a library of reusable styled-components, you can save time and improve the consistency of your UI across your application. And by using Storybook to document and test your components, you can ensure that they are well-documented and thoroughly tested.

Conclusion

In conclusion, building reusable styled-components for React and Material UI can be a powerful way to improve the efficiency and consistency of your UI development. With Storybook, you can easily document and test these components, making them even more valuable to your development process.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Fredrick Mbugua
Fredrick Mbugua

Written by Fredrick Mbugua

Software Developer @Safaricom. Experienced in Web, Mobile (Flutter & Kotlin), CrytpoCurrency, Smart Contracts, API and Software Design, Interaction Design

No responses yet

Write a response