When dealing with an important React project at work, I was manipulating multiple CSS Modules class names with a function I wrote 2 and a half years ago, accepting an object for conditionals.
The early hours of the morning of this last day of the year brought me an idea for a shorter, simpler syntax that works better for imported CSS Modules names:
/** * Generates the `className` attribute with the given class names. * * @example * cn( 'abc' ); * cn( 'abc', 'def' ); * cn( 'abc', ['def', true] ); */ export function cn(...items: (string | null | undefined | [string, boolean])[]): string { let fin = ''; for (let i = 0; i < items.length; ++i) { const item = items[i]; if (item === null || item === undefined) { continue; } else if (typeof item === 'string') { fin += item + ' '; } else if (Array.isArray(item) && item.length === 2) { if (typeof item[0] === 'string') { if (item[1]) fin += item[0] + ' '; } else { throw new Error(`cn() item #${i} is an invalid tuple: ${JSON.stringify(item)}`); } } else { throw new Error(`cn() item #${i} is invalid: ${JSON.stringify(item)}`); } } return fin.length ? fin.substring(0, fin.length - 1) : ''; }
And this new function covers all my current needs.
No comments:
Post a Comment