aboutsummaryrefslogtreecommitdiffstats
path: root/src/bem/_modifier.scss
diff options
context:
space:
mode:
Diffstat (limited to 'src/bem/_modifier.scss')
-rw-r--r--src/bem/_modifier.scss227
1 files changed, 113 insertions, 114 deletions
diff --git a/src/bem/_modifier.scss b/src/bem/_modifier.scss
index 07267fe..10e2826 100644
--- a/src/bem/_modifier.scss
+++ b/src/bem/_modifier.scss
@@ -4,6 +4,11 @@
4/// @access public 4/// @access public
5//// 5////
6 6
7@use 'sass:list';
8@use 'sass:map';
9@use 'sass:meta';
10@use 'sass:selector';
11@use 'sass:string';
7@use './validators'; 12@use './validators';
8@use './vars'; 13@use './vars';
9@use '../functions'; 14@use '../functions';
@@ -111,22 +116,22 @@
111/// } 116/// }
112/// 117///
113@mixin modifier($name, $names...) { 118@mixin modifier($name, $names...) {
114 $result: modifier($name, $names...); 119 $result: modifier($name, $names...);
115 $selector: nth($result, 1); 120 $selector: list.nth($result, 1);
116 $context: nth($result, 2); 121 $context: list.nth($result, 2);
117 122
118 @include validators.validate( 123 @include validators.validate(
119 'modifier', 124 'modifier',
120 (name: $name, names: $names), 125 (name: $name, names: $names),
121 $selector, 126 $selector,
122 $context 127 $context
123 ); 128 );
124 129
125 @include contexts.push(vars.$context-id, $context...); 130 @include contexts.push(vars.$context-id, $context...);
126 @at-root #{$selector} { 131 @at-root #{$selector} {
127 @content; 132 @content;
128 } 133 }
129 @include contexts.pop(vars.$context-id); 134 @include contexts.pop(vars.$context-id);
130} 135}
131 136
132/// 137///
@@ -137,121 +142,115 @@
137/// @see {mixin} modifier 142/// @see {mixin} modifier
138/// 143///
139@function modifier($name, $names...) { 144@function modifier($name, $names...) {
140 $noop: contexts.assert-stack-count(vars.$context-id, vars.$max-depth); 145 $noop: contexts.assert-stack-count(vars.$context-id, vars.$max-depth);
141 $noop: contexts.assert-stack-must-contain(vars.$context-id, 'block'); 146 $noop: contexts.assert-stack-must-contain(vars.$context-id, 'block');
142 147
143 $parent-context: contexts.get(vars.$context-id, 'block' 'element' 'modifier' 'suffix' 'state'); 148 $parent-context: contexts.get(vars.$context-id, 'block' 'element' 'modifier' 'suffix' 'state');
144 $parent-selector: map-get(nth($parent-context, 2), 'selector'); 149 $parent-selector: map.get(list.nth($parent-context, 2), 'selector');
145 $selector: (); 150 $selector: ();
146 $parts-data: (); 151 $parts-data: ();
147 152
148 @if not functions.selector-suffix-match(&, $parent-selector) { 153 @if not functions.selector-suffix-match(&, $parent-selector) {
149 // 154 //
150 // The current selector doesn't match the parent selector. 155 // The current selector doesn't match the parent selector.
151 // The user manually added a selector between parent context and this modifier call. 156 // The user manually added a selector between parent context and this modifier call.
152 // This case is forbidden because any outcome semantically wouldn't make sense: 157 // This case is forbidden because any outcome semantically wouldn't make sense:
153 // - {b,e,m,s} [manual selector] {b,e,m,s}--modifier 158 // - {b,e,m,s} [manual selector] {b,e,m,s}--modifier
154 // - {b,e,m,s}--modifier [manual selector] 159 // - {b,e,m,s}--modifier [manual selector]
155 // The first case would make the modifier behave like an element. 160 // The first case would make the modifier behave like an element.
156 // The second case is unintuitive, the code would be more clear by nesting the manual 161 // The second case is unintuitive, the code would be more clear by nesting the manual
157 // selector in the modifier instead. 162 // selector in the modifier instead.
158 // 163 //
159 164
160 @error 'A modifier must be an immediate child of the parent context'; 165 @error 'A modifier must be an immediate child of the parent context';
161 } 166 }
162 167
163 @each $name in functions.list-prepend($names, $name) { 168 @each $name in functions.list-prepend($names, $name) {
164 $extend: false; 169 $extend: false;
165 @if type-of($name) == list { 170 @if meta.type-of($name) == list {
166 $extend: nth($name, 2); 171 $extend: list.nth($name, 2);
167 $name: nth($name, 1); 172 $name: list.nth($name, 1);
168 } 173 }
169 174
170 @if index('block' 'element', nth($parent-context, 1)) or $extend == true { 175 @if list.index('block' 'element', list.nth($parent-context, 1)) or $extend == true {
171 // 176 //
172 // Either the parent context is block or element, or a modifier or suffix 177 // Either the parent context is block or element, or a modifier or suffix
173 // is to be extended. The modifier part can simply be appended. 178 // is to be extended. The modifier part can simply be appended.
174 // Possible outcomes: 179 // Possible outcomes:
175 // - {b,e,m,s}--modifier 180 // - {b,e,m,s}--modifier
176 // 181 //
177 182
178 $sel: selector-append(&, vars.$modifier-separator + $name); 183 $sel: selector.append(&, vars.$modifier-separator + $name);
179 $selector: join($selector, $sel, comma); 184 $selector: list.join($selector, $sel, comma);
180 $parts-data: append( 185 $parts-data: list.append($parts-data, (
181 $parts-data, ( 186 'name': $name,
182 'name': $name, 187 'selector': $sel
183 'selector': $sel 188 ));
184 ) 189 } @else {
185 ); 190 //
186 } @else { 191 // Parent context is modifier, suffix or state and $extend is false.
187 // 192 //
188 // Parent context is modifier, suffix or state and $extend is false.
189 //
190 193
191 $be-context: contexts.get(vars.$context-id, 'block' 'element'); 194 $be-context: contexts.get(vars.$context-id, 'block' 'element');
192 195
193 @if nth($be-context, 1) == 'element' { 196 @if list.nth($be-context, 1) == 'element' {
194 // 197 //
195 // Latest context is element. Since element contexts can consist of multiple single 198 // Latest context is element. Since element contexts can consist of multiple single
196 // elements, inspect all elements and append its selector with the suffix "--$name". 199 // elements, inspect all elements and append its selector with the suffix "--$name".
197 // This has to be done with string comparison since none of Sass selector functions 200 // This has to be done with string comparison since none of Sass selector functions
198 // is of use here. 201 // is of use here.
199 // Possible outcomes: 202 // Possible outcomes:
200 // - {m,s}.{e}--modifier 203 // - {m,s}.{e}--modifier
201 // 204 //
202 205
203 $nsel: (); 206 $nsel: ();
204 207
205 @each $elem-part-data in map-get(nth($be-context, 2), 'parts') { 208 @each $elem-part-data in map.get(list.nth($be-context, 2), 'parts') {
206 $elem-part-selector: map-get($elem-part-data, 'selector'); 209 $elem-part-selector: map.get($elem-part-data, 'selector');
207 210
208 $sel: (); 211 $sel: ();
209 @each $s in & { 212 @each $s in & {
210 @each $ps in $elem-part-selector { 213 @each $ps in $elem-part-selector {
211 @if str-index(inspect($s), inspect($ps) + vars.$modifier-separator) or str-index(inspect($s), inspect($ps) + vars.$suffix-separator) { 214 @if string.index(meta.inspect($s), meta.inspect($ps) + vars.$modifier-separator) or string.index(meta.inspect($s), meta.inspect($ps) + vars.$suffix-separator) {
212 $sel: join($sel, selector-unify($s, selector-append($ps, vars.$modifier-separator + $name)), comma); 215 $sel: list.join($sel, selector.unify($s, selector.append($ps, vars.$modifier-separator + $name)), comma);
213 } 216 }
214 } 217 }
215 } 218 }
216 @if length($sel) == 0 { 219 @if list.length($sel) == 0 {
217 @error 'Could not generate modifier selector.'; 220 @error 'Could not generate modifier selector.';
218 } 221 }
219 222
220 $nsel: join($nsel, $sel, comma); 223 $nsel: list.join($nsel, $sel, comma);
221 } 224 }
222 225
223 $selector: join($selector, $nsel, comma); 226 $selector: list.join($selector, $nsel, comma);
224 $parts-data: append( 227 $parts-data: list.append($parts-data, (
225 $parts-data, ( 228 'name': $name,
226 'name': $name, 229 'selector': $nsel
227 'selector': $nsel 230 ));
228 ) 231 } @else {
229 ); 232 //
230 } @else { 233 // Latest context is block. Just append the modifier part.
231 // 234 // Possible outcomes:
232 // Latest context is block. Just append the modifier part. 235 // - {m,s}.{b}--modifier
233 // Possible outcomes: 236 //
234 // - {m,s}.{b}--modifier
235 //
236 237
237 $block-base-selector: map-get(nth($be-context, 2), 'base-selector'); 238 $block-base-selector: map.get(list.nth($be-context, 2), 'base-selector');
238 239
239 $sel: selector-append(&, $block-base-selector, vars.$modifier-separator + $name); 240 $sel: selector.append(&, $block-base-selector, vars.$modifier-separator + $name);
240 $selector: join($selector, $sel, comma); 241 $selector: list.join($selector, $sel, comma);
241 $parts-data: append( 242 $parts-data: list.append($parts-data, (
242 $parts-data, ( 243 'name': $name,
243 'name': $name, 244 'selector': $sel
244 'selector': $sel 245 ));
245 ) 246 }
246 ); 247 }
247 } 248 }
248 }
249 }
250 249
251 $context: 'modifier', ( 250 $context: 'modifier', (
252 'parts': $parts-data, 251 'parts': $parts-data,
253 'selector': $selector 252 'selector': $selector
254 ); 253 );
255 254
256 @return $selector $context; 255 @return $selector $context;
257} 256}