Search code examples
javascriptcssreactjsemotion

Is there a way to theme with emotion without "styled"


With emotion (https://github.com/emotion-js/emotion) I know I can theme with css and styled together with something like:

const carouselCss = ({ theme }) => css`
 .. css properties etc
`;

const CarouselDiv = styled('div')`
  ${carouselCss};
`;

Then in JSX:

<ThemeProvider theme={{ stuff: 'blah' }}>
  <CarouselDiv>
        ..
  </CarouselDiv>
</ThemeProvider>

But is there any elegant way to theme with only css - prefer not to use componentized styles because I want to keep to semantic html elements in JSX (also have a massive code base and its easier to migrate from sass to emotion without having to use styled)

I know I can do something like:

const carouselCss = (theme) => css`
 .. css properties etc
`;

then jsx:

<div className={carouselCss(this.props.theme)}>
..
</div>

But it means passing a theme prop all the time from the component - which is a little cumbersome

Is there a better way to do this ? Somehow wrap css with something so it has theme vars injected ?


Solution

  • ThemeProvider will get you that. Here is an example with both styled and css options shown :

    /** @jsx jsx */
    import { jsx } from '@emotion/core'
    import styled from '@emotion/styled'
    import { ThemeProvider } from 'emotion-theming'
    
    const theme = {
      colors: {
        primary: 'hotpink'
      }
    }
    
    const SomeText = styled.div`
      color: ${props => props.theme.colors.primary};
    `
    
    render(
      <ThemeProvider theme={theme}>
        <SomeText>some text</SomeText>
        <div css={theme => ({ color: theme.colors.primary })}>
          some other text
        </div>
      </ThemeProvider>
    )