ComponentsPopover
Popover
Show extra content next to a button or other trigger.
On this page
Use this component from the local workspace package. Follow the setup guide first. A public npm package and registry are not available yet.
View registry filesImport the component into your page or component file.
import {
Popover,
PopoverClose,
PopoverContent,
PopoverHeader,
PopoverTitle,
PopoverTrigger,
} from "@dethink/components";Try the examples, then open the code to use them in your app.
Basic
Trigger, titled content, and a footer close button.
Show sourceexamples/popover/basic.tsx
"use client";
import {
Popover,
PopoverClose,
PopoverContent,
PopoverDescription,
PopoverFooter,
PopoverHeader,
PopoverTitle,
PopoverTrigger,
} from "@dethink/components";
export function PopoverBasic() {
return (
<div className="flex justify-center">
<Popover>
<PopoverTrigger variant="outline">Share dashboard</PopoverTrigger>
<PopoverContent>
<PopoverHeader>
<PopoverTitle>Share dashboard</PopoverTitle>
<PopoverDescription>
Anyone in the workspace can view. Focus moves inside and returns
to the trigger on close.
</PopoverDescription>
</PopoverHeader>
<PopoverFooter>
<PopoverClose variant="outline">Done</PopoverClose>
</PopoverFooter>
</PopoverContent>
</Popover>
</div>
);
}Placement and arrow
placement picks the side; showArrow points the panel at its trigger. Sides flip automatically when space runs out.
Show sourceexamples/popover/placement.tsx
"use client";
import {
Popover,
PopoverContent,
PopoverDescription,
PopoverTrigger,
} from "@dethink/components";
const placements = ["top", "right", "bottom", "left"] as const;
export function PopoverPlacement() {
return (
<div className="flex flex-wrap justify-center gap-3">
{placements.map((placement) => (
<Popover key={placement}>
<PopoverTrigger variant="soft" size="sm">
{placement}
</PopoverTrigger>
<PopoverContent placement={placement} showArrow>
<PopoverDescription className="px-[var(--dt-space-4)] py-[var(--dt-space-3)]">
Anchored {placement} with an arrow.
</PopoverDescription>
</PopoverContent>
</Popover>
))}
</div>
);
}Examples that combine components for common tasks.
Inline edit
The value on the page is the trigger. The controlled popover edits a draft, so Cancel discards and Save commits — the displayed value never flickers mid-edit.
Monthly spend limit
Alerts fire at 80% of the limit.
Show sourceexamples/popover/recipe-inline-edit.tsx
"use client";
import { useState } from "react";
import {
Field,
FieldControl,
FieldLabel,
Input,
Popover,
PopoverClose,
PopoverContent,
PopoverFooter,
PopoverHeader,
PopoverTitle,
PopoverTrigger,
} from "@dethink/components";
/**
* Inline edit: the value on the page is the trigger. A controlled popover
* carries a draft, so Cancel discards and Save commits — the page value
* never flickers mid-edit.
*/
export function PopoverRecipeInlineEdit() {
const [limit, setLimit] = useState(500);
const [draft, setDraft] = useState(String(limit));
const [open, setOpen] = useState(false);
return (
<div className="border-border mx-auto flex max-w-sm items-center justify-between rounded-lg border px-4 py-3">
<div>
<p className="text-sm font-medium">Monthly spend limit</p>
<p className="text-muted-foreground text-sm">
Alerts fire at 80% of the limit.
</p>
</div>
<Popover
open={open}
onOpenChange={(next) => {
setOpen(next);
if (next) {
setDraft(String(limit));
}
}}
>
<PopoverTrigger variant="ghost" className="font-mono">
${limit}
</PopoverTrigger>
<PopoverContent placement="bottom end">
<PopoverHeader>
<PopoverTitle>Edit spend limit</PopoverTitle>
</PopoverHeader>
<div className="px-[var(--dt-space-4)] py-[var(--dt-space-2)]">
<Field id="limit-draft">
<FieldLabel>Limit (USD)</FieldLabel>
<FieldControl asChild>
<Input
type="number"
min={0}
value={draft}
onChange={(event) => setDraft(event.target.value)}
/>
</FieldControl>
</Field>
</div>
<PopoverFooter>
<PopoverClose variant="ghost">Cancel</PopoverClose>
<PopoverClose
onPress={() => setLimit(Math.max(0, Number(draft) || 0))}
>
Save
</PopoverClose>
</PopoverFooter>
</PopoverContent>
</Popover>
</div>
);
}Popover coordinates trigger and content; content carries placement and arrow options.
| Prop | What it does | Default |
|---|---|---|
open / defaultOpen / onOpenChangeboolean / boolean / (open) => void | Controlled or uncontrolled visibility. | Not set |
PopoverTrigger / PopoverClosevariant + size (Button API) | Anchor button and close buttons; PopoverClose also accepts onPress for save-on-close patterns. | Not set |
PopoverContent — placement"top" | "bottom" | "left" | "right" (+ " start"/" end") | Preferred side and alignment relative to the trigger. | "bottom" |
PopoverContent — showArrowboolean | Renders a pointing arrow tied to the trigger. | false |
PopoverContent — offsetnumber | Distance in pixels between trigger and panel. | 8 |
PopoverHeader / PopoverTitle / PopoverDescription / PopoverFootersection components | Anatomy pieces; title and description label the popover dialog. | Not set |