UNPKG

8.81 kBSCSSView Raw
1
2// Color Functions
3// --------------------------------------------------
4
5@function color-error($color-value, $color-name: null) {
6 $error-msg: "
7
8 The value `#{$color-value}` must be a color.
9 If you are setting the value as a map make sure
10 both the base and contrast are defined as colors.
11
12 For example:
13
14 $colors: (
15 primary: #327eff,
16 secondary: (base: #32db64, contrast: #000),
17 );";
18
19 // If there was a name passed it means the value doesn't exist
20 // so error that the value isn't defined
21 @if ($color-name) {
22 $error-msg: "
23
24 The map color `#{$color-name}` is not defined.
25 Please make sure the color exists in your
26 `$colors` map.
27
28 For example:
29
30 $colors: (
31 #{$color-name}: #327eff
32 );";
33 }
34
35 @error $error-msg;
36
37 @return null;
38}
39
40@function color-brightness($color-value) {
41 @if (type-of($color-value) != color) {
42 @return color-error($color-value);
43 }
44
45 @return (red($color-value) * .299 + green($color-value) * .587 + blue($color-value) * .114) / 255 * 100%;
46}
47
48
49@function color-inverse($color-value, $dark: #000, $light: #fff) {
50 @if (type-of($color-value) != color) {
51 @return color-error($color-value);
52 }
53
54 $brightness: color-brightness($color-value);
55 $red: red($color-value);
56 $green: green($color-value);
57
58 @if ($brightness > 79) {
59 @return $dark;
60 }
61
62 @if ($green > 240) {
63 @return $dark;
64 }
65
66 @if ($red > 220 and $green > 180) {
67 @return $dark;
68 }
69
70 @return $light;
71}
72
73// Pass dark and light colors based on the mode
74// this is mostly used for toolbar buttons/titles
75//
76// @param {String} $color-value - color to get the inverse of
77// @param {Boolean} $custom-contrast-mode - the mode to use
78// in order to pass the custom colors
79//
80// @return {Color}
81// --------------------------------------------------
82@function mode-inverse($color-value, $custom-contrast-mode) {
83 $dark: #000;
84 $light: #fff;
85
86 @if ($custom-contrast-mode == md) {
87 $dark: #424242;
88 $light: #fff;
89 } @else if ($custom-contrast-mode == ios) {
90 $dark: color($colors-ios, primary);
91 $light: #fff;
92 }
93
94 @return color-inverse($color-value, $dark, $light);
95}
96
97
98@function color-shade($color-value, $amount:8%) {
99 @if (type-of($color-value) != color) {
100 @return color-error($color-value);
101 }
102
103 $lightness: lightness($color-value);
104
105 $shade: #fff;
106
107 @if ($lightness > 50) {
108 $shade: #000;
109 }
110
111 @return mix($shade, $color-value, $amount);
112}
113
114// Copy Colors Map
115// --------------------------------------------------
116
117@function copy-colors($colors-map) {
118 @return map-merge($colors-map, ());
119}
120
121
122// String Replace Function
123// --------------------------------------------------
124
125@function str-replace($string, $search, $replace: "") {
126 $index: str-index($string, $search);
127
128 @if $index {
129 @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);
130 }
131
132 @return $string;
133}
134
135
136// String Split Function
137// --------------------------------------------------
138
139@function str-split($string, $separator) {
140 // empty array/list
141 $split-arr: ();
142 // first index of separator in string
143 $index: str-index($string, $separator);
144 // loop through string
145 @while $index != null {
146 // get the substring from the first character to the separator
147 $item: str-slice($string, 1, $index - 1);
148 // push item to array
149 $split-arr: append($split-arr, $item);
150 // remove item and separator from string
151 $string: str-slice($string, $index + 1);
152 // find new index of separator
153 $index: str-index($string, $separator);
154 }
155 // add the remaining string to list (the last item)
156 $split-arr: append($split-arr, $string);
157
158 @return $split-arr;
159}
160
161
162// Str extract between start and end
163// --------------------------------------------------
164
165@function str-extract($string, $start, $end) {
166 $start-index: str-index($string, $start);
167
168 @if $start-index {
169 $post: str-slice($string, $start-index + str-length($start));
170 $end-index: str-index($post, $end);
171
172 @if $end-index {
173 @return str-slice($post, 1, $end-index - 1);
174 }
175 }
176
177 @return null;
178}
179
180
181// URL Encode Function
182// --------------------------------------------------
183
184@function url-encode($val) {
185 $spaces: str-replace($val, " ", "%20");
186 $encoded: str-replace($spaces, "#", "%23");
187 @return $encoded;
188}
189
190
191// Fetch nested keys
192// @param {Map} $map - Map
193// @param {Arglist} $keys - Keys to fetch
194// @return {*}
195// --------------------------------------------------
196
197@function map-fetch($map, $keys...) {
198 @each $key in $keys {
199 $map: map-get($map, $key);
200 }
201
202 @return $map;
203}
204
205
206// Fetch map color value
207// @param {Map} $map - Map
208// @param {String} $color-name - Color name to get
209// @param {String} $color-key - Color key (optional), default base
210// @return {Color}
211// --------------------------------------------------
212
213@function color($map, $color-name, $color-key:null) {
214 // Get the value from $color-name in the map
215 // this can be of type color or a map
216 $color-value: map-get($map, $color-name);
217
218 // If we were given a map we need to grab the value
219 // of the key that is passed or the base key
220 @if(type-of($color-value) == map) {
221 @if($color-key) {
222 $color-value: map-fetch($map, $color-name, $color-key);
223 } @else {
224 $color-value: map-fetch($map, $color-name, base);
225 }
226 }
227
228 // If the value is a color then return the value
229 // otherwise we need to error with the name
230 @if (type-of($color-value) == color) {
231 @return $color-value;
232 }
233 @return color-error($color-value, $color-name);
234}
235
236// Get the color map key based on the value
237// if it doesn't exist then return the value
238// --------------------------------------------------
239@function color-key($colors, $value) {
240 @each $color-name, $color-value in $colors {
241 $base-value: color($colors, $color-name);
242 @if ($base-value == $value) {
243 @return map-get($colors, $color-name);
244 }
245 }
246
247 @return $value;
248}
249
250// Fetch map color contrast
251// @param {Map} $colors - colors map
252// @param {String} $value - color value or color name
253//
254// Example values
255// --------------------------------------------------
256// primary | #327eff | #444
257// map key | map value | hex color not in map
258// --------------------------------------------------
259//
260// @param {Boolean} $custom-contrast-mode - use custom
261// contrast function
262// @return {Color}
263// --------------------------------------------------
264@function color-contrast($colors, $value, $custom-contrast-mode: null) {
265 $color-value: null;
266
267 // If the value is a color (e.g. #fff)
268 // we need to call color-key to see if
269 // it exists in the color map or not
270 @if (type-of($value) == color) {
271 $color-value: color-key($colors, $value);
272
273 } @else {
274 // If the value is a string (e.g. primary)
275 // we want to get the value from the map
276 // where it is the key
277 $color-value: map-get($colors, $value);
278 }
279
280 // If the value is a map then get the contrast
281 // from the map (e.g. (base: #327eff, contrast: blue))
282 @if (type-of($color-value) == map) {
283 // If the map has the contrast key then use that
284 // otherwise it is a map with just a base so get
285 // the inverse of that base color
286 @if map-has-key($color-value, contrast) {
287 $color-value: map-get($color-value, contrast);
288 } @else {
289 $color-value: color-inverse(map-get($color-value, base));
290 }
291
292 } @elseif ($custom-contrast-mode) {
293 // If a mode was passed we need to call
294 // the custom inverse function to get the inverse
295 // color based on the mode
296 $color-value: mode-inverse($color-value, $custom-contrast-mode);
297
298 } @else {
299 // Otherwise we were passed a color and can use the
300 // function to get the inverse of that color
301 // (e.g. #f4f4f4)
302 $color-value: color-inverse($color-value);
303 }
304
305 // If the final value being returned is not a color
306 // we should error
307 @if (type-of($color-value) != color) {
308 @return color-error($color-value);
309 }
310
311 @return $color-value;
312}
313
314
315// Create a list using the colors map
316// @param {Map} $colors - colors map
317// @return {List} $color-name, $color-base, $color-contrast
318// ----------------------------------------------------------
319@function get-colors($colors, $custom-contrast-mode: null) {
320 $colors-list: ();
321
322 @each $color-name, $color-value in $colors {
323 $color-base: null;
324 $color-contrast: null;
325
326 @if(type-of($color-value) == map) {
327 $color-base: map-get($color-value, base);
328 $color-contrast: map-get($color-value, contrast);
329 } @else {
330 $color-base: $color-value;
331 $color-contrast: color-contrast($colors, $color-value, $custom-contrast-mode);
332 }
333
334 $colors-list: append($colors-list, ($color-name, $color-base, $color-contrast), comma);
335 }
336
337 @return $colors-list;
338}
339