Skip to content

Instantly share code, notes, and snippets.

@FrameMuse
Created July 26, 2024 10:03
Show Gist options
  • Save FrameMuse/aeadd471413a9f49a2569d7c46ead6bf to your computer and use it in GitHub Desktop.
Save FrameMuse/aeadd471413a9f49a2569d7c46ead6bf to your computer and use it in GitHub Desktop.
Light BEM class adapter
import { castArray } from "lodash"
import { isRecord } from "./common"
class BEM {
/**
*
* @returns `class1 class2`
*/
merge(...classNames: Array<string | null | undefined>): string {
const space = " "
return classNames.filter(Boolean).join(space)
}
/**
* Join modifiers with origin class.
* @returns `"origin-class origin-class--modifier"`
*/
modify(originClass: string, ...modifiers: Array<string | number | false | null | undefined>): string {
modifiers = modifiers.filter(Boolean)
if (!modifiers.length) return originClass
const space = " "
const separator = "--"
modifiers = modifiers.map(modifier => originClass + separator + modifier)
return originClass + space + modifiers.join(space)
}
}
export const bemTil = new BEM
type BEMElement = string | number | false | null | undefined
export function bem(classNames: string | string[], ...modifiers: (Record<keyof never, boolean | undefined | null | "" | 0> | BEMElement)[]): string {
const mods = modifiers.flatMap(modifier => isRecord(modifier) ? Object.entries(modifier).reduce((result, [nextKey, nextValue]) => [...result, nextValue && nextKey], []) : modifier)
return bemTil.merge(...castArray(classNames).map(className => bemTil.modify(className, ...mods)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment