HextaUI

Popover: Modal

With modal, page scroll is locked and outside clicks only dismiss the popover. Render a <PopoverClose /> inside so focus can be trapped and touch screen readers have a way out.

import { IconX } from "@tabler/icons-react"

import { Button } from "@/components/ui/button"
import {
  Popover,
  PopoverClose,
  PopoverContent,
  PopoverDescription,
  PopoverHeader,
  PopoverTitle,
  PopoverTrigger,
} from "@/components/ui/popover"

export function PopoverModal() {
  return (
    <Popover modal>
      <PopoverTrigger render={<Button variant="outline" />}>
        Modal
      </PopoverTrigger>
      <PopoverContent>
        <div className="flex items-start justify-between gap-2">
          <PopoverHeader>
            <PopoverTitle>Modal popover</PopoverTitle>
            <PopoverDescription>
              Page scroll is locked and outside clicks only dismiss.
            </PopoverDescription>
          </PopoverHeader>
          <PopoverClose
            aria-label="Close"
            render={<Button variant="ghost" size="icon-sm" />}
          >
            <IconX />
          </PopoverClose>
        </div>
      </PopoverContent>
    </Popover>
  )
}

This adds the example as components/examples/popover/modal.tsx, together with the Popover component and the HextaUI theme tokens it needs.

pnpm dlx shadcn@latest add https://hextaui.com/r/popover-modal.json

To add only the component, follow the Popover installation.

Props in this example

The Popover props this example sets, from the API reference.

PropTypeDefault
modaltrue locks page scroll and outside interaction. trap-focus only traps focus.
boolean | "trap-focus"false
PropTypeDefault
render
ReactElement | (props, state) => ReactElement<button>
PropTypeDefault
render
ReactElement | (props, state) => ReactElement<button>

Every prop is in the Popover API reference.

See them all, with keyboard support and accessibility notes, on the Popover page.