libs/design/scss/theming/illuminate/illuminate.scss
@use 'sass:map';
@use '../contrast/luminance/luminance';
// @docs
// Take a numeric map and sort it.
//
// https://gist.github.com/Jakobud/a0ac11e80a1de453cd86f0d3fc0a1410
// Credit to: https://gist.github.com/iamandrewluca
//
@function _daff-illuminate-sort($map) {
// Transform map to zipped list
$keys: ();
$values: ();
@each $key, $val in $map {
$keys: append($keys, $key);
$values: append($values, $val);
}
$list: zip($keys, $values);
$sorted-map: ();
@while length($list) > 0 {
// Find smallest pair
$smallest-pair: nth($list, 1);
@each $pair in $list {
$value: nth($pair, 2);
$smallest-value: nth($smallest-pair, 2);
@if $value < $smallest-value {
$smallest-pair: $pair;
}
}
// Add smallest pair to sorted map
$key: nth($smallest-pair, 1);
$value: nth($smallest-pair, 2);
$sorted-map: map.merge(
$sorted-map,
(
$key: $value
)
);
// Remove from list smallest pair
$smallest-pair-index: index($list, $smallest-pair);
$new-list: ();
@for $i from 1 through length($list) {
@if $i != $smallest-pair-index {
$new-list: append($new-list, nth($list, $i), 'space');
}
}
$list: $new-list;
}
@return $sorted-map;
}
// Given a map of key, luminance pairs, find the key
// of the value that is "nth" away from zero.
//
// @param $map: a map of key, luminance pairs,
// @param $nth: nth steps away from zero
@function _daff-illuminate-get-key($map, $nth: 1) {
//Cap off "nth" to prevent going out-of-bounds.
@if ($nth > length($map)) {
$nth: length(map);
}
$map: _daff-illuminate-sort($map);
@return nth(nth($map, $nth), 1);
}
// Takes a $color and palette and returns the color in
// the palette which would "illuminate" against that color.
//
// @usage
// ```
// daff-illuminate($palette);
// ```
//
@function daff-illuminate($color, $palette, $nth: 1) {
$luminance-map: ();
//Validate
@each $key, $palette-color in $palette {
@if (type-of($key) == 'string') {
$palette: map.remove($palette, $key);
}
}
//Transform into usable values
@each $key, $palette-color in $palette {
$luminance-map: map.merge(
$luminance-map,
(
$key: (
luminance.daff-luminance($palette-color) - luminance.daff-luminance($color)
)
)
);
}
//Calculate which color to get
$brighter-colors: ();
$darker-colors: ();
@each $key, $luminance in $luminance-map {
@if ($luminance > 0) {
$brighter-colors: map.merge(
$brighter-colors,
(
$key: $luminance
)
);
}
@if ($luminance < 0) {
$darker-colors: map.merge(
$darker-colors,
(
$key: abs($luminance)
)
);
}
}
$key: null;
@if (luminance.daff-luminance($color) >= 0.5) {
//If the color is bright
$key: _daff-illuminate-get-key($darker-colors, $nth);
}
@else {
//If the color is dark
$key: _daff-illuminate-get-key($brighter-colors, $nth);
}
@return map.get($palette, $key);
}