Skip to content

Instantly share code, notes, and snippets.

@hoseferrera
Forked from lukaskleinschmidt/app.scss
Created October 29, 2022 20:32
Show Gist options
  • Select an option

  • Save hoseferrera/70c3c303ebdf9d97b6dca1634dfc67c7 to your computer and use it in GitHub Desktop.

Select an option

Save hoseferrera/70c3c303ebdf9d97b6dca1634dfc67c7 to your computer and use it in GitHub Desktop.
Utility class generator like tailwindcss but in pure Sass.
@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;
// }
// }
// }
@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