HextaUI

Popover: Controlled

Pass open and onOpenChange to drive it from your own state. The second argument tells you why it changed, such as trigger-press, outside-press or escape-key.

Open: false · Last reason: none

"use client"

import * as React from "react"

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

export function PopoverControlled() {
  const [open, setOpen] = React.useState(false)
  const [reason, setReason] = React.useState("none")

  return (
    <div className="flex flex-col items-center gap-3">
      <div className="flex flex-wrap justify-center gap-2">
        <Popover
          open={open}
          onOpenChange={(next, details) => {
            setOpen(next)
            setReason(details.reason)
          }}
        >
          <PopoverTrigger render={<Button variant="outline" />}>
            Controlled
          </PopoverTrigger>
          <PopoverContent>
            <PopoverHeader>
              <PopoverTitle>Controlled</PopoverTitle>
              <PopoverDescription>
                The open state lives in the parent.
              </PopoverDescription>
            </PopoverHeader>
          </PopoverContent>
        </Popover>
        <Button variant="ghost" onClick={() => setOpen(!open)}>
          Toggle from outside
        </Button>
      </div>
      <p className="text-sm text-muted-foreground">
        Open: {String(open)} · Last reason: {reason}
      </p>
    </div>
  )
}

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

pnpm dlx shadcn@latest add https://hextaui.com/r/popover-controlled.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
open
boolean–
onOpenChangedetails.reason says what caused the change.
(open: boolean, details) => void–
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.