Search code examples
sassnext.jsscss-mixins

Why @use and @include works in global scss file but not components scss files?


Context

I'm using NextJS v12.1.0, React v17.0.2 and sass v1.49.9.

I'm trying to create a theme switcher based on that article. My folder structure is like that :

myProject
└───src
|   └───styles
│   │   _color-themes.scss // Themes and themed() mixin + t($key) function
│   │   _colors.scss // Colors variables
│   │   globals.scss // My global app style
│   │
│   └───components
│   |   └───my-component
│   |   │   index.tsx
│   |   │   MyComponent.module.scss // My component style

I'm using that part of code in globals.scss which is working well :

@use "src/styles/color-themes" as *;

#content {
  padding: 48px 80px;
  @include themed() {
    background-color: t($bg); // Property is applied
  }
}

But when I'm using it in MyComponent.module.scss the SCSS added property is not applied to the rendered element :

@use "src/styles/color-themes" as *;

$border-radius: 8px;
$shadow: rgba(0, 0, 0, 0.06) 0px 5px 15px;

.input {
  font-size: 1rem; // Applied well
  padding: 24px 74px; // Applied well
  width: 476px; // Applied well
  border: none; // Applied well
  border-radius: $border-radius; // Applied well
  box-shadow: $shadow; // Applied well
  @include themed() {
    color: t($input); // Property is never applied
  }
}

My problem

The color property is never applied to my elements, even if others properties I'm adding outside the themed() are applied. I've also tried to use t($bg) and that's not applied too.

Here is the only applied properties (defined in MyComponent.module.scss):

Screenshot of applied properties (input class)

And here is the well applied property (defined in globals.scss): Screenshot of well applied property (content id)

I've done researches and I can't find any case like me on Google or Stackoverflow, I'm new in SCSS so I'm probably misunderstanding something. Does someone have an idea of what I'm doing wrong ?


Solution

  • Finaly came to a solution in that Denis Pasin's article.

    So I just needed to update create two mixins: themed for components style gthemed for globals style

    @mixin themed() {
        @each $theme, $map in $themes {
            :global(.theme--#{$theme}) & {
                $theme-map: () !global;
                @each $key, $submap in $map {
                    $value: map-get(map-get($themes, $theme), "#{$key}");
                    $theme-map: map-merge(
                        $theme-map,
                        (
                            $key: $value,
                        )
                    ) !global;
                }
                @content;
                $theme-map: null !global;
            }
        }
    }
    
    @mixin gthemed() {
        @each $theme, $map in $themes {
            .theme--#{$theme} & {
                $theme-map: () !global;
                @each $key, $submap in $map {
                    $value: map-get(map-get($themes, $theme), "#{$key}");
                    $theme-map: map-merge(
                        $theme-map,
                        (
                            $key: $value,
                        )
                    ) !global;
                }
                @content;
                $theme-map: null !global;
            }
        }
    }