Reputation: 6991
I am trying to implement a material designed based button component using styled-components. The component will have a number of props (such as size, icon, floating, etc).
It is getting rather overwhelming, though, to manage all the various combinations of props.
For instance, buttons come in three sizes: default, small and large.
But the size of a small button changes based on whether or not it is a regular button or a floating button. The same goes for a large button.
So I have the following sizes:
And, of course, I have other combinations that I haven't listed.
As a result, my code is starting to get a bit convoluted as I have to not only check for the existence of a prop (${props => { if (props.floating)...
), but also for whether or not that particular prop exists in combination with another prop (${props => { if (props.floating && props.small)...
).
As such, I am wondering if anyone has any suggestions on how to best organize and structure props when dealing with large numbers of combinations?
Thanks.
Upvotes: 0
Views: 2854
Reputation: 14927
I prefer to keep my css separate, like in a styles.js
file. Take the following code for example. It keeps the css organized, and makes implementing the different options pretty clean. Of course, add your css into the appropriate definitions
//styles.js
import { css } from 'styled-components';
export const buttonbase = css`/*base styles for all buttons*/`;
export const small = css`/*small size styles*/`;
export const medium = css`/*default size styles*/`;
export const large = css`/*large size styles*/`;
export const floating = css`/*float styles*/`;
And in your component file:
//Button.js
import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';
import * as Styles from './styles';
const propTypes = {
floating: PropTypes.bool,
size: PropTypes.oneOf(['small', 'medium', 'large']),
children: PropTypes.node,
};
const defaultProps = {
floating: false,
size: 'medium',
};
const ButtonBase = styled.button`
${Styles.buttonbase};
${props => (props.floating ? Styles.floating : '')};
${props => Styles[props.size]};
`;
const Button = ({ floating, size, children, ...rest }) => (
<ButtonBase
size={size}
floating={floating}
{...rest}
>
{children}
</ButtonBase>
);
Button.propTypes = propTypes;
Button.defaultProps = defaultProps;
export default Button;
The result would be, say given these values:
export const buttonbase = css`
border: 1px solid black;
padding: 10px;
`;
export const medium = css`
font-size: 16px;
height: 30px;
`;
export const floating = css`
float: left;
`;
And this component:
<Button size="medium" floating />
The <ButtonBase/>
component puts together buttonbase
, medium
, and floating
from the imported styles, generating the complete style:
border: 1px solid black;
padding: 10px;
font-size: 16px;
height: 30px;
float: left;
Upvotes: 2
Reputation: 191
I use a package called styled-is to help style my styled-components, it comes with helper functions you just use directly with styled-components.
Upvotes: 1
Reputation: 459
Keep in mind you can destructure within your instantiation. For example you might write like so:
${({ floating, small }) => {
if (floating && small){
...
}
}
It will cut down some of the bloat.
Upvotes: 3