@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}; } } }