Copybara bot | be50d49 | 2023-11-30 00:16:42 +0100 | [diff] [blame^] | 1 | /// |
| 2 | /// Returns the opposite direction of each direction in a list |
| 3 | /// Modified from: https://css-tricks.com/snippets/sass/opposite-direction-function/ |
| 4 | /// @author Hugo Giraudel |
| 5 | /// @param {List} $directions - List of initial directions |
| 6 | /// @return {List} - List of opposite directions |
| 7 | @function mdlext-opposite-direction($directions) { |
| 8 | $opposite-directions: (); |
| 9 | $direction-map: ( |
| 10 | 'top': 'bottom', |
| 11 | 'right': 'left', |
| 12 | 'bottom': 'top', |
| 13 | 'left': 'right', |
| 14 | 'center': 'center', |
| 15 | 'ltr': 'rtl', |
| 16 | 'rtl': 'ltr' |
| 17 | ); |
| 18 | |
| 19 | @each $direction in $directions { |
| 20 | $direction: to-lower-case($direction); |
| 21 | |
| 22 | @if map-has-key($direction-map, $direction) { |
| 23 | $opposite-directions: append($opposite-directions, unquote(map-get($direction-map, $direction))); |
| 24 | } |
| 25 | @else { |
| 26 | @warn "No opposite direction can be found for `#{$direction}`. Direction omitted."; |
| 27 | } |
| 28 | } |
| 29 | |
| 30 | @return $opposite-directions; |
| 31 | } |
| 32 | |
| 33 | /// |
| 34 | /// Strip unit from value |
| 35 | /// @author Hugo Giraudel |
| 36 | /// http://hugogiraudel.com/2013/08/12/sass-functions/ |
| 37 | /// https://css-tricks.com/snippets/sass/strip-unit-function/ |
| 38 | /// @param {Number} $number - Number to remove unit from |
| 39 | /// @return {Number} - Unitless number |
| 40 | |
| 41 | @function strip-unit($number) { |
| 42 | @return if(type-of($number) == 'number' and not unitless($number), $number / ($number * 0 + 1), $number); |
| 43 | } |
| 44 | |
| 45 | /// |
| 46 | /// Clamping a number means restricting it between min and max values. |
| 47 | /// 4 clamped to 1-3 equals 3. |
| 48 | /// -5 clamped to 1-10 equals 1. |
| 49 | /// 42 clamped to 10-100 equals 42. |
| 50 | /// @author Hugo Giraudel |
| 51 | /// http://hugogiraudel.com/2013/08/12/sass-functions/ |
| 52 | /// @param {Number} $value - The value to clamp |
| 53 | /// @param {Number} $min - min value in range |
| 54 | /// @param {Number} $max - Max value in range |
| 55 | /// @return {Number} - The clamped value |
| 56 | |
| 57 | @function clamp($value, $min, $max) { |
| 58 | @return if($value > $max, $max, if($value < $min, $min, $value)); |
| 59 | } |
| 60 | |
| 61 | /// |
| 62 | /// Convert one unit into another |
| 63 | /// @author Hugo Giraudel |
| 64 | /// http://www.sitepoint.com/understanding-sass-units/ |
| 65 | /// @param {Number} $value - Initial value |
| 66 | /// @param {String} $unit - Desired unit |
| 67 | /// @return {Number} |
| 68 | /// @throw Error if `$unit` does not exist or if units are incompatible. |
| 69 | |
| 70 | /* stylelint-disable */ |
| 71 | @function convert-unit($value, $unit) { |
| 72 | $units: ( |
| 73 | 'px' : 0px, |
| 74 | 'cm' : 0cm, |
| 75 | 'mm' : 0mm, |
| 76 | '%' : 0%, |
| 77 | 'ch' : 0ch, |
| 78 | 'in' : 0in, |
| 79 | 'em' : 0em, |
| 80 | 'rem' : 0rem, |
| 81 | 'pt' : 0pt, |
| 82 | 'pc' : 0pc, |
| 83 | 'ex' : 0ex, |
| 84 | 'vw' : 0vw, |
| 85 | 'vh' : 0vh, |
| 86 | 'vmin': 0vmin, |
| 87 | 'vmax': 0vmax, |
| 88 | 'deg' : 0deg, |
| 89 | 'turn': 0turn, |
| 90 | 'rad' : 0rad, |
| 91 | 'grad': 0grad, |
| 92 | 's' : 0s, |
| 93 | 'ms' : 0ms, |
| 94 | 'Hz' : 0Hz, |
| 95 | 'kHz' : 0kHz, |
| 96 | 'dppx': 0dppx, |
| 97 | 'dpcm': 0dpcm, |
| 98 | 'dpi' : 0dpi, |
| 99 | ); |
| 100 | |
| 101 | @if map-has-key($units, $unit) { |
| 102 | @return map-get($units, $unit) + $value; |
| 103 | } |
| 104 | |
| 105 | @error "Unknown unit `#{$unit}`."; |
| 106 | } |
| 107 | /* stylelint-enable */ |
| 108 | |
| 109 | |
| 110 | /// |
| 111 | /// Replace `$search` with `$replace` in `$string` |
| 112 | /// @author Hugo Giraudel, http://hugogiraudel.com/2014/01/13/sass-string-replacement-function/ |
| 113 | /// @param {String} $string - Initial string |
| 114 | /// @param {String} $search - Substring to replace |
| 115 | /// @param {String} $replace ('') - New value |
| 116 | /// @return {String} - Updated string |
| 117 | @function str-replace($string, $search, $replace: '') { |
| 118 | $index: str-index($string, $search); |
| 119 | |
| 120 | @if $index { |
| 121 | @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); |
| 122 | } |
| 123 | @return $string; |
| 124 | } |
| 125 | |
| 126 | /// |
| 127 | /// @function explode() -- split a string into a list of strings |
| 128 | /// @author https://gist.github.com/danielpchen/3677421ea15dcf2579ff |
| 129 | /// {string} $string: the string to be split |
| 130 | /// {string} $delimiter: the boundary string |
| 131 | /// @return {list} the result list |
| 132 | @function explode($string, $delimiter: ',') { |
| 133 | $result: (); |
| 134 | @if $delimiter == "" { |
| 135 | @for $i from 1 through str-length($string) { |
| 136 | $result: append($result, str-slice($string, $i, $i)); |
| 137 | } |
| 138 | @return $result; |
| 139 | } |
| 140 | $exploding: true; |
| 141 | @while $exploding { |
| 142 | $d-index: str-index($string, $delimiter); |
| 143 | @if $d-index { |
| 144 | @if $d-index > 1 { |
| 145 | $result: append($result, str-slice($string, 1, $d-index - 1)); |
| 146 | $string: str-slice($string, $d-index + str-length($delimiter)); |
| 147 | } |
| 148 | @else if $d-index == 1 { |
| 149 | $string: str-slice($string, 1, $d-index + str-length($delimiter)); |
| 150 | } |
| 151 | @else { |
| 152 | $result: append($result, $string); |
| 153 | $exploding: false; |
| 154 | } |
| 155 | } |
| 156 | @else { |
| 157 | $result: append($result, $string); |
| 158 | $exploding: false; |
| 159 | } |
| 160 | } |
| 161 | @return $result; |
| 162 | } |
| 163 | |
| 164 | /// |
| 165 | /// Add `$unit` to `$value` |
| 166 | /// @author Hugo Giraudel |
| 167 | /// |
| 168 | /// @param {Number} $value - Value to add unit to |
| 169 | /// @param {String} $unit - String representation of the unit |
| 170 | /// |
| 171 | /// @return {Number} - `$value` expressed in `$unit` |
| 172 | /// @throw Error if `$unit` does not exist or if units are incompatible. |
| 173 | /// |
| 174 | @function to-length($value, $unit) { |
| 175 | $units: ( |
| 176 | 'px' : 1px, |
| 177 | 'cm' : 1cm, |
| 178 | 'mm' : 1mm, |
| 179 | '%' : 1%, |
| 180 | 'ch' : 1ch, |
| 181 | 'pc' : 1pc, |
| 182 | 'in' : 1in, |
| 183 | 'em' : 1em, |
| 184 | 'rem' : 1rem, |
| 185 | 'pt' : 1pt, |
| 186 | 'ex' : 1ex, |
| 187 | 'vw' : 1vw, |
| 188 | 'vh' : 1vh, |
| 189 | 'vmin': 1vmin, |
| 190 | 'vmax': 1vmax |
| 191 | ); |
| 192 | |
| 193 | @if not index(map-keys($units), $unit) { |
| 194 | @error('Invalid unit `#{$unit}`.'); |
| 195 | } |
| 196 | |
| 197 | @return $value * map-get($units, $unit); |
| 198 | } |
| 199 | |
| 200 | /// |
| 201 | /// Casts a string into a number |
| 202 | /// |
| 203 | /// @author Hugo Giraudel |
| 204 | // @param {String | Number} $value - Value to be parsed |
| 205 | /// |
| 206 | /// @return {Number} |
| 207 | /// @throw Error if `$value` is not a number or a string. |
| 208 | /// |
| 209 | @function to-number($value) { |
| 210 | @if type-of($value) == 'number' { |
| 211 | @return $value; |
| 212 | } |
| 213 | @else if type-of($value) != 'string' { |
| 214 | @error('Value for `to-number` should be a number or a string.'); |
| 215 | } |
| 216 | |
| 217 | $result: 0; |
| 218 | $digits: 0; |
| 219 | $minus: str-slice($value, 1, 1) == '-'; |
| 220 | $numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9); |
| 221 | |
| 222 | @for $i from if($minus, 2, 1) through str-length($value) { |
| 223 | $character: str-slice($value, $i, $i); |
| 224 | |
| 225 | @if not (index(map-keys($numbers), $character) or $character == '.') { |
| 226 | @return to-length(if($minus, -$result, $result), str-slice($value, $i)); |
| 227 | } |
| 228 | |
| 229 | @if $character == '.' { |
| 230 | $digits: 1; |
| 231 | } |
| 232 | @else if $digits == 0 { |
| 233 | $result: $result * 10 + map-get($numbers, $character); |
| 234 | } |
| 235 | @else { |
| 236 | $digits: $digits * 10; |
| 237 | $result: $result + map-get($numbers, $character) / $digits; |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | @return if($minus, -$result, $result); |
| 242 | } |
| 243 | |
| 244 | /// |
| 245 | /// Convert `$rgb-string` to a number list |
| 246 | /// @author Leif Olsen |
| 247 | /// @param {String | Number} $value - Value to be parsed |
| 248 | /// @return {list} the rgb number list |
| 249 | /// @throw Error if `$value` is not a number, color or a string. |
| 250 | @function rgb-string-to-numbers($value) { |
| 251 | @if type-of($value) == 'number' or type-of($value) == 'color' { |
| 252 | @return $value; |
| 253 | } |
| 254 | @else if type-of($value) != 'string' { |
| 255 | @error('Value for `rgb-string-to-numbers` should be a number or a string.'); |
| 256 | } |
| 257 | |
| 258 | $s: str-replace($value, "rgba"); |
| 259 | $s: str-replace($s, "rgb"); |
| 260 | $s: str-replace($s, "("); |
| 261 | $s: str-replace($s, ")"); |
| 262 | $s: str-replace($s, " "); |
| 263 | $l: explode($s); |
| 264 | $result: (); |
| 265 | @for $i from 1 through length($l) { |
| 266 | $result: append($result, to-number(nth($l, $i))); |
| 267 | } |
| 268 | @return $result; |
| 269 | } |
| 270 | |
| 271 | /// |
| 272 | /// Convert `$rgb-string` to a corresponding hex value |
| 273 | /// @author Leif Olsen |
| 274 | /// @param {String | Number} $value - Value to be parsed |
| 275 | /// @return {number} the rgb hex value |
| 276 | /// @throw Error if `$value` is not a number, color or a string. |
| 277 | @function rgb-string-to-hex($value) { |
| 278 | @if type-of($value) == 'number' or type-of($value) == 'color' { |
| 279 | @return $value; |
| 280 | } |
| 281 | @else if type-of($value) != 'string' { |
| 282 | @error('Value for `rgb-string-to-numbers` should be a number or a string.'); |
| 283 | } |
| 284 | $l: rgb-string-to-numbers($value); |
| 285 | @return rgb(nth($l, 1), nth($l, 2), nth($l, 3)); |
| 286 | } |
| 287 | |
| 288 | |
| 289 | /// |
| 290 | /// Convert hex color to a coresponding `$rgb-string` |
| 291 | /// @author https://github.com/google/material-design-lite/issues/1689 |
| 292 | /// @param {Number} $hexColor - Value to convert |
| 293 | /// @return {String} the rgb string value |
| 294 | /// |
| 295 | /// @example - $color-primary: hex-to-string(#333); |
| 296 | @function hex-to-rgb-string($hexColor) { |
| 297 | // 0.999999 val in alpha actually compiles to 1.0 |
| 298 | $rgbaVal: inspect(rgba($hexColor, 0.9999999)); |
| 299 | |
| 300 | // slice substring between 'rgba(' and '1.0)' |
| 301 | @return str-slice($rgbaVal, 6, str-length($rgbaVal)-4); |
| 302 | } |