The package contains the default naming convention presets and the tool to create a custom naming conventions.
You can use this package to:
- Import an existing preset with a naming convention.
- Create a preset with a custom naming convention.
This package is useful when you want to create a new preset based on another preset, for example, to change only the modifier delimiter and keep other options unchanged.
Note. If you don't have any BEM projects available to try out the
@bem/sdk.naming.presets
package, the quickest way to create one is to use bem-express.
An example is available in the RunKit editor.
Attention. To use
@bem/sdk.naming.presets
, you must install Node.js 8.0+.
In this quick start you will learn how to import a preset with a naming convention and create a preset with a custom naming convention.
To run the @bem/sdk.naming.presets
package:
- Install the
@bem/sdk.naming.presets
package. - Import a preset with a naming convention.
- Create a preset with a custom naming convention.
To install the @bem/sdk.naming.presets
package, run the following command:
$ npm install --save @bem/sdk.naming.presets
To import a preset with a default naming convention, create a JavaScript file with any name (for example, app.js) and insert the following:
const originNaming = require('@bem/sdk.naming.presets/origin');
This code imports the preset with the origin naming convention. To import another preset, change origin
to the preset name.
Examples:
const legacyNaming = require('@bem/sdk.naming.presets/legacy');
const originReactNaming = require('@bem/sdk.naming.presets/origin-react');
const reactNaming = require('@bem/sdk.naming.presets/react');
const twoDashesNaming = require('@bem/sdk.naming.presets/two-dashes');
After you've imported the preset, you can use it for your own purposes, such as to create a parse()
function from the @bem/sdk.naming.entity.parse package.
Example:
const originNaming = require('@bem/sdk.naming.presets/origin');
const parse = require('@bem/sdk.naming.entity.parse')(originNaming);
// Parse a block name.
parse('my-block');
// Parse an element name.
parse('my-block__my-element');
// Parse a block modifier name.
parse('my-block_my-modifier');
// Parse a block modifier name with a value.
parse('my-block_my-modifier_some-value');
// Parse an element modifier name.
parse('my-block__my-element_my-modifier');
// Parse an element modifier name with a value.
parse('my-block__my-element_my-modifier_some-value');
To create a preset with a custom naming convention, use the create function. In the arguments, pass options that you want to overwrite in the default naming convention. For example, you can define that the values of modifiers are delimited with the equal sign (=
).
Example:
const myNamingOptions = {
delims: {
mod: { val: '=' }
}
};
const myNaming = require('@bem/sdk.naming.presets/create')(myNamingOptions);
// Parse a BEM entity name to test the created preset.
const parse = require('@bem/sdk.naming.entity.parse')(myNaming);
parse('my-block_my-modifier=some-value');
/**
* => BemEntityName {
* block: 'my-block',
* mod: { name: 'my-modifier', val: 'some-value' } }
*/
Creates a preset with the specified naming convention.
This function will get all options from the default preset, overwrite them with the passed options and return the result. Options are overwritten in the following order:
- Options from the default preset.
- Options from the
userDefaults
parameter. - Options from the
options
parameter.
/**
* @typedef INamingConventionDelims
* @property {string} elem — Separates an element name from block.
* @property {string|Object} mod — Separates a modifier name and the value of a modifier.
* @property {string} mod.name — Separates a modifier name from a block or an element.
* @property {string|boolean} mod.val — Separates the value of a modifier from the modifier name.
*/
/**
* Returns created preset with the specified naming convention.
*
* @param {(Object|string)} [options] — User options or the name of the preset to return.
* If not specified, the default preset will be returned.
* @param {string} [options.preset] — Preset name that should be used as the default preset.
* @param {Object} [options.delims] — Strings to separate names of bem entities.
* This object has the same structure as `INamingConventionDelims`,
* but all properties inside are optional.
* @param {Object} [options.fs] — User options to separate names of files with bem entities.
* @param {Object} [options.fs.delims] — Strings to separate names of files in a BEM project.
* This object has the same structure as `INamingConventionDelims`,
* but all properties inside are optional.
* @param {string} [options.fs.pattern] — Pattern that describes the file structure of a BEM project.s
* @param {string} [options.fs.scheme] — Schema name that describes the file structure of one BEM entity.
* @param {string} [options.wordPattern] — A regular expression that will be used to match an entity name.
* @param {(Object|string)} [userDefaults] — User default options or the name of the preset to use.
* If the name of the preset is incorrect, the `origin` preset will be used.
* @returns {INamingConvention} — An object with `delims`, `fs` and `wordPattern` properties
* that describes the naming convention.
*/
create(options, userDefaults);
You can use the create()
function to get the default preset from this package. Call the create()
function without parameters.
const defaultPreset = require('@bem/sdk.naming.presets/create')();
// Check that the origin preset is default.
const originPreset = require('@bem/sdk.naming.presets/origin');
if (defaultPreset === originPreset) {
console.log('Origin is the default preset now.');
}
The default preset is origin
, but you can set another preset as default in the options.preset
parameter.
Example:
const myNamingOptions = {
preset: 'two-dashes',
delims: {
mod: { val: '=' }
}
};
const myNaming = require('@bem/sdk.naming.presets/create')(myNamingOptions);
// Parse a BEM entity name to test the created preset.
const parse = require('@bem/sdk.naming.entity.parse')(myNaming);
parse('my-block--my-modifier=some-value');
/**
* => BemEntityName {
* block: 'my-block',
* mod: { name: 'my-modifier', val: 'some-value' } }
*/
You can set the default preset in the userDefaults
parameter. To use this method, pass the name of the preset in the second argument.
Example:
const myNamingOptions = {
delims: {
mod: { val: '=' }
}
};
const myNaming = require('@bem/sdk.naming.presets/create')(myNamingOptions, 'two-dashes');
// Parse a BEM entity name to test the created preset.
const parse = require('@bem/sdk.naming.entity.parse')(myNaming);
parse('my-block--my-modifier=some-value');
/**
* => BemEntityName {
* block: 'my-block',
* mod: { name: 'my-modifier', val: 'some-value' } }
*/
If you pass a preset name in the userDefaults
parameter, it will completely overwrite the default preset. For example, all these lines return the two-dashes
preset:
const createPreset = require('@bem/sdk.naming.presets/create');
const twoDashesPreset1 = createPreset({ preset:'legacy' }, 'two-dashes');
const twoDashesPreset2 = createPreset({}, 'two-dashes');
const twoDashesPreset3 = require('@bem/sdk.naming.presets/two-dashes');
You can pass an object with default options to use it on the userDefaults
level. Pass this object in the second argument of the create()
function.
Example:
const userDefaults = {
fs: {
delims: {
elem: '__',
mod: '_'
},
scheme: 'flat'
}
}
// Use well-known presets with the flat scheme.
const reactFlatPreset = require('@bem/sdk.naming.presets/create')({ preset: 'react' }, userDefaults);
const twoDashesFlatPreset = require('@bem/sdk.naming.presets/create')({ preset: 'two-dashes' }, userDefaults);
// Create a custom preset with the flat scheme.
const customPreset = require('@bem/sdk.naming.presets/create')({ wordPattern: '[a-z]+' }, userDefaults);
// Create preset with overwritten delimiters.
const presetOptions = {
delims: {
mod: { val: '='}
},
fs: {
delims: {
mod: { val: '='}
}
}
}
const anotherPreset = require('@bem/sdk.naming.presets/create')(presetOptions, userDefaults);
The main idea of the naming convention is to make names of BEM entities as informative and clear as possible.
This package contains the following presets with naming conventions:
- origin — Default naming convention.
- legacy — Similar to the origin naming convention, but with a different file structure organization.
- origin-react — Mix of origin and react naming conventions.
- react — Naming convention in React style.
- two-dashes — According to this naming convention, modifiers are delimited by two hyphens (
--
).
In addition, you can invent your own naming convention. To learn how to do this, see Custom naming convention.
The BEM methodology provides an idea for creating naming rules and implements that idea in its canonical naming convention: origin naming convention.
Word pattern:
Every name must match the regular expression: [a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*
.
Examples: my-element
, myElement
, element1
, 2element
.
Delimiters:
Elements are delimited with two underscores (__
), while modifiers and values of modifiers are delimited by one underscore (_
).
Example: my-block__my-element_my-modifier_some-value
.
File structure:
- BEM entities structure scheme:
nested
. - Project structure pattern:
${layer?${layer}.}blocks/${entity}.${tech}
.
Examples:
blocks/my-block.js
blocks/my-block/_my-modifier.js
blocks/my-block/__my-element.js
blocks/my-block/__my-element/_my-modifier_some-value.css
layer.blocks/my-block/__my-element/_my-modifier_some-value.css
This preset based on the origin preset but provides another project structure pattern.
Word pattern:
Every name must match the regular expression: [a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*
.
Examples: my-element
, myElement
, element1
, 2element
.
Delimiters:
Elements are delimited with two underscores (__
), while modifiers and values of modifiers are delimited by one underscore (_
).
Example: my-block__my-element_my-modifier_some-value
.
File structure:
- BEM entities structure scheme:
nested
. - Project structure pattern:
${entity}${layer?@${layer}}.${tech}
.
Examples:
[email protected]
my-block/_my-modifier.js
my-block/[email protected]
my-block/__my-element/_my-modifier_some-value.css
my-block/__my-element/[email protected]
The origin-react
preset is an implementation of the React style naming convention.
This preset is based on the origin preset but provides a different word pattern and element delimiters.
Word pattern:
Every name must match the regular expression: [a-zA-Z0-9]+
.
Examples: MyElement
, myModifier
, modValue1
.
Delimiters:
Elements are delimited by one hyphen (-
), while modifiers and values of modifiers are delimited by one underscore (_
).
Example: MyBlock-MyElement_myModifier_modValue
.
File structure:
- Element names in the file structure don't have any delimiters.
- BEM entities structure scheme:
nested
. - Project structure pattern:
${layer?${layer}.}blocks/${entity}.${tech}
.
Examples:
blocks/MyBlock.js
blocks/MyBlock/_myModifier.js
blocks/MyBlock/MyElement.js
blocks/MyBlock/MyElement/_myModifier_modValue.css
layer.blocks/MyBlock/MyElement/_myModifier_modValue.css
The react
preset is an implementation of the React style naming convention.
This preset is based on the origin-react preset but provides another project structure pattern like in the legacy preset.
Word pattern:
Every name must match the regular expression: [a-zA-Z0-9]+
.
Examples: MyElement
, myModifier
, modValue1
.
Delimiters:
Elements are delimited by one hyphen (-
), while modifiers and values of modifiers are delimited by one underscore (_
).
Example: MyBlock-MyElement_myModifier_modValue
.
File structure:
- Element names in the file structure don't have any delimiters.
- BEM entities structure scheme:
nested
. - Project structure pattern:
${entity}${layer?@${layer}}.${tech}
.
Examples:
MyBlock.js
[email protected]
MyBlock/_myModifier.js
MyBlock/[email protected]
MyBlock/MyElement/_myModifier_modValue.css
MyBlock/MyElement/[email protected]
The two-dashes
preset is an implementation of the Two Dashes style naming convention.
This preset is based on the origin preset but modifiers are delimited by two hyphens (--
).
Word pattern:
Every name must match the regular expression: [a-zA-Z0-9]+(?:-[a-zA-Z0-9]+)*
.
Examples: my-element
, myElement
, element1
, 2element
.
Delimiters:
Elements are delimited with two underscores (__
), while modifiers are delimited by two hyphens (--
), and values of modifiers are delimited by one underscore (_
).
Example: my-block__my-element--my-modifier_some-value
.
File structure:
- BEM entities structure scheme:
nested
. - Project structure pattern:
${layer?${layer}.}blocks/${entity}.${tech}
.
Examples:
blocks/my-block/--my-modifier.js
blocks/my-block/__my-element/--my-modifier_some-value.css
my-layer.blocks/my-block/__my-element/--my-modifier_some-value.css