cssinjs / jss

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

Variable values in @global #1335

Open ilan-schemoul opened 4 years ago

ilan-schemoul commented 4 years ago

Is your feature request related to a problem? Please describe. I want to use variables values in @global but if @global is a function then "Uncaught TypeError: Cannot set property 'fnStyle1587427462315' of null", if fields of @global are functions they are ignored

const useStyles = createUseStyles({
  '@global':  {
    '#sntch_block': {
      display: () => 'none',
    },
  },
});

Describe the solution you'd like Variables values like already implemented but working inside @global

Are you willing to implement it? Yes if it's simple to do (your code seems so clean and easy to understand) I have updated from early 10 version to the latest (react-jss and jss 10.1.1, I first only updated react-jss to 10.1.1 and let jss in 10.0.1 which triggers an error "sheet.updateOne" is not a function, you should consider printing a warning when incompatible version are being run together because it is hard otherwise to debug what is wrong). And both of these version have this issue.

TimboKZ commented 3 years ago

Any plans to implement this?

louisabraham commented 3 years ago

Hi, is there a way for me to put a bounty on this issue? Tim and I really need it in the following weeks. Is there a 3-digit amount that could motivate someone?

kof commented 3 years ago

https://www.bountysource.com/

kof commented 3 years ago

Make it high enough and I will work on it

louisabraham commented 3 years ago

Following our conversation by email, do you think $580 is a good rate?

louisabraham commented 3 years ago

Hi, while waiting for an answer, I realized that the workaround was pretty simple (even for the JS noob that I am): less than 20 SLOC. It should work properly now in #1427:

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;
}
kof commented 3 years ago

I think it makes sense to support value and rule functions, but the syntax in your example where fn returns the entire @global declaration is a big departure from the current syntax. E.g. media queries don't support this either.

This is the syntax that I think should work out of the box

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

Oh, I must admit I never used JSS so I didn't understand this was not the intended syntax (I thought @global were considered as function rules).

So I understand even less, since your example seems to work, even before my commit (at 5341eea232f1963d0beaeb5892f27e456fc92830).

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

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

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

sheet.update({height: '42px', display: 'none'})

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

gives

button {
  width: 100;
}

-----

button {
  width: 100;
  height: 42px;
}
#sntch_block {
  display: none;
}

Was this issue already solved?

kof commented 3 years ago

I haven't tested it with global rules and assumed it doesn't work since this report.

louisabraham commented 3 years ago

@NitroBAY @TimboKZ do you need @global function values (like https://github.com/cssinjs/jss/issues/1335#issuecomment-727893215) or @global function rules (like https://github.com/cssinjs/jss/issues/1335#issuecomment-727249119)?

The former seem to work already in master, the latter require my PR.

kof commented 3 years ago

Please someone add failing tests to jss-plugin-rule-value-function plugin for both function rules and function values syntax as mentioned here