blob: 2571fec97b39525966e5176bebce923265825771 [file] [log] [blame]
Copybara botbe50d492023-11-30 00:16:42 +01001///
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}