Тематическое приложение react с модулями sass и css

#sass #next.js #scss-mixins

Вопрос:

Я хочу реализовать тематизацию в своем приложении react. Поэтому я использовал этот учебник (sass-mixins).

Но это не работает в сочетании с css-модулями, так как тематический класс находится за пределами css-модуля, который я хочу создать.

У кого-нибудь есть обходной путь для этой проблемы или другой подход к созданию приложения react с помощью sass?

App.js

 const theme = require('../../Theming.sass)

<div class={theme['theme-dark'}>
  <SearchBar/>
  ...
</div>
 

SearchBar.js

 const styles = require('./SearchBar.scss)
const theme = require('../../Theming.sass)

<div class={styles.searchBar}>
  ...
</div>
 

Панель поиска.scss

 .searchBar {
  @include themify($themes) {
    color: themed('primary');
    background: themed('secondary');
  }

  height: 3em;
  overflow: hidden;
 

Панель поиска.css (скомпилирована)

 .searchBar {
  height: 3em;
  overflow: hidden;
}

.theme-light .searchBar {
  color: #fff;
  background: #bfbfbf;
}

.theme-dark .searchBar {
  color: #000;
  background: #1a1a1a;
}
 

Тема.сасс

 .theme-dark { background: #000; }

.theme-light { background: #fff; }

$themes: (
  light: (
    primary: #fff,
    secondary: #bfbfbf,
  ),
  dark: (
    primary: #000,
    secondary: #1a1a1a,
  ),
);

@function themed($key) {
  @return map-get($theme-map, $key);
}

@mixin themify($themes: $themes) {
  @each $theme, $map in $themes {

    .theme-#{$theme} amp; { /* HOW TO USE CSS-MODULES HERE ?*/
      $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;
    }

  }
}
 

Ответ №1:

У меня была аналогичная проблема, я использую SASS с модулями CSS в приложении React, и в итоге я использовал класс темы как глобальный класс, а не модули CSS, потому что каждый раз, когда я использовал микс, он добавлял префикс модуля в стиль.

Я добавил :global в тематический класс в миксине:

 @mixin themify($themes: $themes) {
  @each $theme, $map in $themes {

    :global(.theme-#{$theme}) amp; { 
      $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;
    }

  }
}
 

И я указал класс непосредственно в своем JSX в App.js:

 <div class="theme-dark">
  <SearchBar/>
  ...
</div>
 

Я надеюсь, что это кому-то поможет.

Ответ №2:

Вам также необходимо импортировать .theme-dark через css-модули.

Должно быть что-то вроде:

 <div class={styles.themeDark}>
  <SearchBar/>
  ...
</div>
 

Вы также должны использовать для этого загрузчик ресурсов sass: https://github.com/shakacode/sass-resources-loader

Комментарии:

1. Это отличный намек. Но я думаю, что мне придется использовать css-модули внутри функций mixins. Я обновил вопрос и отметил строку внутри функции mixins. Знаете ли вы, как использовать css-модули в этом случае?

2. Это не работает, потому что миксин добавляет необработанный класс .тема-темная. Мы должны ссылаться на класс css-модуля .тема-темная внутри миксина.