Styled-System for better Styled-Components

karthik balaji
Nov 5 · 3 min read

Recently I was facing a problem with my react components, I use styled-components for styling react components.

So, whats the problem ?

I have a checkbox, Toggle button components etc. and many other re-usable atomic components.

Ok .. Then what

One of my colleague wants to use the toggle component and apply margin CSS to it . So currently toggle component doesn’t accept margin prop that’s the problem .

How do we solve it before using styled-system ?

Toggle.js without styled-system

APPROACH 1: Create a wrapper component to apply margin CSS to Toggle component

// some component using Toggle componentimport Toggle from './Toggle';
import styled from 'styled-components';
const Demo = () => (
<StyledToggleWrapper>
<Toggle />
</StyledToggleWrapper>
);
const StyledToggleWrapper = styled.div`
margin-left: 5px;
margin-right: 10px;
`;

uh .. This solves the problem but we ended up writing a lot of wrapper styled components .

APPROACH 2: Add a new prop to Toggle component to accept margin

// Toggle.jsimport React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Toggle = ({ margin, checked, onToggle }) => (
<Container checked={checked} onClick={() => onToggle(checked)}>
<IndicatorCircle checked={checked} />
</Container>
);

Toggle.propTypes = {
margin: PropTypes.string,
checked: PropTypes.bool.isRequired,
onToggle: PropTypes.func.isRequired,
}
Toggle.defaultProps = {
margin: "0px",
}
export default Toggle;

const Container = styled.div`
height: 11px;
width: 21px;
margin: ${({ margin }) => `${margin}`};
`;
const IndicatorCircle = styled.div`
// removed for demo purpose
`;
// some component using Toggle componentimport Toggle from './Toggle';const Demo = () => (
<Toggle margin="0px 10px 0px 5px"/>
);

This solves the problem of having wrapper component and now supports margin.

So what now ?

Requirements keep on increasing in near future we need Toggle component to accept padding, color etc … list grows

So you end up adding new prop to the re-usable components . This is doesn’t scale well.

APPROACH 3: STYLED-SYSTEM for RESCUE !!!!

// Toggle.js with styled-systemimport React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import { space, color } from 'styled-system';

const Toggle = ({ checked, onToggle, ...rest }) => (
<Container checked={checked} onClick={() => onToggle(checked)} {...rest}>
<IndicatorCircle checked={checked} />
</Container>
);

Toggle.propTypes = {
checked: PropTypes.bool.isRequired,
onToggle: PropTypes.func.isRequired,
};

export default Toggle;

const Container = styled.div`
height: 11px;
width: 21px;
${space}
${color}

`;

const IndicatorCircle = styled.div`
// removed for demo
`;

Just adding space and color utility from styled-system to styled component will add the capability for margin, padding, color, background-color CSS.

Also styled-system provides CSS shorthand out-of-box like Bootstrap and Material-UI frameworks

API reference:

So this is how to use our Toggle component

// some component using Toggle componentimport Toggle from './Toggle';const Demo = () => (
<Toggle ml="5px" mr="10px" />
);
// Example 2: supports padding and background colorconst Demo = () => (
<Toggle ml="5px" mr="10px" p="2px" bg="red" />
);

Now by using styled-system its easy to support new CSS properties . If you need to support width and height for Toggle component just use layoututility from styled-system .

Styled-System is not limited to this , it has a lot of good features . You can checkout here

Happy to hear from you how styled-system helps you !!!

karthik balaji

Written by

ME(R/A)N Stack Developer , Hitting the keyboard hard until the magic happens !!!

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade