Reputation: 518
I have these styled components:
import styled, { css } from 'styled-components'
const Container = styled.div`
background-color: ${props => props.theme === "light" ? "hsl(0, 0%, 98%)" : "hsl(235, 24%, 19%)" };
border-radius: 4px;
box-shadow: ${props => props.theme === "light" ? "0px 35px 50px -15px rgba(194, 195, 214, 0.5)" : "0px 35px 50px -15px rgba(0, 0, 0, 0.5)" };
`
const Footer = styled.footer`
padding: 25px;
display: flex;
align-items: center;
justify-content: space-between;
color: ${props => props.theme === "light" ? "hsl(236, 9%, 61%)" : "hsl(234, 11%, 52%)" };
font-size: 14px;
`
const Nav = styled.nav`
display: flex;
align-items: center;
justify-content: space-between;
color: inherit;
`
const NavItem = styled.a`
cursor: pointer;
display: inline-block;
color: inherit;
&:hover {
color: ${props => props.theme === "light" ? "hsl(235, 19%, 35%)" : "hsl(236, 33%, 92%)" };
}
&:not(:last-of-type) {
margin-right: 15px;
}
${({ active }) =>
active &&
css`
color: hsl(220, 98%, 61%);
`
}
`
const ClearList = styled.p`
color: inherit;
cursor: pointer;
&:hover {
color: ${props => props.theme === "light" ? "hsl(235, 19%, 35%)" : "hsl(234, 39%, 85%)" };
}
`
And I have this component called TodoList
with a theme
props that get passed to the styled components like this:
const TodoList = ({ theme }) => {
return (
<Container theme={theme}>
<Footer theme={theme}>
<p>5 items left</p>
<Nav>
<NavItem theme={theme}>All</NavItem>
<NavItem theme={theme}>Active</NavItem>
<NavItem theme={theme}>Completed</NavItem>
</Nav>
<ClearList theme={theme}>Clear Completed</ClearList>
</Footer>
</Container>
)
}
export default TodoList
How do I call the theme
props only once in the Container
element and make it accessible to all the child elements such as Clearlist, NavItems and Footer without explicitly passing them
Thank you
Upvotes: 1
Views: 1416
Reputation: 116
You can solve this issue by using ThemeProvider
visit this link https://styled-components.com/docs/advanced
Example
// Define our button, but with the use of props.theme this time
const Button = styled.button`
color: ${props => props.theme.fg};
border: 2px solid ${props => props.theme.fg};
background: ${props => props.theme.bg};
font-size: 1em;
margin: 1em;
padding: 0.25em 1em;
border-radius: 3px;
`;
// Define our `fg` and `bg` on the theme
const theme = {
fg: "palevioletred",
bg: "white"
};
// This theme swaps `fg` and `bg`
const invertTheme = ({ fg, bg }) => ({
fg: bg,
bg: fg
});
render(
<ThemeProvider theme={theme}>
<div>
<Button>Default Theme</Button>
<ThemeProvider theme={invertTheme}>
<Button>Inverted Theme</Button>
</ThemeProvider>
</div>
</ThemeProvider>
);
Upvotes: 1