Multiple Props Options for Styled Components
Styled components also accepts a function where in you can read props. Moreover if you choose to pass a theme prop instead, you can also define an object for your themes.
const themes = {
dark: css `
background: ${colors.dark};
color: ${colors.light};
`,
light: css`
background: ${colors.light};
color: ${colors.dark};
`
}
export const Navbar = styled.nav(({theme})=>`
width: 100%;
background: ${colors.light};
color: ${colors.dark};
... // rest of the css
${theme?themes[theme]:''}
`)
<Navbar theme="dark" />
This is the solution I ended up using:
export const Navbar = styled.nav`
width: 100%;
... // rest of the regular CSS code
${props => {
if (props.dark) {
return `
background: ${colors.dark};
color: ${colors.light};
`
} else if (props.light) {
return `
background: ${colors.light};
color: ${colors.dark};
`
} else {
return `
background: ${colors.light};
color: ${colors.dark};
`
}
}}
`
Keep the passed in prop
name the same. Then you can utilize a switch/case
statement. For example, passing in a color
prop and using it as a type
to be matched against a case
.
Working example:
For example:
<Button color="primary">Example</Button>
components/Button
import styled from "styled-components";
const handleColorType = color => {
switch (color) {
case "primary":
return "#03a9f3";
case "danger":
return "#f56342";
default:
return "#fff";
}
};
const Button = styled.button`
display: block;
cursor: pointer;
border: 0;
margin: 5px 0;
background: #000;
font-size: 20px;
color: ${({ color }) => handleColorType(color)};
&:focus {
outline: 0;
}
`;
export default Button;
If you have multiple attributes (like a color
and a background
pair), then utilizing the same concept as above, alter the handleColorType
to return a string
with attributes and invoke the handleColorType
function without a style property.
For example:
<MultiButton color="primary">Example</MultiButton>
components/MultiButton
import styled from "styled-components";
const handleColorType = color => {
switch (color) {
case "primary":
return "color: #03a9f3; background: #000;";
case "danger":
return "color: #fff; background: #f56342;";
default:
return "color: #000; background: #eee;";
}
};
const MultiButton = styled.button`
display: block;
margin: 5px 0;
cursor: pointer;
border: 0;
font-size: 20px;
${({ color }) => handleColorType(color)};
&:focus {
outline: 0;
}
`;
export default MultiButton;
Something more elegant (I guess) and modern would be a combination of destructuring the props and using the switch statement such as:
const Button = styled.button`
${({primary, secondary}) => {
switch(true) {
case primary:
return `background-color : green`
case secondary:
return `background-color : red`
}
}
}
`