cssinjs / styled-jss

Styled Components on top of JSS.
http://cssinjs.org/styled-jss
MIT License
217 stars 25 forks source link

Extend doesn't seem to work #21

Closed RickEyre closed 7 years ago

RickEyre commented 7 years ago

Extend preset plugin doesn't seem to be working.

export const button = {
  display: `inline-block`,
  fontSize: `1.2em`
};

export const primary = {
  extend: 'button',
  color: `white`
};

And usage:

import styled from 'styled-jss';

const Button = styled('button')(button);

export const PrimaryButton = styled('button')(primary);
RickEyre commented 7 years ago

I know I can use the composition pattern here that was shown in the README. I'm curious if there is a way to leverage 'extend' plugin in JSS to begin with.

lttb commented 7 years ago

@RickEyre thanks for your answer, and let me clarify this behavior.

let's take a look on your example:

const Button = styled('button')({
  display: 'inline-block',
  fontSize: '1.2em',
});

const PrimaryButton = styled('button')({
  extend: 'button',
  color: 'white',
});

In this case extend: 'button' - is a string, so jss-extend will look for the className button to extend suitable rule. but there is no declared className called button in the styles scope, because Button Component - is just a separate Component, with it's own scoping, it doesn't matches to button className.

For this cases we've implemented scoping via Styled function. And with scoping by Styled your example will look like this:

Online example

import {Styled} from 'styled-jss'

// bind styles scope to the styled function
const styled = Styled({
  button: {
    display: 'inline-block',
    fontSize: '1.2em'
  }
})

// we can use className `button` from the scope
const PrimaryButton = styled('button')({
  extend: 'button',
  color: 'white'
})

// we can use composes the same way
const Button = styled('button')({
  composes: '$button'
})

export default () => (
  <div>
    <Button>button</Button>
    <PrimaryButton>primary button</PrimaryButton>
  </div>
)

With const styled = Styled(styles) we bind that styles scope to the styled function, and we can get shared scope for this styled function, and rules created by this function have access to that scope.

BTW you can use jss-extend without scoping in the following way:

Online example

import styled from 'styled-jss'

const button = {
  display: 'inline-block',
  fontSize: '1.2em'
}

const primary = {
  extend: button, // note that this is a variable with styles, not a string
  color: 'white'
}

const Button = styled('button')(button)
const PrimaryButton = styled('button')(primary)
RickEyre commented 7 years ago

Wow, thanks for this answer. This really helps clarify the issue I was having.

I'll use one of the patterns you suggested.