bem-constructor 0.1
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3 -0
- data/README.md +282 -0
- data/lib/bem-constructor.rb +8 -0
- data/stylesheets/_bem-constructor.scss +37 -0
- data/stylesheets/_block.scss +91 -0
- data/stylesheets/_element.scss +43 -0
- data/stylesheets/_error-checks.scss +50 -0
- data/stylesheets/_hack.scss +38 -0
- data/stylesheets/_index.scss +7 -0
- data/stylesheets/_logger.scss +12 -0
- data/stylesheets/_modifier.scss +49 -0
- data/stylesheets/_modifies-element.scss +37 -0
- data/stylesheets/_scope.scss +40 -0
- data/stylesheets/_state.scss +28 -0
- data/stylesheets/_theme.scss +33 -0
- data/stylesheets/logger/_block-logger.scss +30 -0
- data/stylesheets/logger/_context-logger.scss +40 -0
- data/stylesheets/logger/_element-logger.scss +59 -0
- data/stylesheets/logger/_modifier-logger.scss +94 -0
- data/stylesheets/logger/_scope-logger.scss +30 -0
- data/stylesheets/test.css +26 -0
- data/stylesheets/test.css.map +7 -0
- data/stylesheets/test.scss +59 -0
- metadata +99 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 8d21417bbbbf72744f4f58dbf75f61313f4f0c0f
|
4
|
+
data.tar.gz: 4e6598835ffaaac7ed06cb3cfea6d8b9f14b0e7c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: b6ea8f0194709514cf397580c63858d5c5a4ea54e2e2d9f3db9de0f049db8dcf1df6399267aa19a96020d6b022a16aafbe9da568d45748bf04fc5c2a0e9e988d
|
7
|
+
data.tar.gz: 6e1f86e490a5d18ece7bfc4d9f68f9402b42de7f6595220fb0623f66daac14350a7c09db82f1ebceb2458c241f894d7b6063dc7bc9f512f0c223c519a382ddb5
|
data/CHANGELOG.md
ADDED
data/README.md
ADDED
@@ -0,0 +1,282 @@
|
|
1
|
+
# BEM Constructor
|
2
|
+
|
3
|
+
BEM Constructor is a Sass library for building immutable and namespaced BEM-style CSS objects.
|
4
|
+
|
5
|
+
By enforcing a consistent and programatic way of defining objects (blocks, elements and modifiers) it ensures a more structured, robust and secure object codebase that is easy to understand and maintain. Objects defined using the constructor are impossible to modify and reassign by mistake or omission.
|
6
|
+
|
7
|
+
Jump to [🍔 The Burger Example™](#example) to see the mixins in action.
|
8
|
+
|
9
|
+
----
|
10
|
+
|
11
|
+
## Key ideas
|
12
|
+
|
13
|
+
The key ideas behind this library are well explained by Harry Roberts in his articles [Immutable CSS](http://csswizardry.com/2015/03/immutable-css/), [More Transparent UI Code with Namespaces](http://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/) and [MindBEMding – getting your head ’round BEM syntax](http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/),
|
14
|
+
|
15
|
+
### 1. Immutability
|
16
|
+
|
17
|
+
Some CSS objects in your project shouldn't be able to change (mutate). They have a very specific role and you need to make sure they're not reassigned somewhere else in your codebase. In order to ensure immutability you'll need three things: a way of defining those objects, a way of recognising them and a way to guarantee you won't be able to modify them later on. By constructing objects programatically you can be confident that they are assigned once and just once.
|
18
|
+
|
19
|
+
### 2. Namespacing
|
20
|
+
|
21
|
+
Objects have a clear function. Whethere they are components, utilities o dirty hacks, we need a consistent way of telling them apart. By namespacing objects, our UI code becomes more transparent and understandable. BEM Constructor supports the following object types:
|
22
|
+
|
23
|
+
- Objects
|
24
|
+
- Components
|
25
|
+
- Utilities
|
26
|
+
- Themes
|
27
|
+
- States
|
28
|
+
- Scopes
|
29
|
+
- Hacks
|
30
|
+
|
31
|
+
Read [Harry's post on namespaces](http://csswizardry.com/2015/03/more-transparent-ui-code-with-namespaces/) to get a deep look at why and how they are used.
|
32
|
+
|
33
|
+
|
34
|
+
### 3. BEM structure
|
35
|
+
|
36
|
+
BEM objects are composed of a block and any number of elements and/or modifiers. Using the BEM syntax for naming classes you'll produce structured code that helps you and other developers understand at a glance the relationship between those classes. The BEM constructor takes care of generating bem-compliant selectors.
|
37
|
+
|
38
|
+
----
|
39
|
+
|
40
|
+
## Installation
|
41
|
+
|
42
|
+
There are 3 ways of installing BEM Constructor:
|
43
|
+
|
44
|
+
### Download
|
45
|
+
|
46
|
+
Download the Sass files in [stylesheets/](/stylesheets/) and place them in your Sass directory.
|
47
|
+
|
48
|
+
### Bower
|
49
|
+
|
50
|
+
Run the following command:
|
51
|
+
|
52
|
+
bower install --save-dev bem-constructor
|
53
|
+
|
54
|
+
### Compass extension
|
55
|
+
|
56
|
+
1. `gem install bem-constructor`
|
57
|
+
2. Add `require 'bem-constructor'` to your `config.rb`
|
58
|
+
|
59
|
+
----
|
60
|
+
|
61
|
+
## Usage
|
62
|
+
|
63
|
+
Import it into your main stylesheet:
|
64
|
+
|
65
|
+
@import 'bem-constructor';
|
66
|
+
|
67
|
+
### block($name, $type)
|
68
|
+
|
69
|
+
Constructs a new block element of a given type. `$type` being one of: `'object'`, `'component'` or `'utility'`.
|
70
|
+
|
71
|
+
@include block($name, $type) { ... }
|
72
|
+
|
73
|
+
|
74
|
+
#### object($name)
|
75
|
+
|
76
|
+
A shortcut for `block($name, $type: 'object')`
|
77
|
+
|
78
|
+
#### component($name)
|
79
|
+
|
80
|
+
A shortcut for `block($name, $type: 'component')`
|
81
|
+
|
82
|
+
#### utility($name)
|
83
|
+
|
84
|
+
A shortcut for `block($name, $type: 'utility')`
|
85
|
+
|
86
|
+
|
87
|
+
### element($name...)
|
88
|
+
|
89
|
+
Creates a new element of the parent block. It should always be nested within a block constructor. You can create multiple elements at once by passing a comma separated list (Arglist) of element names.
|
90
|
+
|
91
|
+
@include element($name...) { ... }
|
92
|
+
|
93
|
+
|
94
|
+
### modifier($name...)
|
95
|
+
|
96
|
+
Creates a new modifier of the parent block or element. Should always be nested within a block or element constructor. You can declare multiple modifiers at once by passing a comma separated list (Arglist) of modifier names.
|
97
|
+
|
98
|
+
@include modifier($name...) { ... }
|
99
|
+
|
100
|
+
|
101
|
+
### modifies-element($modified-elements...)
|
102
|
+
|
103
|
+
When declaring a block modifier, a state you may need to target and modify some of the block elements too. Use the following mixin to scope the ruleset to those elements.
|
104
|
+
|
105
|
+
@include modifies-element($modified-elements...) { ... }
|
106
|
+
|
107
|
+
|
108
|
+
### theme($themes...)
|
109
|
+
|
110
|
+
Style your objects given a parent theme class.
|
111
|
+
|
112
|
+
@include theme($themes...) { ... }
|
113
|
+
|
114
|
+
### state($states...)
|
115
|
+
|
116
|
+
Modifies objects by appending a state class
|
117
|
+
|
118
|
+
@include state($states...) { ... }
|
119
|
+
|
120
|
+
### hack()
|
121
|
+
|
122
|
+
Signals that the following code is a hack.
|
123
|
+
|
124
|
+
@include hack() { ... }
|
125
|
+
|
126
|
+
|
127
|
+
### scope($name)
|
128
|
+
|
129
|
+
Creates a new scope
|
130
|
+
|
131
|
+
Scopes allow you to isolate code you don't have control over.
|
132
|
+
|
133
|
+
@include scope($name) { ... }
|
134
|
+
|
135
|
+
|
136
|
+
----
|
137
|
+
|
138
|
+
## Options
|
139
|
+
|
140
|
+
### Namespaces
|
141
|
+
|
142
|
+
Switch namespaces on/off by setting the following variable:
|
143
|
+
|
144
|
+
$bem-use-namespaces: false; // defaults to true
|
145
|
+
|
146
|
+
Override the default block namespaces:
|
147
|
+
|
148
|
+
$bem-block-namespaces: (
|
149
|
+
'object': 'obj', // defaults to 'o'
|
150
|
+
'component': 'comp', // defaults to 'c'
|
151
|
+
'utility': 'helper', // defaults to 'u'
|
152
|
+
);
|
153
|
+
|
154
|
+
Override the default theme namespace:
|
155
|
+
|
156
|
+
$bem-theme-namespace: 'theme'; // defaults to 't'
|
157
|
+
|
158
|
+
Override the default state namespace:
|
159
|
+
|
160
|
+
$bem-state-namespace: 'has'; // defaults to 'is'
|
161
|
+
|
162
|
+
Override the default hack namespace:
|
163
|
+
|
164
|
+
$bem-hack-namespace: 'it-wasnt-me-'; // defaults to '_'
|
165
|
+
|
166
|
+
|
167
|
+
|
168
|
+
### BEM separators
|
169
|
+
|
170
|
+
By default BEM Constructor uses the following BEM convention:
|
171
|
+
- Two underscores (__) for elements
|
172
|
+
- Two hyphens for modifiers (--).
|
173
|
+
|
174
|
+
You can customize them to whatever fits you needs:
|
175
|
+
|
176
|
+
$bem-element-separator: '-'; // Defaults to '__'
|
177
|
+
|
178
|
+
$bem-modifier-separator: '-_-_'; // Defaults to '--'
|
179
|
+
|
180
|
+
|
181
|
+
|
182
|
+
----
|
183
|
+
|
184
|
+
##<a name="example"></a> 🍔 The Burger Example™
|
185
|
+
|
186
|
+
|
187
|
+
*Disclaimer: the following Sass code may not compile into a real burger.*
|
188
|
+
|
189
|
+
```` scss
|
190
|
+
|
191
|
+
@include object('burger') {
|
192
|
+
texture: juicy;
|
193
|
+
|
194
|
+
@include element('lettuce', 'tomato') {
|
195
|
+
quality: fresh;
|
196
|
+
}
|
197
|
+
|
198
|
+
@include element('cheese') {
|
199
|
+
type: gouda;
|
200
|
+
|
201
|
+
@include modifier('parmigiano') {
|
202
|
+
type: parmigiano;
|
203
|
+
}
|
204
|
+
}
|
205
|
+
|
206
|
+
@include element('extra-topping') {
|
207
|
+
ingredient: bacon;
|
208
|
+
}
|
209
|
+
|
210
|
+
@include element('meat') {
|
211
|
+
type: beef;
|
212
|
+
}
|
213
|
+
|
214
|
+
@include modifier('veggie') {
|
215
|
+
texture: smooth;
|
216
|
+
|
217
|
+
@include modifies-element('meat') {
|
218
|
+
type: lentils;
|
219
|
+
}
|
220
|
+
|
221
|
+
@include modifies-element('extra-topping') {
|
222
|
+
ingredient: avocado;
|
223
|
+
|
224
|
+
@include hack() {
|
225
|
+
ingredient: bacon;
|
226
|
+
}
|
227
|
+
}
|
228
|
+
}
|
229
|
+
|
230
|
+
@include theme('mexican') {
|
231
|
+
spicy: hell-yeah;
|
232
|
+
}
|
233
|
+
|
234
|
+
@include state('cold') {
|
235
|
+
taste: terrible;
|
236
|
+
}
|
237
|
+
}
|
238
|
+
|
239
|
+
The compiled CSS:
|
240
|
+
|
241
|
+
```` css
|
242
|
+
|
243
|
+
/* The main Burger object */
|
244
|
+
.o-burger { texture: juicy; }
|
245
|
+
|
246
|
+
/* lettuce and Tomato elements */
|
247
|
+
.o-burger__lettuce, .o-burger__tomato { quality: fresh; }
|
248
|
+
|
249
|
+
/* Cheese element */
|
250
|
+
.o-burger__cheese { type: gouda; }
|
251
|
+
|
252
|
+
/* Cheese modifier */
|
253
|
+
.o-burger__cheese--parmigiano { type: parmigiano; }
|
254
|
+
|
255
|
+
/* Extra topping element */
|
256
|
+
.o-burger__extra-topping { ingredient: bacon; }
|
257
|
+
|
258
|
+
/* Meat element */
|
259
|
+
.o-burger__meat { type: beef; }
|
260
|
+
|
261
|
+
/* Veggie Burger block modifier */
|
262
|
+
.o-burger--veggie { texture: smooth; }
|
263
|
+
|
264
|
+
/* Veggie Burger block modifier modifies the Meat element too */
|
265
|
+
.o-burger--veggie .o-burger__meat { type: lentils; }
|
266
|
+
|
267
|
+
/* Veggie Burger block modifier modifies the Extra Topping element too */
|
268
|
+
.o-burger--veggie .o-burger__extra-topping { ingredient: avocado; }
|
269
|
+
|
270
|
+
/* But we are hackers and couldn't resist adding some Bacon back */
|
271
|
+
._o-burger--veggie .o-burger__extra-topping { ingredient: bacon; }
|
272
|
+
|
273
|
+
/* When the party Theme is Mexican, we make everything spicy */
|
274
|
+
.t-mexican .o-burger { spicy: hell-yeah; }
|
275
|
+
|
276
|
+
/* And we're all sad when the burge Is Cold */
|
277
|
+
.o-burger.is-cold { taste: terrible; }
|
278
|
+
|
279
|
+
|
280
|
+
## This is overkill, who is this for?
|
281
|
+
|
282
|
+
If constructing objects programatically seems too verbose or abstract to you that's perfectly OK. This tool is not for everybody. However if you need to enforce a strict way of writing BEM objects in your project, want to make sure they won't mutate and thus produce more secure CSS, then this tool might help you.
|
@@ -0,0 +1,37 @@
|
|
1
|
+
// -----------------------------------------------------------------------------
|
2
|
+
// BEM constructor
|
3
|
+
// -----------------------------------------------------------------------------
|
4
|
+
// Table of contents
|
5
|
+
// 1. Default settings
|
6
|
+
// 2. Imports
|
7
|
+
|
8
|
+
// -----------------------------------------------------------------------------
|
9
|
+
// 1. Default settings
|
10
|
+
// -----------------------------------------------------------------------------
|
11
|
+
|
12
|
+
/// Use namespaced class names
|
13
|
+
/// @public
|
14
|
+
$bem-use-namespaces: true !default;
|
15
|
+
|
16
|
+
/// Bem style element separator
|
17
|
+
/// @public
|
18
|
+
$bem-element-separator: '__' !default;
|
19
|
+
|
20
|
+
/// Bem style modifier separator
|
21
|
+
/// @public
|
22
|
+
$bem-modifier-separator: '--' !default;
|
23
|
+
|
24
|
+
// -----------------------------------------------------------------------------
|
25
|
+
// 2. Imports
|
26
|
+
// -----------------------------------------------------------------------------
|
27
|
+
|
28
|
+
@import 'logger';
|
29
|
+
@import 'error-checks';
|
30
|
+
@import 'block';
|
31
|
+
@import 'element';
|
32
|
+
@import 'modifier';
|
33
|
+
@import 'modifies-element';
|
34
|
+
@import 'scope';
|
35
|
+
@import 'theme';
|
36
|
+
@import 'state';
|
37
|
+
@import 'hack';
|
@@ -0,0 +1,91 @@
|
|
1
|
+
// -----------------------------------------------------------------------------
|
2
|
+
// Block constructor
|
3
|
+
// -----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
/// Set namespaces for each block type
|
6
|
+
/// @public
|
7
|
+
|
8
|
+
$bem-block-namespaces: (
|
9
|
+
'utility': 'u',
|
10
|
+
'object': 'o',
|
11
|
+
'component': 'c',
|
12
|
+
) !default;
|
13
|
+
|
14
|
+
/// Initializes a new block object
|
15
|
+
/// @private
|
16
|
+
/// @param {String} $block - Name for the new block
|
17
|
+
/// @param {String} $type - Block type: (utility, object or component)
|
18
|
+
/// @returns The final selector for the new block object
|
19
|
+
|
20
|
+
@function _block($name, $type) {
|
21
|
+
|
22
|
+
// Log new block
|
23
|
+
$new-block: _bem-log-block($name);
|
24
|
+
|
25
|
+
// Error check
|
26
|
+
$outside-check: should-not-be-called-within('scope', 'block');
|
27
|
+
|
28
|
+
// Set namespace
|
29
|
+
$namespace: '';
|
30
|
+
|
31
|
+
@if $bem-use-namespaces {
|
32
|
+
@if not map-has-key($bem-block-namespaces, $type) {
|
33
|
+
@error '`#{$type}` is not a valid `$type` for `block()`';
|
34
|
+
}
|
35
|
+
$namespace: map-get($bem-block-namespaces, $type) + '-';
|
36
|
+
}
|
37
|
+
|
38
|
+
$selector: '.' + $namespace + $name;
|
39
|
+
$set-current: set-current-context('block', $name, $selector);
|
40
|
+
|
41
|
+
@return $selector;
|
42
|
+
}
|
43
|
+
|
44
|
+
|
45
|
+
/// Creates a block object with the given type
|
46
|
+
/// @param {String} $block - Name for the new block
|
47
|
+
/// @param {String} $type - Block type: (utility, object or component)
|
48
|
+
|
49
|
+
@mixin block($name, $type) {
|
50
|
+
|
51
|
+
// Write block selector
|
52
|
+
@at-root #{_block($name, $type)} {
|
53
|
+
@content;
|
54
|
+
}
|
55
|
+
|
56
|
+
// Clear $_bem-current-context block after creation
|
57
|
+
$unset-current: unset-current-context('block');
|
58
|
+
}
|
59
|
+
|
60
|
+
|
61
|
+
// -----------------------------------------------------------------------------
|
62
|
+
// 2. Utility alias
|
63
|
+
// -----------------------------------------------------------------------------
|
64
|
+
|
65
|
+
@mixin utility($name) {
|
66
|
+
@include block($name, 'utility') {
|
67
|
+
@content;
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
|
72
|
+
// -----------------------------------------------------------------------------
|
73
|
+
// 3. Object alias
|
74
|
+
// -----------------------------------------------------------------------------
|
75
|
+
|
76
|
+
@mixin object($name) {
|
77
|
+
@include block($name, 'object') {
|
78
|
+
@content;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
|
82
|
+
|
83
|
+
// -----------------------------------------------------------------------------
|
84
|
+
// 4. Component alias
|
85
|
+
// -----------------------------------------------------------------------------
|
86
|
+
|
87
|
+
@mixin component($name) {
|
88
|
+
@include block($name, 'component') {
|
89
|
+
@content;
|
90
|
+
}
|
91
|
+
}
|
@@ -0,0 +1,43 @@
|
|
1
|
+
// ----------------------------------------------------------------------
|
2
|
+
// Element constructor
|
3
|
+
// ----------------------------------------------------------------------
|
4
|
+
|
5
|
+
/// Initializes a new element for the current block
|
6
|
+
/// @private
|
7
|
+
/// @param {String | Arglist} $elements - List of new element names
|
8
|
+
/// @returns The final selector for the new element(s)
|
9
|
+
|
10
|
+
@function _element($elements...) {
|
11
|
+
|
12
|
+
// Log new element(s)
|
13
|
+
$new-element: _bem-log-element($elements...);
|
14
|
+
|
15
|
+
// Error checks
|
16
|
+
$inside-check: should-be-called-within('block');
|
17
|
+
$outside-check: should-not-be-called-within('modifier', 'state', 'element');
|
18
|
+
|
19
|
+
$selector: ();
|
20
|
+
|
21
|
+
@each $element in $elements {
|
22
|
+
$e: #{&}#{$bem-element-separator}#{$element};
|
23
|
+
$selector: append($selector, $e, 'comma');
|
24
|
+
}
|
25
|
+
|
26
|
+
$set-current: set-current-context('element', $elements, $selector);
|
27
|
+
|
28
|
+
@return $selector;
|
29
|
+
}
|
30
|
+
|
31
|
+
|
32
|
+
/// Creates new element(s)
|
33
|
+
/// @param {String | Arglist} $elements - Name of the new element(s)
|
34
|
+
|
35
|
+
@mixin element($elements...) {
|
36
|
+
|
37
|
+
@at-root #{_element($elements...)} {
|
38
|
+
@content;
|
39
|
+
}
|
40
|
+
|
41
|
+
// Clear $_bem-current-context element after creation
|
42
|
+
$unset-current: unset-current-context('element');
|
43
|
+
}
|
@@ -0,0 +1,50 @@
|
|
1
|
+
// -----------------------------------------------------------------------------
|
2
|
+
// Error checks
|
3
|
+
// -----------------------------------------------------------------------------
|
4
|
+
// Table of contents:
|
5
|
+
// 1. Within
|
6
|
+
// 2. Outside
|
7
|
+
|
8
|
+
// -----------------------------------------------------------------------------
|
9
|
+
// 1. Within
|
10
|
+
// -----------------------------------------------------------------------------
|
11
|
+
|
12
|
+
/// Checks that it's being created within all of the passed $objs...
|
13
|
+
@function _should-be-called-within($objs...) {
|
14
|
+
|
15
|
+
$found: false;
|
16
|
+
|
17
|
+
@each $obj in $objs {
|
18
|
+
@if map-get($_bem-current-context, $obj) != null {
|
19
|
+
$found: true;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
@if not $found {
|
24
|
+
@error 'It should be called within #{inspect($objs)}';
|
25
|
+
}
|
26
|
+
|
27
|
+
@return true;
|
28
|
+
}
|
29
|
+
|
30
|
+
|
31
|
+
// -----------------------------------------------------------------------------
|
32
|
+
// 2. Outside
|
33
|
+
// -----------------------------------------------------------------------------
|
34
|
+
|
35
|
+
/// Checks that it's being created outside all of the passed $objs...
|
36
|
+
@function _should-not-be-called-within($objs...) {
|
37
|
+
|
38
|
+
$found: false;
|
39
|
+
|
40
|
+
@each $obj in $objs {
|
41
|
+
@if map-get($_bem-current-context, $obj) != null {
|
42
|
+
$found: true;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
@if $found {
|
46
|
+
@error 'It should not be called within #{inspect($objs)}';
|
47
|
+
}
|
48
|
+
|
49
|
+
@return true;
|
50
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
// -----------------------------------------------------------------------------
|
2
|
+
// 11. Hack constructor
|
3
|
+
// -----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
/// Hack namespace prepended to the selector
|
6
|
+
$hack-namespace: '_' !default;
|
7
|
+
|
8
|
+
@function _hack() {
|
9
|
+
|
10
|
+
// You may not hack a hack
|
11
|
+
$recursive-check: should-not-be-called-recursively('hack');
|
12
|
+
|
13
|
+
$selector: ();
|
14
|
+
$namespace: if($bem-use-namespaces, $hack-namespace, '');
|
15
|
+
|
16
|
+
@each $s in & {
|
17
|
+
$selector-to-str: inspect(nth($s, 1));
|
18
|
+
$selector-without-dot: str-slice($selector-to-str, 2, -1);
|
19
|
+
$new-selector: '.' + $namespace + $selector-without-dot;
|
20
|
+
$sl: selector-replace($s, nth($s, 1), $new-selector);;
|
21
|
+
$selector: append($selector, $sl, 'comma');
|
22
|
+
}
|
23
|
+
|
24
|
+
$set-current: set-current-context('hack', 'some-hack', $selector);
|
25
|
+
|
26
|
+
@return $selector;
|
27
|
+
|
28
|
+
}
|
29
|
+
|
30
|
+
@mixin hack() {
|
31
|
+
|
32
|
+
@at-root #{_hack()} {
|
33
|
+
@content;
|
34
|
+
}
|
35
|
+
|
36
|
+
$unset-current: unset-current-context('hack');
|
37
|
+
|
38
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
// -----------------------------------------------------------------------------
|
2
|
+
// Logger
|
3
|
+
// -----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
/// Stores the whole BEM structure
|
6
|
+
$_bem-log: () !global;
|
7
|
+
|
8
|
+
@import 'logger/_context-logger';
|
9
|
+
@import 'logger/_block-logger';
|
10
|
+
@import 'logger/_element-logger';
|
11
|
+
@import 'logger/_modifier-logger';
|
12
|
+
@import 'logger/_scope-logger';
|
@@ -0,0 +1,49 @@
|
|
1
|
+
// ----------------------------------------------------------------------
|
2
|
+
// Modifier constructor
|
3
|
+
// ----------------------------------------------------------------------
|
4
|
+
|
5
|
+
/// Initializes a new modifier for the current block or element(s)
|
6
|
+
/// @private
|
7
|
+
/// @param {String | Arglist} $modifiers - List of new modifier names
|
8
|
+
/// @returns The final selector for the new modifier(s)
|
9
|
+
|
10
|
+
|
11
|
+
@function _modifier($modifiers...) {
|
12
|
+
|
13
|
+
// Log new modifier(s)
|
14
|
+
$new-modifier: _bem-log-modifier($modifiers...);
|
15
|
+
|
16
|
+
// Error checks
|
17
|
+
$inside-check: _should-be-called-within('block');
|
18
|
+
$outside-check: _should-not-be-called-within('modifier');
|
19
|
+
|
20
|
+
$selector: ();
|
21
|
+
|
22
|
+
@each $modifier in $modifiers {
|
23
|
+
$new-selector: ();
|
24
|
+
|
25
|
+
@each $sel in & {
|
26
|
+
$modified-selector: #{$sel}#{$bem-modifier-separator}#{$modifier};
|
27
|
+
$new-selector: append($new-selector, $modified-selector, 'comma');
|
28
|
+
}
|
29
|
+
|
30
|
+
$selector: append($selector, $new-selector, 'comma');
|
31
|
+
}
|
32
|
+
|
33
|
+
$set-current: set-current-context('modifier', $modifiers, $selector);
|
34
|
+
|
35
|
+
@return $selector;
|
36
|
+
}
|
37
|
+
|
38
|
+
|
39
|
+
/// Creates new modifier(s)
|
40
|
+
/// @param {String | Arglist} $modifiers - Name of the new modifier(s)
|
41
|
+
|
42
|
+
@mixin modifier($modifiers...) {
|
43
|
+
|
44
|
+
@at-root #{_modifier($modifiers...)} {
|
45
|
+
@content;
|
46
|
+
}
|
47
|
+
|
48
|
+
$unset-current: unset-current-context('modifier');
|
49
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
// ----------------------------------------------------------------------
|
2
|
+
// Element modifier
|
3
|
+
// ----------------------------------------------------------------------
|
4
|
+
|
5
|
+
/// Scopes the @content ruleset to an element of the block being modified
|
6
|
+
/// @private
|
7
|
+
/// @param {String | Arglist} $modified-elements - List of elements that should be modified
|
8
|
+
/// @returns The final selector for the element(s) modified by the block modifier
|
9
|
+
|
10
|
+
@function _modifies-element($modified-element...) {
|
11
|
+
|
12
|
+
$inside-check: should-be-called-within('modifier', 'state');
|
13
|
+
$outside-check: should-not-be-called-within('element');
|
14
|
+
|
15
|
+
$selectors: ();
|
16
|
+
|
17
|
+
@each $element in $modified-element {
|
18
|
+
$element: map-get(map-get($_bem-current-context, 'block'), 'selector') + $bem-element-separator + $element;
|
19
|
+
$selectors: append($selectors, $element, 'comma');
|
20
|
+
}
|
21
|
+
|
22
|
+
$selector: selector-nest(&, $selectors);
|
23
|
+
|
24
|
+
$set-current: set-current-context('modifies-element', $modified-element, $selector);
|
25
|
+
|
26
|
+
@return $selector;
|
27
|
+
}
|
28
|
+
|
29
|
+
|
30
|
+
/// Scopes the @content ruleset to an element of the block being modified
|
31
|
+
/// @param {String | Arglist} $modified-elements - Name of the element(s) that should be modified
|
32
|
+
|
33
|
+
@mixin modifies-element($modified-elements...) {
|
34
|
+
@at-root #{_modifies-element($modified-elements...)} {
|
35
|
+
@content;
|
36
|
+
}
|
37
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
// -----------------------------------------------------------------------------
|
2
|
+
// Scope constructor
|
3
|
+
// -----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
/// Set namespace for scopes
|
6
|
+
/// @public
|
7
|
+
|
8
|
+
$bem-scope-namespace: 's';
|
9
|
+
|
10
|
+
/// Initializes a new scope object
|
11
|
+
/// @private
|
12
|
+
/// @param {String} $scope - Name for the new scope
|
13
|
+
/// @returns The final selector for the new scope object
|
14
|
+
|
15
|
+
@function _scope($scope) {
|
16
|
+
|
17
|
+
// Log new block
|
18
|
+
$new-scope: _bem-log-scope($scope);
|
19
|
+
|
20
|
+
// Check it's not called inside another scope
|
21
|
+
// and it's called at the root-level
|
22
|
+
$recursive-check: should-not-be-called-recursively('scope');
|
23
|
+
$outside-check: should-not-be-called-within('block');
|
24
|
+
|
25
|
+
$namespace: if($bem-use-namespaces, $bem-scope-namespace + '-', '');
|
26
|
+
$selector: '.' + $namespace + $scope;
|
27
|
+
|
28
|
+
$set-current: set-current-context('scope', $scope, $selector);
|
29
|
+
|
30
|
+
@return $selector;
|
31
|
+
}
|
32
|
+
|
33
|
+
@mixin scope($scope) {
|
34
|
+
|
35
|
+
@at-root #{_scope($scope)} {
|
36
|
+
@content;
|
37
|
+
}
|
38
|
+
|
39
|
+
$unset-current: unset-current-context('scope');
|
40
|
+
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
// -----------------------------------------------------------------------------
|
2
|
+
// State constructor
|
3
|
+
// -----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
$state-namespace: 'is' !default;
|
6
|
+
|
7
|
+
@function _state($states...) {
|
8
|
+
$selector: ();
|
9
|
+
$namespace: if($bem-use-namespaces, $state-namespace + '-', '');
|
10
|
+
|
11
|
+
@each $state in $states {
|
12
|
+
$s: selector-append(&, '.#{$namespace}#{$state}');
|
13
|
+
$selector: append($selector, $s, 'comma');
|
14
|
+
}
|
15
|
+
|
16
|
+
$set-current: set-current-context('state', $states, $selector);
|
17
|
+
|
18
|
+
@return $selector;
|
19
|
+
}
|
20
|
+
|
21
|
+
@mixin state($states...) {
|
22
|
+
|
23
|
+
@at-root #{_state($states...)} {
|
24
|
+
@content;
|
25
|
+
}
|
26
|
+
|
27
|
+
$unset-state: unset-current-context('state');
|
28
|
+
}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
// -----------------------------------------------------------------------------
|
2
|
+
// Theme constructor
|
3
|
+
// -----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
$bem-theme-namespace: 't' !default;
|
6
|
+
|
7
|
+
@function _theme($themes...) {
|
8
|
+
|
9
|
+
// If you try to hack a hack you can break the internet.
|
10
|
+
// So please, no one try it.
|
11
|
+
$recursive-test: should-not-be-called-recursively('theme');
|
12
|
+
|
13
|
+
$selector: ();
|
14
|
+
$namespace: if($bem-use-namespaces, $bem-theme-namespace + '-', '');
|
15
|
+
|
16
|
+
@each $theme in $themes {
|
17
|
+
$t: selector-nest('.#{$namespace}#{$theme}', &);
|
18
|
+
$selector: append($selector, $t, 'comma');
|
19
|
+
}
|
20
|
+
|
21
|
+
$set-current: set-current-context('theme', $themes, $selector);
|
22
|
+
|
23
|
+
@return $selector;
|
24
|
+
}
|
25
|
+
|
26
|
+
@mixin theme($themes...) {
|
27
|
+
|
28
|
+
@at-root #{_theme($themes...)} {
|
29
|
+
@content;
|
30
|
+
}
|
31
|
+
|
32
|
+
$unset-current: unset-current-context('theme');
|
33
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
// -----------------------------------------------------------------------------
|
2
|
+
// Block Logger
|
3
|
+
// -----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
/// Find if a given $block has already been created
|
6
|
+
/// @param {String} $block - Name of the block
|
7
|
+
|
8
|
+
@function block-exists($block) {
|
9
|
+
@return map-has-key($_bem-log, $block);
|
10
|
+
}
|
11
|
+
|
12
|
+
/// Log the new $block
|
13
|
+
/// @param {String} $block - Block name
|
14
|
+
|
15
|
+
@function _bem-log-block($block) {
|
16
|
+
|
17
|
+
// Check if the block has already been created
|
18
|
+
@if block-exists($block) {
|
19
|
+
@error '`#{$block}` block has already been created';
|
20
|
+
}
|
21
|
+
|
22
|
+
// Initialize a new block map
|
23
|
+
$new-block: ($block: ('elements': (), 'modifiers': ()));
|
24
|
+
|
25
|
+
// Update bem log with new block
|
26
|
+
$_bem-log: map-merge($_bem-log, $new-block) !global;
|
27
|
+
|
28
|
+
// Everything OK
|
29
|
+
@return true;
|
30
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
// -----------------------------------------------------------------------------
|
2
|
+
// Context logger
|
3
|
+
// -----------------------------------------------------------------------------
|
4
|
+
// Table of contents:
|
5
|
+
// 1. Store current context
|
6
|
+
// 2. Clear current context
|
7
|
+
|
8
|
+
|
9
|
+
/// Used to stores the current object being constructed
|
10
|
+
/// @private
|
11
|
+
|
12
|
+
$_bem-current-context: () !global;
|
13
|
+
|
14
|
+
|
15
|
+
// -----------------------------------------------------------------------------
|
16
|
+
// 1. Store current context
|
17
|
+
// -----------------------------------------------------------------------------
|
18
|
+
|
19
|
+
/// Sets the current object, stores name and generated selector
|
20
|
+
|
21
|
+
@function set-current-context($obj, $name, $selector) {
|
22
|
+
$new-current: (#{$obj}: (name: $name, selector: $selector));
|
23
|
+
$_bem-current-context: map-merge($_bem-current-context, $new-current) !global;
|
24
|
+
|
25
|
+
@return $selector;
|
26
|
+
}
|
27
|
+
|
28
|
+
|
29
|
+
// -----------------------------------------------------------------------------
|
30
|
+
// 2. Clear current context
|
31
|
+
// -----------------------------------------------------------------------------
|
32
|
+
|
33
|
+
/// Clears the current object
|
34
|
+
|
35
|
+
@function unset-current-context($obj) {
|
36
|
+
$new-current: (#{$obj}: null);
|
37
|
+
$_bem-current-context: map-merge($_bem-current-context, $new-current) !global;
|
38
|
+
|
39
|
+
@return null;
|
40
|
+
}
|
@@ -0,0 +1,59 @@
|
|
1
|
+
// -----------------------------------------------------------------------------
|
2
|
+
// Element Logger
|
3
|
+
// -----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
/// Find if the given $elements have already been created
|
6
|
+
/// @param {Arglist | String} $elements - A single or multiple element names
|
7
|
+
|
8
|
+
@function element-exists($elements...) {
|
9
|
+
|
10
|
+
// Get the current block name
|
11
|
+
// Then get the current block map
|
12
|
+
// Then get the current block element map
|
13
|
+
$current-block-name: map-get(map-get($_bem-current-context, 'block'), 'name');
|
14
|
+
$current-block: map-get($_bem-log, $current-block-name);
|
15
|
+
$current-elements: map-get($current-block, 'elements');
|
16
|
+
|
17
|
+
@each $element in $elements {
|
18
|
+
@if map-has-key($current-elements, $element) {
|
19
|
+
@return true;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
@return false;
|
24
|
+
}
|
25
|
+
|
26
|
+
|
27
|
+
/// Log the new $elements
|
28
|
+
/// @param {Arglist | String} $elements - A single or multiple element names
|
29
|
+
|
30
|
+
@function _bem-log-element($elements...) {
|
31
|
+
|
32
|
+
// Check any $elements has already been defined for the current block
|
33
|
+
@if element-exists($elements...) {
|
34
|
+
@error 'One or more elements from `#{inspect($elements)}` have already been created';
|
35
|
+
}
|
36
|
+
|
37
|
+
// Find the current block name
|
38
|
+
// Then get the map for the current block
|
39
|
+
// Then get the element list
|
40
|
+
$current-block-name: map-get(map-get($_bem-current-context, 'block'), 'name');
|
41
|
+
$current-block: map-get($_bem-log, $current-block-name);
|
42
|
+
$current-elements: map-get($current-block, 'elements');
|
43
|
+
|
44
|
+
// For each possible name in $name
|
45
|
+
// Create an updated block map
|
46
|
+
// Add it to the list of elements
|
47
|
+
@each $element in $elements {
|
48
|
+
$updated: ($element: ('modifiers': ()));
|
49
|
+
$current-elements: map-merge($current-elements, $updated);
|
50
|
+
}
|
51
|
+
|
52
|
+
// Update the block
|
53
|
+
$updated-block: ($current-block-name: ('elements': ($current-elements), 'modifiers': map-get($current-block, 'modifiers')));
|
54
|
+
|
55
|
+
// Update the log
|
56
|
+
$_bem-log: map-merge($_bem-log, $updated-block) !global;
|
57
|
+
|
58
|
+
@return true;
|
59
|
+
}
|
@@ -0,0 +1,94 @@
|
|
1
|
+
// -----------------------------------------------------------------------------
|
2
|
+
// Modifier Logger
|
3
|
+
// -----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
/// Find if the given $modifiers have already been created
|
6
|
+
/// @param {Arglist | String} $modifiers - A single or multiple modifier names
|
7
|
+
|
8
|
+
@function modifier-exists($modifiers...) {
|
9
|
+
|
10
|
+
// Get the current block name
|
11
|
+
// Then get the current block map
|
12
|
+
// Then get the current block modifiers map
|
13
|
+
$current-block-name: map-get(map-get($_bem-current-context, 'block'), 'name');
|
14
|
+
$current-block: map-get($_bem-log, $current-block-name);
|
15
|
+
$current-modifiers: map-get($current-block, 'modifiers');
|
16
|
+
|
17
|
+
@each $modifier in $modifiers {
|
18
|
+
@if map-has-key($current-modifiers, $modifier) {
|
19
|
+
@return true;
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
@return false;
|
24
|
+
}
|
25
|
+
|
26
|
+
/// Log the new $modifiers
|
27
|
+
/// @param {Arglist | String} $modifiers - A single or multiple modifier names
|
28
|
+
|
29
|
+
|
30
|
+
@function _bem-log-modifier($modifiers...) {
|
31
|
+
|
32
|
+
// Check if the modifier has already been defined for the current block or element
|
33
|
+
@if modifier-exists($modifiers...) {
|
34
|
+
@error 'One or more elements from `#{inspect($modifiers)}` have already been created';
|
35
|
+
}
|
36
|
+
|
37
|
+
// Find the current block name
|
38
|
+
$current-block-name: map-get(map-get($_bem-current-context, 'block'), 'name');
|
39
|
+
$current-item-name: $current-block-name;
|
40
|
+
|
41
|
+
// Get the map for the current block
|
42
|
+
$current-block: map-get($_bem-log, $current-block-name);
|
43
|
+
$current-item: $current-block;
|
44
|
+
|
45
|
+
// Get the map for the current block modifiers
|
46
|
+
$current-block-modifiers: map-get($current-block, 'modifiers');
|
47
|
+
$current-item-modifiers: $current-block-modifiers;
|
48
|
+
|
49
|
+
// Check whether the current context is a block or an element
|
50
|
+
$context-type: if(map-get($_bem-current-context, 'element') == null, 'block', 'element');
|
51
|
+
|
52
|
+
// Update item modifier list if within an Element
|
53
|
+
@if $context-type == 'element' {
|
54
|
+
// @todo: should work if there are multiple current items
|
55
|
+
$current-item-name: nth(map-get(map-get($_bem-current-context, 'element'), 'name'),1);
|
56
|
+
$current-item: map-get(map-get($current-block, 'elements'), $current-item-name);
|
57
|
+
$current-item-modifiers: map-get($current-item, 'modifiers');
|
58
|
+
}
|
59
|
+
|
60
|
+
// For each possible name in $name
|
61
|
+
@each $modifier in $modifiers {
|
62
|
+
|
63
|
+
// Create an updated block/element map
|
64
|
+
$updated: ();
|
65
|
+
|
66
|
+
@if $context-type == 'element' {
|
67
|
+
$updated: (#{$modifier}: ('modified-by': ()))
|
68
|
+
} @else {
|
69
|
+
$modifies-element: map-get($_bem-current-context, 'modifies-element');
|
70
|
+
$updated: (#{$modifier}: ('modifies-element': ()));
|
71
|
+
}
|
72
|
+
|
73
|
+
// Add it to the list of modifiers
|
74
|
+
$current-item-modifiers: map-merge($current-item-modifiers, $updated);
|
75
|
+
}
|
76
|
+
|
77
|
+
$updated-block: ();
|
78
|
+
|
79
|
+
@if $context-type == 'element' {
|
80
|
+
// update the element map;
|
81
|
+
$updated-item: (#{$current-item-name}: ('modifiers': $current-item-modifiers));
|
82
|
+
// @error $updated-item;
|
83
|
+
$updated-elements: map-merge(map-get($current-block, 'elements'), $updated-item);
|
84
|
+
$updated-block: (#{$current-block-name}: ('modifiers': map-get($current-block, 'modifiers'), 'elements': $updated-elements));
|
85
|
+
} @else {
|
86
|
+
$updated-block: (#{$current-block-name}: ('modifiers': ($current-item-modifiers), 'elements': map-get($current-block, 'elements')));;
|
87
|
+
}
|
88
|
+
|
89
|
+
// // Update the log
|
90
|
+
$_bem-log: map-merge($_bem-log, $updated-block) !global;
|
91
|
+
|
92
|
+
@return true;
|
93
|
+
|
94
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
// -----------------------------------------------------------------------------
|
2
|
+
// Scope Logger
|
3
|
+
// -----------------------------------------------------------------------------
|
4
|
+
|
5
|
+
/// Find if a given $scope has already been created
|
6
|
+
/// @param {String} $scope - Name of the scope
|
7
|
+
|
8
|
+
@function scope-exists($scope) {
|
9
|
+
@return map-has-key($_bem-log, $scope);
|
10
|
+
}
|
11
|
+
|
12
|
+
/// Log the new $scope
|
13
|
+
/// @param {String} $scope - scope name
|
14
|
+
|
15
|
+
@function _bem-log-scope($scope) {
|
16
|
+
|
17
|
+
// Check if the scope has already been created
|
18
|
+
@if scope-exists($scope) {
|
19
|
+
@error '`#{$scope}` scope has already been created';
|
20
|
+
}
|
21
|
+
|
22
|
+
// Initialize a new scope map
|
23
|
+
$new-scope: ($scope: ());
|
24
|
+
|
25
|
+
// Update bem log with new scope
|
26
|
+
$_bem-log: map-merge($_bem-log, $new-scope) !global;
|
27
|
+
|
28
|
+
// Everything OK
|
29
|
+
@return true;
|
30
|
+
}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
.o-burger {
|
2
|
+
texture: juicy; }
|
3
|
+
.o-burger__letuce, .o-burger__tomato {
|
4
|
+
quality: fresh; }
|
5
|
+
.o-burger__cheese {
|
6
|
+
type: gouda; }
|
7
|
+
.o-burger__cheese--parmigiano {
|
8
|
+
type: parmigiano; }
|
9
|
+
.o-burger__extra-topping {
|
10
|
+
ingredient: bacon; }
|
11
|
+
.o-burger__meat {
|
12
|
+
type: beef; }
|
13
|
+
.o-burger--veggie {
|
14
|
+
texture: smooth; }
|
15
|
+
.o-burger--veggie .o-burger__meat {
|
16
|
+
type: lentils; }
|
17
|
+
.o-burger--veggie .o-burger__extra-topping {
|
18
|
+
ingredient: avocado; }
|
19
|
+
._o-burger--veggie .o-burger__extra-topping {
|
20
|
+
ingredient: bacon; }
|
21
|
+
.t-mexican .o-burger {
|
22
|
+
spicy: hell-yeah; }
|
23
|
+
.o-burger.is-cold {
|
24
|
+
taste: terrible; }
|
25
|
+
|
26
|
+
/*# sourceMappingURL=test.css.map */
|
@@ -0,0 +1,7 @@
|
|
1
|
+
{
|
2
|
+
"version": 3,
|
3
|
+
"mappings": "AAmDa,SAAwB;EC9CjC,OAAO,EAAE,KAAK;EC+BL,oCAA0B;ID5B/B,OAAO,EAAE,KAAK;EC4BT,iBAA0B;IDxB/B,IAAI,EAAE,KAAK;IE+BN,6BAA4B;MF5B7B,IAAI,EAAE,UAAU;ECqBf,wBAA0B;IDhB/B,UAAU,EAAE,KAAK;ECgBZ,eAA0B;IDZ/B,IAAI,EAAE,IAAI;EEmBL,iBAA4B;IFfjC,OAAO,EAAE,MAAM;IGKV,iCAA4C;MHF7C,IAAI,EAAE,OAAO;IGEZ,0CAA4C;MHE7C,UAAU,EAAE,OAAO;MIJlB,2CAAW;QJOR,UAAU,EAAE,KAAK;EKXpB,oBAAsB;ILiB3B,KAAK,EAAE,SAAS;EMtBX,iBAAsB;IN0B3B,KAAK,EAAE,QAAQ",
|
4
|
+
"sources": ["_block.scss","test.scss","_element.scss","_modifier.scss","_modifies-element.scss","_hack.scss","_theme.scss","_state.scss"],
|
5
|
+
"names": [],
|
6
|
+
"file": "test.css"
|
7
|
+
}
|
@@ -0,0 +1,59 @@
|
|
1
|
+
@import 'bem-constructor';
|
2
|
+
|
3
|
+
// The Burger Test™
|
4
|
+
|
5
|
+
@include object('burger') {
|
6
|
+
texture: juicy;
|
7
|
+
|
8
|
+
@include element('letuce', 'tomato') {
|
9
|
+
quality: fresh;
|
10
|
+
}
|
11
|
+
|
12
|
+
@include element('cheese') {
|
13
|
+
type: gouda;
|
14
|
+
|
15
|
+
@include modifier('parmigiano') {
|
16
|
+
type: parmigiano;
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
@include element('extra-topping') {
|
21
|
+
ingredient: bacon;
|
22
|
+
}
|
23
|
+
|
24
|
+
@include element('meat') {
|
25
|
+
type: beef;
|
26
|
+
}
|
27
|
+
|
28
|
+
@include modifier('veggie') {
|
29
|
+
texture: smooth;
|
30
|
+
|
31
|
+
@include modifies-element('meat') {
|
32
|
+
type: lentils;
|
33
|
+
}
|
34
|
+
|
35
|
+
@include modifies-element('extra-topping') {
|
36
|
+
ingredient: avocado;
|
37
|
+
|
38
|
+
@include hack() {
|
39
|
+
ingredient: bacon;
|
40
|
+
}
|
41
|
+
}
|
42
|
+
}
|
43
|
+
|
44
|
+
@include theme('mexican') {
|
45
|
+
spicy: hell-yeah;
|
46
|
+
}
|
47
|
+
|
48
|
+
@include state('cold') {
|
49
|
+
taste: terrible;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
// @include scope(test) {
|
54
|
+
// a: shite
|
55
|
+
// }
|
56
|
+
|
57
|
+
// .bem-log {
|
58
|
+
// log: inspect($_bem-log);
|
59
|
+
// }
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bem-constructor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Daniel Guillan
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: sass
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.4'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.4'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: compass
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.0'
|
41
|
+
description: A Sass library for building immutable and namespaced BEM-style CSS objects
|
42
|
+
email:
|
43
|
+
- daniel.guillan@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- CHANGELOG.md
|
49
|
+
- README.md
|
50
|
+
- lib/bem-constructor.rb
|
51
|
+
- stylesheets/_bem-constructor.scss
|
52
|
+
- stylesheets/_block.scss
|
53
|
+
- stylesheets/_element.scss
|
54
|
+
- stylesheets/_error-checks.scss
|
55
|
+
- stylesheets/_hack.scss
|
56
|
+
- stylesheets/_index.scss
|
57
|
+
- stylesheets/_logger.scss
|
58
|
+
- stylesheets/_modifier.scss
|
59
|
+
- stylesheets/_modifies-element.scss
|
60
|
+
- stylesheets/_scope.scss
|
61
|
+
- stylesheets/_state.scss
|
62
|
+
- stylesheets/_theme.scss
|
63
|
+
- stylesheets/logger/_block-logger.scss
|
64
|
+
- stylesheets/logger/_context-logger.scss
|
65
|
+
- stylesheets/logger/_element-logger.scss
|
66
|
+
- stylesheets/logger/_modifier-logger.scss
|
67
|
+
- stylesheets/logger/_scope-logger.scss
|
68
|
+
- stylesheets/test.css
|
69
|
+
- stylesheets/test.css.map
|
70
|
+
- stylesheets/test.scss
|
71
|
+
homepage: https://github.com/danielguillan/bem-constructor
|
72
|
+
licenses:
|
73
|
+
- MIT
|
74
|
+
metadata: {}
|
75
|
+
post_install_message:
|
76
|
+
rdoc_options: []
|
77
|
+
require_paths:
|
78
|
+
- lib
|
79
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 1.3.6
|
89
|
+
requirements: []
|
90
|
+
rubyforge_project: bem-constructor
|
91
|
+
rubygems_version: 2.2.2
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: BEM Constructor is a Sass library for building immutable and namespaced BEM-style
|
95
|
+
CSS objects. By enforcing a consistent and programatic way of defining objects (blocks,
|
96
|
+
elements and modifiers) it ensures a more structured, robust and secure object codebase
|
97
|
+
that is easy to understand and maintain. Objects defined using the constructor are
|
98
|
+
impossible to modify and reassign by mistake or omission.
|
99
|
+
test_files: []
|