
React, MUI Reusable components using Storybooks.
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.