diff --git a/packages/@headlessui-react/CHANGELOG.md b/packages/@headlessui-react/CHANGELOG.md index 758a8dc..10eeead 100644 --- a/packages/@headlessui-react/CHANGELOG.md +++ b/packages/@headlessui-react/CHANGELOG.md @@ -45,6 +45,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add new `CloseButton` component and `useClose` hook ([#3096](https://github.com/tailwindlabs/headlessui/pull/3096)) - Allow passing a boolean to the `anchor` prop ([#3121](https://github.com/tailwindlabs/headlessui/pull/3121)) - Add `portal` prop to `Combobox`, `Listbox`, `Menu` and `Popover` components ([#3124](https://github.com/tailwindlabs/headlessui/pull/3124)) +- Add frozen value to `ComboboxOptions` component ([#3126](https://github.com/tailwindlabs/headlessui/pull/3126)) ## [1.7.19] - 2024-04-15 diff --git a/packages/@headlessui-react/src/components/combobox/combobox.test.tsx b/packages/@headlessui-react/src/components/combobox/combobox.test.tsx index 912964d..4012bd6 100644 --- a/packages/@headlessui-react/src/components/combobox/combobox.test.tsx +++ b/packages/@headlessui-react/src/components/combobox/combobox.test.tsx @@ -4289,7 +4289,6 @@ describe.each([{ virtual: true }, { virtual: false }])( // Verify that we don't have an selected option anymore assertNotActiveComboboxOption(options[1]) - assertNoSelectedComboboxOption() // Verify that we saw the `null` change coming in expect(handleChange).toHaveBeenCalledTimes(1) diff --git a/packages/@headlessui-react/src/components/combobox/combobox.tsx b/packages/@headlessui-react/src/components/combobox/combobox.tsx index 204a2bc..118d8df 100644 --- a/packages/@headlessui-react/src/components/combobox/combobox.tsx +++ b/packages/@headlessui-react/src/components/combobox/combobox.tsx @@ -1646,17 +1646,35 @@ function OptionsFn( }) } + // Frozen state, the selected value will only update visually when the user re-opens the + let [frozenValue, setFrozenValue] = useState(data.value) + if ( + data.value !== frozenValue && + data.comboboxState === ComboboxState.Open && + data.mode !== ValueMode.Multi + ) { + setFrozenValue(data.value) + } + + let isSelected = useEvent((compareValue: unknown) => { + return data.compare(frozenValue, compareValue) + }) + return ( - {render({ - ourProps, - theirProps, - slot, - defaultTag: DEFAULT_OPTIONS_TAG, - features: OptionsRenderFeatures, - visible, - name: 'Combobox.Options', - })} + + {render({ + ourProps, + theirProps, + slot, + defaultTag: DEFAULT_OPTIONS_TAG, + features: OptionsRenderFeatures, + visible, + name: 'Combobox.Options', + })} + ) } @@ -1796,7 +1814,7 @@ function OptionFn< } if (data.mode === ValueMode.Single) { - requestAnimationFrame(() => actions.closeCombobox()) + actions.closeCombobox() } })