bem-constructor 0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|