Emotion: Question about theming css (without styled)

Created on 1 Sep 2018  路  8Comments  路  Source: emotion-js/emotion

Sorry this is more of a question about ideal usage than an actual issue (hope this is the right place for it)

  • emotion version: 9.2.6
  • react version: 16.2.0

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 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 ?

question

All 8 comments

Do you meam withTheme https://emotion.sh/docs/emotion-theming#withthemecomponent-reactcomponent-function ?

withTheme will only work with react components - not sure if there is a way for css to work with withTheme.

It still needs to return the dynamic classname but be theme aware based on whats in context

Will this be easier with the css prop in emotion 10?

I can see the docs here:
https://github.com/emotion-js/emotion/pull/799/files

Not sure if I can get around prop passing without inlining the css into JSX - ideally want the css to be imported from another file
Eg like this:

// i want to have this in a seperate file
const blah = `
    background-color: ${props.theme.color};
`;

function SomeComponent(props) {
  return (
    <div
      css={blah}
    >
      <p>Blah</p>
    </div>
  )
}

But obviously the above code i get a ReferenceError: props is not defined error

From what I understand you'd have to export this

export const blah = props => theme => `
    color: red;
    font-size: ${theme.fontSize}px;

    &:hover {
      color: red;
    }

    & .some-class {
      font-size: 20px;
    }
`;

and use it like this:

function SomeComponent(props) {
  // Create styles as if you're calling css and the class will be applied to the component
  return (
    <div
      css={blah(props)}
    >
      This will be blue until hovered.
      <div className="some-class">This font size will be 20px</div>
      <div css={{ color: 'hotpink' }}>This is hotpink</div>
    </div>
  )
}
render(<SomeComponent fontSize={15} />)

Ok thanks - thats basically the same as what I currently have

Figured as much that i needed to pass prop down explicitly .. was hoping there was a nicer way :/

@Andarist should i re-open as it seems it could be improved?

Sure, u can open an issue to see if we can improve this or not

Was this page helpful?
0 / 5 - 0 ratings