tetra-ui Logotetra ui

Popover

Displays content in a portal relative to the triggering button element.

popover

Installation

npx shadcn@latest add @tetra-ui/popover

Usage

First ensure that you have the PortalHost component in your root layout.

import { PortalHost } from "@/components/ui/portal";

export default function RootLayout() {
  return (
    <>
      <Stack />
      <PortalHost />
    </>
  );
}
import { Button, ButtonText } from "@/components/ui/button";
import {
  Popover,
  PopoverContent,
  PopoverOverlay,
  PopoverPortal,
  PopoverTrigger,
} from "@/components/ui/popover";
<Popover>
  <PopoverTrigger asChild>
    <Button>
      <ButtonText>Open</ButtonText>
    </Button>
  </PopoverTrigger>
  <PopoverPortal>
    <PopoverOverlay />
    <PopoverContent>
      <Text>Popover Content</Text>
    </PopoverContent>
  </PopoverPortal>
</Popover>

Positioning

Control placement with side and align on PopoverContent:

<PopoverContent side="top" align="center">
  <Text>Tooltip above the trigger</Text>
</PopoverContent>

Supported values:

  • side: "top" | "bottom" | "left" | "right"
  • align: "start" | "center" | "end" (defaults to "center")

Use sideOffset and alignOffset to fine-tune distance from the trigger. By default width="fit" sizes to the content and wraps long text at 280px so the popover stays compact. Set width="trigger" to match the trigger width, or pass a percentage or pixel value.

Without overlay

Omit PopoverOverlay for lightweight tooltips that don't dim the background:

<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline">Open</Button>
  </PopoverTrigger>
  <PopoverPortal>
    <PopoverContent>
      <Text>No backdrop</Text>
      <PopoverClose asChild>
        <Button size="sm" variant="link">Close</Button>
      </PopoverClose>
    </PopoverContent>
  </PopoverPortal>
</Popover>

Controlled

Pass open and onOpenChange for controlled state:

const [open, setOpen] = useState(false);

<Popover open={open} onOpenChange={setOpen}>
  {/* ... */}
</Popover>

Scrollable content

Wrap long content in a ScrollView and constrain the popover height:

<PopoverContent className="h-1/2 p-0" width="50%">
  <ScrollView className="p-4">
    {/* long content */}
  </ScrollView>
</PopoverContent>

API Reference

Popover

Root open state. Controlled when open is set.

Prop

Type

PopoverTrigger

Extends React Native Pressable props. Measures itself and opens the popover on press. Must be used within Popover.

Prop

Type

PopoverClose

Extends React Native Pressable props. Closes the popover on press. Must be used within Popover.

Prop

Type

PopoverPortal

Accepts Portal props. Renders nothing when closed. Must be used within Popover.

Prop

Type

PopoverOverlay

Dimmed backdrop. Must be used within Popover (typically inside PopoverPortal).

Prop

Type

PopoverContent

Extends React Native View props. Positions relative to the trigger. Must be used within Popover (typically inside PopoverPortal).

Prop

Type

On this page