@volverjs/style 0.1.23 → 0.1.24-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/README.md +30 -0
  2. package/dist/base.css +1 -1
  3. package/dist/components/vv-accordion.css +1 -1
  4. package/dist/components/vv-alert.css +1 -1
  5. package/dist/components/vv-badge.css +1 -1
  6. package/dist/components/vv-button.css +1 -1
  7. package/dist/components/vv-card.css +1 -1
  8. package/dist/components/vv-checkbox.css +1 -1
  9. package/dist/components/vv-dialog.css +1 -1
  10. package/dist/components/vv-dropdown-action.css +1 -1
  11. package/dist/components/vv-dropdown-option.css +1 -1
  12. package/dist/components/vv-dropdown.css +1 -1
  13. package/dist/components/vv-input-file.css +1 -1
  14. package/dist/components/vv-input-text.css +1 -1
  15. package/dist/components/vv-nav.css +1 -1
  16. package/dist/components/vv-radio.css +1 -1
  17. package/dist/components/vv-select.css +1 -1
  18. package/dist/components/vv-text.css +1 -1
  19. package/dist/components/vv-tooltip.css +1 -1
  20. package/dist/components.css +1 -1
  21. package/dist/export.css +1 -1
  22. package/dist/props/breakpoints.css +1 -1
  23. package/dist/props/colors.css +1 -1
  24. package/dist/props/effects.css +1 -1
  25. package/dist/props/spacing.css +1 -1
  26. package/dist/props/transitions.css +1 -1
  27. package/dist/props/typography.css +1 -1
  28. package/dist/props.css +1 -1
  29. package/dist/themes/dark/components.css +1 -1
  30. package/dist/themes/dark/props.css +1 -1
  31. package/dist/themes/dark/volver.css +1 -1
  32. package/dist/utilities/borders.css +1 -1
  33. package/dist/utilities/colors.css +1 -1
  34. package/dist/utilities/effects.css +1 -1
  35. package/dist/utilities/flexbox.css +1 -1
  36. package/dist/utilities/grid.css +1 -1
  37. package/dist/utilities/layout.css +1 -1
  38. package/dist/utilities/sizing.css +1 -1
  39. package/dist/utilities/typography.css +1 -1
  40. package/dist/utilities.css +1 -1
  41. package/dist/volver.css +1 -1
  42. package/package.json +17 -17
  43. package/src/_config.scss +12 -0
  44. package/src/_layers.scss +4 -0
  45. package/src/_preflight.scss +2 -0
  46. package/src/components/vv-accordion-group.scss +4 -1
  47. package/src/components/vv-accordion.scss +4 -1
  48. package/src/components/vv-alert-group.scss +4 -1
  49. package/src/components/vv-alert.scss +4 -1
  50. package/src/components/vv-avatar-group.scss +4 -1
  51. package/src/components/vv-avatar.scss +4 -1
  52. package/src/components/vv-badge.scss +4 -1
  53. package/src/components/vv-breadcrumb.scss +4 -1
  54. package/src/components/vv-button-group.scss +4 -1
  55. package/src/components/vv-button.scss +5 -2
  56. package/src/components/vv-card.scss +4 -1
  57. package/src/components/vv-checkbox-group.scss +4 -1
  58. package/src/components/vv-checkbox.scss +4 -1
  59. package/src/components/vv-dialog.scss +4 -1
  60. package/src/components/vv-dropdown-action.scss +4 -1
  61. package/src/components/vv-dropdown-optgroup.scss +4 -1
  62. package/src/components/vv-dropdown-option.scss +4 -1
  63. package/src/components/vv-dropdown.scss +4 -1
  64. package/src/components/vv-input-file.scss +4 -1
  65. package/src/components/vv-input-text.scss +4 -1
  66. package/src/components/vv-nav.scss +4 -1
  67. package/src/components/vv-progress.scss +4 -1
  68. package/src/components/vv-radio-group.scss +4 -1
  69. package/src/components/vv-radio.scss +4 -1
  70. package/src/components/vv-select.scss +4 -1
  71. package/src/components/vv-skeleton.scss +4 -1
  72. package/src/components/vv-tab.scss +4 -1
  73. package/src/components/vv-table.scss +4 -1
  74. package/src/components/vv-text.scss +4 -1
  75. package/src/components/vv-textarea.scss +4 -1
  76. package/src/components/vv-tooltip.scss +6 -8
  77. package/src/export.scss +0 -1
  78. package/src/props/background.scss +5 -3
  79. package/src/props/borders.scss +5 -3
  80. package/src/props/breakpoints.scss +11 -9
  81. package/src/props/colors.scss +4 -2
  82. package/src/props/effects.scss +5 -3
  83. package/src/props/filters.scss +6 -4
  84. package/src/props/input.scss +4 -2
  85. package/src/props/layout.scss +5 -3
  86. package/src/props/sizing.scss +5 -3
  87. package/src/props/spacing.scss +18 -16
  88. package/src/props/transitions.scss +150 -118
  89. package/src/props/typography.scss +26 -24
  90. package/src/reset.scss +4 -0
  91. package/src/settings/_colors.scss +80 -50
  92. package/src/settings/_effects.scss +7 -7
  93. package/src/settings/components/_vv-badge.scss +2 -10
  94. package/src/settings/components/_vv-button.scss +1 -1
  95. package/src/settings/components/_vv-card.scss +3 -17
  96. package/src/settings/components/_vv-dialog.scss +1 -0
  97. package/src/settings/components/_vv-nav.scss +1 -6
  98. package/src/settings/components/_vv-text.scss +1 -0
  99. package/src/themes/dark/components/_vv-alert.scss +15 -10
  100. package/src/themes/dark/components/_vv-avatar.scss +15 -10
  101. package/src/themes/dark/components/_vv-badge.scss +15 -10
  102. package/src/themes/dark/components/_vv-button.scss +15 -10
  103. package/src/themes/dark/components/_vv-dropdown-action.scss +15 -10
  104. package/src/themes/dark/components/_vv-dropdown-option.scss +15 -10
  105. package/src/themes/dark/components/_vv-nav.scss +15 -10
  106. package/src/themes/dark/components/_vv-select.scss +15 -10
  107. package/src/themes/dark/props/_background.scss +3 -0
  108. package/src/themes/dark/props/_colors.scss +3 -0
  109. package/src/themes/dark/props/_input.scss +3 -0
  110. package/src/themes/dark/settings/_colors.scss +42 -28
  111. package/src/themes/dark/settings/components/_vv-alert.scss +23 -0
  112. package/src/themes/dark/settings/components/_vv-avatar.scss +3 -0
  113. package/src/themes/dark/settings/components/_vv-button.scss +0 -1
  114. package/src/tools/_breakpoints.scss +20 -4
  115. package/src/tools/_functions.scss +157 -0
  116. package/src/tools/_mixins.scss +5 -1216
  117. package/src/tools/mixin-modules/_attrs.scss +178 -0
  118. package/src/tools/mixin-modules/_bem.scss +751 -0
  119. package/src/tools/mixin-modules/_helpers.scss +23 -0
  120. package/src/tools/mixin-modules/_index.scss +25 -0
  121. package/src/tools/mixin-modules/_layers.scss +42 -0
  122. package/src/tools/mixin-modules/_props.scss +41 -0
  123. package/src/tools/mixin-modules/_theme.scss +373 -0
  124. package/src/tools/mixin-modules/_utilities.scss +121 -0
  125. package/src/utilities/backgrounds.scss +3 -0
  126. package/src/utilities/borders.scss +3 -0
  127. package/src/utilities/colors.scss +3 -0
  128. package/src/utilities/effects.scss +3 -0
  129. package/src/utilities/filters.scss +3 -0
  130. package/src/utilities/flexbox.scss +3 -0
  131. package/src/utilities/grid.scss +3 -0
  132. package/src/utilities/interactivity.scss +3 -0
  133. package/src/utilities/layout.scss +3 -0
  134. package/src/utilities/sizing.scss +3 -0
  135. package/src/utilities/spacing.scss +3 -0
  136. package/src/utilities/tables.scss +3 -0
  137. package/src/utilities/transforms.scss +11 -6
  138. package/src/utilities/transitions.scss +3 -0
  139. package/src/utilities/typography.scss +3 -0
  140. package/src/volver.scss +2 -1
@@ -0,0 +1,23 @@
1
+ @use 'sass:meta';
2
+ @use 'sass:string';
3
+
4
+ // ============================================
5
+ // Utility Helpers
6
+ // ============================================
7
+
8
+ // Wrap selector with :where() for zero specificity
9
+ // @param {String|List} $selector - The selector to wrap
10
+ // @param {Bool} $enabled - Whether to wrap in :where()
11
+ @mixin wrap-with-where($selector, $enabled: true) {
12
+ @if meta.type-of($selector) == 'map' or meta.type-of($selector) == 'list' {
13
+ $selector: #{$selector};
14
+ }
15
+
16
+ @if $enabled {
17
+ $selector: ':where(#{string.unquote($selector)})';
18
+ }
19
+
20
+ #{$selector} {
21
+ @content;
22
+ }
23
+ }
@@ -0,0 +1,25 @@
1
+ // ============================================
2
+ // Mixins Index
3
+ // Re-exports all mixins for easy importing
4
+ // ============================================
5
+
6
+ // Core helpers (wrap-with-where)
7
+ @forward 'helpers';
8
+
9
+ // CSS Custom Properties (spread-map-into-props)
10
+ @forward 'props';
11
+
12
+ // CSS Attributes (spread-map-into-attrs)
13
+ @forward 'attrs';
14
+
15
+ // CSS Layers (layer, define-layers)
16
+ @forward 'layers';
17
+
18
+ // Utilities (spread-map-into-utilities)
19
+ @forward 'utilities';
20
+
21
+ // BEM structure (spread-map-into-bem, modifiers, elements, states, breakpoints, transitions)
22
+ @forward 'bem';
23
+
24
+ // Theme utilities (spread-theme-component)
25
+ @forward 'theme';
@@ -0,0 +1,42 @@
1
+ // ============================================
2
+ // CSS @layer utilities
3
+ // ============================================
4
+
5
+ // Wrap content in a CSS @layer
6
+ // @param {String} $name - Layer name (reset, props, utilities, components, themes)
7
+ // @param {Bool} $enabled - Whether to wrap in @layer (default: false)
8
+ // @param {String} $prefix - Layer prefix (default: 'volver')
9
+ @mixin layer($name, $enabled: false, $prefix: 'volver') {
10
+ @if $enabled {
11
+ /* stylelint-disable-next-line layer-name-pattern */
12
+ @layer #{$prefix + '.' + $name} {
13
+ @content;
14
+ }
15
+ } @else {
16
+ @content;
17
+ }
18
+ }
19
+
20
+ // Define layer order (call once at the start of your stylesheet)
21
+ // This establishes the cascade priority: later layers win
22
+ // @param {Bool} $enabled - Whether to output @layer declaration
23
+ // @param {List} $order - Layer order list
24
+ // @param {String} $prefix - Layer prefix
25
+ @mixin define-layers($enabled: false, $order: (reset, props, utilities, components, themes), $prefix: 'volver') {
26
+ @if $enabled {
27
+ $layers: null;
28
+
29
+ @each $name in $order {
30
+ $layer-name: $prefix + '.' + $name;
31
+
32
+ @if $layers {
33
+ $layers: $layers + ', ' + $layer-name;
34
+ } @else {
35
+ $layers: $layer-name;
36
+ }
37
+ }
38
+
39
+ /* stylelint-disable-next-line layer-name-pattern */
40
+ @layer #{$layers};
41
+ }
42
+ }
@@ -0,0 +1,41 @@
1
+ @use 'sass:map';
2
+ @use 'sass:meta';
3
+ @use 'sass:string';
4
+ @use '../functions' as *;
5
+
6
+ // ============================================
7
+ // CSS Custom Properties (Variables) Mixin
8
+ // ============================================
9
+
10
+ // Transform a map into a list of CSS custom properties
11
+ // @param {Map} $map - The map to transform
12
+ // @param {String} $prefix - Variable name prefix
13
+ // @param {String} $old-key - Previous key for recursion
14
+ // @param {Bool} $deep - Whether to recurse into nested maps
15
+ @mixin spread-map-into-props($map: (), $prefix: '', $old-key: '', $deep: true) {
16
+ @each $key, $value in $map {
17
+ $name: meta.inspect($key);
18
+
19
+ @if $name == meta.inspect($old-key) {
20
+ $name: $prefix;
21
+ } @else if $prefix != '' and meta.inspect($prefix) != meta.inspect($key) {
22
+ $name: $prefix + '-' + $key;
23
+ }
24
+
25
+ // fix name
26
+ $name: str-replace($name, '\\/', '-');
27
+
28
+ @if string.slice(meta.inspect($key), 1, 1) != '_' and
29
+ string.slice(meta.inspect($key), 1, 2) != '--' and
30
+ string.slice(meta.inspect($key), 1, 1) != '['
31
+ {
32
+ @if meta.type-of($value) == 'map' {
33
+ @if $deep {
34
+ @include spread-map-into-props($value, $name, $key);
35
+ }
36
+ } @else {
37
+ #{'--' + $name}: #{$value};
38
+ }
39
+ }
40
+ }
41
+ }
@@ -0,0 +1,373 @@
1
+ @use 'sass:map';
2
+ @use 'sass:list';
3
+ @use 'sass:meta';
4
+ @use 'props' as *;
5
+ @use 'attrs' as *;
6
+ @use 'helpers' as *;
7
+
8
+ // ============================================
9
+ // Theme component utilities
10
+ // Generates CSS for theme overrides without @extend
11
+ // (needed to work inside media queries)
12
+ // ============================================
13
+
14
+ // Extract values from base-map that match the keys in theme-map
15
+ // This is used to generate light reset rules
16
+ // @param {Map} $base-map - Original component map with light values
17
+ // @param {Map} $theme-map - Theme override map (used to determine which keys to extract)
18
+ // @return {Map|null} - Map with light values for keys modified in theme-map, or null if empty
19
+ @function extract-light-values($base-map, $theme-map) {
20
+ $result: ();
21
+
22
+ @each $key, $value in $theme-map {
23
+ @if map.has-key($base-map, $key) {
24
+ $base-value: map.get($base-map, $key);
25
+
26
+ @if meta.type-of($value) == 'map' and meta.type-of($base-value) == 'map' {
27
+ // Recursively extract nested maps
28
+ $nested: extract-light-values($base-value, $value);
29
+
30
+ @if $nested and list.length(map.keys($nested)) > 0 {
31
+ $result: map.set($result, $key, $nested);
32
+ }
33
+ } @else {
34
+ // Direct value - use the base (light) value
35
+ $result: map.set($result, $key, $base-value);
36
+ }
37
+ }
38
+ }
39
+
40
+ // Return null if empty map
41
+ @if list.length(map.keys($result)) == 0 {
42
+ @return null;
43
+ }
44
+
45
+ @return $result;
46
+ }
47
+
48
+ // Apply theme overrides to a component
49
+ // - With $use-custom-props: true → generates CSS variables only
50
+ // - With $use-custom-props: false → generates CSS attributes directly
51
+ // @param {Map} $base-map - Original component map (e.g., $vv-button)
52
+ // @param {Map} $theme-map - Theme override map (e.g., $dark-vv-button)
53
+ // @param {String} $component-name - Component name (e.g., 'vv-button')
54
+ // @param {Map} $bps - Breakpoints map
55
+ // @param {Bool} $use-custom-props - Whether to use CSS custom properties
56
+ // @param {Bool} $generate-light-reset - Auto-generate light reset from base-map (default: true)
57
+ // @param {String} $light-reset-selector - Selector for light reset (default: '.theme.theme--light')
58
+ // @param {Bool} $zero-specificity - Whether to wrap selectors in :where()
59
+ @mixin spread-theme-component(
60
+ $base-map,
61
+ $theme-map,
62
+ $component-name,
63
+ $bps: (xxs: 0),
64
+ $use-custom-props: true,
65
+ $generate-light-reset: true,
66
+ $light-reset-selector: '.theme.theme--light',
67
+ $zero-specificity: true
68
+ ) {
69
+ // Calculate light reset map from base-map if needed
70
+ $light-reset-map: null;
71
+
72
+ @if $generate-light-reset {
73
+ $light-reset-map: extract-light-values($base-map, $theme-map);
74
+ }
75
+
76
+ @if $use-custom-props {
77
+ // Generate CSS variables only (themes override variables)
78
+ @include spread-map-into-props(
79
+ $map: $theme-map,
80
+ $prefix: $component-name
81
+ );
82
+
83
+ // Light reset with custom props
84
+ @if $light-reset-map and $generate-light-reset {
85
+ #{$light-reset-selector} {
86
+ @include spread-map-into-props(
87
+ $map: $light-reset-map,
88
+ $prefix: $component-name
89
+ );
90
+ }
91
+ }
92
+ } @else {
93
+ // Generate CSS attributes directly for theme overrides
94
+ $selector: '.' + $component-name;
95
+
96
+ // Block styles (base attributes, ignoring nested structures)
97
+ @include wrap-with-where($selector: $selector, $enabled: $zero-specificity) {
98
+ @include spread-map-into-attrs(
99
+ $map: $theme-map,
100
+ $prefix: $component-name,
101
+ $use-custom-props: false,
102
+ $ignore: (modifier, element, state, breakpoint, transition)
103
+ );
104
+ }
105
+
106
+ // Process modifiers recursively
107
+ @if map.has-key($theme-map, 'modifier') {
108
+ @include _theme-spread-modifiers(
109
+ $map: map.get($theme-map, 'modifier'),
110
+ $prefix: $component-name,
111
+ $block: $selector,
112
+ $bps: $bps,
113
+ $zero-specificity: $zero-specificity
114
+ );
115
+ }
116
+
117
+ // Process elements
118
+ @if map.has-key($theme-map, 'element') {
119
+ @include _theme-spread-elements(
120
+ $map: map.get($theme-map, 'element'),
121
+ $prefix: $component-name,
122
+ $block: $selector,
123
+ $bps: $bps,
124
+ $zero-specificity: $zero-specificity
125
+ );
126
+ }
127
+
128
+ // Process states at block level
129
+ @if map.has-key($theme-map, 'state') {
130
+ @include _theme-spread-states(
131
+ $map: map.get($theme-map, 'state'),
132
+ $prefix: $component-name,
133
+ $block: $selector,
134
+ $parent-selector: $selector,
135
+ $bps: $bps,
136
+ $zero-specificity: $zero-specificity
137
+ );
138
+ }
139
+
140
+ // Generate light reset rules if enabled
141
+ @if $light-reset-map and $generate-light-reset {
142
+ #{$light-reset-selector} {
143
+ @include _theme-generate-all(
144
+ $map: $light-reset-map,
145
+ $prefix: $component-name,
146
+ $block: $selector,
147
+ $bps: $bps,
148
+ $zero-specificity: $zero-specificity
149
+ );
150
+ }
151
+ }
152
+ }
153
+ }
154
+
155
+ // Helper to generate all theme rules (block, modifiers, elements, states)
156
+ @mixin _theme-generate-all($map, $prefix, $block, $bps, $zero-specificity: true) {
157
+ // Block styles
158
+ @include wrap-with-where($selector: $block, $enabled: $zero-specificity) {
159
+ @include spread-map-into-attrs(
160
+ $map: $map,
161
+ $prefix: $prefix,
162
+ $use-custom-props: false,
163
+ $ignore: (modifier, element, state, breakpoint, transition)
164
+ );
165
+ }
166
+
167
+ // Process modifiers
168
+ @if map.has-key($map, 'modifier') {
169
+ @include _theme-spread-modifiers(
170
+ $map: map.get($map, 'modifier'),
171
+ $prefix: $prefix,
172
+ $block: $block,
173
+ $bps: $bps,
174
+ $zero-specificity: $zero-specificity
175
+ );
176
+ }
177
+
178
+ // Process elements
179
+ @if map.has-key($map, 'element') {
180
+ @include _theme-spread-elements(
181
+ $map: map.get($map, 'element'),
182
+ $prefix: $prefix,
183
+ $block: $block,
184
+ $bps: $bps,
185
+ $zero-specificity: $zero-specificity
186
+ );
187
+ }
188
+
189
+ // Process states
190
+ @if map.has-key($map, 'state') {
191
+ @include _theme-spread-states(
192
+ $map: map.get($map, 'state'),
193
+ $prefix: $prefix,
194
+ $block: $block,
195
+ $parent-selector: $block,
196
+ $bps: $bps,
197
+ $zero-specificity: $zero-specificity
198
+ );
199
+ }
200
+ }
201
+
202
+ // ============================================
203
+ // Private helper mixins for theme spreading
204
+ // ============================================
205
+
206
+ // Spread modifiers for theme (no @extend)
207
+ @mixin _theme-spread-modifiers($map, $prefix, $block, $parent-selector: null, $bps: (xxs: 0), $zero-specificity: true) {
208
+ @each $mod-name, $mod-value in $map {
209
+ $mod-selector: '#{$block}#{$block}--#{$mod-name}';
210
+
211
+ @if $parent-selector {
212
+ $mod-selector: '#{$parent-selector}#{$block}--#{$mod-name}';
213
+ }
214
+
215
+ // Modifier base styles
216
+ @include wrap-with-where($selector: $mod-selector, $enabled: $zero-specificity) {
217
+ @include spread-map-into-attrs(
218
+ $map: $mod-value,
219
+ $prefix: $prefix,
220
+ $use-custom-props: false,
221
+ $ignore: (modifier, element, state, breakpoint)
222
+ );
223
+ }
224
+
225
+ // States inside modifier
226
+ @if map.has-key($mod-value, 'state') {
227
+ @include _theme-spread-states(
228
+ $map: map.get($mod-value, 'state'),
229
+ $prefix: $prefix,
230
+ $block: $block,
231
+ $parent-selector: $mod-selector,
232
+ $bps: $bps,
233
+ $zero-specificity: $zero-specificity
234
+ );
235
+ }
236
+
237
+ // Elements inside modifier
238
+ @if map.has-key($mod-value, 'element') {
239
+ @include _theme-spread-elements(
240
+ $map: map.get($mod-value, 'element'),
241
+ $prefix: $prefix,
242
+ $block: $block,
243
+ $parent-selector: $mod-selector,
244
+ $bps: $bps,
245
+ $zero-specificity: $zero-specificity
246
+ );
247
+ }
248
+
249
+ // Nested modifiers
250
+ @if map.has-key($mod-value, 'modifier') {
251
+ @include _theme-spread-modifiers(
252
+ $map: map.get($mod-value, 'modifier'),
253
+ $prefix: $prefix,
254
+ $block: $block,
255
+ $parent-selector: $mod-selector,
256
+ $bps: $bps,
257
+ $zero-specificity: $zero-specificity
258
+ );
259
+ }
260
+ }
261
+ }
262
+
263
+ // Spread elements for theme (no @extend)
264
+ @mixin _theme-spread-elements($map, $prefix, $block, $parent-selector: null, $bps: (xxs: 0), $zero-specificity: true) {
265
+ @each $el-name, $el-value in $map {
266
+ $el-selector: '#{$block}__#{$el-name}';
267
+ $full-selector: $el-selector;
268
+
269
+ @if $parent-selector {
270
+ $full-selector: '#{$parent-selector} #{$el-selector}';
271
+ }
272
+
273
+ // Element base styles
274
+ @include wrap-with-where($selector: $full-selector, $enabled: $zero-specificity) {
275
+ @include spread-map-into-attrs(
276
+ $map: $el-value,
277
+ $prefix: $prefix,
278
+ $use-custom-props: false,
279
+ $ignore: (modifier, element, state, breakpoint)
280
+ );
281
+ }
282
+
283
+ // States inside element
284
+ @if map.has-key($el-value, 'state') {
285
+ @include _theme-spread-states(
286
+ $map: map.get($el-value, 'state'),
287
+ $prefix: $prefix,
288
+ $block: $el-selector,
289
+ $parent-selector: $parent-selector,
290
+ $bps: $bps,
291
+ $zero-specificity: $zero-specificity
292
+ );
293
+ }
294
+ }
295
+ }
296
+
297
+ // Spread states for theme (no @extend)
298
+ @mixin _theme-spread-states($map, $prefix, $block, $parent-selector: null, $bps: (xxs: 0), $zero-specificity: true) {
299
+ $state-list: (
300
+ active, focus, hover, focus-within, target, visited, focus-visible,
301
+ disabled, checked, checked-within, multiple, selected, readonly,
302
+ empty, placeholder-shown, dirty, valid, invalid, indeterminate,
303
+ first-child, last-child, open, close, determinate, pressed, current
304
+ );
305
+
306
+ @each $state-name, $state-value in $map {
307
+ @if list.index($state-list, $state-name) {
308
+ $base: $block;
309
+
310
+ @if $parent-selector {
311
+ $base: $parent-selector;
312
+ }
313
+
314
+ // BEM modifier style: .block--state
315
+ // Class style: .block.state
316
+ $state-selectors: (
317
+ '#{$base}#{$block}--#{$state-name}',
318
+ '#{$base}.#{$state-name}'
319
+ );
320
+
321
+ @include wrap-with-where($selector: $state-selectors, $enabled: $zero-specificity) {
322
+ @include spread-map-into-attrs(
323
+ $map: $state-value,
324
+ $prefix: $prefix,
325
+ $use-custom-props: false,
326
+ $ignore: (modifier, element, state, breakpoint)
327
+ );
328
+ }
329
+
330
+ // Pseudo-class style based on state type
331
+ @if $state-name == 'disabled' or $state-name == 'readonly' or $state-name == 'multiple' {
332
+ @include wrap-with-where($selector: '#{$base}[#{$state-name}]', $enabled: $zero-specificity) {
333
+ @include spread-map-into-attrs(
334
+ $map: $state-value,
335
+ $prefix: $prefix,
336
+ $use-custom-props: false,
337
+ $ignore: (modifier, element, state, breakpoint)
338
+ );
339
+ }
340
+ } @else if $state-name == 'focus-visible' {
341
+ @include wrap-with-where($selector: '#{$base}:not(:active):not([disabled]):not([tabindex="-1"]):not([aria-disabled="true"]):#{$state-name}', $enabled: $zero-specificity) {
342
+ @include spread-map-into-attrs(
343
+ $map: $state-value,
344
+ $prefix: $prefix,
345
+ $use-custom-props: false,
346
+ $ignore: (modifier, element, state, breakpoint)
347
+ );
348
+ }
349
+ } @else if $state-name != 'current' {
350
+ @include wrap-with-where($selector: '#{$base}:not([disabled]):#{$state-name}', $enabled: $zero-specificity) {
351
+ @include spread-map-into-attrs(
352
+ $map: $state-value,
353
+ $prefix: $prefix,
354
+ $use-custom-props: false,
355
+ $ignore: (modifier, element, state, breakpoint)
356
+ );
357
+ }
358
+ }
359
+
360
+ // Elements inside state
361
+ @if map.has-key($state-value, 'element') {
362
+ @include _theme-spread-elements(
363
+ $map: map.get($state-value, 'element'),
364
+ $prefix: $prefix,
365
+ $block: $block,
366
+ $parent-selector: '#{$base}#{$block}--#{$state-name}',
367
+ $bps: $bps,
368
+ $zero-specificity: $zero-specificity
369
+ );
370
+ }
371
+ }
372
+ }
373
+ }
@@ -0,0 +1,121 @@
1
+ @use 'sass:meta';
2
+ @use 'sass:string';
3
+ @use '../functions' as *;
4
+ @use '../breakpoints' as *;
5
+ @use 'helpers' as *;
6
+
7
+ // ============================================
8
+ // Utilities Mixin
9
+ // Generates utility classes from maps
10
+ // ============================================
11
+
12
+ // Transform a map into a list of utility classes
13
+ // @param {Map|List} $map - The map or list to transform
14
+ // @param {String} $class - Base class name
15
+ // @param {String|List} $attribute - CSS attribute(s) to set
16
+ // @param {String} $prop - CSS custom property name
17
+ // @param {String} $name - Name for nested recursion
18
+ // @param {Bool} $deep - Whether to recurse into nested maps
19
+ // @param {Map} $bps - Breakpoints map
20
+ // @param {String} $prefix - Class prefix for breakpoints
21
+ // @param {Bool} $zero-specificity - Whether to wrap in :where()
22
+ @mixin spread-map-into-utilities(
23
+ $map: (),
24
+ $class: '',
25
+ $attribute: '',
26
+ $prop: '',
27
+ $name: '',
28
+ $deep: true,
29
+ $bps: (xxs: 0),
30
+ $prefix: '',
31
+ $zero-specificity: false
32
+ ) {
33
+ @if (meta.type-of($map) == 'map' or meta.type-of($map) == 'list') and $attribute != '' {
34
+ @each $breakpoint, $breakpoint-value in $bps {
35
+ @if $breakpoint-value > 0 {
36
+ $prefix: $breakpoint + '\\:';
37
+ }
38
+
39
+ @each $key, $value in $map {
40
+ @if $name != '' and meta.inspect($key) != meta.inspect($name) {
41
+ $key: #{$name}-#{meta.inspect($key)};
42
+ }
43
+
44
+ @if meta.type-of($value) == 'map' and $deep {
45
+ @include spread-map-into-utilities(
46
+ $map: $value,
47
+ $class: $class,
48
+ $attribute: $attribute,
49
+ $prop: $prop,
50
+ $name: $key,
51
+ $bps: $bps,
52
+ $prefix: $prefix,
53
+ $zero-specificity: $zero-specificity
54
+ );
55
+ } @else {
56
+ $default: null;
57
+ $class-name: $class;
58
+ $key: meta.inspect($key);
59
+ $var: $prop;
60
+
61
+ // fix class name
62
+ @if $class-name != $key and $prop != $key {
63
+ @if $class-name != '' {
64
+ $class-name: $class-name + '-';
65
+ }
66
+
67
+ $class-name: $class-name + $key;
68
+ }
69
+
70
+ // fix variable name
71
+ @if $var != '' and $var != $key {
72
+ $var: $var + '-' + $key;
73
+ }
74
+
75
+ $var: str-replace($var, '\\/', '-');
76
+
77
+ // check if value is not a map (spacing-dynamic)
78
+ @if meta.type-of($value) != 'map' {
79
+ $default: $value;
80
+ }
81
+
82
+ // check if map is a list
83
+ @if meta.type-of($map) == 'list' and (not $default or $default == '') {
84
+ $default: $key;
85
+ }
86
+
87
+ @if meta.type-of($default) == 'string' {
88
+ $default: string.unquote($default);
89
+ }
90
+
91
+ %#{$prefix}#{$class-name} {
92
+ @include media-breakpoint-up($breakpoint, $bps) {
93
+ @if meta.type-of($attribute) != 'list' {
94
+ $attribute: ($attribute);
95
+ }
96
+
97
+ @each $attr in $attribute {
98
+ @if $default {
99
+ @if $var != '' {
100
+ #{$attr}: var(--#{$var}, $default);
101
+ } @else {
102
+ #{$attr}: $default;
103
+ }
104
+ } @else if $var != '' {
105
+ #{$attr}: var(--#{$var});
106
+ }
107
+ }
108
+ }
109
+ }
110
+
111
+ @include wrap-with-where(
112
+ $selector: '.' + $prefix + $class-name,
113
+ $enabled: $zero-specificity
114
+ ) {
115
+ @extend %#{$prefix}#{$class-name};
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+ }
@@ -1,5 +1,6 @@
1
1
  @use '../context' as *;
2
2
 
3
+ @include layer(utilities, $use-css-layers, $layer-prefix) {
3
4
  // background-attachment
4
5
  @include spread-map-into-utilities(
5
6
  $map: $background-attachment,
@@ -65,3 +66,5 @@
65
66
  $prop: gradient,
66
67
  $zero-specificity: $zero-specificity-for-utilities
67
68
  );
69
+
70
+ }
@@ -1,6 +1,7 @@
1
1
  @use 'sass:map';
2
2
  @use '../context' as *;
3
3
 
4
+ @include layer(utilities, $use-css-layers, $layer-prefix) {
4
5
  // border-radius
5
6
  @include spread-map-into-utilities(
6
7
  $map: $border-radius,
@@ -88,3 +89,5 @@
88
89
  $bps: $breakpoints,
89
90
  $zero-specificity: $zero-specificity-for-utilities
90
91
  );
92
+
93
+ }
@@ -1,5 +1,6 @@
1
1
  @use '../context' as *;
2
2
 
3
+ @include layer(utilities, $use-css-layers, $layer-prefix) {
3
4
  // background-color
4
5
  @include spread-map-into-utilities(
5
6
  $map: $colors,
@@ -35,3 +36,5 @@
35
36
  $prop: color,
36
37
  $zero-specificity: $zero-specificity-for-utilities
37
38
  );
39
+
40
+ }
@@ -1,5 +1,6 @@
1
1
  @use '../context' as *;
2
2
 
3
+ @include layer(utilities, $use-css-layers, $layer-prefix) {
3
4
  // box shadow
4
5
  @include spread-map-into-utilities(
5
6
  $map: $box-shadow,
@@ -31,3 +32,5 @@
31
32
  $attribute: background-blend-mode,
32
33
  $zero-specificity: $zero-specificity-for-utilities
33
34
  );
35
+
36
+ }
@@ -1,5 +1,6 @@
1
1
  @use '../context' as *;
2
2
 
3
+ @include layer(utilities, $use-css-layers, $layer-prefix) {
3
4
  // blur
4
5
  @include spread-map-into-utilities(
5
6
  $map: $blur,
@@ -31,3 +32,5 @@
31
32
  $attribute: backdrop-filter,
32
33
  $zero-specificity: $zero-specificity-for-utilities
33
34
  );
35
+
36
+ }