headlessui
headlessui copied to clipboard
Combobox firing select value onChange when clearing the input value
https://github.com/tailwindlabs/headlessui/blob/5eb3b12a95a980397d4cf055f120691911631e85/packages/%40headlessui-react/src/components/combobox/combobox.tsx#L1309
Based on the line above and the preceding comment, it looks like when the user clears the input value, there is an onChange event fired.
Is there a reason for this? I would have thought that the input value and the selected option concerns should be different.
Why would we want to trigger an onChange and send null when the user is just typing and clearing the input field?
This is a reproduction: https://stackblitz.com/edit/vitejs-vite-6e5rus1w?file=src%2FApp.tsx,src%2Findex.css,src%2Fmain.tsx&terminal=dev
Is this a new change in v2 or it's always like that? (Yes it is)
@RobinMalfait Sorry for the ping. The intention is reasonable here, but at least it should provide an option or be explicitly documented in the docs. Otherwise, it's like surprising behaviour, where no one knows.
Explicitly passing null to onChange without documenting it anywhere should be breaking most of the usage.
This should at least be
T | null in the docs from my perspective.
Thanks.
Does this functionality makes sense? When we clear the search input, the value probably shouldn’t be set to null, right?
Since we’re always working with a string when we modify this value, it should just be an empty string instead here, correct?
Hey!
In @headlessui/react v1 the Combobox could be marked as nullable which allows you to clear the value which in turn uses null as the onChange value when you cleared the input. We noticed that we essentially always wanted the component to be nullable, so in v2 we made the combobox nullable by default.
We did document this in the release notes when we published v2: https://github.com/tailwindlabs/headlessui/releases/tag/%40headlessui%2Freact%40v2.0.0#:~:text=Comboboxes%20now%20always%20support%20empty%20values
If you don't want to the value to be nullable, then you can use something like this:
<Combobox
value={selected}
- onChange={setSelected}
+ onChange={(newValue) => setSelected((oldValue) => newValue ?? oldValue)}
onClose={() => setQuery('')}
>
or you could also ignore the newValue if it is null, that's up to you.
@xsjcTony Good catch! I've updated the docs to include the | null for the onChange callback.
@kwconrad The ComboboxInput deals with strings, but the actual Combobox can deal with any kind of value. If we were only dealing with strings then we could call the onChange with '' but that value doesn't make sense for objects or anything else, which is why we picked null instead.
Note: If you are dealing with any other type than a string, then that's why you would need the displayValue https://headlessui.com/react/combobox#binding-objects-as-values
Going to close this since this is the expected behavior, but I did update the docs to include the T | null change.