Created
August 20, 2023 20:52
-
-
Save felds/04e4698c128a547cd38b21cca4b01adb to your computer and use it in GitHub Desktop.
Sass Palette generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@use "sass:color"; | |
@use "sass:list"; | |
@use "sass:math"; | |
@use "sass:meta"; | |
// Create a list of numbers | |
@function range($from, $to, $step: 1) { | |
// validation | |
@if meta.type-of($from) != "number" { | |
@error "$from must be a number."; | |
} | |
@if meta.type-of($to) != "number" { | |
@error "$to must be a number."; | |
} | |
@if meta.type-of($step) != "number" { | |
@error "$step must be a number."; | |
} | |
@if $from > $to { | |
@error "$from must be smaller than $to."; | |
} | |
$list: []; | |
@while $from <= $to { | |
$list: list.append($list, $from); | |
$from: $from + $step; | |
} | |
@return $list; | |
} | |
// A little juggling is necessary because lists in SASS start from 1 | |
// instead of 0 | |
// This makes it tricky to convert the a 0~1 $position into the indices | |
// of the adjencent colors on the gradient | |
@function get-color-by-position($colors, $position) { | |
// a zero-based index for the last item in the color list | |
$lastIdx: list.length($colors) - 1; | |
// calculate the real index on the list based on the position | |
$stop: ($position * $lastIdx) + 1; | |
// based on the stop, get the indices for the pevious and next colors in the list | |
$prevIdx: math.floor($stop); | |
$nextIdx: math.ceil($stop); | |
// get the previous and next colors from the list | |
$prevColor: list.nth($colors, $prevIdx); | |
$nextColor: list.nth($colors, $nextIdx); | |
// calculate the amount of each color to mix | |
$amount: $stop - $prevIdx; | |
@return color.mix($nextColor, $prevColor, math.percentage($amount)); | |
} | |
@mixin generator($colors, $from: 100, $to: 900, $step: 100) { | |
// creates a list of weights, from 100 to 900 (default) | |
$weights: range($from, $to, $step); | |
// get the index of the last weight | |
$lastIdx: list.length($weights) - 1; | |
// loops through the weights | |
@for $idx from 0 through $lastIdx { | |
// get the weight by index | |
$weight: list.nth($weights, $idx + 1); | |
// get the position of the weight on the gradient | |
$pos: math.div($idx, $lastIdx); | |
// pick the color | |
$color: #{get-color-by-position($colors, $pos)}; | |
@content ($weight, $color); | |
} | |
} | |
@mixin as-props($name, $colors, $from: 100, $to: 900, $step: 100) { | |
@include generator($colors, $from, $to, $step) using ($weight, $color) { | |
--#{$name}-#{$weight}: #{$color}; | |
} | |
} | |
@mixin as-utility-classes($name, $colors, $from: 100, $to: 900, $step: 100) { | |
@include generator($colors, $from, $to, $step) using ($weight, $color) { | |
.text-#{$name}-#{$weight} { | |
color: $color !important; | |
} | |
.bg-#{$name}-#{$weight} { | |
background-color: $color !important; | |
} | |
.border-#{$name}-#{$weight} { | |
border-color: $color !important; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment