bempug
v1.1.1
Published
Simple mixins to help you writing code on BEM methodology in pug or jade projects.
Downloads
27
Readme
BemPug
Simple mixins to help you writing code on BEM methodology in pug or jade projects.
You like BEM? Try BemGo — starter kit for developing BEM apps using Gulp and Webpack.
Anchors
Install | Mixins | Examples | Helpers | Changelog
Install
Install from npm:
npm i bempug -D
Then include index
file to your pug or jade project:
include ../../node_modules/bempug/index
Mixins
Block mixin:
+b( name, data, tag )
- name
String
- data
String or Object
- data.m
String
— block modifier - data.p
Boolean
— disable parent mode - data.e
Array or String
— mix block with element - data.b
Array or String
— mix block with another block - data.t
String
— block tag - data.s
String
— block separators
- data.m
- tag
String
If data argument is String it will be a modifier.
Element mixin:
+e( name, data, tag )
- name
String
- data
String or Object
- data.m
String
— element modifier - data.p
String
— parent block - data.e
Array or String
— mix element with another element - data.b
Array or String
— mix element with block - data.t
String
— element tag - data.s
String
— element separators
- data.m
- tag
String
If data argument is String it will be a modifier.
Examples
Block | Element | Modifier | Tag | Mix | Separators
Block
Simple example:
+b( 'block' )
+e( 'element' ) Text
<div class="block">
<div class="block__element">Text</div>
</div>
You can to disable parent mode and element will ignore this block:
+b( 'header' )
+b( 'grid', {p: false} ) // or short {p:0}
+e( 'logo' ) Logo
<div class="header">
<div class="grid">
<div class="header__logo">Logo</div>
</div>
</div>
Element
Element depends on parent block:
+b( 'content' )
+e( 'layout' ) Content
<div class="content">
<div class="content__layout">Content</div>
</div>
You can set parent block for element directly:
+b( 'content' )
+e( 'layout', {p: 'page'} ) Content
<div class="content">
<div class="page__layout">Content</div>
</div>
Modifier
Block and element have modifier:
+b( 'alert', 'success' )
+e( 'text', 'bolder' ) Success
<div class="alert alert--success">
<div class="alert__text alert__text--bolder">Success</div>
</div>
Block and element have more than one modifier:
+b( 'alert', 'success.active' )
+e( 'text', 'bolder.italic' ) Success
<div class="alert alert--success alert--active">
<div class="alert__text alert__text--bolder alert__text--italic">Success</div>
</div>
Also, you can set modifiers in Object
:
+b( 'alert', {m: 'success.active'} ) Success
<div class="alert alert--success alert--active">Success</div>
Tag
Default tag is div, but you can set it directly:
+b( 'news', {}, 'article' )
+e( 'title', {}, 'h1' ) Title
// Or in data Object
+b( 'news', {t: 'article'} )
+e( 'title', {t: 'h1'} ) Title
<article class="news">
<h1 class="news__title">Title</h1>
</article>
Sometimes mixin can be smart and tag depends on parent or attributes:
+b( 'list', {t: 'ul'} )
+e( 'item' ) My item 1
+e( 'item' ) My item 2
+e( 'item' ) My item 3
+b( 'link' )(href='https://www.npmjs.com/package/bempug')
+b( 'text' ) My text
<ul class="list">
<li class="list__item">My item 1</li>
<li class="list__item">My item 2</li>
<li class="list__item">My item 3</li>
</ul>
<a class="link" href="https://www.npmjs.com/package/bempug">
<span class="text">My text</span>
</a>
Also, you can use tagByName
global option for set default tag by name:
- BEMPUG.tagByName = {list: 'ul', form: 'form', fields: 'fieldset'};
+b( 'list' )
+e( 'item' ) Item
+e( 'item' ) Item
+b( 'form' )
+e( 'fields' ) Fields
<ul class="list">
<li class="list__item">Item</li>
<li class="list__item">Item</li>
</ul>
<form class="form">
<fieldset class="form__fields">Fields</fieldset>
</form>
Mix
Block is mixed with element:
+b( 'title', {e: 'article'} ) Title
<div class="title article__title">Title</div>
You can set name of element in mix with colon:
+b( 'title', {e: 'article:my-name'} ) Title
<div class="title article__my-name">Title</div>
Block is mixed with two elements:
+b( 'title', {e: ['article', 'content']} ) Title
<div class="title article__title content__title">Title</div>
Also, you can use ampersand &
sign as parent block reference:
+b( 'news' )
+b( 'title', {e: '&'} ) Title
+b( 'text', {e: '&:description'} ) Text
<div class="news">
<div class="title news__title">Title</div>
<div class="text news__description">Text</div>
</div>
Block is mixed with element which has modifiers:
+b( 'title', {e: 'news|bolder.size-m'} ) Title
<div class="title news__title news__title--bolder news__title--size-m">Title</div>
Element is mixed with another element:
+b( 'footer' )
+e( 'bottom', {e: 'page'} )
<div class="footer">
<div class="footer__bottom page__bottom"></div>
</div>
Element is mixed with block:
+b( 'footer' )
+e( 'bottom', {b: 'grid'} )
<div class="footer">
<div class="footer__bottom grid"></div>
</div>
Block is mixed with another block:
+b( 'article', {b: 'news'} ) Content
<div class="article news">Content</div>
Block is mixed with another block which has modifiers:
+b( 'article', {b: 'news|first'} ) Content
<div class="article news news--first">Content</div>
Block is mixed with two blocks which have modifiers:
+b( 'article', {b: ['news|first','fixed|active']} ) Content
<div class="article news news--first fixed fixed--active">Content</div>
Separators
You can change global separators:
- BEMPUG.modifier = '_';
- BEMPUG.element = '__';
+b( 'alert', 'success.active' )
+e( 'text', 'bolder.italic' ) Success
<div class="alert alert_success alert_active">
<div class="alert__text alert__text_bolder alert__text_italic">Success</div>
</div>
Also, you can set separators for each block and ignore global settings 'modifier|element'
:
+b( 'news', {e: 'content', m: 'first', s: '---|___' } )
+b( 'text', {e: true, m: 'bolder'} ) Text
<div class="news news---first content___news">
<div class="text text---bolder news___text">Text</div>
</div>
Helpers
Get current block | Get current parent | Callbacks
Get current block
You can get current block name:
+b( 'nav' )
+e( 'item' )
- console.log( BEMPUG.getCurrentBlock() ); // 'nav'
+b( 'img' )
- console.log( BEMPUG.getCurrentBlock() ); // 'img'
Get current parent
You can get current parent Object
:
+b( 'html', 'no-js', 'html' )(lang='en')
- console.log( BEMPUG.getCurrentParent() );
{ type: 'block',
name: 'html',
tag: 'html',
attributes: { lang: 'en' },
sep: { modifier: '--', element: '__' },
classes: [ 'html', 'html--no-js' ],
parent: {},
selfClosing: false }
Callbacks
You can set beforeParse
callback:
- BEMPUG.beforeParse[ 'input' ] = function( block ) {
if ( typeof block.data.m === 'undefined' ) block.data.m = 'default';
}
+b( 'input', {m: 'search'} ) // Have modifier 'search'
+b( 'input' ) // No modifier, but we set modifier 'default' by callback
<input class="input input--search">
<input class="input input--default">
You can set afterParse
callback:
- BEMPUG.afterParse[ 'page' ] = function( block ) {
block.setTag( 'body' );
block.addModifier( 'test' );
block.attributes.itemscope = true;
block.attributes.itemtype = 'http://schema.org/WebPage';
}
+b( 'page' ) My page
<body class="page page--test" itemscope itemtype="http://schema.org/WebPage">My page</body>
Changelog
1.1.1
- Fixed: disable parent mode not work in cb
- Fixed: name of element in mix with another element
1.1.0
- Add: ampersand sign for mix
- Add: mix element with blocks and another elements
1.0.2
- Add: some global helpers
- Add: before / after parse callback
- Fixed: block and element separators work for any descendant
- Fixed: default tag depends on parent tag for any descendant
1.0.1
- Add: disable parent mode for blocks
1.0.0
- Release version
Thanks
Many thanks to Roman Komarov for the original idea.