Skip to content
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

Add frozen value to ComboboxOptions component #3126

Merged
merged 4 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/@headlessui-react/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `ComboboxOption` component ([#3126](https://github.com/tailwindlabs/headlessui/pull/3126))

## [1.7.19] - 2024-04-15

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
38 changes: 28 additions & 10 deletions packages/@headlessui-react/src/components/combobox/combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1646,17 +1646,35 @@ function OptionsFn<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(
})
}

// Frozen state, the selected value will only update visually when the user re-opens the <Combobox />
let [frozenValue, setFrozenValue] = useState(data.value)
if (
data.value !== frozenValue &&
data.comboboxState === ComboboxState.Open &&
data.mode !== ValueMode.Multi
) {
setFrozenValue(data.value)
thecrypticace marked this conversation as resolved.
Show resolved Hide resolved
}

let isSelected = useEvent((compareValue: unknown) => {
return data.compare(frozenValue, compareValue)
})

return (
<Portal enabled={visible && portal}>
{render({
ourProps,
theirProps,
slot,
defaultTag: DEFAULT_OPTIONS_TAG,
features: OptionsRenderFeatures,
visible,
name: 'Combobox.Options',
})}
<ComboboxDataContext.Provider
value={data.mode === ValueMode.Multi ? data : { ...data, isSelected }}
>
{render({
ourProps,
theirProps,
slot,
defaultTag: DEFAULT_OPTIONS_TAG,
features: OptionsRenderFeatures,
visible,
name: 'Combobox.Options',
})}
</ComboboxDataContext.Provider>
</Portal>
)
}
Expand Down Expand Up @@ -1796,7 +1814,7 @@ function OptionFn<
}

if (data.mode === ValueMode.Single) {
requestAnimationFrame(() => actions.closeCombobox())
actions.closeCombobox()
}
})

Expand Down
Loading