This is a matter of convention. Another, equally valid convention:
classNames({
mainClass: true, // first key is main class
[props.className]: true, // derived
otherClass: true, // rest
yetAnotherClass: true // ...
})
At the end of the day, everyone has to learn their codebase's convention, and that's all that really matters. One convention isn't better or worse than any other, but it's best to have one and stick with it. I don't need a library which supports 10 different conventions if my chosen convention only requires 2 lines of code. Your convention could be implemented in a few lines of code, as well, and then you'd be forced to stick with it, which is probably better. Using this library, 5 different developers could be using 5 different conventions. The helper function I suggest forces a single convention, which lowers complexity.
The props.className one in particular is pretty garish. Probably should do !!props.className to help explain intent a bit, which adds to the tedium. Once you've added falsy thinning and arbitrary arguments, you're 99% of the way to classnames.
This is a matter of convention. Another, equally valid convention:
At the end of the day, everyone has to learn their codebase's convention, and that's all that really matters. One convention isn't better or worse than any other, but it's best to have one and stick with it. I don't need a library which supports 10 different conventions if my chosen convention only requires 2 lines of code. Your convention could be implemented in a few lines of code, as well, and then you'd be forced to stick with it, which is probably better. Using this library, 5 different developers could be using 5 different conventions. The helper function I suggest forces a single convention, which lowers complexity.