codekingpro/portable-devtools
115k
1// Bootstrap functions2//3// Utility mixins and functions for evaluating source code across our variables, maps, and mixins.4 5// Ascending6// Used to evaluate Sass maps like our grid breakpoints.7@mixin _assert-ascending($map, $map-name) {8 $prev-key: null;9 $prev-num: null;10 @each $key, $num in $map {11 @if $prev-num == null or unit($num) == "%" or unit($prev-num) == "%" {12 // Do nothing13 } @else if not comparable($prev-num, $num) {14 @warn "Potentially invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} whose unit makes it incomparable to #{$prev-num}, the value of the previous key '#{$prev-key}' !";15 } @else if $prev-num >= $num {16 @warn "Invalid value for #{$map-name}: This map must be in ascending order, but key '#{$key}' has value #{$num} which isn't greater than #{$prev-num}, the value of the previous key '#{$prev-key}' !";17 }18 $prev-key: $key;19 $prev-num: $num;20 }21}22 23// Starts at zero24// Used to ensure the min-width of the lowest breakpoint starts at 0.25@mixin _assert-starts-at-zero($map, $map-name: "$grid-breakpoints") {26 @if length($map) > 0 {27 $values: map-values($map);28 $first-value: nth($values, 1);29 @if $first-value != 0 {30 @warn "First breakpoint in #{$map-name} must start at 0, but starts at #{$first-value}.";31 }32 }33}34 35// Replace `$search` with `$replace` in `$string`36// Used on our SVG icon backgrounds for custom forms.37//38// @author Hugo Giraudel39// @param {String} $string - Initial string40// @param {String} $search - Substring to replace41// @param {String} $replace ('') - New value42// @return {String} - Updated string43@function str-replace($string, $search, $replace: "") {44 $index: str-index($string, $search);45 46 @if $index {47 @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace);48 }49 50 @return $string;51}52 53// See https://codepen.io/kevinweber/pen/dXWoRw54//55// Requires the use of quotes around data URIs.56 57@function escape-svg($string) {58 @if str-index($string, "data:image/svg+xml") {59 @each $char, $encoded in $escaped-characters {60 // Do not escape the url brackets61 @if str-index($string, "url(") == 1 {62 $string: url("#{str-replace(str-slice($string, 6, -3), $char, $encoded)}");63 } @else {64 $string: str-replace($string, $char, $encoded);65 }66 }67 }68 69 @return $string;70}71 72// Color contrast73@function color-yiq($color, $dark: $yiq-text-dark, $light: $yiq-text-light) {74 $r: red($color);75 $g: green($color);76 $b: blue($color);77 78 $yiq: (($r * 299) + ($g * 587) + ($b * 114)) * .001;79 80 @if ($yiq >= $yiq-contrasted-threshold) {81 @return $dark;82 } @else {83 @return $light;84 }85}86 87// Retrieve color Sass maps88@function color($key: "blue") {89 @return map-get($colors, $key);90}91 92@function theme-color($key: "primary") {93 @return map-get($theme-colors, $key);94}95 96@function gray($key: "100") {97 @return map-get($grays, $key);98}99 100// Request a theme color level101@function theme-color-level($color-name: "primary", $level: 0) {102 $color: theme-color($color-name);103 $color-base: if($level > 0, $black, $white);104 $level: abs($level);105 106 @return mix($color-base, $color, $level * $theme-color-interval);107}108 109// Return valid calc110@function add($value1, $value2, $return-calc: true) {111 @if $value1 == null {112 @return $value2;113 }114 115 @if $value2 == null {116 @return $value1;117 }118 119 @if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {120 @return $value1 + $value2;121 }122 123 @return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + unquote(" + ") + $value2);124}125 126@function subtract($value1, $value2, $return-calc: true) {127 @if $value1 == null and $value2 == null {128 @return null;129 }130 131 @if $value1 == null {132 @return -$value2;133 }134 135 @if $value2 == null {136 @return $value1;137 }138 139 @if type-of($value1) == number and type-of($value2) == number and comparable($value1, $value2) {140 @return $value1 - $value2;141 }142 143 @if type-of($value2) != number {144 $value2: unquote("(") + $value2 + unquote(")");145 }146 147 @return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(" - ") + $value2);148}149 150@function divide($dividend, $divisor, $precision: 10) {151 $sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);152 $dividend: abs($dividend);153 $divisor: abs($divisor);154 @if $dividend == 0 {155 @return 0;156 }157 @if $divisor == 0 {158 @error "Cannot divide by 0";159 }160 $remainder: $dividend;161 $result: 0;162 $factor: 10;163 @while ($remainder > 0 and $precision >= 0) {164 $quotient: 0;165 @while ($remainder >= $divisor) {166 $remainder: $remainder - $divisor;167 $quotient: $quotient + 1;168 }169 $result: $result * 10 + $quotient;170 $factor: $factor * .1;171 $remainder: $remainder * 10;172 $precision: $precision - 1;173 @if ($precision < 0 and $remainder >= $divisor * 5) {174 $result: $result + 1;175 }176 }177 $result: $result * $factor * $sign;178 $dividend-unit: unit($dividend);179 $divisor-unit: unit($divisor);180 $unit-map: (181 "px": 1px,182 "rem": 1rem,183 "em": 1em,184 "%": 1%185 );186 @if ($dividend-unit != $divisor-unit and map-has-key($unit-map, $dividend-unit)) {187 $result: $result * map-get($unit-map, $dividend-unit);188 }189 @return $result;190}191 