Skip to content

Commit 9da063f

Browse files
committed
+ @container queries support
1 parent 25c895d commit 9da063f

File tree

5 files changed

+83
-6
lines changed

5 files changed

+83
-6
lines changed

src/_private.functions.scss

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@
241241
/// @access private
242242
/// @return {Boolean} True if mixin register was already called in current selector.
243243
@function _default-mixin-was-already-called() {
244-
$current-media-selector: _wrap-into-media-selector(&);
244+
$current-media-selector: _wrap-into-media-selector(_wrap-into-container-selector(&));
245245
@return index($_default-called-on, $current-media-selector) != null;
246246
}
247247

@@ -262,6 +262,22 @@
262262
}
263263

264264

265+
/// Wraps given selector into current container query stack to return unique selector
266+
/// to avoid duplicite usage of modifiers.
267+
@function _wrap-into-container-selector($selector) {
268+
$current-container-selector: '';
269+
$is_container: length($_current-container-stack)>0;
270+
@if $is_container {
271+
$current-container-selector: '@container ' + inspect($_current-container-stack) + ' { ';
272+
}
273+
$current-container-selector: $current-container-selector + $selector;
274+
@if $is_container {
275+
$current-container-selector: $current-container-selector + inspect($_current-container-stack) + ' }';
276+
}
277+
@return $current-container-selector;
278+
}
279+
280+
265281
/// Check if given modifier name is context-like modifier.
266282
/// @access private
267283
/// @param {String} $modifier-name - name of modifier

src/_private.mixins.scss

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@
155155
@mixin _apply-modifier($modifier-name, $args...) {
156156
$selectors: ();
157157
$medias: ();
158+
$containers: ();
158159
$original-modifier-name: str-replace($modifier-name, ' &', '');
159160
$component: component();
160161
$component-to-extend: str-trim(self());
@@ -328,6 +329,9 @@
328329
@if str-index($extension, '@media')==1 {
329330
$medias: append($medias, str-replace(str-replace($extension, '@media ', ''), ' &', ''), 'comma');
330331
}
332+
@else if str-index($extension, '@container')==1 {
333+
$containers: append($containers, str-replace(str-replace($extension, '@container ', ''), ' &', ''), 'comma');
334+
}
331335
@else {
332336
@if str-index($extension, '&') {
333337
$context-extension: str-replace($extension, ' &', '');
@@ -350,7 +354,7 @@
350354
}
351355
}
352356
}
353-
@if length($selectors)==0 and length($medias)==0 {
357+
@if length($selectors)==0 and length($medias)==0 and length($containers)==0 {
354358
// @feature Forcing to register all modifiers at first
355359
@error $SPOT_ERROR_PREFIX + $original-modifier-name+"/wrong-modifier-type - the modifier '"+$identifier+"' is not registered in component '"+&+"' as "+$modifier-name+". Check it out!";
356360
}
@@ -363,6 +367,9 @@
363367
@if str-index($extension, '@media')==1 {
364368
$medias: append($medias, str-replace(str-replace($extension, '@media ', ''), ' &', ''), 'comma');
365369
}
370+
@else if str-index($extension, '@container')==1 {
371+
$containers: append($containers, str-replace(str-replace($extension, '@container ', ''), ' &', ''), 'comma');
372+
}
366373
@else {
367374
@if str-index($extension, '&') {
368375
$context-extension: str-replace($extension, ' &', '');
@@ -402,7 +409,7 @@
402409
@if $second-param-index!='' { $second-param-index: '[['+$second-param-index+']]'; }
403410
@each $single-selector in $selectors {
404411
$i: $i + 1;
405-
$single-selector: _wrap-into-media-selector( str-replace($single-selector+'', '&', &) )+$second-param-index;
412+
$single-selector: _wrap-into-media-selector( _wrap-into-container-selector( str-replace($single-selector+'', '&', &) ) )+$second-param-index;
406413
@if index($_already-used-selectors, $single-selector) {
407414
@error $SPOT_ERROR_PREFIX + $original-modifier-name+"/already-used-modifier - the "+$original-modifier-name+"('" + nth($args,$i) + "') is already used somewhere higher! Do not break the SPOT rule and use just single place for every variant "+$modifier-name+".";
408415
}
@@ -422,7 +429,18 @@
422429
$_current-media-stack: pop($_current-media-stack) !global;
423430
}
424431

425-
@if length($selectors)>0 {
432+
@else if length($containers)>0 {
433+
// store current container selector (into stack)
434+
$_current-container-stack: append($_current-container-stack, $containers, 'space') !global;
435+
436+
@container #{$containers} {
437+
@content;
438+
}
439+
// remove current container selector (from stack)
440+
$_current-container-stack: pop($_current-container-stack) !global;
441+
}
442+
443+
@else if length($selectors)>0 {
426444
@at-root #{$selectors} {
427445
@content;
428446
}

src/_private.variables.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ $_current-component-mode: $_default-component-mode;
6262
$_current-media-stack: [];
6363

6464

65+
/// Current container or stack of current container queries (if multiple are used).
66+
/// @group Component
67+
/// @access private
68+
/// @type List
69+
$_current-container-stack: [];
70+
71+
6572
/// Flag of register mode - if parser enters mixin register.
6673
/// @group Component
6774
/// @access private

src/_public.mixins.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@
403403
}
404404

405405
// run only once per component selector
406-
$current-media-selector: _wrap-into-media-selector(&);
406+
$current-media-selector: _wrap-into-media-selector(_wrap-into-container-selector(&));
407407
@if index($_default-called-on, $current-media-selector) and $_is-in-only-for-block==false {
408408
@error $SPOT_ERROR_PREFIX + "default/already-called - the mixin default was already called for element '"+$current-media-selector+"'.";
409409
}

test/sass/input/public/responsive/responsive.mixins.sass

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,40 @@
6767

6868
+responsive('{lg}')
6969

70-
+responsive('{xl}')
70+
+responsive('{xl}')
71+
72+
73+
74+
75+
+component("my-component-3")
76+
+register
77+
+state(':hover')
78+
+responsive('@container (max-width: 1024px)')
79+
+responsive('{container}', '@container (min-width: 700px)')
80+
+responsive('{container-with-name}', '@container nickname (min-width: 450px)')
81+
+element('.wrapper')
82+
83+
+default
84+
display: block
85+
86+
+responsive('@container (max-width: 1024px)')
87+
display: table
88+
89+
+responsive('{container}')
90+
display: flex
91+
92+
+responsive('{container-with-name}')
93+
display: grid
94+
95+
+______________________
96+
+element('.wrapper')
97+
+default
98+
99+
+state(':hover')
100+
+default
101+
color: blue
102+
103+
+responsive('{container-with-name}')
104+
color: green
105+
106+

0 commit comments

Comments
 (0)