Creative Tim UICreative Tim UI

Shadcn Popover

PreviousNext

A floating panel that appears on top of the content, triggered by a button or other interactive element, perfect for displaying additional information or actions.

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

export function PopoverDemo() {
  return (
    <div className="min-h-28">
      <Popover>
        <PopoverTrigger asChild>
          <Button>Open</Button>
        </PopoverTrigger>
        <PopoverContent className="max-w-sm">
          <p className="text-foreground text-sm">
            This is a very beautiful popover, show some love.
          </p>
        </PopoverContent>
      </Popover>
    </div>
  )
}

Installation

pnpm dlx @creative-tim/ui@latest add popover

Usage

import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover"
<Popover>
  <PopoverTrigger asChild>
    <Button>Open</Button>
  </PopoverTrigger>
  <PopoverContent>
    <p>Content goes here</p>
  </PopoverContent>
</Popover>

Examples

Popover Placement

Popovers with different placement options (top, right, bottom, left) and alignment variations (start, center, end), demonstrating how to position popovers relative to their trigger elements.

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

export function PopoverPlacement() {
  return (
    <div className="flex min-h-[600px] w-full items-center justify-center rounded-lg border p-8">
      <div className="flex flex-col items-center gap-6">
        <div className="flex gap-3">
          <Popover>
            <PopoverTrigger asChild>
              <Button>Top</Button>
            </PopoverTrigger>
            <PopoverContent className="max-w-sm" side="top">
              <p className="text-foreground text-sm">
                This is a very beautiful popover, show some love.
              </p>
            </PopoverContent>
          </Popover>
          <Popover>
            <PopoverTrigger asChild>
              <Button>Top Start</Button>
            </PopoverTrigger>
            <PopoverContent className="max-w-sm" side="top" align="start">
              <p className="text-foreground text-sm">
                This is a very beautiful popover, show some love.
              </p>
            </PopoverContent>
          </Popover>
          <Popover>
            <PopoverTrigger asChild>
              <Button>Top End</Button>
            </PopoverTrigger>
            <PopoverContent className="max-w-sm" side="top" align="end">
              <p className="text-foreground text-sm">
                This is a very beautiful popover, show some love.
              </p>
            </PopoverContent>
          </Popover>
        </div>

        <div className="flex items-center gap-12">
          <div className="flex flex-col gap-3">
            <Popover>
              <PopoverTrigger asChild>
                <Button>Left</Button>
              </PopoverTrigger>
              <PopoverContent className="max-w-sm" side="left">
                <p className="text-foreground text-sm">
                  This is a very beautiful popover, show some love.
                </p>
              </PopoverContent>
            </Popover>
            <Popover>
              <PopoverTrigger asChild>
                <Button>Left Start</Button>
              </PopoverTrigger>
              <PopoverContent className="max-w-sm" side="left" align="start">
                <p className="text-foreground text-sm">
                  This is a very beautiful popover, show some love.
                </p>
              </PopoverContent>
            </Popover>
            <Popover>
              <PopoverTrigger asChild>
                <Button>Left End</Button>
              </PopoverTrigger>
              <PopoverContent className="max-w-sm" side="left" align="end">
                <p className="text-foreground text-sm">
                  This is a very beautiful popover, show some love.
                </p>
              </PopoverContent>
            </Popover>
          </div>

          <div className="flex flex-col gap-3">
            <Popover>
              <PopoverTrigger asChild>
                <Button>Right</Button>
              </PopoverTrigger>
              <PopoverContent className="max-w-sm" side="right">
                <p className="text-foreground text-sm">
                  This is a very beautiful popover, show some love.
                </p>
              </PopoverContent>
            </Popover>
            <Popover>
              <PopoverTrigger asChild>
                <Button>Right Start</Button>
              </PopoverTrigger>
              <PopoverContent className="max-w-sm" side="right" align="start">
                <p className="text-foreground text-sm">
                  This is a very beautiful popover, show some love.
                </p>
              </PopoverContent>
            </Popover>
            <Popover>
              <PopoverTrigger asChild>
                <Button>Right End</Button>
              </PopoverTrigger>
              <PopoverContent className="max-w-sm" side="right" align="end">
                <p className="text-foreground text-sm">
                  This is a very beautiful popover, show some love.
                </p>
              </PopoverContent>
            </Popover>
          </div>
        </div>

        <div className="flex gap-3">
          <Popover>
            <PopoverTrigger asChild>
              <Button>Bottom</Button>
            </PopoverTrigger>
            <PopoverContent className="max-w-sm" side="bottom">
              <p className="text-foreground text-sm">
                This is a very beautiful popover, show some love.
              </p>
            </PopoverContent>
          </Popover>
          <Popover>
            <PopoverTrigger asChild>
              <Button>Bottom Start</Button>
            </PopoverTrigger>
            <PopoverContent className="max-w-sm" side="bottom" align="start">
              <p className="text-foreground text-sm">
                This is a very beautiful popover, show some love.
              </p>
            </PopoverContent>
          </Popover>
          <Popover>
            <PopoverTrigger asChild>
              <Button>Bottom End</Button>
            </PopoverTrigger>
            <PopoverContent className="max-w-sm" side="bottom" align="end">
              <p className="text-foreground text-sm">
                This is a very beautiful popover, show some love.
              </p>
            </PopoverContent>
          </Popover>
        </div>
      </div>
    </div>
  )
}

Popover with Description

A popover that displays detailed information including a title, description, status badge, and metadata indicators, perfect for showing repository information, project details, or item descriptions.

import { CheckCircle2, Star } from "lucide-react"

import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Chip } from "@/components/ui/chip"
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover"

export function PopoverWithDescription() {
  return (
    <div className="min-h-48">
      <Popover>
        <PopoverTrigger asChild>
          <Button>Repository Info</Button>
        </PopoverTrigger>
        <PopoverContent className="max-w-sm">
          <div className="mb-1 flex items-center gap-2">
            <a
              href="#"
              className="text-foreground hover:text-primary font-bold"
            >
              @creative-tim-ui
            </a>
            <Chip size="sm" variant="default">
              Public
            </Chip>
          </div>
          <p className="text-foreground text-sm">
            Creative Tim UI is an easy-to-use components library for Tailwind
            CSS and shadcn/ui.
          </p>
          <div className="mt-4 flex items-center gap-4">
            <div className="flex items-center gap-1.5">
              <span className="h-2.5 w-2.5 rounded-full bg-blue-500" />
              <p className="text-foreground text-xs">TypeScript</p>
            </div>
            <div className="flex items-center gap-1.5">
              <Star className="h-4 w-4 text-yellow-500" />
              <p className="text-foreground text-xs">1,480</p>
            </div>
            <div className="flex items-center gap-1.5">
              <CheckCircle2 className="h-4 w-4 text-green-500" />
              <p className="text-foreground text-xs">Verified</p>
            </div>
          </div>
        </PopoverContent>
      </Popover>
    </div>
  )
}

Popover with Image

A popover that combines text content with an image, creating a rich information display that's ideal for product previews, feature highlights, or detailed descriptions with visual context.

import { ArrowRight } from "lucide-react"

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

export function PopoverWithImage() {
  return (
    <div className="min-h-80">
      <Popover>
        <PopoverTrigger asChild>
          <Button>More Info</Button>
        </PopoverTrigger>
        <PopoverContent className="grid w-[30rem] grid-cols-2 gap-4">
          <div className="pl-1">
            <h3 className="text-foreground mb-1 font-semibold">
              Creative Tim UI
            </h3>
            <p className="text-foreground mb-4 block text-sm">
              Creative Tim UI is an easy to use components library for Tailwind
              CSS and shadcn/ui. It features multiple React and HTML components,
              all written with Tailwind CSS classes and shadcn/ui guidelines.
            </p>
            <Button asChild size="sm">
              <a href="#popover-with-image">
                Read More
                <ArrowRight className="ml-1.5 h-4 w-4" />
              </a>
            </Button>
          </div>
          <img
            src="https://raw.githubusercontent.com/creativetimofficial/public-assets/master/ct-assets/mt-demo.jpg"
            alt="image"
            className="h-auto max-h-[220px] w-full rounded-[5px] object-cover"
          />
        </PopoverContent>
      </Popover>
    </div>
  )
}

Contact Popover

A popover that displays contact information including profile picture, name, role, company, phone, and email, perfect for user profiles, team member cards, or contact directories.

import { Building2, Mail, Phone } from "lucide-react"

import { Avatar, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover"

export function ContactPopover() {
  return (
    <div className="min-h-60">
      <Popover>
        <PopoverTrigger asChild>
          <Button>Contact Info</Button>
        </PopoverTrigger>
        <PopoverContent className="max-w-sm p-1">
          <div className="space-y-1">
            <div className="flex items-center gap-3 p-2">
              <Avatar>
                <AvatarImage
                  src="https://images.unsplash.com/photo-1750223642533-1b74b17edae8?auto=format&fit=crop&q=80&w=400&h=400"
                  alt="profile-picture"
                />
              </Avatar>
              <div>
                <p className="text-foreground font-semibold">Alex Andrew</p>
                <p className="text-muted-foreground text-sm">General Manager</p>
              </div>
            </div>
            <hr className="border-border" />
            <div className="flex items-center gap-3 p-2">
              <Building2 className="text-muted-foreground h-[18px] w-[18px]" />
              <p className="text-foreground text-sm">ABC Construction</p>
            </div>
            <div className="flex items-center gap-3 p-2">
              <Phone className="text-muted-foreground h-[18px] w-[18px]" />
              <p className="text-foreground text-sm">00 123 456 789</p>
            </div>
            <div className="flex items-center gap-3 p-2">
              <Mail className="text-muted-foreground h-[18px] w-[18px]" />
              <p className="text-foreground text-sm">[email protected]</p>
            </div>
          </div>
        </PopoverContent>
      </Popover>
    </div>
  )
}

Profile Info Popover

A comprehensive profile popover that includes avatar, follow button, username, bio, and location information, ideal for social media interfaces, user directories, or profile previews.

import { Building2, MapPin } from "lucide-react"

import { Avatar, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover"

export function ProfileInfoPopover() {
  return (
    <div className="min-h-72">
      <Popover>
        <PopoverTrigger asChild>
          <Button>Profile Info</Button>
        </PopoverTrigger>
        <PopoverContent className="max-w-sm">
          <div className="mb-2 flex items-center justify-between gap-4">
            <Avatar>
              <AvatarImage
                src="https://images.unsplash.com/photo-1750223642533-1b74b17edae8?auto=format&fit=crop&q=80&w=400&h=400"
                alt="profile-picture"
              />
            </Avatar>
            <Button size="sm" className="mr-2">
              Follow
            </Button>
          </div>
          <div className="text-foreground mb-1 flex items-center gap-2 font-bold">
            <span>Alex Andrew</span> •{" "}
            <a href="#profile-info-popover" className="hover:underline">
              @alex
            </a>
          </div>
          <p className="text-foreground text-sm">
            Frontend Developer • Major interest in Web Development: motivated to
            achieve measurable results, to deepen my knowledge and improve my
            skills.
          </p>
          <hr className="border-border my-2.5" />
          <div className="flex items-center gap-8">
            <p className="text-foreground flex items-center gap-1.5 text-xs">
              <MapPin className="h-4 w-4" />
              United Kingdom
            </p>
            <p className="text-foreground flex items-center gap-1.5 text-xs">
              <Building2 className="h-4 w-4" />
              Material Tailwind
            </p>
          </div>
        </PopoverContent>
      </Popover>
    </div>
  )
}

Subscription Popover

A popover that contains a subscription form with email input and submit button, perfect for newsletter signups, email capture, or subscription prompts.

import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover"

export function SubscriptionPopover() {
  return (
    <div className="min-h-40">
      <Popover>
        <PopoverTrigger asChild>
          <Button>Subscribe</Button>
        </PopoverTrigger>
        <PopoverContent className="w-96">
          <h3 className="text-foreground font-bold">Newsletter Subscription</h3>
          <form
            action="#"
            className="mt-3 flex w-full items-center justify-center gap-2"
          >
            <Input type="email" placeholder="[email protected]" />
            <Button type="submit">Subscribe</Button>
          </form>
        </PopoverContent>
      </Popover>
    </div>
  )
}

Props

The popover component is built using Radix UI's Popover primitive and accepts the following props:

Popover (Root Component)

PropTypeDefaultDescription
openboolean-The controlled open state of the popover
defaultOpenboolean-The default open state of the popover (uncontrolled)
onOpenChangefunction-Event handler called when the open state changes
modalbooleantrueWhen true, prevents interaction with elements outside the popover

PopoverTrigger

PropTypeDefaultDescription
asChildbooleanfalseWhen true, merges props with the child element
classNamestring-Additional CSS classes to apply to the trigger
childrenReactNode-The element that triggers the popover

PopoverContent

PropTypeDefaultDescription
side"top" | "right" | "bottom" | "left""bottom"The side of the trigger where the popover should appear
align"start" | "center" | "end""center"The alignment of the popover relative to the trigger
sideOffsetnumber4The distance in pixels from the trigger
alignOffsetnumber0The distance in pixels to offset the alignment
classNamestring-Additional CSS classes to apply to the content container
childrenReactNode-The content to display inside the popover

Accessibility

The popover component follows accessibility best practices:

  • Uses proper ARIA attributes for screen readers
  • Supports keyboard navigation (Escape to close)
  • Focus management ensures focus is trapped within the popover when modal
  • Focus is returned to the trigger when the popover closes
  • Works with assistive technologies through Radix UI primitives

Best Practices

  • Use popovers for contextual information that doesn't require immediate attention
  • Keep popover content concise and focused
  • Provide clear visual indicators for the trigger element
  • Use appropriate placement to avoid covering important content
  • Consider mobile responsiveness when positioning popovers
  • Ensure popover content is accessible and keyboard navigable
  • Use modal={false} when you want users to interact with content behind the popover
  • Test with screen readers to ensure proper accessibility

The popover component provides a clean and accessible way to display additional information or actions. It's ideal for tooltips, contextual menus, information cards, forms, and any interface where you need to show supplementary content without navigating away from the current page.