/** @module Dom */
export type TClsTypes = string | boolean | undefined
export type TClsItems =
| string
| boolean
| Record<string, TClsTypes[]>
| TClsTypes[]
| undefined
/**
* Formats the passed in classes
* @function
* @private
*/
const formatCls = (classes: Array<string | boolean>) =>
classes
.filter(item => typeof item === 'string' && Boolean(item))
.join(` `)
.trim()
/**
* Formats the passed in classes argument into a space separated string of classNames
* @function
* @param {Object|Array<string>|string} classes - Classes that should be formatted
* @example
* cls({ class1: true, class2: false }) === `class1`
* cls({ class1: true, class2: true }) === `class1 class2`
* @example
* let class2Active = false
* cls([`class1`, class2Active && `class2`]) === `class1`
* class2Active = true
* cls([`class1`, class2Active && `class2`]) === `class1 class2`
* @example
* cls(`class1`, `class2`, [`class3`], { class4: true }) === `class1 class2 class3 class4`
* @returns {string} - Formatted class names
*/
export const cls = (...classGroup: TClsItems[]): string => {
return formatCls(
classGroup.map(classes => {
return Array.isArray(classes)
? cls(...classes)
: typeof classes !== `object`
? formatCls([classes])
: formatCls(
Object.entries(classes).map(([item, val]) => {
return typeof val === 'boolean'
? val && formatCls([item])
: cls(val)
})
)
})
)
}