140 lines
3.2 KiB
SCSS
140 lines
3.2 KiB
SCSS
@use "sass:color";
|
||
@use "sass:list";
|
||
@use "sass:map";
|
||
@use "sass:meta";
|
||
@use "sass:string";
|
||
|
||
@function is-upper-case($char) {
|
||
@return string.to-lower-case($char) != $char;
|
||
}
|
||
|
||
@function is-lower-case($char) {
|
||
@return string.to-upper-case($char) != $char;
|
||
}
|
||
|
||
@function camel-to-kebab($string) {
|
||
$length: string.length($string);
|
||
$property: "--";
|
||
|
||
@for $i from 1 through $length {
|
||
$char: string.slice($string, $i, $i);
|
||
$property: "#{$property}#{if(is-upper-case($char), "-#{string.to-lower-case(
|
||
$char
|
||
)}",$char)}";
|
||
}
|
||
|
||
@return $property;
|
||
}
|
||
|
||
@function color-is-legal($value) {
|
||
// single color
|
||
@if meta.type-of($value) == color {
|
||
@return true;
|
||
}
|
||
|
||
// it’s a valid map color config
|
||
@if (
|
||
(meta.type-of($value) == map) and
|
||
(meta.type-of(map.get($value, "light")) == color) and
|
||
(meta.type-of(map.get($value, "dark")) == color)
|
||
) {
|
||
@return true;
|
||
}
|
||
|
||
@warn "Unexpected variable value: getting #{$value}";
|
||
@return false;
|
||
}
|
||
|
||
@function get-color($color, $is-dark: false) {
|
||
@if meta.type-of($color) == color {
|
||
@return $color;
|
||
}
|
||
|
||
$light-color: map.get($color, "light");
|
||
$dark-color: map.get($color, "dark");
|
||
|
||
@if $light-color and $dark-color {
|
||
@return if($is-dark, $dark-color, $light-color);
|
||
}
|
||
|
||
@warn "Unexpected color: getting #{$color}";
|
||
@return transparent;
|
||
}
|
||
|
||
@function get-dark-color($color) {
|
||
@return get-color($color, $is-dark: true);
|
||
}
|
||
|
||
@function get-variables($variables, $dark-selector: "") {
|
||
$root-variables: ();
|
||
$dark-variables: ();
|
||
|
||
@each $name, $value in $variables {
|
||
$key: camel-to-kebab($name);
|
||
|
||
@if meta.type-of($value) == number or meta.type-of($value) == string {
|
||
$root-variables: map.set($root-variables, $key, $value);
|
||
} @else if color-is-legal($value) {
|
||
$light-color: get-color($value, false);
|
||
$root-variables: map.set($root-variables, $key, $light-color);
|
||
|
||
@if $dark-selector {
|
||
$dark-color: get-color($value, true);
|
||
|
||
@if $light-color != $dark-color {
|
||
$dark-variables: map.set(
|
||
$dark-variables,
|
||
$key,
|
||
get-color($value, true)
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
@return ("root": $root-variables, "dark": $dark-variables);
|
||
}
|
||
|
||
@mixin inject-color($key, $config, $dark-selector: "") {
|
||
@if meta.type-of($config) == color {
|
||
:root {
|
||
#{$key}: #{$config};
|
||
}
|
||
} @else {
|
||
$light-color: map.get($config, "light");
|
||
$dark-color: map.get($config, "dark");
|
||
|
||
@if $light-color and $dark-color {
|
||
:root {
|
||
#{$key}: #{$light-color};
|
||
}
|
||
|
||
@if $light-color != $dark-color and $dark-selector {
|
||
#{$dark-selector} {
|
||
#{$key}: #{$dark-color};
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
@mixin inject($variables, $dark-selector: "") {
|
||
$result: get-variables($variables, $dark-selector);
|
||
$root-variables: map.get($result, "root");
|
||
$dark-variables: map.get($result, "dark");
|
||
|
||
@if $dark-selector {
|
||
#{$dark-selector} {
|
||
@each $key, $value in $dark-variables {
|
||
#{$key}: #{$value};
|
||
}
|
||
}
|
||
}
|
||
|
||
:root {
|
||
@each $key, $value in $root-variables {
|
||
#{$key}: #{$value};
|
||
}
|
||
}
|
||
}
|