Popover

Usage

import { Button } from '@jamie/ui/button'
import { Field, FieldLabel } from '@jamie/ui/field'
import { Input } from '@jamie/ui/input'
import {
  Popover,
  PopoverContent,
  PopoverHeader,
  PopoverTitle,
  PopoverTrigger
} from '@jamie/ui/popover'
import { SlidersHorizontalIcon } from 'lucide-react'
 
export function PopoverDemo() {
  return (
    <Popover>
      <PopoverTrigger render={<Button variant="outline" />}>
        <SlidersHorizontalIcon className="size-4" />
        Filter Meetings
      </PopoverTrigger>
      <PopoverContent className="w-80">
        <PopoverHeader>
          <PopoverTitle>Filter meetings</PopoverTitle>
        </PopoverHeader>
        <div className="flex flex-col gap-3">
          <Field>
            <FieldLabel>From</FieldLabel>
            <Input type="date" />
          </Field>
          <Field>
            <FieldLabel>To</FieldLabel>
            <Input type="date" />
          </Field>
          <Field>
            <FieldLabel>Attendees</FieldLabel>
            <Input placeholder="Search attendees..." />
          </Field>
        </div>
      </PopoverContent>
    </Popover>
  )
}

With Description

Use PopoverTitle and PopoverDescription together for informational popovers.

import { Button } from '@jamie/ui/button'
import {
  Popover,
  PopoverContent,
  PopoverDescription,
  PopoverHeader,
  PopoverTitle,
  PopoverTrigger
} from '@jamie/ui/popover'
import { InfoIcon } from 'lucide-react'
 
export function PopoverWithDescriptionDemo() {
  return (
    <Popover>
      <PopoverTrigger render={<Button variant="ghost" size="icon" />}>
        <InfoIcon className="size-4" />
      </PopoverTrigger>
      <PopoverContent>
        <PopoverHeader>
          <PopoverTitle>Meeting privacy</PopoverTitle>
          <PopoverDescription>
            Only participants and workspace admins can view this meeting&apos;s transcript and
            summary. External shares require explicit permission.
          </PopoverDescription>
        </PopoverHeader>
      </PopoverContent>
    </Popover>
  )
}

Placement

Use the side prop on PopoverContent to control where the popover appears relative to the trigger.

import { Button } from '@jamie/ui/button'
import {
  Popover,
  PopoverContent,
  PopoverDescription,
  PopoverHeader,
  PopoverTitle,
  PopoverTrigger
} from '@jamie/ui/popover'
 
export function PopoverPlacementDemo() {
  return (
    <div className="flex flex-wrap items-center justify-center gap-4">
      <Popover>
        <PopoverTrigger render={<Button variant="outline" />}>Top</PopoverTrigger>
        <PopoverContent side="top">
          <PopoverHeader>
            <PopoverTitle>Top placement</PopoverTitle>
            <PopoverDescription>This popover opens above the trigger.</PopoverDescription>
          </PopoverHeader>
        </PopoverContent>
      </Popover>
      <Popover>
        <PopoverTrigger render={<Button variant="outline" />}>Right</PopoverTrigger>
        <PopoverContent side="right">
          <PopoverHeader>
            <PopoverTitle>Right placement</PopoverTitle>
            <PopoverDescription>This popover opens to the right.</PopoverDescription>
          </PopoverHeader>
        </PopoverContent>
      </Popover>
      <Popover>
        <PopoverTrigger render={<Button variant="outline" />}>Bottom</PopoverTrigger>
        <PopoverContent side="bottom">
          <PopoverHeader>
            <PopoverTitle>Bottom placement</PopoverTitle>
            <PopoverDescription>This popover opens below the trigger.</PopoverDescription>
          </PopoverHeader>
        </PopoverContent>
      </Popover>
      <Popover>
        <PopoverTrigger render={<Button variant="outline" />}>Left</PopoverTrigger>
        <PopoverContent side="left">
          <PopoverHeader>
            <PopoverTitle>Left placement</PopoverTitle>
            <PopoverDescription>This popover opens to the left.</PopoverDescription>
          </PopoverHeader>
        </PopoverContent>
      </Popover>
    </div>
  )
}

With Actions

Add buttons inside the popover for actionable content.

import { Button } from '@jamie/ui/button'
import {
  Popover,
  PopoverContent,
  PopoverDescription,
  PopoverHeader,
  PopoverTitle,
  PopoverTrigger
} from '@jamie/ui/popover'
import { ShareIcon } from 'lucide-react'
 
export function PopoverWithActionsDemo() {
  return (
    <Popover>
      <PopoverTrigger render={<Button variant="outline" />}>
        <ShareIcon className="size-4" />
        Share Meeting
      </PopoverTrigger>
      <PopoverContent className="w-80">
        <PopoverHeader>
          <PopoverTitle>Share &ldquo;Q3 Revenue Review&rdquo;</PopoverTitle>
          <PopoverDescription>
            Share this meeting&apos;s summary and action items with your team.
          </PopoverDescription>
        </PopoverHeader>
        <div className="flex gap-2">
          <Button variant="outline" className="flex-1" size="sm">
            Copy Link
          </Button>
          <Button className="flex-1" size="sm">
            Send Email
          </Button>
        </div>
      </PopoverContent>
    </Popover>
  )
}