Created
July 9, 2019 10:37
-
-
Save brookback/0f46aadcafa75d05837857b3e232dfbb to your computer and use it in GitHub Desktop.
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
type ValidClass = string | number | undefined | null | ObjectClass; | |
type ObjectClass = { | |
[key: string]: boolean | undefined; | |
}; | |
type ClassName = ValidClass | ValidClass[]; | |
/** | |
* Easier class names management for JSX elements. | |
* | |
* Usage: | |
* | |
* ```js | |
<div className={classNames('some-class', 'another', ['arr', 'of', 'classes'], { | |
'conditional-class': this.state.someValue | |
})}> | |
``` | |
* Note that the order of the keys in a passed object will not be explicitly | |
* preserved: that's up to the Javascript engine (most engines preserve key order). | |
*/ | |
export default function classNames(...args: ClassName[]): string { | |
return args | |
.filter((_) => !!_) // Filter out falsiness | |
.map((arg) => { | |
const type = typeof arg; | |
// We can add numbers and strings as class names instantly, | |
// but for arrays and objects, we need to traverse. | |
if (type === 'string' || type === 'number') { | |
return arg; | |
} else if (Array.isArray(arg) && arg.length) { | |
// Recuuuurse | |
return classNames(...arg); | |
} else if (type === 'object' && arg) { | |
const objMap = <ObjectClass>arg; | |
return Object.keys(objMap) | |
.filter((cl) => objMap[cl]) | |
.join(' '); | |
} | |
return ''; | |
}) | |
.join(' '); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment