-
-
Save hoseferrera/70c3c303ebdf9d97b6dca1634dfc67c7 to your computer and use it in GitHub Desktop.
Utility class generator like tailwindcss but in pure Sass.
This file contains hidden or 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:map'; | |
| @use 'variants' as * with ( | |
| $breakpoints: ( | |
| 'small': 640px, | |
| 'medium': 768px, | |
| 'large': 1024px, | |
| 'larger': 1280px, | |
| ) | |
| ); | |
| .banana { | |
| @include variants('hover') { | |
| color: yellow; | |
| } | |
| } | |
| // $options: ( | |
| // '0': 0, | |
| // '1': 1, | |
| // '2': 2, | |
| // '3': 3, | |
| // ); | |
| // | |
| // .col { | |
| // @include variants($options, 'responsive') using ($key, $value) { | |
| // &-#{$key} { | |
| // column-count: $value; | |
| // } | |
| // } | |
| // } | |
| // $options: ( | |
| // '0': 0, | |
| // '1': 1rem, | |
| // '2': 2rem, | |
| // '3': 3rem, | |
| // ); | |
| // | |
| // .col-gap { | |
| // @include variants($options, 'responsive') using ($key, $value) { | |
| // &-#{$key} { | |
| // column-gap: $value; | |
| // } | |
| // } | |
| // } | |
| // | |
| // | |
| // $options: ( | |
| // 'px': 1px, | |
| // '0': 0, | |
| // '1': .25rem, | |
| // '2': .5rem, | |
| // '3': .75rem, | |
| // '4': 1rem, | |
| // '5': 1.25rem, | |
| // '6': 1.5rem, | |
| // '8': 2rem, | |
| // '10': 2.5rem, | |
| // '12': 3rem, | |
| // '16': 4rem, | |
| // '20': 5rem, | |
| // '24': 6rem, | |
| // '32': 8rem, | |
| // '40': 10rem, | |
| // '48': 12rem, | |
| // '56': 14rem, | |
| // '64': 16rem, | |
| // ); | |
| // | |
| // .p { | |
| // @include variants($options, 'responsive') using ($key, $value) { | |
| // &-#{$key} { | |
| // padding: $value; | |
| // } | |
| // | |
| // &x-#{$key} { | |
| // padding-right: $value; | |
| // padding-left: $value; | |
| // } | |
| // | |
| // &y-#{$key} { | |
| // padding-bottom: $value; | |
| // padding-top: $value; | |
| // } | |
| // | |
| // &t-#{$key} { | |
| // padding-top: $value; | |
| // } | |
| // | |
| // &r-#{$key} { | |
| // padding-right: $value; | |
| // } | |
| // | |
| // &b-#{$key} { | |
| // padding-bottom: $value; | |
| // } | |
| // | |
| // &l-#{$key} { | |
| // padding-left: $value; | |
| // } | |
| // } | |
| // } | |
| // | |
| // | |
| // $options: map.merge(( | |
| // 'auto': auto, | |
| // ), $options); | |
| // | |
| // .m { | |
| // @include variants($options, 'responsive') using ($key, $value) { | |
| // &-#{$key} { | |
| // margin: $value; | |
| // } | |
| // | |
| // &x-#{$key} { | |
| // margin-right: $value; | |
| // margin-left: $value; | |
| // } | |
| // | |
| // &y-#{$key} { | |
| // margin-bottom: $value; | |
| // margin-top: $value; | |
| // } | |
| // | |
| // &t-#{$key} { | |
| // margin-top: $value; | |
| // } | |
| // | |
| // &r-#{$key} { | |
| // margin-right: $value; | |
| // } | |
| // | |
| // &b-#{$key} { | |
| // margin-bottom: $value; | |
| // } | |
| // | |
| // &l-#{$key} { | |
| // margin-left: $value; | |
| // } | |
| // } | |
| // } |
This file contains hidden or 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:string'; | |
| @use 'sass:list'; | |
| $breakpoints: () !default; | |
| @function _remove($list, $value) { | |
| $result: (); | |
| @for $i from 1 through list.length($list) { | |
| @if list.nth($list, $i) != $value { | |
| $result: list.append($result, list.nth($list, $i)); | |
| } | |
| } | |
| @return $result; | |
| } | |
| @function _selector($variant: null, $breakpoint: null) { | |
| $selectors: (); | |
| @each $selector in & { | |
| $selector: list.nth($selector, 1); | |
| $selector: string.slice($selector, 2); | |
| // Add the variant to the current selector | |
| @if $variant { | |
| $selector: '#{$variant}\\:#{$selector}'; | |
| } | |
| // Add the breakpoint to the current selector | |
| @if $breakpoint { | |
| $selector: '#{$breakpoint}\\:#{$selector}'; | |
| } | |
| // Convert back to a proper class | |
| $selectors: list.append($selectors, '.#{$selector}', comma); | |
| } | |
| @return $selectors; | |
| } | |
| @function _pseudo-class($key, $variant: null) { | |
| @if $variant { | |
| $key: '#{$key}:#{$variant}'; | |
| } | |
| @return $key; | |
| } | |
| @mixin _options($options, $variant: null, $breakpoint: null) { | |
| $pseudo-class: $variant; | |
| $group: null; | |
| @if type-of($variant) == 'string' and string.index($variant, 'group-') { | |
| $pseudo-class: string.slice($pseudo-class, 7); | |
| $group: '.group'; | |
| } | |
| $selector: _selector($variant, $breakpoint); | |
| @if $options { | |
| @each $key, $value in $options { | |
| @if $group { | |
| #{_pseudo-class($group, $pseudo-class)} #{$selector} { | |
| @content($key, $value); | |
| } | |
| } @else { | |
| #{$selector} { | |
| @content(_pseudo-class($key, $pseudo-class), $value); | |
| } | |
| } | |
| } | |
| } @else { | |
| @if $group { | |
| #{_pseudo-class($group, $pseudo-class)} #{$selector} { | |
| @content; | |
| } | |
| } @else { | |
| #{_pseudo-class($selector, $pseudo-class)} { | |
| @content; | |
| } | |
| } | |
| } | |
| } | |
| @mixin _variants($options, $variants, $breakpoint: null) { | |
| @include _options($options, null, $breakpoint) using ($data...) { | |
| @content($data...); | |
| } | |
| @each $variant in $variants { | |
| @include _options($options, $variant, $breakpoint) using ($data...) { | |
| @content($data...); | |
| } | |
| } | |
| } | |
| @mixin variants($options.../*, $variants: ()*/) { | |
| $variants: list.nth($options, -1); | |
| $options: list.nth($options, 1); | |
| @if (type-of($variants) == 'map') { | |
| $variants: null; | |
| } | |
| @if (type-of($options) != 'map') { | |
| $options: null; | |
| } | |
| $responsive: list.index($variants, 'responsive'); | |
| @if $responsive { | |
| $variants: _remove($variants, 'responsive'); | |
| } | |
| @at-root { | |
| @include _variants($options, $variants) using ($data...) { | |
| @content($data...); | |
| } | |
| @if $responsive { | |
| @each $breakpoint, $value in $breakpoints { | |
| @media screen and (min-width: #{$value}) { | |
| @include _variants($options, $variants, $breakpoint) using ($data...) { | |
| @content($data...); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment