vanilla-extract icon indicating copy to clipboard operation
vanilla-extract copied to clipboard

Using a recipe with a global style creates incorrect selector chain.

Open caranicas opened this issue 3 years ago • 1 comments

Describe the bug

When using a recipe with a global style the css that gets created expects the variant class to be child and not a chained selector.

I have a codesandbox demo linked to to provide the full context, but this is the long and short of it.

creating a style like this

globalStyle(`${exampleRecipe({ orientation: "vertical" })} > div`, {
  backgroundColor: "red"
});

and DOM like this

 <div class="${exampleRecipe({
    orientation: "vertical"
  })}">
      <div>Hello</div>
 </div>

results in DOM like this

<div class="styles__14w0md60 styles_orientation_vertical__14w0md61">
      <div>Hello</div>
</div>

BUT css like this

.styles__14w0md60 .styles_orientation_vertical__14w0md61 > div {
  background-color: red;
}

there is a space between .styles__14w0md60 and .styles_orientation_vertical__14w0md61

which means my div is not red like I would expect. the two class selectors should be chained to properly target the dom node.

.styles__14w0md60.styles_orientation_vertical__14w0md61 > div {
  background-color: red;
}

Reproduction

https://codesandbox.io/s/vanilla-extract-recipe-bug-xpnu2j?file=/src/index.js

System Info

System:
    OS: Windows 10 10.0.19044
    CPU: (24) x64 AMD Ryzen 9 3900X 12-Core Processor
    Memory: 4.73 GB / 15.95 GB
  Binaries:
    Node: 16.16.0 - C:\Program Files\nodejs\node.EXE
    npm: 8.15.1 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Chrome: 105.0.5195.127
    Edge: Spartan (44.19041.1266.0), Chromium (106.0.1370.34)
    Internet Explorer: 11.0.19041.1566
  npmPackages:
    @vanilla-extract/css: ^1.9.0 => 1.9.0
    @vanilla-extract/css-utils: ^0.1.2 => 0.1.2
    @vanilla-extract/recipes: ^0.2.5 => 0.2.5
    @vanilla-extract/sprinkles: ^1.5.0 => 1.5.0
    @vanilla-extract/vite-plugin: ^3.5.0 => 3.5.0
    vite: ^3.0.7 => 3.1.0

Used Package Manager

npm

Logs

No response

Validations

caranicas avatar Oct 05 '22 20:10 caranicas

As a workaround, you need to use .split(' ')[1] like this:

globalStyle(`${exampleRecipe({ orientation: "vertical" }).split(' ')[1]} > div`, {
  backgroundColor: "red"
});

You can see an example in #464 and this is also discussed in #737.

ArmandPhilippot avatar Oct 16 '22 14:10 ArmandPhilippot

I don't think this is fixable other than to clarify in the docs, as calling the recipe returns a string of all the classnames combined and there's no way to detect this automatically.

As another workaround, create a basic style that you use in the recipe and declare the globalStyle related to that. You can even do this with variants:

const baseStyle = style({
  fontSize: '12px',
  lineHeight: 1.5,
});

globalStyle(`${baseStyle} thead th, ${baseStyle} tfoot td`, {
  textAlign: 'inherit',
  padding: '8px 24px',
  fontWeight: 'normal',
});

globalStyle(`${baseStyle} td`, {
  padding: '16px 24px',
});

const tableVariants = styleVariants({
  simple: {

  },
});

globalStyle(`${tableVariants.simple} thead`, {
  fontSize: '10px',
});

export const tableRecipe = recipe({
  base: [
    baseStyle,
  ],
  variants: {
    variant: tableVariants,
  },
});

graup avatar Jan 17 '23 02:01 graup

Fixed in #1104

graup avatar Jul 24 '23 02:07 graup