-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#24 Implement js script for bem. Change core to be more performant
- Loading branch information
Andrii Kirmas
committed
Mar 10, 2021
1 parent
fbb5cec
commit 990751b
Showing
10 changed files
with
200 additions
and
135 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { bem2arr, BemAbsraction } from "./bem.core"; | ||
|
||
describe(bem2arr.name, () => { | ||
describe("singletons", () => { | ||
const suites = { | ||
"block singleton": [ | ||
[{block: false }, ""], | ||
[{block: true }, "block"], | ||
[{block: {} }, "" /* or "block" */], | ||
[{block: {$: undefined }}, "block"], | ||
[{block: {$: false }}, "block"], | ||
[{block: {$: { }}}, "block"], | ||
[{block: {$: {mod: false}}}, "block"], | ||
[{block: {$: {mod: true }}}, "block block--mod"], | ||
[{block: {$: {mod: "" }}}, "block"], | ||
[{block: {$: {mod: "val"}}}, "block block--mod--val"], | ||
], | ||
"element singleton": [ | ||
[{block: {el: false }}, ""], | ||
[{block: {el: true }}, "block__el"], | ||
[{block: {el: {} }}, "block__el"], | ||
[{block: {el: {mod: false}}}, "block__el"], | ||
[{block: {el: {mod: true }}}, "block__el block__el--mod"], | ||
[{block: {el: {mod: "" }}}, "block__el"], | ||
[{block: {el: {mod: "val"}}}, "block__el block__el--mod--val"], | ||
], | ||
"block and el combine": [ | ||
[{block: { | ||
$: {mod: true}, | ||
el: true }}, "block block--mod block__el"] | ||
] | ||
} as Record<string, [BemAbsraction, string][]> | ||
|
||
Object.entries(suites).forEach(([title, launches]) => describe(title, () => launches | ||
.forEach(([query, output]) => it( | ||
JSON.stringify(query, (_, v) => v === undefined ? "`undefined`" : v), | ||
() => expect(bem2arr(query).join(" ")).toBe(output)) | ||
) | ||
)) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
const elementDelimiter = "__" | ||
, modDelimiter = "--" | ||
, blockModKey = "$" as const | ||
|
||
export type BemAbsraction = { | ||
[block: string]: boolean | { | ||
[blockModKey]?: { | ||
[mod: string]: boolean | string | ||
} | ||
[el: string]: undefined|boolean | { | ||
[mod: string]: boolean | string | ||
} | ||
} | ||
} | ||
|
||
export { | ||
bem2arr | ||
} | ||
|
||
function bem2arr(query: BemAbsraction) { | ||
const $return: string[] = [] | ||
|
||
for (const block in query) { | ||
const blockQ = query[block] | ||
|
||
if (!blockQ) | ||
continue | ||
if (typeof blockQ !== "object") { | ||
$return.push(block) | ||
continue | ||
} | ||
|
||
for (const el in blockQ) { | ||
const elementQ = blockQ[el] | ||
, element = el === blockModKey ? block : `${block}${elementDelimiter}${el}` | ||
|
||
if (!elementQ) { | ||
el === blockModKey && $return.push(element) | ||
continue | ||
} | ||
|
||
$return.push(element) | ||
|
||
if (typeof elementQ !== "object") | ||
continue | ||
|
||
for (const mod in elementQ) { | ||
const modValue: string|boolean = elementQ[mod] | ||
if (!modValue) | ||
continue | ||
|
||
$return.push(`${element}${modDelimiter}${mod}${ | ||
typeof modValue !== "string" | ||
? "" | ||
: `${modDelimiter}${modValue}` | ||
}`) | ||
} | ||
} | ||
} | ||
|
||
return $return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,31 @@ | ||
import { bem2arr, BemAbsraction } from "./bem"; | ||
import { classBeming } from "./bem"; | ||
|
||
describe(bem2arr.name, () => { | ||
describe("singletons", () => { | ||
const suites = { | ||
"block singleton": [ | ||
[{block: false }, ""], | ||
[{block: true }, "block"], | ||
[{block: {} }, "" /* or "block" */], | ||
[{block: {$: undefined }}, "block"], | ||
[{block: {$: false }}, "block"], | ||
[{block: {$: { }}}, "block"], | ||
[{block: {$: {mod: false}}}, "block"], | ||
[{block: {$: {mod: true }}}, "block block--mod"], | ||
[{block: {$: {mod: "" }}}, "block"], | ||
[{block: {$: {mod: "val"}}}, "block block--mod--val"], | ||
], | ||
"element singleton": [ | ||
[{block: {el: false }}, ""], | ||
[{block: {el: true }}, "block__el"], | ||
[{block: {el: {} }}, "block__el"], | ||
[{block: {el: {mod: false}}}, "block__el"], | ||
[{block: {el: {mod: true }}}, "block__el block__el--mod"], | ||
[{block: {el: {mod: "" }}}, "block__el"], | ||
[{block: {el: {mod: "val"}}}, "block__el block__el--mod--val"], | ||
], | ||
"block and el combine": [ | ||
[{block: { | ||
$: {mod: true}, | ||
el: true }}, "block block--mod block__el"] | ||
] | ||
} as Record<string, [BemAbsraction, string][]> | ||
describe("contexting", () => { | ||
describe("empty", () => { | ||
const bem = classBeming() | ||
|
||
Object.entries(suites).forEach(([title, launches]) => describe(title, () => launches | ||
.forEach(([query, output]) => it( | ||
JSON.stringify(query, (_, v) => v === undefined ? "`undefined`" : v), | ||
() => expect(bem2arr(query).join(" ")).toBe(output)) | ||
) | ||
)) | ||
it("1", () => expect(bem({ | ||
"block1": true, | ||
"block2": { "el": true } | ||
})).toStrictEqual({ | ||
className: "block1 block2__el" | ||
})) | ||
}) | ||
|
||
describe("full", () => { | ||
const bem = classBeming({ | ||
className: "propagated", | ||
classnames: { | ||
"block1": "hash1", | ||
"block2__el": "hash2" | ||
} | ||
}) | ||
|
||
it("1", () => expect(bem(true, { | ||
"block1": true, | ||
"block2": { "el": true } | ||
})).toStrictEqual({ | ||
className: "propagated hash1 hash2" | ||
})) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,62 +1,43 @@ | ||
const elementDelimiter = "__" | ||
, modDelimiter = "--" | ||
, blockModKey = "$" as const | ||
|
||
export type BemAbsraction = { | ||
[block: string]: boolean | { | ||
[blockModKey]?: { | ||
[mod: string]: boolean | string | ||
} | ||
[el: string]: undefined|boolean | { | ||
[mod: string]: boolean | string | ||
} | ||
} | ||
} | ||
import type { BemAbsraction } from "./bem.core"; | ||
import type { CssModule } from "./definitions.defs"; | ||
import { bem2arr } from "./bem.core"; | ||
import { joinWithLead, picker } from "./core" | ||
import { EMPTY_OBJECT } from "./consts.json" | ||
|
||
export { | ||
bem2arr | ||
classBeming | ||
} | ||
|
||
function bem2arr(query: BemAbsraction) { | ||
const $return: string[] = [] | ||
|
||
for (const block in query) { | ||
const blockQ = query[block] | ||
|
||
if (!blockQ) | ||
continue | ||
if (typeof blockQ !== "object") { | ||
$return.push(block) | ||
continue | ||
} | ||
|
||
for (const el in blockQ) { | ||
const elementQ = blockQ[el] | ||
, element = el === blockModKey ? block : `${block}${elementDelimiter}${el}` | ||
|
||
if (!elementQ) { | ||
el === blockModKey && $return.push(element) | ||
continue | ||
} | ||
|
||
$return.push(element) | ||
|
||
if (typeof elementQ !== "object") | ||
continue | ||
|
||
for (const mod in elementQ) { | ||
const modValue: string|boolean = elementQ[mod] | ||
if (!modValue) | ||
continue | ||
function classBeming< | ||
Ctx extends {classnames: Source, className?: string}, | ||
Source extends CssModule = Ctx["classnames"], | ||
// WithClassName extends boolean = Ctx["className"] extends string ? true : false | ||
>( | ||
context: Ctx = EMPTY_OBJECT as Ctx | ||
) { | ||
//@ts-expect-error | ||
const host = (arg0?, arg1?) => bem(context, arg0, arg1) | ||
|
||
return host | ||
} | ||
|
||
$return.push(`${element}${modDelimiter}${mod}${ | ||
typeof modValue !== "string" | ||
? "" | ||
: `${modDelimiter}${modValue}` | ||
}`) | ||
} | ||
} | ||
} | ||
|
||
return $return | ||
function bem< | ||
Source extends CssModule, | ||
>( | ||
{ | ||
className, | ||
classnames, | ||
}: { | ||
className?: string, | ||
classnames?: Source, | ||
}, | ||
arg0?: boolean | BemAbsraction, | ||
arg1?: BemAbsraction | ||
) { | ||
const source = typeof arg0 === "object" ? arg0 : arg1 | ||
, debemed = source && bem2arr(source) | ||
, picked = debemed && picker(classnames, debemed) | ||
, result = joinWithLead(arg0 === true && className, picked) | ||
|
||
return {className: result} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.