aboutsummaryrefslogtreecommitdiffstats
path: root/src/bem/_multi.scss
diff options
context:
space:
mode:
Diffstat (limited to 'src/bem/_multi.scss')
-rw-r--r--src/bem/_multi.scss131
1 files changed, 131 insertions, 0 deletions
diff --git a/src/bem/_multi.scss b/src/bem/_multi.scss
new file mode 100644
index 0000000..9e47ce4
--- /dev/null
+++ b/src/bem/_multi.scss
@@ -0,0 +1,131 @@
1////
2/// @group BEM
3///
4/// @access public
5////
6
7///
8/// Generate multiple entities (BEM or not) at once.
9///
10/// NOTE: This mixin does not generate perfectly optimized selectors in order to keep track of contexts.
11///
12/// @param {string | list} $first - First selector. Either a string for a manual selector, or a list with the first items standing for a BEM selector function (optionally suffixed by a colon) and other items being passed as arguments to said function.
13/// @param {string | list} $others - Other selectors. Either a string for a manual selector, or a list with the first items standing for a BEM selector function (optionally suffixed by a colon) and other items being passed as arguments to said function.
14///
15/// @content
16///
17/// @example scss - Creating multiple elements, a modifier and an anchor
18/// @include iro-bem-object('buttonstrip') {
19/// display: none;
20///
21/// @include iro-bem-multi('modifier' 'mod', 'element' 'button' 'separator', '> a') {
22/// display: block;
23/// }
24/// }
25///
26/// // Generates:
27///
28/// .o-buttonstrip {
29/// display: none;
30/// }
31///
32/// .o-buttonstrip--mod {
33/// display: block;
34/// }
35///
36/// .o-buttonstrip__button, {
37/// .o-buttonstrip__separator {
38/// display: block;
39/// }
40///
41/// .o-buttonstrip > a {
42/// display: block;
43/// }
44///
45/// @example scss - Creating multiple elements, a modifier and an anchor - optional colons included
46/// @include iro-bem-object('buttonstrip') {
47/// display: none;
48///
49/// @include iro-bem-multi('modifier:' 'mod', 'element:' 'button' 'separator', '> a') {
50/// display: block;
51/// }
52/// }
53///
54/// // Generates:
55///
56/// .o-buttonstrip {
57/// display: none;
58/// }
59///
60/// .o-buttonstrip--mod {
61/// display: block;
62/// }
63///
64/// .o-buttonstrip__button, {
65/// .o-buttonstrip__separator {
66/// display: block;
67/// }
68///
69/// .o-buttonstrip > a {
70/// display: block;
71/// }
72///
73@mixin iro-bem-multi($first, $others...) {
74 @include iro-context-assert-stack-count($iro-bem-context-id, $iro-bem-max-depth);
75
76 @each $entity in iro-list-prepend($others, $first) {
77 $is-manual-selector: false;
78
79 @if type-of($entity) == string and not function-exists('iro-bem-' + $entity) {
80 $is-manual-selector: true;
81 }
82
83 @if $is-manual-selector {
84 $sel: if(&, selector-nest(&, $entity), selector-parse($entity));
85
86 @at-root #{$sel} {
87 @content;
88 }
89 } @else {
90 $entity-func-id: null;
91
92 @if type-of($entity) == list {
93 $entity-func-id: nth($entity, 1);
94 $entity: iro-list-slice($entity, 2);
95 } @else {
96 $entity-func-id: $entity;
97 $entity: ();
98 }
99
100 @if str-slice($entity-func-id, str-length($entity-func-id)) == ':' {
101 $entity-func-id: str-slice($entity-func-id, 1, str-length($entity-func-id) - 1);
102 }
103
104 $sel-func: null;
105
106 @if function-exists('iro-bem-' + $entity-func-id) {
107 $sel-func: get-function('iro-bem-' + $entity-func-id);
108 } @else if function-exists($entity-func-id) {
109 $sel-func: get-function($entity-func-id);
110 }
111
112 @if $sel-func == null {
113 @error 'Function "#{inspect($entity-func-id)}" was not found.';
114 }
115
116 $entity-result: call($sel-func, $entity...);
117 $entity-result-selector: nth($entity-result, 1);
118 $entity-result-context: nth($entity-result, 2);
119
120 @if $entity-result-context != null {
121 @include iro-context-push($iro-bem-context-id, $entity-result-context...);
122 }
123 @at-root #{$entity-result-selector} {
124 @content;
125 }
126 @if $entity-result-context != null {
127 @include iro-context-pop($iro-bem-context-id);
128 }
129 }
130 }
131}