|
3 | 3 | @use "sass:meta"; |
4 | 4 | @use "sass:string"; |
5 | 5 | @use "../config" as *; |
| 6 | +@use "../vendor/rfs" as *; |
| 7 | + |
| 8 | +// stylelint-disable scss/dollar-variable-pattern |
6 | 9 |
|
7 | 10 | // Utility generator |
8 | | -// Used to generate utilities & print utilities |
| 11 | + |
| 12 | +// - Utilities can three different types of selectors: |
| 13 | +// - class: .class |
| 14 | +// - attr-starts: [class^="class"] |
| 15 | +// - attr-includes: [class*="class"] |
| 16 | +// - Utilities can generate a regular CSS property or a CSS custom property |
| 17 | +// - Utilities can be responsive or not |
| 18 | +// - Utilities can have a state (e.g., :hover, :focus, :active, etc.) |
| 19 | + |
9 | 20 | @mixin generate-utility($utility, $infix: "", $is-rfs-media-query: false) { |
10 | | - $values: map.get($utility, values); |
| 21 | + // Determine if we're generating a class, or an attribute selector |
| 22 | + $selectorType: if(map.has-key($utility, selector), map.get($utility, selector), "class"); |
| 23 | + // Then get the class name to use in a class (e.g., .class) or in a attribute selector (e.g., [class^="class"]) |
| 24 | + $selectorClass: map.get($utility, class); |
11 | 25 |
|
12 | | - // If the values are a list or string, convert it into a map |
13 | | - @if meta.type-of($values) == "string" or meta.type-of(list.nth($values, 1)) != "list" { |
14 | | - // A single value is converted to a map with a null key. |
15 | | - @if list.length($values) == 1 { |
16 | | - $values: (null: list.nth($values, 1)); |
| 26 | + // Get the list or map of values and ensure it's a map |
| 27 | + $values: map.get($utility, values); |
| 28 | + @if meta.type-of($values) != "map" { |
| 29 | + @if meta.type-of($values) == "list" { |
| 30 | + $list: (); |
| 31 | + @each $value in $values { |
| 32 | + $list: map.merge($list, ($value: $value)); |
| 33 | + } |
| 34 | + $values: $list; |
17 | 35 | } @else { |
18 | | - $values: list.zip($values, $values); |
| 36 | + $values: (null: $values); |
19 | 37 | } |
20 | 38 | } |
21 | 39 |
|
| 40 | + // Calculate infix once, before the loop |
| 41 | + $infix: if($infix == "", "", "-" + $infix); |
| 42 | + |
22 | 43 | @each $key, $value in $values { |
23 | 44 | $properties: map.get($utility, property); |
24 | 45 |
|
|
27 | 48 | $properties: list.append((), $properties); |
28 | 49 | } |
29 | 50 |
|
30 | | - // Use custom class if present |
31 | | - $property-class: if(map.has-key($utility, class), map.get($utility, class), list.nth($properties, 1)); |
32 | | - $property-class: if($property-class == null, "", $property-class); |
| 51 | + // Use custom class if present, otherwise use the first value from the list of properties |
| 52 | + $customClass: if(map.has-key($utility, class), map.get($utility, class), list.nth($properties, 1)); |
| 53 | + $customClass: if($customClass == null, "", $customClass); |
33 | 54 |
|
34 | 55 | // Use custom CSS variable name if present, otherwise default to `class` |
35 | | - $css-variable-name: if(map.has-key($utility, css-variable-name), map.get($utility, css-variable-name), map.get($utility, class)); |
| 56 | + // mdo-do: restore? |
| 57 | + // $css-variable-name: if(map.has-key($utility, css-variable-name), map.get($utility, css-variable-name), map.get($utility, class)); |
36 | 58 |
|
37 | 59 | // State params to generate pseudo-classes |
38 | 60 | $state: if(map.has-key($utility, state), map.get($utility, state), ()); |
39 | 61 |
|
40 | | - $infix: if($property-class == "" and string.slice($infix, 1, 1) == "-", string.slice($infix, 2), $infix); |
| 62 | + // $infix: if($customClass == "" and str-slice($infix, 1, 1) == "-", str-slice($infix, 2), $infix); |
41 | 63 |
|
42 | 64 | // Don't prefix if value key is null (e.g. with shadow class) |
43 | | - $property-class-modifier: if($key, if($property-class == "" and $infix == "", "", "-") + $key, ""); |
| 65 | + $customClassModifier: if($key, if($customClass == "" and $infix == "", "", "-") + $key, ""); |
44 | 66 |
|
45 | | - @if map.get($utility, rfs) { |
46 | | - // Inside the media query |
47 | | - @if $is-rfs-media-query { |
48 | | - $val: rfs-value($value); |
49 | | - |
50 | | - // Do not render anything if fluid and non fluid values are the same |
51 | | - $value: if($val == rfs-fluid-value($value), null, $val); |
52 | | - } |
53 | | - @else { |
54 | | - $value: rfs-fluid-value($value); |
| 67 | + $selector: ""; |
| 68 | + @if $selectorType == "class" { |
| 69 | + // Use the fallback of the first property if no `class` key is used |
| 70 | + @if $customClass != "" { |
| 71 | + $selector: ".#{$customClass + $infix + $customClassModifier}"; |
| 72 | + } @else { |
| 73 | + $selector: ".#{$selectorClass + $infix + $customClassModifier}"; |
55 | 74 | } |
| 75 | + } @else if $selectorType == "attr-starts" { |
| 76 | + $selector: "[class^=\"#{$selectorClass}\"]"; |
| 77 | + } @else if $selectorType == "attr-includes" { |
| 78 | + $selector: "[class*=\"#{$selectorClass}\"]"; |
56 | 79 | } |
57 | 80 |
|
58 | | - $is-css-var: map.get($utility, css-var); |
59 | | - $is-local-vars: map.get($utility, local-vars); |
60 | | - $is-rtl: map.get($utility, rtl); |
61 | | - $is-important: map.get($utility, important); |
| 81 | + // @debug $utility; |
| 82 | + // @debug $selectorType; |
| 83 | + // @debug $selector; |
| 84 | + // @debug $properties; |
| 85 | + // @debug $values; |
62 | 86 |
|
63 | | - @if $value != null { |
64 | | - @if $is-rtl == false { |
65 | | - /* rtl:begin:remove */ |
66 | | - } |
67 | | - |
68 | | - @if $is-css-var { |
69 | | - .#{$property-class + $infix + $property-class-modifier} { |
70 | | - --#{$prefix}#{$css-variable-name}: #{$value}; |
| 87 | + #{$selector} { |
| 88 | + @if map.get($utility, rfs) { |
| 89 | + @if map.get($utility, important) { |
| 90 | + @warn "The `important` option is not compatible with `rfs`. The `important` declaration will be ignored."; |
71 | 91 | } |
72 | | - |
73 | | - @each $pseudo in $state { |
74 | | - .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} { |
75 | | - --#{$prefix}#{$css-variable-name}: #{$value}; |
| 92 | + @if $is-rfs-media-query { |
| 93 | + @each $property in $properties { |
| 94 | + @include rfs($value, $property); |
76 | 95 | } |
77 | 96 | } |
78 | | - } @else { |
79 | | - .#{$property-class + $infix + $property-class-modifier} { |
| 97 | + @else { |
80 | 98 | @each $property in $properties { |
81 | | - @if $is-local-vars { |
82 | | - @each $local-var, $variable in $is-local-vars { |
83 | | - --#{$prefix}#{$local-var}: #{$variable}; |
84 | | - } |
85 | | - } |
86 | | - #{$property}: $value if($is-important, !important, null); |
| 99 | + @include rfs($value, $property); |
87 | 100 | } |
88 | 101 | } |
89 | | - |
90 | | - @each $pseudo in $state { |
91 | | - .#{$property-class + $infix + $property-class-modifier}-#{$pseudo}:#{$pseudo} { |
92 | | - @each $property in $properties { |
93 | | - @if $is-local-vars { |
94 | | - @each $local-var, $variable in $is-local-vars { |
95 | | - --#{$prefix}#{$local-var}: #{$variable}; |
96 | | - } |
97 | | - } |
98 | | - #{$property}: $value if($is-important, !important, null); |
99 | | - } |
| 102 | + } @else { |
| 103 | + @each $property in $properties { |
| 104 | + @if map.get($utility, important) { |
| 105 | + #{$property}: $value !important; // stylelint-disable-line declaration-no-important |
| 106 | + } @else { |
| 107 | + #{$property}: $value; |
100 | 108 | } |
101 | 109 | } |
102 | 110 | } |
103 | | - |
104 | | - @if $is-rtl == false { |
105 | | - /* rtl:end:remove */ |
106 | | - } |
107 | 111 | } |
| 112 | + |
| 113 | + // @if $value != null { |
| 114 | + // #{$selector} { |
| 115 | + // @each $property in $properties { |
| 116 | + // #{$property}: $value; |
| 117 | + // } |
| 118 | + // } |
| 119 | + |
| 120 | + // @if $is-css-var { |
| 121 | + // #{$selector} { |
| 122 | + // --#{$prefix}#{$css-variable-name}: #{$value}; |
| 123 | + // } |
| 124 | + |
| 125 | + // @each $pseudo in $state { |
| 126 | + // #{$selector}-#{$pseudo}:#{$pseudo} { |
| 127 | + // --#{$prefix}#{$css-variable-name}: #{$value}; |
| 128 | + // } |
| 129 | + // } |
| 130 | + // } @else { |
| 131 | + // #{$selector} { |
| 132 | + // @each $property in $properties { |
| 133 | + // // @if $is-local-vars { |
| 134 | + // // @each $local-var, $variable in $is-local-vars { |
| 135 | + // // --#{$prefix}#{$local-var}: #{$variable}; |
| 136 | + // // } |
| 137 | + // // } |
| 138 | + // #{$property}: $value; |
| 139 | + // } |
| 140 | + // } |
| 141 | + |
| 142 | + // // @each $pseudo in $state { |
| 143 | + // // #{$selector}-#{$pseudo}:#{$pseudo} { |
| 144 | + // // @each $property in $properties { |
| 145 | + // // @if $is-local-vars { |
| 146 | + // // @each $local-var, $variable in $is-local-vars { |
| 147 | + // // --#{$prefix}#{$local-var}: #{$variable}; |
| 148 | + // // } |
| 149 | + // // } |
| 150 | + // // #{$property}: $value; |
| 151 | + // // } |
| 152 | + // // } |
| 153 | + // // } |
| 154 | + // } |
| 155 | + // } |
| 156 | + |
| 157 | + $is-css-var: map.get($utility, css-var); |
| 158 | + $is-local-vars: map.get($utility, local-vars); |
| 159 | + // $is-rtl: map.get($utility, rtl); |
108 | 160 | } |
109 | 161 | } |
0 commit comments