diff options
| author | Feuerfuchs <git@feuerfuchs.dev> | 2020-11-01 20:55:14 +0100 |
|---|---|---|
| committer | Feuerfuchs <git@feuerfuchs.dev> | 2020-11-01 20:55:14 +0100 |
| commit | d07f664450ddaaebb44127a4bd057763d13d3f82 (patch) | |
| tree | 234cfd673ac527869a8dda4f32afbec48c87b512 /src/_functions.scss | |
| download | iro-sass-d07f664450ddaaebb44127a4bd057763d13d3f82.tar.gz iro-sass-d07f664450ddaaebb44127a4bd057763d13d3f82.tar.bz2 iro-sass-d07f664450ddaaebb44127a4bd057763d13d3f82.zip | |
Init
Diffstat (limited to 'src/_functions.scss')
| -rw-r--r-- | src/_functions.scss | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/src/_functions.scss b/src/_functions.scss new file mode 100644 index 0000000..2f34dc4 --- /dev/null +++ b/src/_functions.scss | |||
| @@ -0,0 +1,328 @@ | |||
| 1 | //// | ||
| 2 | /// Various functions. | ||
| 3 | /// | ||
| 4 | /// This file contains various and mostly unrelated functions. Some of which | ||
| 5 | /// are used in this framework, while others are just there and may be used. | ||
| 6 | /// | ||
| 7 | /// @group Functions | ||
| 8 | /// | ||
| 9 | /// @access public | ||
| 10 | //// | ||
| 11 | |||
| 12 | /// | ||
| 13 | /// Replace a substring with a new string. | ||
| 14 | /// | ||
| 15 | /// @param {string} $string - String to search | ||
| 16 | /// @param {string} $search - Substring that gets replaced | ||
| 17 | /// @param {string} $replace - String that replaces $search | ||
| 18 | /// | ||
| 19 | /// @return {string} A string with all instances of $search replaced with $replace | ||
| 20 | /// | ||
| 21 | @function iro-str-replace($string, $search, $replace) { | ||
| 22 | $index: str-index($string, $search); | ||
| 23 | |||
| 24 | @if $index { | ||
| 25 | @return str-slice($string, 1, $index - 1) + $replace + iro-str-replace(str-slice($string, $index + str-length($search)), $search, $replace); | ||
| 26 | } | ||
| 27 | |||
| 28 | @return $string; | ||
| 29 | } | ||
| 30 | |||
| 31 | /// | ||
| 32 | /// Concatenate all items from $list. | ||
| 33 | /// | ||
| 34 | /// @param {list} $list | ||
| 35 | /// @param {number} $glue - Delimiter | ||
| 36 | /// | ||
| 37 | /// @return {string} | ||
| 38 | /// | ||
| 39 | @function iro-str-implode($list, $glue: '') { | ||
| 40 | $result: ''; | ||
| 41 | |||
| 42 | @each $item in $list { | ||
| 43 | $result: $result + if(length($item) > 1, iro-str-implode($item, $glue), $item); | ||
| 44 | |||
| 45 | @if $item != nth($list, length($list)) { | ||
| 46 | $result: $result + $glue; | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | @return $result; | ||
| 51 | } | ||
| 52 | |||
| 53 | /// | ||
| 54 | /// Extract a subset from the given list. | ||
| 55 | /// | ||
| 56 | /// @param {list} $list | ||
| 57 | /// @param {number} $start [1] - Indices before this value will be discarded | ||
| 58 | /// @param {number} $end [length($list)] - Indices starting after this value will be discarded | ||
| 59 | /// | ||
| 60 | /// @return {list} A slice of the list | ||
| 61 | /// | ||
| 62 | @function iro-list-slice($list, $start: 1, $end: length($list)) { | ||
| 63 | $result: (); | ||
| 64 | |||
| 65 | @for $i from $start through $end { | ||
| 66 | @if $i != 0 { | ||
| 67 | $result: append($result, nth($list, $i), list-separator($list)); | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | @return $result; | ||
| 72 | } | ||
| 73 | |||
| 74 | /// | ||
| 75 | /// Add a new item to the beginning of a list. | ||
| 76 | /// | ||
| 77 | /// @param {list} $list | ||
| 78 | /// @param {number} $value | ||
| 79 | /// | ||
| 80 | /// @return {list} A list with $value at the beginning, followed by the other items | ||
| 81 | /// | ||
| 82 | @function iro-list-prepend($list, $value) { | ||
| 83 | $result: append((), $value, list-separator($list)); | ||
| 84 | |||
| 85 | @if length($list) > 0 { | ||
| 86 | @for $i from 1 through length($list) { | ||
| 87 | $result: append($result, nth($list, $i), list-separator($list)); | ||
| 88 | } | ||
| 89 | } | ||
| 90 | |||
| 91 | @return $result; | ||
| 92 | } | ||
| 93 | |||
| 94 | /// | ||
| 95 | /// Sort numeric items in a list. | ||
| 96 | /// | ||
| 97 | /// The implementation is based on the algorithm on the German Wikipedia article | ||
| 98 | /// about quicksort: https://de.wikipedia.org/wiki/Quicksort#Pseudocode | ||
| 99 | /// | ||
| 100 | /// @param {list} $l | ||
| 101 | /// | ||
| 102 | /// @return {list} Sorted list | ||
| 103 | /// | ||
| 104 | @function iro-quicksort($l, $left: 1, $right: length($l)) { | ||
| 105 | @if $left < $right { | ||
| 106 | $pvr: iro-quicksort-partition($l, $left, $right); | ||
| 107 | $pivot: nth($pvr, 1); | ||
| 108 | $l: nth($pvr, 2); | ||
| 109 | $l: iro-quicksort($l, $left, $pivot); | ||
| 110 | $l: iro-quicksort($l, $pivot + 1, $right); | ||
| 111 | } | ||
| 112 | |||
| 113 | @return $l; | ||
| 114 | } | ||
| 115 | |||
| 116 | /// | ||
| 117 | /// @access private | ||
| 118 | /// | ||
| 119 | @function iro-quicksort-partition($l, $left, $right) { | ||
| 120 | $start: true; | ||
| 121 | $i: $left; | ||
| 122 | $j: $right - 1; | ||
| 123 | $pivot: nth($l, $right); | ||
| 124 | |||
| 125 | @while ($i < $j) or $start { | ||
| 126 | @while (nth($l, $i) < $pivot) and ($i < $right - 1) { | ||
| 127 | $i: $i + 1; | ||
| 128 | } | ||
| 129 | |||
| 130 | @while (nth($l, $j)>= $pivot) and ($j > $left) { | ||
| 131 | $j: $j - 1; | ||
| 132 | } | ||
| 133 | |||
| 134 | @if $i < $j { | ||
| 135 | $i-val: nth($l, $i); | ||
| 136 | $l: set-nth($l, $i, nth($l, $j)); | ||
| 137 | $l: set-nth($l, $j, $i-val); | ||
| 138 | } | ||
| 139 | |||
| 140 | $start: false; | ||
| 141 | } | ||
| 142 | |||
| 143 | @if nth($l, $i) > $pivot { | ||
| 144 | $i-val: nth($l, $i); | ||
| 145 | $l: set-nth($l, $i, nth($l, $right)); | ||
| 146 | $l: set-nth($l, $right, $i-val); | ||
| 147 | } | ||
| 148 | |||
| 149 | @return $i $l; | ||
| 150 | } | ||
| 151 | |||
| 152 | /// | ||
| 153 | /// Try to get the value for the given key from the given map. If it doesn't contain that key, | ||
| 154 | /// return the provided default value instead. | ||
| 155 | /// | ||
| 156 | /// @param {map} $map | ||
| 157 | /// @param {string} $key | ||
| 158 | /// @param {any} $default | ||
| 159 | /// | ||
| 160 | /// @return {any} Either the value assigned to $key or $default | ||
| 161 | /// | ||
| 162 | @function iro-map-get-default($map, $key, $default) { | ||
| 163 | @return if(map-has-key($map, $key), map-get($map, $key), $default); | ||
| 164 | } | ||
| 165 | |||
| 166 | /// | ||
| 167 | /// Get the value for a map within a map (or deeper). | ||
| 168 | /// | ||
| 169 | /// @param {map} $map | ||
| 170 | /// @param {string | list} $key | ||
| 171 | /// @param {any} $default [null] | ||
| 172 | /// | ||
| 173 | /// @return {any} Either the value assigned to $key or $default | ||
| 174 | /// | ||
| 175 | @function iro-map-get-deep($map, $key, $default: null) { | ||
| 176 | $value: null; | ||
| 177 | |||
| 178 | @if type-of($key) == list { | ||
| 179 | $value: $map; | ||
| 180 | |||
| 181 | @each $k in $key { | ||
| 182 | $value: map-get($value, $k); | ||
| 183 | |||
| 184 | @if $value == null { | ||
| 185 | @return $default; | ||
| 186 | } | ||
| 187 | } | ||
| 188 | } @else { | ||
| 189 | $value: map-get($map, $key); | ||
| 190 | |||
| 191 | @if $value == null { | ||
| 192 | @return $default; | ||
| 193 | } | ||
| 194 | } | ||
| 195 | |||
| 196 | @return $value; | ||
| 197 | } | ||
| 198 | |||
| 199 | /// | ||
| 200 | /// Merge two maps recursively. | ||
| 201 | /// | ||
| 202 | /// @param {map} $map1 | ||
| 203 | /// @param {map} $map2 | ||
| 204 | /// | ||
| 205 | /// @return {map} The result of a recursive merge of $map1 and $map2 | ||
| 206 | /// | ||
| 207 | @function iro-map-merge-recursive($map1, $map2) { | ||
| 208 | @if type-of($map1) != map or type-of($map2) != map { | ||
| 209 | @error 'Two maps expected.'; | ||
| 210 | } | ||
| 211 | |||
| 212 | $result: $map1; | ||
| 213 | |||
| 214 | @each $key, $value in $map2 { | ||
| 215 | @if type-of(map-get($result, $key)) == map and type-of($value) == map { | ||
| 216 | $result: map-merge($result, ($key: iro-map-merge-recursive(map-get($result, $key), $value))); | ||
| 217 | } @else { | ||
| 218 | $result: map-merge($result, ($key: $value)); | ||
| 219 | } | ||
| 220 | } | ||
| 221 | |||
| 222 | @return $result; | ||
| 223 | } | ||
| 224 | |||
| 225 | /// | ||
| 226 | /// Get the contents of a map as a user-friendly string representation. | ||
| 227 | /// | ||
| 228 | /// @param {map} $map | ||
| 229 | /// | ||
| 230 | /// @return {string} | ||
| 231 | /// | ||
| 232 | @function iro-map-print($map) { | ||
| 233 | $output: ''; | ||
| 234 | |||
| 235 | @each $key, $value in $map { | ||
| 236 | $value-str: ''; | ||
| 237 | |||
| 238 | @if type-of($value) == map { | ||
| 239 | $value-str: '[ ' + iro-map-print($value) + ' ]'; | ||
| 240 | } @else if type-of($value) == list { | ||
| 241 | $value-str: '[ ' + iro-str-implode($value, ', ') + ' ]'; | ||
| 242 | } @else if type-of($value) == string { | ||
| 243 | $value-str: '\'' + $value + '\''; | ||
| 244 | } @else { | ||
| 245 | $value-str: $value; | ||
| 246 | } | ||
| 247 | |||
| 248 | @if $output == '' { | ||
| 249 | $output: $key + ': ' + $value-str; | ||
| 250 | } @else { | ||
| 251 | $output: $output + ', ' + $key + ': ' + $value-str; | ||
| 252 | } | ||
| 253 | } | ||
| 254 | |||
| 255 | @return $output; | ||
| 256 | } | ||
| 257 | |||
| 258 | /// | ||
| 259 | /// Check if the given selector ends with one of the provided suffixes. | ||
| 260 | /// | ||
| 261 | /// @param {selector} $selector | ||
| 262 | /// @param {selector} $suffixes | ||
| 263 | /// | ||
| 264 | /// @return {bool} `true` if the selector matches at least one suffix, otherwise `false`. | ||
| 265 | /// | ||
| 266 | @function iro-selector-suffix-match($selector, $suffixes) { | ||
| 267 | $match: true; | ||
| 268 | |||
| 269 | @each $sel in $selector { | ||
| 270 | @if $match { | ||
| 271 | $sel-match: false; | ||
| 272 | |||
| 273 | @each $suffix in $suffixes { | ||
| 274 | @if not $sel-match { | ||
| 275 | $suf-match: true; | ||
| 276 | |||
| 277 | @for $i from 1 through length($suffix) { | ||
| 278 | @if $suf-match and (nth($sel, -$i) != nth($suffix, -$i)) { | ||
| 279 | $suf-match: false; | ||
| 280 | } | ||
| 281 | } | ||
| 282 | |||
| 283 | @if $suf-match { | ||
| 284 | $sel-match: true; | ||
| 285 | } | ||
| 286 | } | ||
| 287 | } | ||
| 288 | |||
| 289 | @if not $sel-match { | ||
| 290 | $match: false; | ||
| 291 | } | ||
| 292 | } | ||
| 293 | } | ||
| 294 | |||
| 295 | @return $match; | ||
| 296 | } | ||
| 297 | |||
| 298 | /// | ||
| 299 | /// Remove the unit from any variable. | ||
| 300 | /// | ||
| 301 | /// @param {any} $n | ||
| 302 | /// | ||
| 303 | /// @return {number} Unit-less variable | ||
| 304 | /// | ||
| 305 | @function iro-strip-unit($n) { | ||
| 306 | @return $n / ($n * 0 + 1); | ||
| 307 | } | ||
| 308 | |||
| 309 | /// | ||
| 310 | /// Convert a pixel value to a rem value. | ||
| 311 | /// | ||
| 312 | /// @param {number} $size - Pixel value to convert | ||
| 313 | /// @param {number} $base [$iro-root-size] - Reference base font size used for conversion | ||
| 314 | /// | ||
| 315 | /// @return {number} Pixel value converted to rem | ||
| 316 | /// | ||
| 317 | @function iro-px-to-rem($size, $base: $iro-root-size) { | ||
| 318 | @return $size / $base * 1rem; | ||
| 319 | } | ||
| 320 | |||
| 321 | /// | ||
| 322 | /// A mixin with the sole purpose of letting you use temporary variables without polluting the global namespace. | ||
| 323 | /// | ||
| 324 | /// @content | ||
| 325 | /// | ||
| 326 | @mixin iro-execute { | ||
| 327 | @content; | ||
| 328 | } | ||
