cssinjs / jss

JSS is an authoring tool for CSS which uses JavaScript as a host language.
https://cssinjs.org
MIT License
7.08k stars 399 forks source link

make rule-value-function and global work together #1427

Open louisabraham opened 4 years ago

louisabraham commented 4 years ago

Fix #1335

Implementation details

I attach an attribute updateFun to rules with type 'global' that have a function as declaration (i.e. rules that match both plugins).

I already had to modify RuleList.js to prevent the special case rule.rules instanceof RuleList from skipping the update, so I included the code that executes updateFun in RuleList.js. An important choice (that is easily modifiable) is that plugins.onUpdate will not be launched on the global rule that is updated with a function: other plugins will not run on the updated properties.

Another meaningful possibility would be to include the call to updateFun in the onUpdate method of the rule-value-function. This would allow us to call plugins.onUpdate from RuleList.js, so have other plugins run on the rule after update. I was not sure what interactions this could create with other plugins so I didn't handle it this way.

It is my first contribution to a JS project, so please feel free to give me advice to improve my coding style :smiley:

Example

import jss, {SheetsRegistry} from 'jss'
import funplugin from 'jss-plugin-rule-value-function'
import globplugin from 'jss-plugin-global'

const jss_ = jss.default

jss_.use(funplugin.default(), globplugin.default())

const sheet = jss_.createStyleSheet({
  '@global': (data) => ({
    button: {
      width: 100,
      height: 100
    },
    '#sntch_block': {
      display: data.display
    }
  }),

  a: {
    display: 'inline',
    color: (data) => data.color
  },

  div: (data) => ({
    color: data.color
  })
})

const sheets = new SheetsRegistry()
sheets.add(sheet)
var str = sheets.toString()
console.log(str)

console.log('\n-----\n')

sheet.update({color: 'red', display: 'none'})

str = sheets.toString()
console.log(str)

console.log('\n-----\n')

sheet.update({color: 'blue', display: 'none'})

str = sheets.toString()
console.log(str)

gives

.a-0-0-1 {
  display: inline;
}

-----

button {
  width: 100;
  height: 100;
}
#sntch_block {
  display: none;
}
.a-0-0-1 {
  display: inline;
  color: red;
}
.div-0-0-2 {
  color: red;
}

-----

button {
  width: 100;
  height: 100;
}
#sntch_block {
  display: none;
}
.a-0-0-1 {
  display: inline;
  color: blue;
}
.div-0-0-2 {
  color: blue;
}
louisabraham commented 4 years ago

I don't know how to add tests, but I think it would be a nice thing if someone has a bit of time!

(also it looks that there are issues in master that prevent the tests from running)

kof commented 4 years ago

See https://github.com/cssinjs/jss/issues/1335#issuecomment-727893215 regarding the syntax.

kof commented 3 years ago

Would be great if someone added tests to rule-value-function package, so we can play with the implementation details and find a better way