React offers basically zero support for CSS. Personally I’m fond of CSS Modules along with SCSS instead of the slow CSS-in-JS solutions out there. Still, we need a way to manage multiple classes in className property.
In order to mitigate this problem, I wrote a TypeScript function to deal with sequential or conditional class names situations:
/**
* Generates the className attribute with the given class names.
*/
export function cn(
...items: (
string
| null
| undefined
| (string | null | undefined)[]
| Record<string, boolean>
)[]
): string {
let fin = ' ';
for (const item of items) {
if (typeof item === 'string') {
fin += item + ' ';
} else if (Array.isArray(item)) {
for (const s of item) {
if (typeof s === 'string') fin += s + ' ';
}
} else if (typeof item === 'object') {
for (const key in item) {
if (item[key]) fin += key + ' ';
}
}
}
return fin.substring(0, fin.length - 1);
}
Example using some argument possibilities:
import {cn} from '@/funcs';
import c from './App.module.css';
function App() {
return <>
<div className={cn( c.first )} />
<div className={cn( c.first, c.second )} />
<div className={cn( [c.first, c.second], c.third )} />
<div className={cn( c.first, {[c.second]: true} )} />
</>;
}
This covers all situations I ever faced, and it's basically the same syntax of classnames.
The spread operator version was added in February 9, 2023.
The multi-combination of parameters was added in December 30, 2024.
No comments:
Post a Comment