import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"
export function PopoverDemo() {
return (
<Popover>
<PopoverTrigger render={<Button variant="outline" />}>
Open popover
</PopoverTrigger>
<PopoverContent className="w-80">
<div className="grid gap-4">
<div className="space-y-2">
<h4 className="leading-none font-medium">Dimensions</h4>
<p className="text-sm text-muted-foreground">
Set the dimensions for the layer.
</p>
</div>
<div className="grid gap-2">
<div className="grid grid-cols-3 items-center gap-4">
<Label htmlFor="width">Width</Label>
<Input
id="width"
defaultValue="100%"
className="col-span-2 h-8"
/>
</div>
<div className="grid grid-cols-3 items-center gap-4">
<Label htmlFor="maxWidth">Max. width</Label>
<Input
id="maxWidth"
defaultValue="300px"
className="col-span-2 h-8"
/>
</div>
<div className="grid grid-cols-3 items-center gap-4">
<Label htmlFor="height">Height</Label>
<Input
id="height"
defaultValue="25px"
className="col-span-2 h-8"
/>
</div>
<div className="grid grid-cols-3 items-center gap-4">
<Label htmlFor="maxHeight">Max. height</Label>
<Input
id="maxHeight"
defaultValue="none"
className="col-span-2 h-8"
/>
</div>
</div>
</div>
</PopoverContent>
</Popover>
)
}Installation
npx shadcn@latest add @fulldev/popover
Usage
import {
Popover,
PopoverContent,
PopoverDescription,
PopoverHeader,
PopoverTitle,
PopoverTrigger,
} from "@/components/ui/popover"
<Popover>
<PopoverTrigger render={<Button variant="outline" />}>
Open Popover
</PopoverTrigger>
<PopoverContent>
<PopoverHeader>
<PopoverTitle>Title</PopoverTitle>
<PopoverDescription>Description text here.</PopoverDescription>
</PopoverHeader>
</PopoverContent>
</Popover>
Composition
Use the following composition to build a Popover:
Popover
├── PopoverTrigger
└── PopoverContent
Basic
A simple popover with a header, title, and description.
import { Button } from "@/components/ui/button"
import {
Popover,
PopoverContent,
PopoverDescription,
PopoverHeader,
PopoverTitle,
PopoverTrigger,
} from "@/components/ui/popover"
export function PopoverBasic() {
return (
<>
<Popover>
<PopoverTrigger render={<Button variant="outline" className="w-fit" />}>
Open Popover
</PopoverTrigger>
<PopoverContent align="start">
<PopoverHeader>
<PopoverTitle>Dimensions</PopoverTitle>
<PopoverDescription>
Set the dimensions for the layer.
</PopoverDescription>
</PopoverHeader>
</PopoverContent>
</Popover>
</>
)
}Align
Use the align prop on PopoverContent to control the horizontal alignment.
import { Button } from "@/components/ui/button"
import {
Popover,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover"
export function PopoverAlignments() {
return (
<>
<div className="flex gap-6">
<Popover>
<PopoverTrigger render={<Button variant="outline" size="sm" />}>
Start
</PopoverTrigger>
<PopoverContent align="start" className="w-40">
Aligned to start
</PopoverContent>
</Popover>
<Popover>
<PopoverTrigger render={<Button variant="outline" size="sm" />}>
Center
</PopoverTrigger>
<PopoverContent align="center" className="w-40">
Aligned to center
</PopoverContent>
</Popover>
<Popover>
<PopoverTrigger render={<Button variant="outline" size="sm" />}>
End
</PopoverTrigger>
<PopoverContent align="end" className="w-40">
Aligned to end
</PopoverContent>
</Popover>
</div>
</>
)
}With Form
A popover with form fields inside.
import { Button } from "@/components/ui/button"
import { Field, FieldGroup, FieldLabel } from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import {
Popover,
PopoverContent,
PopoverDescription,
PopoverHeader,
PopoverTitle,
PopoverTrigger,
} from "@/components/ui/popover"
export function PopoverForm() {
return (
<>
<Popover>
<PopoverTrigger render={<Button variant="outline" />}>
Open Popover
</PopoverTrigger>
<PopoverContent className="w-64" align="start">
<PopoverHeader>
<PopoverTitle>Dimensions</PopoverTitle>
<PopoverDescription>
Set the dimensions for the layer.
</PopoverDescription>
</PopoverHeader>
<FieldGroup className="gap-4">
<Field orientation="horizontal">
<FieldLabel htmlFor="width" className="w-1/2">
Width
</FieldLabel>
<Input id="width" defaultValue="100%" />
</Field>
<Field orientation="horizontal">
<FieldLabel htmlFor="height" className="w-1/2">
Height
</FieldLabel>
<Input id="height" defaultValue="25px" />
</Field>
</FieldGroup>
</PopoverContent>
</Popover>
</>
)
}RTL
To enable RTL support in shadcn/ui, see the RTL configuration guide.
"use client"
import { Button } from "@/components/ui/button"
import {
Popover,
PopoverContent,
PopoverDescription,
PopoverHeader,
PopoverTitle,
PopoverTrigger,
} from "@/components/ui/popover"
import {
useTranslation,
type Translations,
} from "@/components/language-selector"
const translations: Translations = {
en: {
dir: "ltr",
values: {
title: "Dimensions",
description: "Set the dimensions for the layer.",
"inline-start": "Inline Start",
left: "Left",
top: "Top",
bottom: "Bottom",
right: "Right",
"inline-end": "Inline End",
},
},
ar: {
dir: "rtl",
values: {
title: "الأبعاد",
description: "تعيين الأبعاد للطبقة.",
"inline-start": "بداية السطر",
left: "يسار",
top: "أعلى",
bottom: "أسفل",
right: "يمين",
"inline-end": "نهاية السطر",
},
},
he: {
dir: "rtl",
values: {
title: "מימדים",
description: "הגדר את המימדים לשכבה.",
"inline-start": "תחילת השורה",
left: "שמאל",
top: "למעלה",
bottom: "למטה",
right: "ימין",
"inline-end": "סוף השורה",
},
},
}
const physicalSides = ["left", "top", "bottom", "right"] as const
const logicalSides = ["inline-start", "inline-end"] as const
export function PopoverRtl() {
const { dir, t } = useTranslation(translations, "ar")
return (
<div className="grid gap-4">
<div className="flex flex-wrap justify-center gap-2">
{physicalSides.map((side) => (
<Popover key={side}>
<PopoverTrigger render={<Button variant="outline" />}>
{t[side]}
</PopoverTrigger>
<PopoverContent side={side} dir={dir}>
<PopoverHeader>
<PopoverTitle>{t.title}</PopoverTitle>
<PopoverDescription>{t.description}</PopoverDescription>
</PopoverHeader>
</PopoverContent>
</Popover>
))}
</div>
<div className="flex flex-wrap justify-center gap-2">
{logicalSides.map((side) => (
<Popover key={side}>
<PopoverTrigger render={<Button variant="outline" />}>
{t[side]}
</PopoverTrigger>
<PopoverContent side={side} dir={dir}>
<PopoverHeader>
<PopoverTitle>{t.title}</PopoverTitle>
<PopoverDescription>{t.description}</PopoverDescription>
</PopoverHeader>
</PopoverContent>
</Popover>
))}
</div>
</div>
)
}API Reference
Source: react/src/components/ui/popover.tsx
See the Base UI Popover documentation.