-
Notifications
You must be signed in to change notification settings - Fork 565
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
return undefined for empty class list #183
Conversation
This is a breaking change unfortunately. If anyone assumed the returned value was The end result is that |
You're right. Can you ship it with major version bump? I can update the docs if needed |
I don't think this will ever ship to be honest. My understanding is the benefits do not out weigh the risks. |
I think that this should be shipped - in the worst case if someone does not follow semver there would be unexpected |
I think this change is scary enough, that I'd want confirmation from @JedWatson and other users of the package to weigh in before anything was changed or released. |
So in terms of avoiding unexpected behaviour, I don't think we can ship this. It's not so much the hassle of a major version, as the possible usage where Imagine the following case where the usage of classNames is abstracted away in a library: // in a library
function getClassnameForButton(opts) {
// this could return undefined
return classnames(opts.specialClass);
}
// in user-land
const MyButton = (props) => <button class={`${getClassnameForButton(props)} my-button`} /> In this case the button would have a class of That's pretty contrived but I'm sure there are more valid scenarios where the usage of You can always wrap it, if concatenating strings onto the result is something you'd never do in your components: const cx = args => classnames(...args) || undefined;
const MyThing = ({ customClass }) => <span class={cx(customClass)} />; |
Also worth mentioning that we're talking about React here but this library is framework-agnostic, and I'm not sure we can guarantee that this isn't used in an environment where the result could be coerced into a string anyway. |
@JedWatson maybe it's possible to export a separate function which return |
Good point @JedWatson |
@JedWatson I don't think your example is contrived, but one that's possible. More importantly, I'd say that shouldn't be a concern in terms of making an improvement to the library. That same user should be told that they should be using You say that the library's priority should be safety and predictability, but I found the issue this PR attempts to solve to be unexpected. While a massive micro-optimization, you'll also be helping the web to ship smaller bundles collectively with this change. Major version bumps are exactly for this purpose, and people can choose not to upgrade if they'd like to maintain old behavior. I just wanted to add another voice to the discussion in hopes that you'd change your mind. No worries if not. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, but, its a breaking change.
@@ -27,8 +27,8 @@ describe('classNames', function () { | |||
assert.equal(classNames('', 'b', {}, ''), 'b'); | |||
}); | |||
|
|||
it('returns an empty string for an empty configuration', function () { | |||
assert.equal(classNames({}), ''); | |||
it('returns undefined for an empty configuration', function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you should check if undefined will become string in the template
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
empty string is better and predictable for UI developers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
... the whole point of this PR is to make it undefined. Read the above posts to understand why.
The npm package has an alternate dedupe and bind version. I understand this PR as being problematic for projects that expect empty string so, thoughts on another alternate version? All it'd need to do is bring in the base class and and add the empty string check to return undefined. I use classnames in many of my projects and in most of those I end up writing a wrapper util to do the above. Would love to get it OOTB in a single npm install! :) |
As is, I think this PR should close for the aforementioned breaking change reasons, but as hinted by @soluml maybe the path forward is another variant. |
Fixes #182