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

2.1.3 breaks listbox when ListboxOptions is used without anchor #3464

Closed
razzeee opened this issue Sep 9, 2024 · 2 comments · Fixed by #3466
Closed

2.1.3 breaks listbox when ListboxOptions is used without anchor #3464

razzeee opened this issue Sep 9, 2024 · 2 comments · Fixed by #3466
Assignees

Comments

@razzeee
Copy link

razzeee commented Sep 9, 2024

What package within Headless UI are you using?

@headlessui/react

What version of that package are you using?

v2.1.3

What browser are you using?

Firefox

Reproduction URL

import { Dispatch, SetStateAction } from 'react'

import {
  Listbox,
  ListboxButton,
  ListboxOption,
  ListboxOptions,
  Field,
} from '@headlessui/react'
import clsx from 'clsx'

const ListBox = <
  T extends {
    id: number
    name?: string
  }
>({
  items,
  selectedItem,
  setSelectedItem,
  onChange,
}: {
  items: T[]
  selectedItem: T
  setSelectedItem: Dispatch<SetStateAction<T>>
  onChange?: (selectedItem: T) => void
}): JSX.Element => {
  function updateSelection(newSelectedItem: T) {
    setSelectedItem(newSelectedItem)
    onChange?.(newSelectedItem)
  }

  return (
    <Field>
      <Listbox value={selectedItem} by="name" onChange={updateSelection}>
        <ListboxButton>{selectedItem.name}</ListboxButton>
        <ListboxOptions className="dark:bg-grayscale-muted dark:text-grayscale-light absolute z-50 mt-1 max-h-60 w-full overflow-auto rounded-xl bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none">
          {items.map((item) => (
            <ListboxOption
              key={item.id}
              className={({ focus }) =>
                clsx(
                  focus ? 'bg-primary-grapefruit-200 text-white' : '',
                  'relative cursor-default select-none py-2 pl-3 pr-9'
                )
              }
              value={item}
            >
              {({ focus, selected }) => (
                <>
                  <span
                    className={clsx(
                      selected ? 'font-semibold' : 'font-normal',
                      'block truncate'
                    )}
                  >
                    {item.name}
                  </span>

                  {selected ? (
                    <span
                      className={clsx(
                        focus ? 'text-white' : 'text-primary-grapefruit-200',
                        'absolute inset-y-0 right-0 flex items-center pr-4'
                      )}
                    ></span>
                  ) : null}
                </>
              )}
            </ListboxOption>
          ))}
        </ListboxOptions>
      </Listbox>
    </Field>
  )
}

export default ListBox

If I add an anchor to ListboxOptions it seems to start to work again, pretty unexpected for a bugfix release?

Describe your issue

I still get a listbox and can seemingly click items, but they never get selected. I would guess I end up clicking stuff above it.

@Trinidus
Copy link

Trinidus commented Sep 9, 2024

Same problem here. Tried to fix it with anchors but unfortunately I am not able to fix design issues in some cases because of the auto-portal of ListboxOptions with anchor set...

@RobinMalfait RobinMalfait self-assigned this Sep 9, 2024
RobinMalfait added a commit that referenced this issue Sep 9, 2024
This PR fixes an issue where the `ListboxOptions` component was
incorrectly marked as `inert`.

We only mark the other elements on the page as `inert` once the
`Listbox` is in a visible state. The issue is that the
`data.optionsElement` (a reference to the DOM node) was not populated
with the actual DOM node yet at the time the `useInertOthers(…)` hook
was applied.

Due to the usage of `useEvent(…)`, instead of `useCallback(…)` the
internal `useEffect(…)` hook didn't re-run because the `allowed`
function was already stable.

With this fix, the `allowed` function will change whenever its
dependencies change.

Fixes: #3464
@RobinMalfait
Copy link
Member

RobinMalfait commented Sep 9, 2024

Hey! Thanks for the bug report.

This should be fixed by #3466, and has been released in the latest release (2.1.6).

You can try it using:

  • npm install @headlessui/react@latest.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants