From c5eef0e6b0b6d5f72e1af6c39d568bf6805fe2fd Mon Sep 17 00:00:00 2001 From: Oyster Lee Date: Fri, 22 Jul 2022 18:56:16 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat:=20add=20`generateBEM`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/generator/index.ts | 50 ++++++++++++++++++++++++++++ src/generator/test/generator.test.ts | 21 ++++++++++++ src/types/index.ts | 2 ++ 3 files changed, 73 insertions(+) create mode 100644 src/generator/index.ts create mode 100644 src/generator/test/generator.test.ts diff --git a/src/generator/index.ts b/src/generator/index.ts new file mode 100644 index 0000000..a1e8a6c --- /dev/null +++ b/src/generator/index.ts @@ -0,0 +1,50 @@ +import type { Modifier } from "../types"; + +const _formatModifier = ( + be: string, + modifiers: Modifier | Modifier[], +): string => { + if (typeof modifiers === "string") return ` ${be}--${modifiers}`; + + if (Array.isArray(modifiers)) { + return modifiers.reduce( + (acc: string, curr) => acc + _formatModifier(be, curr), + "", + ); + } + + return Object.keys(modifiers).reduce((acc, curr) => { + if (modifiers[curr]) return acc + _formatModifier(be, curr); + return acc; + }, ""); +}; + +/** + * Generate Block Element Modifier string + * @typedef {string | Record} Modifier + * @method + * @param name {string} Block name + * @return {generateBEM~string} + * @example + * generateBEM("facil-button")() // "facil-button" + * generateBEM("facil-button")("block") // "facil-button__block" + * @category Generator + * @version v0.3.0 + */ +export const generateBEM = (name: string) => { + /** + * @param {Modifier | Modifier[]} elementOrModifiers= + * @param {Modifier | Modifier[]} modifiers= + */ + return ( + elementOrModifiers?: Modifier | Modifier[], + modifiers?: Modifier | Modifier[], + ): string => { + if (elementOrModifiers && typeof elementOrModifiers !== "string") { + modifiers = elementOrModifiers; + elementOrModifiers = ""; + } + const be = elementOrModifiers ? `${name}__${elementOrModifiers}` : name; + return modifiers ? be + _formatModifier(be, modifiers) : be; + }; +}; diff --git a/src/generator/test/generator.test.ts b/src/generator/test/generator.test.ts new file mode 100644 index 0000000..483c0a7 --- /dev/null +++ b/src/generator/test/generator.test.ts @@ -0,0 +1,21 @@ +import { describe, it, expect } from "vitest"; +import { generateBEM } from "../index"; + +describe("test bem", () => { + it("should generate proper bem", () => { + const bem = generateBEM("facil-button"); + const disabled = true; + const primary = false; + expect(bem()).toBe("facil-button"); + expect(bem("block")).toBe("facil-button__block"); + expect(bem("block", ["disabled", "primary"])).toBe( + "facil-button__block facil-button__block--disabled facil-button__block--primary", + ); + expect(bem(["disabled", "primary"])).toBe( + "facil-button facil-button--disabled facil-button--primary", + ); + expect(bem("block", { disabled, primary })).toBe( + "facil-button__block facil-button__block--disabled", + ); + }); +}); diff --git a/src/types/index.ts b/src/types/index.ts index 902dcc9..952eb22 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -13,3 +13,5 @@ export type NestedObject = { export interface Func { (): void; } + +export type Modifier = string | { [modifier: string]: boolean };