vanilla-extract-css / vanilla-extract

Zero-runtime Stylesheets-in-TypeScript
https://vanilla-extract.style
MIT License
9.51k stars 287 forks source link

Recipes generating incorrect class names #1470

Closed timdickson closed 4 days ago

timdickson commented 2 weeks ago

Describe the bug

I am having an issue with recipes where the class names generated in the css file aren't matching the class names outputted in the browser.

With the specific example that I am working on, container.classNames.variants.background["background-default"] is generating this class name in the css file:

And this class name in the browser:

I want to be able to use globalStyles, so that I can style headings a certain colour within that variant.

I have set up a sample repo of the issue, where I have set up a textColor variant that has a red or blue option.

When using container.classNames.variants.textColor.red in the css file it generates:

In the browser it is showing as:

Reproduction

https://github.com/timdickson/recipes-test

System Info

System:
    OS: macOS 14.5
    CPU: (8) x64 Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz
    Memory: 402.99 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.18.1 - /usr/local/bin/node
    Yarn: 1.22.22 - ~/.yarn/bin/yarn
    npm: 10.8.1 - /usr/local/bin/npm
    Watchman: 2024.08.12.00 - /usr/local/bin/watchman
  Browsers:
    Chrome: 128.0.6613.113
    Safari: 17.5
  npmPackages:
    @vanilla-extract/css: ^1.15.5 => 1.15.5 
    @vanilla-extract/next-plugin: ^2.4.5 => 2.4.5 
    @vanilla-extract/recipes: ^0.5.5 => 0.5.5

Used Package Manager

yarn

Logs

No response

Validations

askoufis commented 2 weeks ago

This is occurring because the recipes function (container) is returning the classname created by the style calls in your variants. This is expected behaviour, because you can put many things inside a variant, e.g. a list of classnames from sprinkles. However, the classnames inside container.classNames.variants are referencing classnames created by recipe.

There are two ways you can fix the issue in your example. The first would be to separate out the red and blue variant styles so that you can reference them directly, and then use them in your global style instead of container.classNames.variants:

const red = style({
  color: "red",
});

const blue = style({
  color: "blue",
});

export const container = recipe({
  base: {},
  variants: {
    textColor: {
      red,
      blue,
    },
  },
});

globalStyle(`.${red} h1`, {
  color: "pink",
});

This works, but is more verbose than it needs to be. For regular style rules, you can just define them inline within variants, without calling style (recipe will make the style for you):

export const container = recipe({
  base: {},
  variants: {
    textColor: {
      red: {
        color: "red",
      },
      blue: {
        color: "blue",
      },
    },
  },
});

globalStyle(`.${container.classNames.variants.textColor.red} h1`, {
  color: "pink",
});
timdickson commented 1 week ago

Thanks for the prompt response on this. That makes sense now, thank you for clarifying.

On 31 Aug 2024, at 11:20, Adam Skoufis @.***> wrote:

This is occurring because the recipes function (container) is returning the classname created by the style calls in your variants. This is expected behaviour, because you can put many things inside a variant, e.g. a list of classnames from sprinkles. However, the classnames inside container.classNames.variants are referencing classnames created by recipe.

There are two ways you can fix the issue in your example. The first would be to separate out the red and blue variant styles so that you can reference them directly, and then use them in your global style instead of container.classNames.variants:

const red = style({ color: "red", });

const blue = style({ color: "blue", });

export const container = recipe({ base: {}, variants: { textColor: { red, blue, }, }, });

globalStyle(.${red} h1, { color: "pink", }); This works, but is more verbose than it needs to be. For regular style rules, you can just define them inline within variants, without calling style (recipe will make the style for you):

export const container = recipe({ base: {}, variants: { textColor: { red: { color: "red", }, blue: { color: "blue", }, }, }, });

globalStyle(.${container.classNames.variants.textColor.red} h1, { color: "pink", }); — Reply to this email directly, view it on GitHub https://github.com/vanilla-extract-css/vanilla-extract/issues/1470#issuecomment-2322652794, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGCQ4NO4CWCWL6UICKOMXMLZUEK63AVCNFSM6AAAAABNNLMWBOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDGMRSGY2TENZZGQ. You are receiving this because you authored the thread.