kobalte
kobalte copied to clipboard
fix: Select's onChange sends undefined if current value is selected
Describe the bug
Implementing the Select primitive I found that the onChange function passes undefined as an argument to the callback if the current value selected is reselected. This breaks the type declared for the requested callback. In other terms: the function behaves as onChange?: (value: T | undefined) => void;.
To Reproduce Steps to reproduce the behavior:
- Go to https://kobalte.dev/docs/core/components/select
- At the demo, click on the Select component
- Select the currently selected value (i.e. Blueberry)
- See error: value is lost in the select content
Expected behavior
If the current value is selected, the onChange function should be called with it as a value or it shouldn't be called. Test the same flow in https://www.radix-ui.com/primitives/docs/components/select, it doesn't affect the current value selected
Desktop:
- OS: macOS
- Browser Arc
- Version Chromium Engine Version 124
Additional context None
By default Kobalte allows you to unselect an option (by clicking on the current option) and so send undefined to onChange. You're correct that the type doesn't match, I'll update it to include undefined.
If you wish to have the same behavior as radix set disallowEmptySelection on your Select (Root).
I fear the issue is slightly more complicated. Unfortunately, onChange gives null instead of undefined when unselecting, which is problematic for user's code. I still apply a workaround to convert null to undefined because of that. It would be good to give undefined instead of null.
Note that for multi select, it's probably fine if value cannot be undefined since supplying empty array when nothing is selected is probably better. These are the function signatures I would expect:
- Single Select
onChange: (value?: T) => void - Multi Select:
onChange: (value: T[]) => void
Note that this is linked to #252
I've changed the type and fixed it for multiselect (now calls with []), I might change the value for single from null to undefined later but this would become a breaking change and is not fully compatible with our current system.