kobaltedev / kobalte

A UI toolkit for building accessible web apps and design systems with SolidJS.
https://kobalte.dev
MIT License
1.2k stars 61 forks source link

fix: Select's onChange sends undefined if current value is selected #412

Open lautaropaske opened 3 months ago

lautaropaske commented 3 months ago

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 asonChange?: (value: T | undefined) => void;.

To Reproduce Steps to reproduce the behavior:

  1. Go to https://kobalte.dev/docs/core/components/select
  2. At the demo, click on the Select component
  3. Select the currently selected value (i.e. Blueberry)
  4. 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:

Additional context None

jer3m01 commented 3 months ago

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).

jcmonnin commented 3 months ago

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:

Note that this is linked to #252

jer3m01 commented 2 weeks ago

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.