Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@dr/bem-helper

Package Overview
Dependencies
Maintainers
43
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@dr/bem-helper - npm Package Compare versions

Comparing version 1.2.1 to 1.2.2

.flowconfig

67

__tests__/index.test.js

@@ -38,3 +38,3 @@ const bem = require("../lib/index");

test("block with modifier with a number value", () => {
test("block with modifier with a value of a number", () => {
expect(bem("block", {modifier: 200})).toBe("block block--modifier-200");

@@ -100,3 +100,3 @@ });

test("block with modifier with a number value", () => {
test("block with modifier with a value of a number", () => {
expect(bem.single("block", {modifier: 200})).toBe("block--modifier-200");

@@ -121,2 +121,63 @@ });

});
});
describe("bem.scoped", () => {
test("block", () => {
expect(bem.scoped("block")).toBe("block");
});
test("block and element", () => {
expect(bem.scoped("block", "element")).toBe("block__element");
});
test("block with modifier with a value of true", () => {
expect(bem.scoped("block", {modifier: true})).toBe("block block--modifier");
});
test("block with modifier with a value of false", () => {
expect(bem.scoped("block", {modifier: false})).toBe("block");
});
test("block with modifier with a value of null", () => {
expect(bem.scoped("block", {modifier: null})).toBe("block");
});
test("block with modifier with a value of undefined", () => {
var value;
expect(bem.scoped("block", {modifier: value})).toBe("block");
});
test("block with modifier with a value of a string", () => {
expect(bem.scoped("block", {modifier: "value"})).toBe("block block--modifier-value");
});
test("block with modifier with a value of an empty string", () => {
expect(bem.scoped("block", {modifier: ""})).toBe("block");
});
test("block with modifier with a value of a number", () => {
expect(bem.scoped("block", {modifier: 200})).toBe("block block--modifier-200");
});
test("block with modifier with a value of 0", () => {
expect(bem.scoped("block", {modifier: 0})).toBe("block block--modifier-0");
});
test("block and element with modifier", () => {
expect(bem.scoped("block", "element", {modifier: true})).toBe("block__element block__element--modifier");
});
test("block and element with multiple modifiers", () => {
expect(bem.scoped("block", "element", {modifier1: true, modifier2: "value"})).toBe("block__element block__element--modifier1 block__element--modifier2-value");
});
test("block with modifier and element", () => {
expect(bem.scoped("block", {modifier: true}, "element")).toBe("block__element block--modifier__element");
});
test("block with modifier and element with modifier", () => {
expect(bem.scoped("block", {modifier: true}, "element", {modifier: true})).toBe("block__element block--modifier__element block__element--modifier block--modifier__element--modifier");
});
});

83

lib/index.js

@@ -7,31 +7,60 @@ "use strict";

function bem() {
return argParser.apply(undefined, arguments).join(" ");
/* @flow */
/*:: type Modifiers = { [key: string]: any }; */
/*:: type Classnames = Array<string>; */
function bem() /*:any*/ /*:string*/{
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return argParser.apply(undefined, [false].concat(args)).join(" ");
}
bem.single = function () {
return argParser.apply(undefined, arguments).pop();
function scoped() /*:any*/ /*:string*/{
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return argParser.apply(undefined, [true].concat(args)).join(" ");
};
function argParser(block) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
function single() /*:any*/ /*:string*/{
for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
args[_key3] = arguments[_key3];
}
return args.reduce(argReducer, [block]);
return argParser.apply(undefined, [true].concat(args)).pop();
};
function argParser(scoped /*:boolean*/, block /*:string*/) /*:any*/ /*:Classnames*/{
for (var _len4 = arguments.length, args = Array(_len4 > 2 ? _len4 - 2 : 0), _key4 = 2; _key4 < _len4; _key4++) {
args[_key4 - 2] = arguments[_key4];
}
return args.reduce(argReducer(scoped), [block]);
}
function argReducer(result, value) {
function argReducer(scoped /*:boolean*/) {
if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === "object") {
return result.concat(modifierParser(value).reduce(function (subresult, modifier) {
return subresult.concat(prefix(result, modifier));
}, []));
}
return function (result /*:any*/, value /*:any*/) /*:Classnames*/{
if ((typeof value === "undefined" ? "undefined" : _typeof(value)) === "object") {
return modifers(result, value, "--");
}
return [value].concat(prefix(result, "__" + value));
var prefixed = concat(result, value, "__");
return scoped ? prefixed : [value].concat(prefixed);
};
}
function modifierParser(modifiers) {
return Object.keys(modifiers).map(function (modifier) {
function modifers(result /*:Classnames*/, value /*:Modifiers*/, delimiter /*:string*/) /*:Classnames*/{
return result.concat(modifierParser(value).reduce(function (subresult /*:Classnames*/, modifier /*:string*/) {
return subresult.concat(concat(result, modifier, delimiter));
}, []));
}
function modifierParser(modifiers /*:Modifiers*/) /*:Classnames*/{
return Object.keys(modifiers).map(function (modifier /*:string*/) {
return [modifier, modifiers[modifier]];

@@ -41,9 +70,9 @@ }).reduce(modifierReducer, []);

function modifierReducer(result, _ref) {
function modifierReducer(result /*:Classnames*/, _ref) /*:Classnames*/{
var _ref2 = _slicedToArray(_ref, 2),
modifier = _ref2[0],
value = _ref2[1];
modifier /*:string*/ = _ref2[0],
value /*:any*/ = _ref2[1];
if (value !== false && value !== "" && value !== null && typeof value !== "undefined") {
result.push("--" + modifier + (value !== true ? "-" + value : ""));
result.push("" + modifier + (value !== true ? "-" + value : ""));
}

@@ -53,8 +82,12 @@ return result;

function prefix(prefixes, value) {
return prefixes.map(function (prefix) {
return "" + prefix + value;
function concat(prefixes /*:Classnames*/, value /*:string*/, delimiter /*:string*/) /*:Classnames*/{
return prefixes.map(function (prefix /*:string*/) {
return "" + prefix + delimiter + value;
});
}
module.exports = bem;
module.exports = bem;
module.exports.scoped = scoped;
module.exports.single = single;
{
"name": "@dr/bem-helper",
"version": "1.2.1",
"version": "1.2.2",
"description": "Helper to create BEM-style classnames",
"main": "lib/index.js",
"scripts": {
"test": "jest",
"test": "jest --no-watchman",
"build": "babel src -d lib",
"prepublish": "npm run build && npm test"
"prepublish": "npm run build && npm test",
"flow": "flow check"
},

@@ -27,8 +28,10 @@ "repository": {

"devDependencies": {
"babel-cli": "^6.18.0",
"babel-jest": "^17.0.2",
"babel-polyfill": "^6.16.0",
"babel-preset-es2015": "^6.18.0",
"jest": "^17.0.2"
"babel-cli": "^6.22.2",
"babel-jest": "^18.0.0",
"babel-plugin-transform-flow-comments": "^6.22.0",
"babel-polyfill": "^6.22.0",
"babel-preset-es2015": "^6.22.0",
"flow-bin": "^0.38.0",
"jest": "^18.1.0"
}
}

@@ -5,2 +5,22 @@ # bem-helper

```js
var className = bem("block", "element", {modifier: true});
/*
className == "element block__element element--modifier block__element--modifier"
______________ ________________________
| | |
______| _________________________| |
\/ \/ |
bem.scoped == "block__element block__element--modifier" |
|
_____________________________________________|
\/
bem.single == "block__element--modifier"
*/
```
## Install

@@ -17,17 +37,21 @@

var className = bem("dr-module", "list");
// className === "list dr-module__list"
var className = bem("block", "element");
// className === "element block__element"
var className = bem("dr-module", { loaded: true });
// className === "dr-module dr-module--loaded"
var className = bem("block", { modifier: true });
// className === "block block--modifier"
// Get all applicable combinations for an element:
var className = bem("dr-module", "list", { expanded: true });
// className === "list dr-module__list list--expanded dr-module__list--expanded"
var className = bem("block", "element", { modifier: true });
// className === "element block__element element--modifier block__element--modifier"
// Get all applicable combinations scoped combinations for an element:
var className = bem.scoped("block", "element", { modifier: true });
// className === "block__element block__element--modifier"
// Get a single classname for an element:
var className = bem.single("dr-module", "list", { expanded: true });
// className === "dr-module__list--expanded"
var className = bem.single("block", "element", { modifier: true });
// className === "block__element--modifier"

@@ -38,9 +62,12 @@

// Get all applicable combinations for an element:
var className = bem("dr-module", "list", { expanded: true, rated: 3 });
// className === "list dr-module__list list--expanded dr-module__list--expanded list--rated-3 dr-module__list--rated-3"
var className = bem("block", "element", { modifier: "value", modifier2: false });
// className === "element block__element element--modifier block__element--modifier element--modifier-value block__element--modifier-value"
// Get all applicable scoped combinations for an element:
var className = bem.scoped("block", "element", { modifier: "value", modifier2: false });
// className === "block__element block__element--modifier block__element--modifier-value"
// Get a single classname for an element:
var className = bem.single("dr-module", "list", { rated: 3 });
// className === "dr-module__list--rated-3"
var className = bem.single("block", "element", { modifier: "value" });
// className === "block__element--modifier-value"

@@ -50,15 +77,21 @@

var block = "dr-module";
var block = "block";
var boundBem = bem.bind(null, block);
// Get all applicable combinations for an element:
var className = boundBem("element", { modifier: true });
// className === "element block__element element--modifier block__element--modifier"
var boundScoped = bem.scoped.bind(null, block);
// Get all applicable scoped combinations for an element:
var className = boundBem("list", { expanded: true });
// className === "list dr-module__list list--expanded dr-module__list--expanded"
var className = boundScoped("element", { modifier: true });
// className === "block__element block__element--modifier"
var boundSingle = bem.single.bind(null, block);
// Get a single scoped classname for an element:
var className = boundSingle("list", { expanded: true });
// className === "dr-module__list--expanded"
// Get a single classname for an element:
var className = boundSingle("element", { modifier: true });
// className === "block__element--modifier"

@@ -76,6 +109,10 @@ ```

* `block` (string) - The block element for the classname.
* `...args` (string|object) - Optional. Elements are described by strings and modifiers are described by objects: keys are use as the modifier names and boolean values trigger whether the modifier is active, and any other type is used as a value; `{expanded: true}` > `"--expanded"`, `{rating: 3}` > `"--rating-3"`.
* `...args` (string|object) - Optional. Elements are described by strings and modifiers are described by objects: keys are use as the modifier names and boolean values trigger whether the modifier is active, and any other type is used as a value; `{modifier: true}` > `"--modifier"`, `{modifier: "value"}` > `"--modifier-value"`.
### bem.scoped
Same as `bem` - but it returns a fully scoped classname.
### bem.single
Same as `bem` above - but it only returns a single classname.
Same as `bem` - but it only returns a single classname.

@@ -1,30 +0,49 @@

function bem (...args) {
return argParser(...args).join(" ");
/* @flow */
/*:: type Modifiers = { [key: string]: any }; */
/*:: type Classnames = Array<string>; */
function bem (...args/*:any*/) /*:string*/ {
return argParser(false, ...args).join(" ");
}
bem.single = (...args) => argParser(...args).pop();
function scoped (...args/*:any*/) /*:string*/ {
return argParser(true, ...args).join(" ");
};
function argParser (block, ...args) {
return args.reduce(argReducer, [block]);
function single (...args/*:any*/) /*:string*/ {
return argParser(true, ...args).pop();
};
function argParser (scoped/*:boolean*/, block/*:string*/, ...args/*:any*/) /*:Classnames*/ {
return args.reduce(argReducer(scoped), [block]);
}
function argReducer (result, value) {
function argReducer (scoped/*:boolean*/) {
if (typeof value === "object") {
return result.concat(
modifierParser(value)
.reduce(
(subresult, modifier) => subresult.concat(prefix(result, modifier)),
[]
)
);
return function (result/*:any*/, value/*:any*/) /*:Classnames*/ {
if (typeof value === "object") {
return modifers(result, value, "--");
}
var prefixed = concat(result, value, "__");
return (scoped) ? prefixed : [value].concat(prefixed);
}
return [value].concat(prefix(result, `__${value}`));
}
function modifers(result/*:Classnames*/, value/*:Modifiers*/, delimiter/*:string*/) /*:Classnames*/ {
return result.concat(
modifierParser(value)
.reduce(
(subresult/*:Classnames*/, modifier/*:string*/) => subresult.concat(concat(result, modifier, delimiter)),
[]
)
);
}
function modifierParser (modifiers) {
function modifierParser (modifiers/*:Modifiers*/) /*:Classnames*/ {
return Object.keys(modifiers).map(
(modifier) => [modifier, modifiers[modifier]]
(modifier/*:string*/) => [modifier, modifiers[modifier]]
).reduce(

@@ -36,5 +55,5 @@ modifierReducer,

function modifierReducer (result, [modifier, value]) {
function modifierReducer (result/*:Classnames*/, [modifier/*:string*/, value/*:any*/]) /*:Classnames*/ {
if (value !== false && value !== "" && value !== null && typeof value !== "undefined") {
result.push(`--${modifier}${(value !== true) ? `-${value}` : "" }`);
result.push(`${modifier}${(value !== true) ? `-${value}` : "" }`);
}

@@ -44,5 +63,5 @@ return result;

function prefix (prefixes, value) {
function concat (prefixes/*:Classnames*/, value/*:string*/, delimiter/*:string*/) /*:Classnames*/ {
return prefixes.map(
(prefix) => `${prefix}${value}`
(prefix/*:string*/) => `${prefix}${delimiter}${value}`
);

@@ -52,1 +71,5 @@ }

module.exports = bem;
module.exports.scoped = scoped;
module.exports.single = single;

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc