1
0
mirror of https://github.com/tabler/tabler.git synced 2025-12-21 17:34:25 +04:00
Files
tabler/core/scss/_bootstrap-functions.scss

258 lines
7.6 KiB
SCSS

@use "sass:color";
@use "sass:map";
@use "sass:math";
@use "sass:meta";
@use "sass:string";
@use "sass:list";
/**
* Converts a color value to RGB format
*
* @param {Color} $value - The color value to convert
* @return {List} - RGB values as a list (red, green, blue)
*
* @example
* to-rgb(#ff0000) // Returns: (255, 0, 0)
*/
@function to-rgb($value) {
@return color.channel($value, "red", $space: rgb), color.channel($value, "green", $space: rgb), color.channel($value, "blue", $space: rgb);
}
/**
* Creates an opaque color by mixing a foreground color with a background color
*
* @param {Color} $background - The background color
* @param {Color} $foreground - The foreground color to make opaque
* @return {Color} - The resulting opaque color
*
* @example
* opaque(#ffffff, rgba(255, 0, 0, 0.5)) // Returns solid red color
*/
@function opaque($background, $foreground) {
@return color.mix(rgba($foreground, 1), $background, opacity($foreground) * 100%);
}
/**
* Adjusts a color channel value for luminance calculation
*
* @param {Number} $channel - The color channel value (0-1)
* @return {Number} - The adjusted channel value
*
* @example
* adjust(0.5) // Returns adjusted value for luminance calculation
*/
@function adjust($channel) {
@return if($channel < 0.03928, math.div($channel, 12.92), pow(($channel + 0.055) / 1.055, 2.4));
}
/**
* Calculates the relative luminance of a color using WCAG formula
*
* @param {Color} $color - The color to calculate luminance for
* @return {Number} - The luminance value (0-1)
*
* @example
* luminance(#ffffff) // Returns: 1
* luminance(#000000) // Returns: 0
*/
@function luminance($color) {
$r: math.div(color.channel($color, "red", $space: rgb), 255);
$g: math.div(color.channel($color, "green", $space: rgb), 255);
$b: math.div(color.channel($color, "blue", $space: rgb), 255);
$r: adjust($r);
$g: adjust($g);
$b: adjust($b);
@return 0.2126 * $r + 0.7152 * $g + 0.0722 * $b;
}
/**
* Determines the best contrasting color for a given background
*
* @param {Color} $background - The background color
* @param {Color} $light - The light color option (default: #ffffff)
* @param {Color} $dark - The dark color option (default: #000000)
* @return {Color} - The contrasting color (light or dark)
*
* @example
* color-contrast(#000000) // Returns: #ffffff
* color-contrast(#ffffff) // Returns: #000000
*/
@function color-contrast($background, $light: #ffffff, $dark: #000000) {
// Get relative luminance using WCAG formula
$bg-luminance: luminance($background);
// If background is dark, return light color, otherwise dark
@return if($bg-luminance > 0.179, $dark, $light);
}
/**
* Adds two values together, handling different data types
*
* @param {*} $value1 - First value to add
* @param {*} $value2 - Second value to add
* @param {Boolean} $return-calc - Whether to return calc() function (default: true)
* @return {*} - The result of addition or calc() expression
*
* @example
* add(10px, 5px) // Returns: 15px
* add(10px, 5px, false) // Returns: 10px + 5px
*/
@function add($value1, $value2, $return-calc: true) {
@if $value1 == null {
@return $value2;
}
@if $value2 == null {
@return $value1;
}
@if meta.type-of($value1) == number and meta.type-of($value2) == number and math.compatible($value1, $value2) {
@return $value1 + $value2;
}
@return if($return-calc == true, calc(#{$value1} + #{$value2}), $value1 + string.unquote(" + ") + $value2);
}
/**
* Subtracts the second value from the first value
*
* @param {*} $value1 - The value to subtract from
* @param {*} $value2 - The value to subtract
* @param {Boolean} $return-calc - Whether to return calc() function (default: true)
* @return {*} - The result of subtraction or calc() expression
*
* @example
* subtract(10px, 5px) // Returns: 5px
* subtract(10px, 5px, false) // Returns: 10px - 5px
*/
@function subtract($value1, $value2, $return-calc: true) {
@if $value1 == null and $value2 == null {
@return null;
}
@if $value1 == null {
@return -$value2;
}
@if $value2 == null {
@return $value1;
}
@if meta.type-of($value1) == number and meta.type-of($value2) == number and math.compatible($value1, $value2) {
@return $value1 - $value2;
}
@if meta.type-of($value2) != number {
$value2: string.unquote("(") + $value2 + string.unquote(")");
}
@return if($return-calc == true, calc(#{$value1} - #{$value2}), $value1 + unquote(" - ") + $value2);
}
/**
* Divides the dividend by the divisor with specified precision
*
* @param {Number} $dividend - The number to be divided
* @param {Number} $divisor - The number to divide by
* @param {Number} $precision - The number of decimal places (default: 10)
* @return {Number} - The result of division
*
* @example
* divide(10, 2) // Returns: 5
* divide(10px, 2) // Returns: 5px
* divide(10, 3) // Returns: 3.3333333333
*/
@function divide($dividend, $divisor, $precision: 10) {
$sign: if($dividend > 0 and $divisor > 0 or $dividend < 0 and $divisor < 0, 1, -1);
$dividend: abs($dividend);
$divisor: abs($divisor);
@if $dividend == 0 {
@return 0;
}
@if $divisor == 0 {
@error "Cannot divide by 0";
}
$remainder: $dividend;
$result: 0;
$factor: 10;
@while ($remainder > 0 and $precision >= 0) {
$quotient: 0;
@while ($remainder >= $divisor) {
$remainder: $remainder - $divisor;
$quotient: $quotient + 1;
}
$result: $result * 10 + $quotient;
$factor: $factor * 0.1;
$remainder: $remainder * 10;
$precision: $precision - 1;
@if ($precision < 0 and $remainder >= $divisor * 5) {
$result: $result + 1;
}
}
$result: $result * $factor * $sign;
$dividend-unit: math.unit($dividend);
$divisor-unit: math.unit($divisor);
$unit-map: (
"px": 1px,
"rem": 1rem,
"em": 1em,
"%": 1%,
);
@if ($dividend-unit != $divisor-unit and map.has-key($unit-map, $dividend-unit)) {
$result: $result * map.get($unit-map, $dividend-unit);
}
@return $result;
}
/**
* Replaces all occurrences of a search string with a replace string
*
* @param {String} $string - The string to search in
* @param {String} $search - The string to search for
* @param {String} $replace - The string to replace with (default: "")
* @return {String} - The string with replacements made
*
* @example
* str-replace("hello world", "world", "universe") // Returns: "hello universe"
* str-replace("hello world", "o") // Returns: "hell wrld"
*/
@function str-replace($string, $search, $replace: "") {
$index: string.index($string, $search);
@if $index {
@return string.slice($string, 1, $index - 1) + $replace + str-replace(string.slice($string, $index + string.length($search)), $search, $replace);
}
@return $string;
}
/**
* Applies a function to each key-value pair in a map
*
* @param {Map} $map - The map to iterate over
* @param {String} $func - The name of the function to apply
* @param {*} $args... - Additional arguments to pass to the function
* @return {Map} - A new map with the function applied to each value
*
* @example
* $colors: (primary: #007bff, secondary: #6c757d);
* map-loop($colors, darken, 10%) // Returns map with darkened colors
*/
@function map-loop($map, $func, $args...) {
$_map: ();
@each $key, $value in $map {
// allow to pass the $key and $value of the map as an function argument
$_args: ();
@each $arg in $args {
$_args: list.append($_args, if($arg == "$key", $key, if($arg == "$value", $value, $arg)));
}
$_map: map.merge($_map, ($key: meta.call(meta.get-function($func), $_args...)));
}
@return $_map;
}