_functions.scss 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. //
  2. // Copyright 2017 Google Inc.
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. @use "sass:color";
  23. @use "sass:list";
  24. @use "sass:map";
  25. @use "sass:math";
  26. @use "sass:meta";
  27. @use "sass:string";
  28. @use "./constants";
  29. // Calculate the luminance for a color.
  30. // See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
  31. @function luminance($color) {
  32. $red: list.nth(constants.$linear-channel-values, color.red($color) + 1);
  33. $green: list.nth(constants.$linear-channel-values, color.green($color) + 1);
  34. $blue: list.nth(constants.$linear-channel-values, color.blue($color) + 1);
  35. @return .2126 * $red + .7152 * $green + .0722 * $blue;
  36. }
  37. // Calculate the contrast ratio between two colors.
  38. // See https://www.w3.org/TR/WCAG20-TECHS/G17.html#G17-tests
  39. @function contrast($back, $front) {
  40. $backLum: luminance($back) + .05;
  41. $foreLum: luminance($front) + .05;
  42. @return math.max($backLum, $foreLum) / math.min($backLum, $foreLum);
  43. }
  44. // Determine whether the color is "light" or "dark".
  45. @function tone($color) {
  46. @if $color == "dark" or $color == "light" {
  47. @return $color;
  48. }
  49. $minimumContrast: 3.1;
  50. $lightContrast: contrast($color, white);
  51. $darkContrast: contrast($color, rgba(black, .87));
  52. @if ($lightContrast < $minimumContrast) and ($darkContrast > $lightContrast) {
  53. @return "light";
  54. } @else {
  55. @return "dark";
  56. }
  57. }
  58. // Determine whether to use dark or light text on top of given color to meet accessibility standards for contrast.
  59. // Returns "dark" if the given color is light and "light" if the given color is dark.
  60. @function contrast-tone($color) {
  61. @return if(tone($color) == "dark", "light", "dark");
  62. }
  63. @function is-var-with-fallback_($style) {
  64. @return meta.type-of($style) == "map" and map.has-key($style, "varname") and map.has-key($style, "fallback");
  65. }
  66. @function get-var-fallback_($style) {
  67. $fallback: map.get($style, "fallback");
  68. @if is-var-with-fallback_($fallback) {
  69. @return get-var-fallback_($fallback);
  70. } @else {
  71. @return $fallback;
  72. }
  73. }
  74. @function var_($style) {
  75. $var: map.get($style, "varname");
  76. $fallback: map.get($style, "fallback");
  77. @if is-var-with-fallback_($fallback) {
  78. @return var(#{$var}, var_($fallback));
  79. } @else {
  80. @return var(#{$var}, $fallback);
  81. }
  82. }
  83. ///
  84. /// @param $color Target color in any color format.
  85. /// @return Returns hash in string format that uniquely represents
  86. /// any given color format. Useful for generating unique keyframe names.
  87. /// @example
  88. /// `color-hash(#6200ee)` => "6200ee"
  89. /// `color-hash(rgb(255, 112, 112))` => "ff7070"
  90. /// `color-hash(var(--my-fancy-color))` => "--my-fancy-color"
  91. ///
  92. @function color-hash($color) {
  93. @if is-var-with-fallback_($color) {
  94. $color: map.get($color, "fallback");
  95. }
  96. @if is-css-var_($color) {
  97. @return get-css-varname_($color);
  98. }
  99. @if meta.type-of($color) == "string" {
  100. @return $color;
  101. }
  102. @return string.slice(color.ie-hex-str($color), 2); // Index starts at 1
  103. }
  104. ///
  105. /// @return Returns true if given color is set to CSS variable.
  106. /// @access Private
  107. ///
  108. @function is-css-var_($color) {
  109. @return str_slice(meta.inspect($color), 1, 4) == "var(";
  110. }
  111. ///
  112. /// @return Returns CSS variable name from color value in CSS variable format.
  113. /// Returns original color value if not in CSS variable format.
  114. /// @example
  115. /// mdc-theme-get-css-varname_(var(--my-fancy-color, #4CAF50)) => --my-fancy-color
  116. /// mdc-theme-get-css-varname_(var(--my-fancy-color)) => --my-fancy-color
  117. /// @access Private
  118. ///
  119. @function get-css-varname_($color) {
  120. @if not is-css-var_($color) {
  121. @return $color;
  122. }
  123. $color: meta.inspect($color);
  124. $var-start-index: string.index($color, "--");
  125. $color: str_slice($color, $var-start-index);
  126. $var-end-index: string.index($color, ",") or string.index($color, ")");
  127. $color: str_slice($color, 0, $var-end-index - 1);
  128. @return $color;
  129. }