Skip to content

Commit e3a98e6

Browse files
author
Andrii Kirmas
committed
#42 Add nested in array support to BEM core
1 parent c016a86 commit e3a98e6

File tree

4 files changed

+62
-24
lines changed

4 files changed

+62
-24
lines changed

src/bem.core.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ describe(bem2arr.name, () => {
1818
[{base: {mod: false}}, "base"],
1919
[{base: {mod: true }}, "base base--mod"],
2020
[{base: {mod: "val"}}, "base base--mod--val"],
21+
[{base: [{mod: false}]}, "base"],
22+
[{base: [{mod: true }]}, "base base--mod"],
23+
[{base: [{mod: "val"}]}, "base base--mod--val"],
2124
],
2225
}
2326

@@ -51,3 +54,12 @@ describe("optioning", () => {
5154
expect(true).toBe(true)
5255
})
5356
})
57+
58+
it("extended values shape", () => expect(bem2arr({
59+
base: [
60+
{"mod1": 1},
61+
"mod2"
62+
]
63+
}).join(" ")).toBe(
64+
"base base--mod1--1 base--mod2"
65+
))

src/bem.core.ts

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { primitive } from "ts-swiss.types"
12
import type { BemInGeneral } from "./bem.types"
23

34
const {isArray: $isArray} = Array
@@ -30,30 +31,50 @@ function bem2arr(query: BemInGeneral) {
3031
continue
3132
}
3233

33-
const isArray = $isArray(baseQ)
34-
35-
// TODO check performance of `const in Array`
36-
for (const mod in baseQ) {
37-
//@ts-expect-error //TODO Split Array and Object?
38-
const modValue = baseQ[mod]
39-
if (!modValue)
40-
continue
41-
42-
$return.push(`${base}${
43-
isArray
44-
? ""
45-
: `${modDelimiter}${mod}`
46-
}${
47-
typeof modValue !== "string"
48-
? ""
49-
: `${modDelimiter}${modValue}`
50-
}`)
34+
if (!$isArray(baseQ))
35+
$return.push(...mods2arr(base, baseQ))
36+
else {
37+
const {length} = baseQ
38+
39+
for (let i = 0; i < length; i++) {
40+
const modQ = baseQ[i]
41+
42+
if (modQ === false)
43+
continue
44+
45+
if (modQ !== null && typeof modQ === "object")
46+
$return.push(...mods2arr(base, modQ))
47+
else
48+
$return.push(bmv(base, modQ))
49+
}
5150
}
5251
}
5352

5453
return $return
5554
}
5655

56+
function mods2arr(base: string, mods: Record<string, primitive>) {
57+
const classes = []
58+
59+
for (const mod in mods) {
60+
const value = mods[mod]
61+
if (value === false)
62+
continue
63+
64+
classes.push(bmv(base, mod, value))
65+
}
66+
67+
return classes
68+
}
69+
70+
function bmv(base: string, mod: string, value: Exclude<primitive, false> = true) {
71+
return `${base}${modDelimiter}${mod}${
72+
value === true
73+
? ""
74+
: `${modDelimiter}${value}`
75+
}`
76+
}
77+
5778
function setOptions({
5879
elementDelimiter: elD = elementDelimiter,
5980
modDelimiter: modDel = modDelimiter

src/bem.types.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ import type {
66
PartDeep,
77
Extends,
88
KeyOf,
9-
Ever
9+
Ever,
10+
primitive
1011
} from "./ts-swiss.types"
1112
import type { ClassNamed } from "./main.types"
1213

@@ -81,9 +82,13 @@ export type Mods<Bools extends string, Enums extends Record<string, string>>
8182
}
8283

8384
export type BemInGeneral = {
84-
[base: string]: undefined | boolean | string
85+
[base: string]: primitive
8586
| (false|string)[]
86-
| {
87-
[mod: string]: undefined | boolean | string
88-
}
87+
| [
88+
// TODO Why not one array expression?
89+
// false | string
90+
| { [mod: string]: primitive },
91+
...(false|string)[]
92+
]
93+
| { [mod: string]: primitive }
8994
}

src/ts-swiss.types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export type KnownKeys<T> = {
2020

2121
export type OmitIndexed<T> = Pick<T, KnownKeys<T> & keyof T>
2222

23-
export type Primitive = undefined | null | boolean | number | string | symbol | bigint
23+
export type primitive = undefined | null | boolean | number | string | bigint
2424

2525
export type Strip<Str extends string, Delimiter extends string, toNever extends boolean = false>
2626
= Str extends `${infer Lead}${Delimiter}${string}` ? Lead : toNever extends false ? Str : never

0 commit comments

Comments
 (0)