@volverjs/style 0.1.25 → 0.1.27

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.
@@ -114,7 +114,7 @@ $vv-dialog: (
114
114
  opacity: var(--opacity-0),
115
115
  element: (
116
116
  wrapper: (
117
- translate: -100%,
117
+ [translate]: calc(-100% * var(--direction, 1)),
118
118
  ),
119
119
  ),
120
120
  ),
@@ -122,7 +122,7 @@ $vv-dialog: (
122
122
  opacity: var(--opacity-0),
123
123
  element: (
124
124
  wrapper: (
125
- translate: 100%,
125
+ [translate]: calc(100% * var(--direction, 1)),
126
126
  ),
127
127
  ),
128
128
  ),
@@ -145,6 +145,24 @@ $vv-dialog: (
145
145
  ),
146
146
  ),
147
147
  ),
148
+ slide-inline-end: (
149
+ active: (
150
+ transition: var(--transition-opacity),
151
+ element: (
152
+ wrapper: (
153
+ transition: var(--transition-transform),
154
+ ),
155
+ ),
156
+ ),
157
+ inert: (
158
+ opacity: var(--opacity-0),
159
+ element: (
160
+ wrapper: (
161
+ [translate]: calc(100% * var(--direction, 1)),
162
+ ),
163
+ ),
164
+ ),
165
+ ),
148
166
  ),
149
167
  modifier: (
150
168
  small: (
@@ -158,7 +176,7 @@ $vv-dialog: (
158
176
  padding: 0,
159
177
  element: (
160
178
  wrapper: (
161
- border-radius: var(--rounded-0),
179
+ border-radius: var(--rounded-none),
162
180
  max-width: auto,
163
181
  max-height: auto,
164
182
  width: 100%,
@@ -166,5 +184,40 @@ $vv-dialog: (
166
184
  ),
167
185
  ),
168
186
  ),
187
+ // Side panel anchored to the inline end, pair it with the
188
+ // slide-inline-end transition. Full width below sm.
189
+ drawer: (
190
+ padding: 0,
191
+ align-items: stretch,
192
+ justify-content: flex-end,
193
+ element: (
194
+ wrapper: (
195
+ width: 100%,
196
+ max-height: 100dvh,
197
+ border-radius: var(--rounded-none),
198
+ breakpoint: (
199
+ up-sm: (
200
+ width: min(75dvw, 32rem),
201
+ ),
202
+ ),
203
+ ),
204
+ // Flat header and footer: on a full height panel the filled
205
+ // bands read as heavy. The footer keeps its divider because
206
+ // the content above it scrolls.
207
+ header: (
208
+ font-weight: var(--font-bold),
209
+ background: var(--color-transparent),
210
+ border-bottom: 0,
211
+ ),
212
+ // Without the divider the header padding already spaces the
213
+ // title from the first field, so drop the duplicate.
214
+ content: (
215
+ padding-top: 0,
216
+ ),
217
+ footer: (
218
+ background: var(--color-transparent),
219
+ ),
220
+ ),
221
+ ),
169
222
  ),
170
223
  ) !default;
@@ -0,0 +1,189 @@
1
+ $vv-input-range: (
2
+ display: var(--input-display),
3
+ flex: var(--input-flex),
4
+ flex-direction: var(--input-flex-direction),
5
+ margin-bottom: var(--input-gap),
6
+ font-size: var(--input-font-size),
7
+ line-height: var(--input-line-height),
8
+ min-width: var(--input-min-width),
9
+ element: (
10
+ label: (
11
+ _alias: '> label',
12
+ _combinator: '>',
13
+ display: var(--input-label-display),
14
+ font-size: var(--input-label-font-size),
15
+ font-weight: var(--input-label-font-weight),
16
+ color: var(--input-label-color),
17
+ margin: 0 0 var(--input-label-gap) 0,
18
+ white-space: var(--input-label-white-space),
19
+ text-overflow: var(--input-label-text-overflow),
20
+ overflow: var(--input-label-overflow),
21
+ max-width: var(--input-label-max-width),
22
+ ),
23
+ wrapper: (
24
+ display: flex,
25
+ align-items: center,
26
+ gap: var(--spacing-sm),
27
+ min-height: var(--input-min-height),
28
+ ),
29
+ input-before: (
30
+ display: flex,
31
+ align-items: center,
32
+ ),
33
+ input-after: (
34
+ display: flex,
35
+ align-items: center,
36
+ ),
37
+ // Everything reading an --input-range-* token is written as a plain
38
+ // declaration: a var() inside a custom property is substituted where
39
+ // that property is declared, so wrapping these in the generated
40
+ // --vv-input-range-* props would freeze them at the :root values and
41
+ // the fill, the accent overrides and the hover halo would never move.
42
+ input: (
43
+ _alias: 'input[type="range"]',
44
+ -webkit-appearance: none,
45
+ appearance: none,
46
+ flex: 1,
47
+ min-width: 0,
48
+ [height]: var(--input-range-thumb-size),
49
+ margin: 0,
50
+ padding: 0,
51
+ background: transparent,
52
+ cursor: pointer,
53
+ pseudo: (
54
+ -webkit-slider-runnable-track: (
55
+ [height]: var(--input-range-track-height),
56
+ border-radius: var(--rounded-full),
57
+ [background]:
58
+ linear-gradient(
59
+ to right,
60
+ var(--input-range-accent-color)
61
+ var(--input-range-progress),
62
+ var(--input-range-track-color)
63
+ var(--input-range-progress)
64
+ ),
65
+ ),
66
+ -webkit-slider-thumb: (
67
+ -webkit-appearance: none,
68
+ appearance: none,
69
+ [width]: var(--input-range-thumb-size),
70
+ [height]: var(--input-range-thumb-size),
71
+ [margin-top]:
72
+ calc(
73
+ (
74
+ var(--input-range-track-height) -
75
+ var(--input-range-thumb-size)
76
+ ) / 2
77
+ ),
78
+ border: var(--border-2) solid var(--color-surface),
79
+ border-radius: var(--rounded-full),
80
+ [background]: var(--input-range-accent-color),
81
+ [box-shadow]: var(--input-range-thumb-shadow),
82
+ will-change: box-shadow,
83
+ transition: var(--transition-shadow),
84
+ ),
85
+ -moz-range-track: (
86
+ [height]: var(--input-range-track-height),
87
+ border-radius: var(--rounded-full),
88
+ [background]: var(--input-range-track-color),
89
+ ),
90
+ -moz-range-progress: (
91
+ [height]: var(--input-range-track-height),
92
+ border-radius: var(--rounded-full),
93
+ [background]: var(--input-range-accent-color),
94
+ ),
95
+ -moz-range-thumb: (
96
+ [width]: var(--input-range-thumb-size),
97
+ [height]: var(--input-range-thumb-size),
98
+ border: var(--border-2) solid var(--color-surface),
99
+ border-radius: var(--rounded-full),
100
+ [background]: var(--input-range-accent-color),
101
+ [box-shadow]: var(--input-range-thumb-shadow),
102
+ will-change: box-shadow,
103
+ transition: var(--transition-shadow),
104
+ ),
105
+ ),
106
+ state: (
107
+ hover: (
108
+ --input-range-thumb-shadow:
109
+ var(--input-range-thumb-shadow-hover),
110
+ ),
111
+ focus-visible: (
112
+ outline: var(--border-2) solid var(--color-brand),
113
+ outline-offset: var(--spacing-2),
114
+ ),
115
+ disabled: (
116
+ cursor: not-allowed,
117
+ ),
118
+ ),
119
+ ),
120
+ value: (
121
+ display: flex,
122
+ align-items: baseline,
123
+ justify-content: center,
124
+ gap: var(--spacing-2),
125
+ flex: 0 0 auto,
126
+ min-width: var(--spacing-64),
127
+ padding: var(--spacing-4) var(--spacing-sm),
128
+ font-size: var(--text-14),
129
+ font-variant-numeric: tabular-nums,
130
+ color: var(--input-color),
131
+ background-color: var(--input-background-color),
132
+ border: var(--border) solid var(--color-surface-3),
133
+ border-radius: var(--rounded-md),
134
+ text-align: center,
135
+ ),
136
+ unit: (
137
+ color: var(--input-placeholder-color),
138
+ font-size: var(--text-12),
139
+ ),
140
+ hint: (
141
+ _alias: '> small',
142
+ _combinator: '>',
143
+ display: var(--input-hint-display),
144
+ font-size: var(--input-hint-font-size),
145
+ color: var(--input-hint-color),
146
+ padding-top: var(--input-hint-gap),
147
+ padding-inline: var(--spacing-xs),
148
+ white-space: var(--input-hint-white-space),
149
+ text-overflow: var(--input-hint-text-overflow),
150
+ overflow: var(--input-hint-overflow),
151
+ ),
152
+ ),
153
+ modifier: (
154
+ valid: (
155
+ --input-range-accent-color: var(--input-valid-color),
156
+ element: (
157
+ hint: (
158
+ color: var(--input-valid-color),
159
+ ),
160
+ value: (
161
+ border-color: var(--input-valid-color),
162
+ ),
163
+ ),
164
+ ),
165
+ invalid: (
166
+ --input-range-accent-color: var(--input-invalid-color),
167
+ element: (
168
+ hint: (
169
+ color: var(--input-invalid-color),
170
+ ),
171
+ value: (
172
+ border-color: var(--input-invalid-color),
173
+ ),
174
+ ),
175
+ ),
176
+ readonly: (
177
+ --input-range-accent-color: var(--color-word-4),
178
+ opacity: var(--opacity-100),
179
+ cursor: default,
180
+ pointer-events: none,
181
+ ),
182
+ ),
183
+ state: (
184
+ disabled: (
185
+ --input-range-accent-color: var(--color-word-4),
186
+ opacity: var(--opacity-50),
187
+ ),
188
+ ),
189
+ ) !default;
@@ -4,7 +4,7 @@ $vv-tooltip: (
4
4
  position: absolute,
5
5
  inset-inline: 100% auto,
6
6
  top: 50%,
7
- translate: var(--spacing-10) -50%,
7
+ [translate]: calc(var(--spacing-10) * var(--direction, 1)) -50%,
8
8
  z-index: var(--z-tooltip),
9
9
  inline-size: max-content,
10
10
  max-inline-size: 25ch,
@@ -24,7 +24,8 @@ $vv-tooltip: (
24
24
  z-index: -1,
25
25
  inset-inline: 0 auto,
26
26
  inset-block: 50% auto,
27
- translate: -100% -50%,
27
+ [translate]: calc(-100% * var(--direction, 1)) -50%,
28
+ [scale]: var(--direction, 1) 1,
28
29
  border-width: var(--spacing-8),
29
30
  border-style: solid,
30
31
  border-color: transparent var(--color-gray-darken-4) transparent
@@ -38,12 +39,13 @@ $vv-tooltip: (
38
39
  top: (
39
40
  inset-inline: 50% 0,
40
41
  inset-block: auto 100%,
41
- translate: -50% calc(var(--spacing-10) * -1),
42
+ [translate]: calc(-50% * var(--direction, 1))
43
+ calc(var(--spacing-10) * -1),
42
44
  pseudo: (
43
45
  after: (
44
46
  inset-inline: 50% auto,
45
47
  inset-block: 100% auto,
46
- translate: -50%,
48
+ [translate]: calc(-50% * var(--direction, 1)),
47
49
  rotate: -90deg,
48
50
  ),
49
51
  ),
@@ -51,24 +53,24 @@ $vv-tooltip: (
51
53
  bottom: (
52
54
  inset-inline: 50% 0,
53
55
  inset-block: 100% auto,
54
- translate: -50% var(--spacing-10),
56
+ [translate]: calc(-50% * var(--direction, 1)) var(--spacing-10),
55
57
  pseudo: (
56
58
  after: (
57
59
  inset-inline: 50% auto,
58
60
  inset-block: 0 auto,
59
- translate: -50% -100%,
61
+ [translate]: calc(-50% * var(--direction, 1)) -100%,
60
62
  rotate: 90deg,
61
63
  ),
62
64
  ),
63
65
  ),
64
66
  left: (
65
67
  inset-inline: auto 100%,
66
- translate: calc(var(--spacing-10) * -1) -50%,
68
+ [translate]: calc(var(--spacing-10) * -1 * var(--direction, 1)) -50%,
67
69
  pseudo: (
68
70
  after: (
69
71
  position: absolute,
70
72
  inset-inline: auto 0,
71
- translate: 100% -50%,
73
+ [translate]: calc(100% * var(--direction, 1)) -50%,
72
74
  rotate: 180deg,
73
75
  ),
74
76
  ),
@@ -53,7 +53,9 @@ $-pseudo-elements: (
53
53
  -webkit-progress-bar, -webkit-progress-value, -webkit-inner-element,
54
54
  -moz-progress-bar, -moz-progress-value, -moz-inner-element,
55
55
  -webkit-details-marker, -webkit-scrollbar,
56
- -webkit-scrollbar-track, -webkit-scrollbar-thumb
56
+ -webkit-scrollbar-track, -webkit-scrollbar-thumb,
57
+ -webkit-slider-runnable-track, -webkit-slider-thumb,
58
+ -moz-range-track, -moz-range-progress, -moz-range-thumb
57
59
  );
58
60
 
59
61
  // Transform a map into a list of CSS attributes
@@ -81,38 +83,50 @@ $-pseudo-elements: (
81
83
  @each $key, $value in $map {
82
84
  @if not list.index($ignore, $key) {
83
85
  @if meta.type-of($value) == 'map' and ($deep or $key == 'pseudo') {
84
- $original: map.get($original, $key);
85
-
86
- @if not $original {
87
- $original: ();
86
+ // Sass assignment reaches the enclosing scope, so the
87
+ // reference map and the property name of a nested map are
88
+ // kept in their own variables: reusing $original and $key
89
+ // left every key after the first one looking itself up in
90
+ // the wrong map.
91
+ $nested-original: map.get($original, $key);
92
+
93
+ @if not $nested-original {
94
+ $nested-original: ();
88
95
  }
89
96
 
97
+ $nested-key: $key;
98
+
90
99
  @if $postfix != '' {
91
- $key: #{$postfix}-#{$key};
100
+ $nested-key: #{$postfix}-#{$key};
92
101
  }
93
102
 
103
+ // The test is on the map key, not on the postfixed name: a
104
+ // pseudo map nested one level down would otherwise be
105
+ // spread as plain declarations on the parent selector.
94
106
  @if $key == 'pseudo' {
95
107
  @each $pseudo-element, $pseudo-map in $value {
96
108
  @if meta.type-of($pseudo-map) == 'map' {
97
109
  @if list.index($-pseudo-elements, $pseudo-element) {
98
- $original: map.get($original, $pseudo-element);
99
- $key: pseudo-#{$pseudo-element};
110
+ $pseudo-original: (
111
+ map.get($nested-original, $pseudo-element)
112
+ );
113
+ $pseudo-key: pseudo-#{$pseudo-element};
100
114
 
101
115
  @include pseudo-element-placeholder($pseudo-element) {
102
- @if not $original {
116
+ @if not $pseudo-original {
103
117
  @if not map.has-key($pseudo-map, 'content') {
104
118
  content: '';
105
119
  }
106
120
 
107
- $original: ();
121
+ $pseudo-original: ();
108
122
  }
109
123
 
110
124
  @include spread-map-into-attrs(
111
- $original: $original,
125
+ $original: $pseudo-original,
112
126
  $map: $pseudo-map,
113
127
  $prefix: $prefix,
114
128
  $variant: $variant,
115
- $postfix: $key,
129
+ $postfix: $pseudo-key,
116
130
  $deep: true,
117
131
  $use-custom-props: $use-custom-props
118
132
  );
@@ -122,11 +136,11 @@ $-pseudo-elements: (
122
136
  }
123
137
  } @else {
124
138
  @include spread-map-into-attrs(
125
- $original: $original,
139
+ $original: $nested-original,
126
140
  $map: $value,
127
141
  $prefix: $prefix,
128
142
  $variant: $variant,
129
- $postfix: $key,
143
+ $postfix: $nested-key,
130
144
  $deep: true,
131
145
  $use-custom-props: $use-custom-props
132
146
  );
@@ -322,6 +322,10 @@ $-state-suffixes: (
322
322
 
323
323
  @if meta.type-of(map.get($map, $key)) == 'map' {
324
324
  @each $element, $value in map.get($map, $key) {
325
+ // `$block` is the block selector alone, threaded down unchanged
326
+ // from `spread-map-into-bem`: what a state or a transition
327
+ // expands to travels in `$modifier` instead. Passing a selector
328
+ // list here would suffix its last entry alone.
325
329
  $selector: $block + '__' + $element;
326
330
 
327
331
  // combinator
@@ -354,6 +358,10 @@ $-state-suffixes: (
354
358
 
355
359
  @if $alias {
356
360
  @if $modifier {
361
+ // One entry per selector of the modifier, in the same
362
+ // order as `$selector` above: `spread-map-into-states`
363
+ // pairs the two lists by index, so an `_alias` has to be
364
+ // a single selector, not a list of them.
357
365
  $aliases: ();
358
366
 
359
367
  @each $item in selector.parse($modifier) {
@@ -442,15 +450,35 @@ $-state-suffixes: (
442
450
  @each $state, $value in map.get($map, $key) {
443
451
  @if list.index($-valid-states, $state) {
444
452
  $selectors: ();
453
+ $block-items: selector.parse($block);
454
+ $alias-items: ();
455
+
456
+ // `$block` and `$alias` are built side by side by the caller,
457
+ // one entry per selector of the parent, so they are walked by
458
+ // index: the alias belongs to the block item it was nested
459
+ // under. Suffixing the list as a whole would reach its last
460
+ // entry alone and leave the ones before it in the rule bare.
461
+ @if $alias {
462
+ $alias-items: selector.parse($alias);
463
+ }
464
+
465
+ $i: 0;
466
+
467
+ @each $block-item in $block-items {
468
+ $i: $i + 1;
469
+ $alias-item: null;
470
+
471
+ @if $i <= list.length($alias-items) {
472
+ $alias-item: list.nth($alias-items, $i);
473
+ }
445
474
 
446
- @each $block-item in selector.parse($block) {
447
475
  $selectors: list.join(
448
476
  $selectors,
449
477
  ('#{$modifier}#{$block-item}--#{$state}', '#{$modifier}#{$block-item}.#{$state}')
450
478
  );
451
479
 
452
- @if $alias {
453
- $selectors: list.join($selectors, '#{$modifier}#{$alias}.#{$state}');
480
+ @if $alias-item {
481
+ $selectors: list.join($selectors, '#{$modifier}#{$alias-item}.#{$state}');
454
482
  }
455
483
 
456
484
  // Special state handling - use function to get updated selectors
@@ -458,7 +486,7 @@ $-state-suffixes: (
458
486
  $state: $state,
459
487
  $block-item: $block-item,
460
488
  $modifier: $modifier,
461
- $alias: $alias,
489
+ $alias: $alias-item,
462
490
  $selectors: $selectors
463
491
  );
464
492
  }
@@ -558,6 +586,27 @@ $-state-suffixes: (
558
586
  $block: &;
559
587
  }
560
588
 
589
+ // A state and a transition hand their whole selector list down as the
590
+ // modifier, so the block is compounded onto each of its entries: written
591
+ // as one interpolation it would reach the last entry alone and leave the
592
+ // ones before it in the rule unscoped.
593
+ $selector: '#{$modifier}#{$block}';
594
+
595
+ @if $modifier and $modifier != '' and $block {
596
+ $selectors: ();
597
+
598
+ @each $modifier-item in selector.parse($modifier) {
599
+ @each $block-item in selector.parse($block) {
600
+ $selectors: list.join(
601
+ $selectors,
602
+ '#{$modifier-item}#{$block-item}'
603
+ );
604
+ }
605
+ }
606
+
607
+ $selector: list-to-string($selectors);
608
+ }
609
+
561
610
  @if meta.type-of(map.get($map, $key)) == 'map' {
562
611
  @each $breakpoint, $value in map.get($map, $key) {
563
612
  @if string.index($breakpoint, '-') {
@@ -566,7 +615,7 @@ $-state-suffixes: (
566
615
 
567
616
  @if map.has-key($bps, $bp) {
568
617
  @if $operator == 'up' {
569
- @include wrap-with-where($selector: '#{$modifier}#{$block}', $enabled: $zero-specificity) {
618
+ @include wrap-with-where($selector: $selector, $enabled: $zero-specificity) {
570
619
  @include media-breakpoint-up($bp, $bps) {
571
620
  @include spread-map-into-attrs(
572
621
  $original: $original,
@@ -581,7 +630,7 @@ $-state-suffixes: (
581
630
  }
582
631
 
583
632
  @if $operator == 'down' {
584
- @include wrap-with-where($selector: '#{$modifier}#{$block}', $enabled: $zero-specificity) {
633
+ @include wrap-with-where($selector: $selector, $enabled: $zero-specificity) {
585
634
  @include media-breakpoint-down($bp, $bps) {
586
635
  @include spread-map-into-attrs(
587
636
  $original: $original,
@@ -596,7 +645,7 @@ $-state-suffixes: (
596
645
  }
597
646
 
598
647
  @if map.has-key($bps, $operator) {
599
- @include wrap-with-where($selector: '#{$modifier}#{$block}', $enabled: $zero-specificity) {
648
+ @include wrap-with-where($selector: $selector, $enabled: $zero-specificity) {
600
649
  @include media-breakpoint-between($operator, $bp, $bps) {
601
650
  @include spread-map-into-attrs(
602
651
  $original: $original,
@@ -611,7 +660,7 @@ $-state-suffixes: (
611
660
  }
612
661
  }
613
662
  } @else if map.has-key($bps, $breakpoint) {
614
- @include wrap-with-where($selector: '#{$modifier}#{$block}', $enabled: $zero-specificity) {
663
+ @include wrap-with-where($selector: $selector, $enabled: $zero-specificity) {
615
664
  @include media-breakpoint-up($breakpoint, $bps) {
616
665
  @include spread-map-into-attrs(
617
666
  $original: $original,
@@ -711,3 +760,125 @@ $-state-suffixes: (
711
760
  }
712
761
  }
713
762
  }
763
+
764
+ // ============================================
765
+ // Control states
766
+ // ============================================
767
+ // A field component is a wrapper element around a native control, so its own
768
+ // `state` maps generate selectors (`.vv-input-text:disabled`) that can never
769
+ // match. This re-applies those placeholders on the control's attribute
770
+ // instead, through `:has()`, block first and then element by element.
771
+
772
+ // `$states` are read from the map's `state` key and must name an attribute of
773
+ // the control: `disabled` and `readonly` for a text field, `disabled` alone
774
+ // where HTML has no readonly (`select`, `input[type="range"]`). Components
775
+ // that spell readonly as a modifier because they freeze the control with the
776
+ // disabled attribute list that modifier in `$except-modifiers`, otherwise the
777
+ // hook would dim a readonly field: `:has()` carries the specificity of its
778
+ // argument, so with `$zero-specificity: false` it outweighs the modifier and
779
+ // source order alone would not settle it.
780
+ @mixin spread-map-into-control-states(
781
+ $map,
782
+ $block,
783
+ $control: 'input',
784
+ $states: ('disabled', 'readonly'),
785
+ $except-modifiers: (),
786
+ $zero-specificity: true
787
+ ) {
788
+ $component-selector: '.#{$block}';
789
+ $exception: '';
790
+
791
+ @each $modifier in $except-modifiers {
792
+ $exception: '#{$exception}:not(#{$component-selector}--#{$modifier})';
793
+ }
794
+
795
+ @each $state in $states {
796
+ $selector: (
797
+ '#{$component-selector}#{$exception}:has(#{$control}[#{$state}])'
798
+ );
799
+
800
+ @include wrap-with-where(
801
+ $selector: $selector,
802
+ $enabled: $zero-specificity
803
+ ) {
804
+ @extend %#{$block}--#{$state} !optional;
805
+ }
806
+
807
+ // element
808
+ @if map.get($map, 'state', $state, 'element') {
809
+ @each $element, $element-map
810
+ in map.get($map, 'state', $state, 'element')
811
+ {
812
+ $element-selector: (
813
+ '#{$selector} #{$component-selector}__#{$element}'
814
+ );
815
+ $alias: map.get($map, 'element', $element, '_alias');
816
+
817
+ // The alias is a second selector for the same element, not a
818
+ // descendant of the first, so the list is glued with a comma
819
+ // before it is emitted: interpolating it would join the two
820
+ // with a space and compile them to one selector that matches
821
+ // a `.vv-input-text` nested inside its own element.
822
+ @if $alias {
823
+ $element-selector: list.append(
824
+ $element-selector,
825
+ ('#{$selector} #{$alias}')
826
+ );
827
+ }
828
+
829
+ @include wrap-with-where(
830
+ $selector: list-to-string($element-selector),
831
+ $enabled: $zero-specificity
832
+ ) {
833
+ @extend %#{$block}-state-#{$state}__#{$element} !optional;
834
+ }
835
+
836
+ // element state
837
+ @each $element-state, $state-map
838
+ in map.get($element-map, 'state')
839
+ {
840
+ @if $element-state {
841
+ $element-selector-state: ();
842
+
843
+ @each $item in $element-selector {
844
+ $element-selector-state: list.append(
845
+ $element-selector-state,
846
+ ('#{$item}:#{$element-state}')
847
+ );
848
+ }
849
+
850
+ @include wrap-with-where(
851
+ $selector: list-to-string($element-selector-state),
852
+ $enabled: $zero-specificity
853
+ ) {
854
+ @extend %#{$block}-state-#{$state}-element-#{$element}--#{$element-state}
855
+ !optional;
856
+ }
857
+ }
858
+ }
859
+
860
+ // element pseudo
861
+ @each $pseudo, $pseudo-map in map.get($element-map, 'pseudo') {
862
+ @if $pseudo {
863
+ $element-selector-pseudo: ();
864
+
865
+ @each $item in $element-selector {
866
+ $element-selector-pseudo: list.append(
867
+ $element-selector-pseudo,
868
+ ('#{$item}::#{$pseudo}')
869
+ );
870
+ }
871
+
872
+ @include wrap-with-where(
873
+ $selector: list-to-string($element-selector-pseudo),
874
+ $enabled: $zero-specificity
875
+ ) {
876
+ @extend %#{$block}-state-#{$state}-element-#{$element}--#{$pseudo}
877
+ !optional;
878
+ }
879
+ }
880
+ }
881
+ }
882
+ }
883
+ }
884
+ }