Search code examples
cssvue.jssassthemeselement-plus

SCSS light and dark theme color, how can make it work?


So i'm using vue js and scss. I'm using PrimeVue and Element plus, and i'm importing there variables. I would like to change dynamically the theme color.

dark-variables.scss

$--color-primary: #c9d1d9 !default;
/// color|1|Background Color|4
$--color-white: #11141a !default;
/// color|1|Background Color|4
$--color-black: #000000 !default;
$--color-primary-light-1: mix($--color-white, $--color-primary, 10%) !default; /* 53a8ff */
$--color-primary-light-2: mix($--color-white, $--color-primary, 20%) !default; /* 66b1ff */
$--color-primary-light-3: mix($--color-white, $--color-primary, 30%) !default; /* 79bbff */
$--color-primary-light-4: mix($--color-white, $--color-primary, 40%) !default; /* 8cc5ff */
$--color-primary-light-5: mix($--color-white, $--color-primary, 50%) !default; /* a0cfff */
$--color-primary-light-6: mix($--color-white, $--color-primary, 60%) !default; /* b3d8ff */
$--color-primary-light-7: mix($--color-white, $--color-primary, 70%) !default; /* c6e2ff */
$--color-primary-light-8: mix($--color-white, $--color-primary, 80%) !default; /* d9ecff */
$--color-primary-light-9: #21262d !default; /* ecf5ff */ // #2c333c | #152344
/// color|1|Functional Color|1
$--color-success: #67c23a !default;
/// color|1|Functional Color|1
$--color-warning: #e6a23c !default;
/// color|1|Functional Color|1
$--color-danger: #f56c6c !default;
/// color|1|Functional Color|1
$--color-info: #909399 !default;

$--color-primary - Can be used in a lot of scss files, and i would like to change the color depends on the theme,

for example:

$--color-primary: white (if light theme and if black theme then it would be black)

** What i'm trying to do**

$themes: (
  darkTheme: (
    "text-color": rgb(245, 0, 0),
    "bg-color": #424242,
  ),
  lightTheme: (
    "text-color": black,
    "bg-color": #f5f5f5,
  ),
);

@mixin theme() {
  @each $theme, $map in $themes {
    $theme-map: $map !global;
    .#{$theme} & {
    }
  }
  $theme-map: null !global;
}

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

// - Error
$--color-primary: theme-get("text-color");

The error it self:

Syntax Error: SassError: Undefined variable.
   ╷
56 │   @return map-get($theme-map, $key);
   │                   ^^^^^^^^^^
   ╵
  src\assets\styles\element-variables.scss 56:19  theme-get()
  src\assets\styles\element-variables.scss 59:19  @import
  src\assets\styles\kendoUI\kendoUI.scss 1:9      @import
  E:\Sproj\Web\src\assets\styles\styles.scss 7:9    

How can make it work?


Solution

  • I think there are two things we need to change,

    1. We need to remove the incorrect syntax of dynamic class with &

    2. We need to include the mixin to initialise $theme-map

        darkTheme: (
          "color": rgb(245, 0, 0),
          "background-color": #424242,
        ),
        lightTheme: (
          "color": black,
          "background-color": #f5f5f5,
        ),
      );
      
      @mixin theme() {
        $theme-map: null !global;
        @each $theme, $map in $themes {
          $theme-map: $map !global;
          .#{$theme} {
          }
        }
      }
      
      @include theme();
      
      @function theme-get($key) {
        @return map-get($theme-map, $key);
      }
      
      // - Error
      $--color-primary: theme-get("text-color");
      
      .theme {
          color: $--color-primary;
      }