| /// |
| /// Returns the opposite direction of each direction in a list |
| /// Modified from: https://css-tricks.com/snippets/sass/opposite-direction-function/ |
| /// @author Hugo Giraudel |
| /// @param {List} $directions - List of initial directions |
| /// @return {List} - List of opposite directions |
| @function mdlext-opposite-direction($directions) { |
| $opposite-directions: (); |
| $direction-map: ( |
| 'top': 'bottom', |
| 'right': 'left', |
| 'bottom': 'top', |
| 'left': 'right', |
| 'center': 'center', |
| 'ltr': 'rtl', |
| 'rtl': 'ltr' |
| ); |
| |
| @each $direction in $directions { |
| $direction: to-lower-case($direction); |
| |
| @if map-has-key($direction-map, $direction) { |
| $opposite-directions: append($opposite-directions, unquote(map-get($direction-map, $direction))); |
| } |
| @else { |
| @warn "No opposite direction can be found for `#{$direction}`. Direction omitted."; |
| } |
| } |
| |
| @return $opposite-directions; |
| } |
| |
| /// |
| /// Strip unit from value |
| /// @author Hugo Giraudel |
| /// http://hugogiraudel.com/2013/08/12/sass-functions/ |
| /// https://css-tricks.com/snippets/sass/strip-unit-function/ |
| /// @param {Number} $number - Number to remove unit from |
| /// @return {Number} - Unitless number |
| |
| @function strip-unit($number) { |
| @return if(type-of($number) == 'number' and not unitless($number), $number / ($number * 0 + 1), $number); |
| } |
| |
| /// |
| /// Clamping a number means restricting it between min and max values. |
| /// 4 clamped to 1-3 equals 3. |
| /// -5 clamped to 1-10 equals 1. |
| /// 42 clamped to 10-100 equals 42. |
| /// @author Hugo Giraudel |
| /// http://hugogiraudel.com/2013/08/12/sass-functions/ |
| /// @param {Number} $value - The value to clamp |
| /// @param {Number} $min - min value in range |
| /// @param {Number} $max - Max value in range |
| /// @return {Number} - The clamped value |
| |
| @function clamp($value, $min, $max) { |
| @return if($value > $max, $max, if($value < $min, $min, $value)); |
| } |
| |
| /// |
| /// Convert one unit into another |
| /// @author Hugo Giraudel |
| /// http://www.sitepoint.com/understanding-sass-units/ |
| /// @param {Number} $value - Initial value |
| /// @param {String} $unit - Desired unit |
| /// @return {Number} |
| /// @throw Error if `$unit` does not exist or if units are incompatible. |
| |
| /* stylelint-disable */ |
| @function convert-unit($value, $unit) { |
| $units: ( |
| 'px' : 0px, |
| 'cm' : 0cm, |
| 'mm' : 0mm, |
| '%' : 0%, |
| 'ch' : 0ch, |
| 'in' : 0in, |
| 'em' : 0em, |
| 'rem' : 0rem, |
| 'pt' : 0pt, |
| 'pc' : 0pc, |
| 'ex' : 0ex, |
| 'vw' : 0vw, |
| 'vh' : 0vh, |
| 'vmin': 0vmin, |
| 'vmax': 0vmax, |
| 'deg' : 0deg, |
| 'turn': 0turn, |
| 'rad' : 0rad, |
| 'grad': 0grad, |
| 's' : 0s, |
| 'ms' : 0ms, |
| 'Hz' : 0Hz, |
| 'kHz' : 0kHz, |
| 'dppx': 0dppx, |
| 'dpcm': 0dpcm, |
| 'dpi' : 0dpi, |
| ); |
| |
| @if map-has-key($units, $unit) { |
| @return map-get($units, $unit) + $value; |
| } |
| |
| @error "Unknown unit `#{$unit}`."; |
| } |
| /* stylelint-enable */ |
| |
| |
| /// |
| /// Replace `$search` with `$replace` in `$string` |
| /// @author Hugo Giraudel, http://hugogiraudel.com/2014/01/13/sass-string-replacement-function/ |
| /// @param {String} $string - Initial string |
| /// @param {String} $search - Substring to replace |
| /// @param {String} $replace ('') - New value |
| /// @return {String} - Updated string |
| @function str-replace($string, $search, $replace: '') { |
| $index: str-index($string, $search); |
| |
| @if $index { |
| @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); |
| } |
| @return $string; |
| } |
| |
| /// |
| /// @function explode() -- split a string into a list of strings |
| /// @author https://gist.github.com/danielpchen/3677421ea15dcf2579ff |
| /// {string} $string: the string to be split |
| /// {string} $delimiter: the boundary string |
| /// @return {list} the result list |
| @function explode($string, $delimiter: ',') { |
| $result: (); |
| @if $delimiter == "" { |
| @for $i from 1 through str-length($string) { |
| $result: append($result, str-slice($string, $i, $i)); |
| } |
| @return $result; |
| } |
| $exploding: true; |
| @while $exploding { |
| $d-index: str-index($string, $delimiter); |
| @if $d-index { |
| @if $d-index > 1 { |
| $result: append($result, str-slice($string, 1, $d-index - 1)); |
| $string: str-slice($string, $d-index + str-length($delimiter)); |
| } |
| @else if $d-index == 1 { |
| $string: str-slice($string, 1, $d-index + str-length($delimiter)); |
| } |
| @else { |
| $result: append($result, $string); |
| $exploding: false; |
| } |
| } |
| @else { |
| $result: append($result, $string); |
| $exploding: false; |
| } |
| } |
| @return $result; |
| } |
| |
| /// |
| /// Add `$unit` to `$value` |
| /// @author Hugo Giraudel |
| /// |
| /// @param {Number} $value - Value to add unit to |
| /// @param {String} $unit - String representation of the unit |
| /// |
| /// @return {Number} - `$value` expressed in `$unit` |
| /// @throw Error if `$unit` does not exist or if units are incompatible. |
| /// |
| @function to-length($value, $unit) { |
| $units: ( |
| 'px' : 1px, |
| 'cm' : 1cm, |
| 'mm' : 1mm, |
| '%' : 1%, |
| 'ch' : 1ch, |
| 'pc' : 1pc, |
| 'in' : 1in, |
| 'em' : 1em, |
| 'rem' : 1rem, |
| 'pt' : 1pt, |
| 'ex' : 1ex, |
| 'vw' : 1vw, |
| 'vh' : 1vh, |
| 'vmin': 1vmin, |
| 'vmax': 1vmax |
| ); |
| |
| @if not index(map-keys($units), $unit) { |
| @error('Invalid unit `#{$unit}`.'); |
| } |
| |
| @return $value * map-get($units, $unit); |
| } |
| |
| /// |
| /// Casts a string into a number |
| /// |
| /// @author Hugo Giraudel |
| // @param {String | Number} $value - Value to be parsed |
| /// |
| /// @return {Number} |
| /// @throw Error if `$value` is not a number or a string. |
| /// |
| @function to-number($value) { |
| @if type-of($value) == 'number' { |
| @return $value; |
| } |
| @else if type-of($value) != 'string' { |
| @error('Value for `to-number` should be a number or a string.'); |
| } |
| |
| $result: 0; |
| $digits: 0; |
| $minus: str-slice($value, 1, 1) == '-'; |
| $numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9); |
| |
| @for $i from if($minus, 2, 1) through str-length($value) { |
| $character: str-slice($value, $i, $i); |
| |
| @if not (index(map-keys($numbers), $character) or $character == '.') { |
| @return to-length(if($minus, -$result, $result), str-slice($value, $i)); |
| } |
| |
| @if $character == '.' { |
| $digits: 1; |
| } |
| @else if $digits == 0 { |
| $result: $result * 10 + map-get($numbers, $character); |
| } |
| @else { |
| $digits: $digits * 10; |
| $result: $result + map-get($numbers, $character) / $digits; |
| } |
| } |
| |
| @return if($minus, -$result, $result); |
| } |
| |
| /// |
| /// Convert `$rgb-string` to a number list |
| /// @author Leif Olsen |
| /// @param {String | Number} $value - Value to be parsed |
| /// @return {list} the rgb number list |
| /// @throw Error if `$value` is not a number, color or a string. |
| @function rgb-string-to-numbers($value) { |
| @if type-of($value) == 'number' or type-of($value) == 'color' { |
| @return $value; |
| } |
| @else if type-of($value) != 'string' { |
| @error('Value for `rgb-string-to-numbers` should be a number or a string.'); |
| } |
| |
| $s: str-replace($value, "rgba"); |
| $s: str-replace($s, "rgb"); |
| $s: str-replace($s, "("); |
| $s: str-replace($s, ")"); |
| $s: str-replace($s, " "); |
| $l: explode($s); |
| $result: (); |
| @for $i from 1 through length($l) { |
| $result: append($result, to-number(nth($l, $i))); |
| } |
| @return $result; |
| } |
| |
| /// |
| /// Convert `$rgb-string` to a corresponding hex value |
| /// @author Leif Olsen |
| /// @param {String | Number} $value - Value to be parsed |
| /// @return {number} the rgb hex value |
| /// @throw Error if `$value` is not a number, color or a string. |
| @function rgb-string-to-hex($value) { |
| @if type-of($value) == 'number' or type-of($value) == 'color' { |
| @return $value; |
| } |
| @else if type-of($value) != 'string' { |
| @error('Value for `rgb-string-to-numbers` should be a number or a string.'); |
| } |
| $l: rgb-string-to-numbers($value); |
| @return rgb(nth($l, 1), nth($l, 2), nth($l, 3)); |
| } |
| |
| |
| /// |
| /// Convert hex color to a coresponding `$rgb-string` |
| /// @author https://github.com/google/material-design-lite/issues/1689 |
| /// @param {Number} $hexColor - Value to convert |
| /// @return {String} the rgb string value |
| /// |
| /// @example - $color-primary: hex-to-string(#333); |
| @function hex-to-rgb-string($hexColor) { |
| // 0.999999 val in alpha actually compiles to 1.0 |
| $rgbaVal: inspect(rgba($hexColor, 0.9999999)); |
| |
| // slice substring between 'rgba(' and '1.0)' |
| @return str-slice($rgbaVal, 6, str-length($rgbaVal)-4); |
| } |