// // Copyright 2017 Google Inc. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // @use "sass:color"; @use "sass:list"; @use "sass:map"; @use "sass:math"; @use "sass:meta"; @use "sass:string"; @use "./constants"; // Calculate the luminance for a color. // See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests @function luminance($color) { $red: list.nth(constants.$linear-channel-values, color.red($color) + 1); $green: list.nth(constants.$linear-channel-values, color.green($color) + 1); $blue: list.nth(constants.$linear-channel-values, color.blue($color) + 1); @return .2126 * $red + .7152 * $green + .0722 * $blue; } // Calculate the contrast ratio between two colors. // See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests @function contrast($back, $front) { $backLum: luminance($back) + .05; $foreLum: luminance($front) + .05; @return math.max($backLum, $foreLum) / math.min($backLum, $foreLum); } // Determine whether the color is "light" or "dark". @function tone($color) { @if $color == "dark" or $color == "light" { @return $color; } $minimumContrast: 3.1; $lightContrast: contrast($color, white); $darkContrast: contrast($color, rgba(black, .87)); @if ($lightContrast < $minimumContrast) and ($darkContrast > $lightContrast) { @return "light"; } @else { @return "dark"; } } // Determine whether to use dark or light text on top of given color to meet accessibility standards for contrast. // Returns "dark" if the given color is light and "light" if the given color is dark. @function contrast-tone($color) { @return if(tone($color) == "dark", "light", "dark"); } @function is-var-with-fallback_($style) { @return meta.type-of($style) == "map" and map.has-key($style, "varname") and map.has-key($style, "fallback"); } @function get-var-fallback_($style) { $fallback: map.get($style, "fallback"); @if is-var-with-fallback_($fallback) { @return get-var-fallback_($fallback); } @else { @return $fallback; } } @function var_($style) { $var: map.get($style, "varname"); $fallback: map.get($style, "fallback"); @if is-var-with-fallback_($fallback) { @return var(#{$var}, var_($fallback)); } @else { @return var(#{$var}, $fallback); } } /// /// @param $color Target color in any color format. /// @return Returns hash in string format that uniquely represents /// any given color format. Useful for generating unique keyframe names. /// @example /// `color-hash(#6200ee)` => "6200ee" /// `color-hash(rgb(255, 112, 112))` => "ff7070" /// `color-hash(var(--my-fancy-color))` => "--my-fancy-color" /// @function color-hash($color) { @if is-var-with-fallback_($color) { $color: map.get($color, "fallback"); } @if is-css-var_($color) { @return get-css-varname_($color); } @if meta.type-of($color) == "string" { @return $color; } @return string.slice(color.ie-hex-str($color), 2); // Index starts at 1 } /// /// @return Returns true if given color is set to CSS variable. /// @access Private /// @function is-css-var_($color) { @return str_slice(meta.inspect($color), 1, 4) == "var("; } /// /// @return Returns CSS variable name from color value in CSS variable format. /// Returns original color value if not in CSS variable format. /// @example /// mdc-theme-get-css-varname_(var(--my-fancy-color, #4CAF50)) => --my-fancy-color /// mdc-theme-get-css-varname_(var(--my-fancy-color)) => --my-fancy-color /// @access Private /// @function get-css-varname_($color) { @if not is-css-var_($color) { @return $color; } $color: meta.inspect($color); $var-start-index: string.index($color, "--"); $color: str_slice($color, $var-start-index); $var-end-index: string.index($color, ",") or string.index($color, ")"); $color: str_slice($color, 0, $var-end-index - 1); @return $color; }