martinandert / babel-plugin-css-in-js

A plugin for Babel v6 which transforms inline styles defined in JavaScript modules into class names so they become available to, e.g. the `className` prop of React elements. While transforming, the plugin processes all JavaScript style definitions found and bundles them up into a CSS file, ready to be requested from your web server.
MIT License
298 stars 11 forks source link

About more universal Nested Rules #26

Open b6pzeusbc54tvhw5jgpyw8pwz2x6gs opened 7 years ago

b6pzeusbc54tvhw5jgpyw8pwz2x6gs commented 7 years ago

Currently babel-plugin-css-in-js support some nested rules using global selectors $, but they are very limited. I'm considering implementing nested rules for a universal case used in css pre-processes such as less and stylus. ( see the example below )

Component:

<div className={ st.box }>
  <div className={ st.hiddenBtn }/>
</div>

css-in-js

const st = cssInJS({
  box: {
    color: 'red',
  },

  hiddenBtn: {
    opacity: 0
  },

  // I want to follow Nested Rules
  'box:hover': {
    '.hiddenBtn': {
      opacity: 1,
    }
  }
})

babel:

const st = {
  box: 'dir_filename_js-styles-box',
  hiddenBtn: 'dir_filename_js-styles-hiddenBtn'
}

css

.dir_filename_js-styles-box {
  color: red;
}
.dir_filename_js-styles-hiddenBtn {
  opacity: 0;
}
.dir_filename_js-styles-box:hover .dir_filename_js-styles-hiddenBtn {
  opacity: 1;
}

screen shot 2017-03-27 at 8 22 18 pm [Image1]

In the First box in Image1 .box .hiddenBtn selector works well. But in the second box, .box .hiddenBtn selector will select all .hiddenBtn in the box. it might be a bug. (Because developers always can write .box .hiddenBtn selector instead of .box > .hiddenBtn selector, I don't mention about .box > .hiddenBtn selector here )

So I like the globally unique (randomized) className this plugin creates. Ever since I use this plugin, no matter how big the application was, there was no bug affected by the unintentional css rule. In order to keep this benefit, in nested rules, both box and hiddenBtn must be uniqued.

The global selector concept is great for theme, but I want to implement nested rules with a more universal concept that is used by other pre-processors that operate independently of the global selector nested rules.

Could I make some PR?

b6pzeusbc54tvhw5jgpyw8pwz2x6gs commented 7 years ago

I also want to use &. (& represents the current selector parent sush a less or stylus )

css-in-js:

const st = cssInJS({
  box: {
    color: 'red',
    width: 100,
    height: 40,
    '&:hover': {
      color: 'blue',
      '.hiddenBtn': {
        opacity: 1
      },
      '& > .normalBtn': {
        marginRight: 10
      }
    }
  }
})

babel:

const st = {
  box: 'dir_filename_js-styles-box',
  hiddenBtn: 'dir_filename_js-styles-hiddenBtn',
  normalBtn: 'dir_filename_js-styles-normalBtn'
}

css:

.dir_filename_js-styles-box {
  color: red;
  width: 100px;
  height: 40px;
}
.dir_filename_js-styles-box:hover {
  color: blue;
}
.dir_filename_js-styles-box:hover .dir_filename_js-styles-hiddenBtn {
  opacity: 1;
}
.dir_filename_js-styles-box:hover > .dir_filename_js-styles-normalBtn {
  marginRight: 10px;
}
martinandert commented 7 years ago

Hi Alfred, sorry for the delay.

Could I make some PR?

Sure! Happy to merge any of the improvements you're talking about. Thanks!

b6pzeusbc54tvhw5jgpyw8pwz2x6gs commented 7 years ago

I'll try it if I have some time. Please let me know if anyone has any idea or feedback on this issue.