Overlays
Popover.
A small floating panel anchored to a trigger, for quick settings and short forms.
import { SlidersHorizontalIcon } from "lucide-react";
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 default function PopoverDemo() {
return (
<Popover>
<PopoverTrigger asChild>
<Button variant="secondary">
<SlidersHorizontalIcon />
Turtle route
</Button>
</PopoverTrigger>
<PopoverContent className="w-80">
<div className="grid gap-4">
<div className="grid gap-1">
<p className="font-mono text-[10px] font-semibold tracking-[0.2em] text-success uppercase">Route</p>
<p className="text-sm text-muted-foreground">Set the mining area for turtle 07.</p>
</div>
<div className="grid gap-2.5">
{[
["route-width", "Width", "16"],
["route-depth", "Depth", "32"],
["route-fuel", "Fuel stop", "every 64"],
].map(([id, label, value]) => (
<div key={id} className="grid grid-cols-3 items-center gap-3">
<Label htmlFor={id}>{label}</Label>
<Input id={id} defaultValue={value} className="col-span-2 h-8" />
</div>
))}
</div>
</div>
</PopoverContent>
</Popover>
);
}Installation#
With the CLI
$npx lanterncn add popoverThis also installs the Lantern theme and any Lantern UI components it depends on. The shadcn CLI works directly too: npx shadcn@latest add httptim/lantern-ui/popover. See Installation if your project is not set up yet.
Manually
Install the dependencies
npm install radix-uiCopy the source into your project
components/ui/popover.tsx"use client"; import * as React from "react"; import { Popover as PopoverPrimitive } from "radix-ui"; import { cn } from "@/lib/utils"; function Popover({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Root>) { return <PopoverPrimitive.Root data-slot="popover" {...props} />; } function PopoverTrigger({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Trigger>) { return <PopoverPrimitive.Trigger data-slot="popover-trigger" {...props} />; } function PopoverContent({ className, align = "center", sideOffset = 6, ...props }: React.ComponentProps<typeof PopoverPrimitive.Content>) { return ( <PopoverPrimitive.Portal> <PopoverPrimitive.Content data-slot="popover-content" align={align} sideOffset={sideOffset} className={cn( "z-50 w-72 max-w-[calc(100vw-1.5rem)] origin-(--radix-popover-content-transform-origin) rounded-lg border bg-popover p-4 text-popover-foreground shadow-block-sm outline-none", "data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95", "data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", className, )} {...props} /> </PopoverPrimitive.Portal> ); } function PopoverAnchor({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Anchor>) { return <PopoverPrimitive.Anchor data-slot="popover-anchor" {...props} />; } function PopoverClose({ ...props }: React.ComponentProps<typeof PopoverPrimitive.Close>) { return <PopoverPrimitive.Close data-slot="popover-close" {...props} />; } export { Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger };Update the import paths to match your project
The source imports
cnfrom@/lib/utils.
Usage#
import {
Popover,
PopoverAnchor,
PopoverClose,
PopoverContent,
PopoverTrigger,
} from "@/components/ui/popover";<Popover>
<PopoverTrigger asChild>
<Button variant="secondary">Open</Button>
</PopoverTrigger>
<PopoverContent>Place content here.</PopoverContent>
</Popover>