Skip to content

Commit cdad0b1

Browse files
authored
feat: allow to receive an array as modifiers (#236)
1 parent eab4625 commit cdad0b1

File tree

4 files changed

+64
-24
lines changed

4 files changed

+64
-24
lines changed

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ b({ mod1: true, mod2: false });
4444
b({ mod1: true, mod2: false, mod3: true });
4545
//=> "block block--mod1 block--mod3"
4646

47+
b(["mod1", null, "mod3"]);
48+
//=> "block block--mod1 block--mod3"
49+
4750
b("element");
4851
//=> "block__element"
4952

@@ -52,6 +55,9 @@ b("element", { mod1: true, mod2: false });
5255

5356
b("element", { mod1: true, mod2: false, mod3: true });
5457
//=> "block__element block__element--mod1 block__element--mod3"
58+
59+
b("element", ["mod1", null, "mod3"]);
60+
//=> "block__element block__element--mod1 block__element--mod3"
5561
```
5662

5763
## Options

docs/index.html

+4-2
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,11 @@ <h2>Output:</h2>
7070
import block from "https://unpkg.com/bem-ts/dist/bem-ts.min.js";
7171
const b = block("block");
7272
print(b());
73-
print(b({ modifier: true }));
73+
print(b({ modifier: true, noModifier: false }));
74+
print(b(["modifier2"]));
7475
print(b("element"));
75-
print(b("element", { modifier: true }));
76+
print(b("element", { modifier: true, noModifier: false }));
77+
print(b("element", ["modifier2", null]));
7678
</script>
7779

7880
<script>

index.ts

+19-8
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,11 @@ export function setup({
3434
}
3535
}
3636

37-
interface Modifiers {
38-
[key: string]: boolean | null | undefined;
39-
}
37+
type Modifiers =
38+
| {
39+
[key: string]: boolean | null | undefined;
40+
}
41+
| (string | null | undefined)[];
4042

4143
type BemBlockFunction = (elementOrModifiers?: string | Modifiers, modifiers?: Modifiers) => string;
4244

@@ -58,16 +60,25 @@ export default function bem(block: string, options: PartialOptions = {}): BemBlo
5860
return baseBlock;
5961
}
6062

61-
const isElement = typeof elementOrModifiers === "string";
62-
const base = isElement ? `${baseBlock}${elementDelimiter}${elementOrModifiers}` : baseBlock;
63-
const mods = isElement ? modifiers : elementOrModifiers;
63+
const base =
64+
typeof elementOrModifiers === "string"
65+
? `${baseBlock}${elementDelimiter}${elementOrModifiers}`
66+
: baseBlock;
67+
const mods = typeof elementOrModifiers === "string" ? modifiers : elementOrModifiers;
6468

6569
if (!mods) {
6670
return base;
6771
}
6872

73+
const reducer = (result: string, modifier: string | null | undefined): string =>
74+
modifier ? `${result} ${base}${modifierDelimiter}${modifier}` : result;
75+
76+
if (Array.isArray(mods)) {
77+
return mods.reduce(reducer, base);
78+
}
79+
6980
return Object.keys(mods)
70-
.filter(mod => (mods as Modifiers)[mod])
71-
.reduce((result, mod) => `${result} ${base}${modifierDelimiter}${mod}`, base);
81+
.filter(mod => mods[mod])
82+
.reduce(reducer, base);
7283
};
7384
}

test.ts

+35-14
Original file line numberDiff line numberDiff line change
@@ -125,40 +125,61 @@ testCases.forEach(({ description, tested, expectations }) => {
125125
const b = tested();
126126

127127
t.test("returns block", assert => {
128-
assert.is(b(), expectations[0]);
129-
assert.is(b({ mod1: false }), expectations[0]);
130-
assert.is(b({ mod1: false, mod2: false }), expectations[0]);
128+
const expected = expectations[0];
129+
assert.is(b(), expected);
130+
assert.is(b({ mod1: false }), expected);
131+
assert.is(b({ mod1: null }), expected);
132+
assert.is(b({ mod1: undefined }), expected);
133+
assert.is(b({ mod1: false, mod2: false, mod3: null, mod4: undefined }), expected);
134+
assert.is(b([]), expected);
135+
assert.is(b([""]), expected);
136+
assert.is(b([null]), expected);
137+
assert.is(b([undefined]), expected);
138+
assert.is(b(["", null, undefined]), expected);
131139
assert.end();
132140
});
133141

134142
t.test("returns block with modifier", assert => {
135-
assert.is(b({ mod1: true }), expectations[1]);
136-
assert.is(b({ mod1: true, mod2: false }), expectations[1]);
137-
assert.is(b({ mod1: true, mod2: null }), expectations[1]);
138-
assert.is(b({ mod1: true, mod2: undefined }), expectations[1]);
143+
const expected = expectations[1];
144+
assert.is(b({ mod1: true }), expected);
145+
assert.is(b({ mod1: true, mod2: false, mod3: null, mod4: undefined }), expected);
146+
assert.is(b(["mod1"]), expected);
147+
assert.is(b(["mod1", "", null, undefined]), expected);
139148
assert.end();
140149
});
141150

142151
t.test("returns block with multiple modifiers", assert => {
143-
assert.is(b({ mod1: true, mod2: true }), expectations[2]);
144-
assert.is(b({ mod1: true, mod2: true, mod3: false }), expectations[2]);
152+
const expected = expectations[2];
153+
assert.is(b({ mod1: true, mod2: true }), expected);
154+
assert.is(b({ mod1: true, mod2: true, mod3: false }), expected);
155+
assert.is(b(["mod1", "mod2"]), expected);
156+
assert.is(b(["mod1", "mod2", null]), expected);
145157
assert.end();
146158
});
147159

148160
t.test("returns block with element", assert => {
149-
assert.is(b("element"), expectations[3]);
161+
const expected = expectations[3];
162+
assert.is(b("element"), expected);
163+
assert.is(b("element", {}), expected);
164+
assert.is(b("element", { mod: false }), expected);
165+
assert.is(b("element", [""]), expected);
150166
assert.end();
151167
});
152168

153169
t.test("returns block with element and modifier", assert => {
154-
assert.is(b("element", { mod1: true }), expectations[4]);
155-
assert.is(b("element", { mod1: true, mod2: false }), expectations[4]);
170+
const expected = expectations[4];
171+
assert.is(b("element", { mod1: true }), expected);
172+
assert.is(b("element", { mod1: true, mod2: false }), expected);
173+
assert.is(b("element", ["mod1"]), expected);
174+
assert.is(b("element", ["mod1", null]), expected);
156175
assert.end();
157176
});
158177

159178
t.test("returns block with element and multiple modifiers", assert => {
160-
assert.is(b("element", { mod1: true, mod2: true }), expectations[5]);
161-
assert.is(b("element", { mod1: true, mod2: true, mod3: false }), expectations[5]);
179+
const expected = expectations[5];
180+
assert.is(b("element", { mod1: true, mod2: true }), expected);
181+
assert.is(b("element", { mod1: true, mod2: true, mod3: false }), expected);
182+
assert.is(b("element", ["mod1", "mod2"]), expected);
162183
assert.end();
163184
});
164185
});

0 commit comments

Comments
 (0)