headlessui: Dialog throws error if there are no focusable elements

I get the following error if I create a Dialog with no interactive components (just text): Error: There are no focusable elements inside the <FocusTrap />

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 53
  • Comments: 29

Most upvoted comments

I found a way around that.

simply add a ref to the dialog and to a div inside the body UPDATE: found this mentioned in the docs https://headlessui.dev/react/dialog#managing-focus-within-your-dialog

let refDiv = useRef(null)

<Dialog
	initialFocus={refDiv}
	as="div"
	className="fixed inset-0 z-10 overflow-y-auto bg-gray-500 bg-opacity-60"
	onClose={closeModal}
>

<div ref={refDiv}>
    {children}
</div>


You have to set initialFocus and also use it in your return code.

Based on the example code @ https://headlessui.dev/react/dialog#rendering-to-a-portal they forgot to place ref={cancelButtonRef} inside an element (doesn’t have to be a button, could be a div or so too).

const cancelButtonRef = useRef();

...

initialFocus={cancelButtonRef}

...

<button
	ref={cancelButtonRef}
	type="button"
	className="inline-flex justify-center px-4 py-2 text-sm font-medium text-blue-900 bg-blue-100 border border-transparent rounded-md hover:bg-blue-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500"
	onClick={closeModal}
>
	Got it, thanks!
</button>

This error also happens on Next.js’s hot reload. However, after you make a hard refresh, it works again. I’ll try to make a sample repo later.

Fixed with this workaround, added a button. image

I’m having the same issue but i have no clue whats wrong im using tailwindui’s new react code for the navbar

Re: FIXED IT!

for anyone else having same issue please go to https://headlessui.dev/react/dialog#managing-focus-within-your-dialog and see the Managing focus within your dialog section

add the ref and initialFocus to the elements as shown and the navigation issue should be fixed!

@RobinMalfait - I’ve been getting this error in @headlessui/react when the component re-renders and then isOpen is set to true using state.

I’m able to work around this by conditionally rendering my component instead of letting the open prop show and hide the modal.

Example of my workaround:

{isOpenState && (
    <Dialog open={true}>dialog content</Dialog>
)}

I’d much prefer to follow the docs and rely on the open prop, so I’d like to figure out what’s going wrong.


Does this issue sound familiar? Do you think it’s something with my usage?

I’ll post another comment if I figure out what’s wrong, and I’ll open a PR if it’s something in the Dialog component.

PS: +1 for this accessibility safeguard!

What @1trackprojects1 has stated, your Dialog needs a focusable element within it. You can use a ref, or a semantic close button which is an implicit focusable element.

For example you can add this to the top of your modal:

<div className="absolute top-1 right-1">
  <button
    type="button"
    className="inline-flex justify-center px-2 py-1 text-sm font-medium text-gray-200 bg-gray-900 border border-transparent rounded hover:bg-gray-700 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-blue-500"
    onClick={closeModal}
  >
    X
  </button>
</div>

And you won’t see this error.

This is very bad, what if I don’t want a focusable element inside my dialog? Like a dialog only for showing text for example?

I am getting the same error when trying to use even the Basic example of Dialog component from @headlessui/react (https://headlessui.dev/react/dialog).

Other components work fine. And I am using in NextJS.

My use case was for displaying a Help Dialog when someone clicks an information bubble in the application. I ended up adding a close button to get around the issue, and you’re probably right that it’s good practice to make sure there’s something interactive on the dialog.

It might be worth adding this to the documentation so that people know this is intended.

I’m having the same issue, but have tried pretty much all the solutions above. The Dialog crashes with the message above Error: There are no focusable elements inside the <FocusTrap /> only when a particular <input type="checkbox" /> is unchecked. Any idea what could be the issue here?

I was running into the same issue until I realized I was trying to display two Dialogs at once based upon the same state. Also, it’s good practice to set an initial state using the useRef() hook when having more than Dialog on one page even though they might be in separate components.

I am getting this error when I do have a focusable element inside a dialog. Does the focusable element need to not be nested?

I met the same issue. I am working on Nextjs.

I tried to replace an existing modal/dialog system. Where the content is loaded in an asynchronous way

I had to add a fake focus ref and then change it when the content is loaded, otherwise that error log will block my render

  public render(): JSX.Element {
    const isVisible = !!this.props.show
    
    return (
      <Dialog initialFocus={this.fakeRef} open={isVisible} onClose={() => this.state.isOpen = false} className="bg-background-tertiary fixed inset-0 m-28 overflow-y-auto z-10">
        <Dialog.Overlay />
        <div className='menu-layer' ref={this.setMenuLayer} />
        <div ref={this.fakeRef} tabIndex={-1} {...this.props}>
          {this.mMenuLayer !== null ? this.props.children : null}
        </div>
      </Dialog>
    );
  }

Installing via yarn add @headlessui/react does not provide Dialog component. How did you install it?

@jamby77 you can use it with:

npm install @headlessui/react@dev

or

yarn add @headlessui/react@dev

I am seeing this warning when I open a modal that was not rendered on initial page load, but appears later. The modal has a button inside, but when I try to open it it throws the warning and does not appear. This doesn’t happen if the modal is present on initial page load.

When we put <Select /> component of material-ui in modal, it causes error.

Installing via yarn add @headlessui/react does not provide Dialog component. How did you install it?