blob: 2571fec97b39525966e5176bebce923265825771 [file] [log] [blame]
///
/// 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);
}