NOCTA UI

Popover

Advanced popover component with smart positioning, collision detection, and smooth animations for displaying rich content

Installation

Install the Popover component using the nocta-ui CLI:

Terminal
npx nocta-ui add popover

Then import the component:

Import
import { 
  Popover, 
  PopoverTrigger, 
  PopoverContent 
} from '@/components/ui/popover';

Basic Usage

The Popover component provides a floating panel that appears on demand, perfect for displaying additional information or controls.

Positioning

Control where the popover appears relative to the trigger with the side prop.

Alignment

Fine-tune the alignment of the popover relative to the trigger using the align prop.

Offsets

Adjust the distance and alignment offset of the popover from the trigger.

Custom Triggers

Use the asChild prop to render custom trigger elements while maintaining popover functionality.

Controlled State

Control the popover's open state programmatically using the open and onOpenChange props.

State: Closed

Rich Content

Popovers can contain complex content including forms, menus, and interactive elements.

Form Integration

Popovers work great for inline forms and quick actions.

Collision Detection

The popover automatically detects viewport edges and flips position to stay visible.

Try these popovers near the edges of the viewport

Keyboard Navigation

The Popover component includes comprehensive keyboard support:

  • Escape: Close the popover and return focus to trigger
  • Enter/Space: Open popover when trigger is focused
  • Tab: Navigate through focusable elements inside popover
  • Click outside: Close popover when clicking outside

Accessibility Features

The Popover component is built with accessibility in mind:

  • ARIA Attributes: Proper role, aria-expanded, aria-controls, and aria-haspopup attributes
  • Focus Management: Focus is properly managed when opening/closing
  • Keyboard Navigation: Full keyboard support for all interactions
  • Screen Reader Support: Announces popover state changes
  • Portal Rendering: Content is rendered in a portal to avoid z-index issues

Advanced Usage

Event Handling

Handle specific events for custom behavior:

Event Handling Example
<Popover>
  <PopoverTrigger>Custom Events</PopoverTrigger>
  <PopoverContent
    onEscapeKeyDown={(event) => {
      console.log('Escape pressed');
      // event.preventDefault() to prevent default close behavior
    }}
    onPointerDownOutside={(event) => {
      console.log('Clicked outside');
      // event.preventDefault() to prevent default close behavior
    }}
  >
    <p>Content with custom event handling</p>
  </PopoverContent>
</Popover>

Custom Styling

Customize the appearance with className props:

Custom Styling Example
<Popover>
  <PopoverTrigger className="custom-trigger-styles">
    Custom Styled Trigger
  </PopoverTrigger>
  <PopoverContent className="custom-content-styles w-96 p-6">
    <p>Custom styled content</p>
  </PopoverContent>
</Popover>

Conditional Rendering

Show different content based on state:

Conditional Rendering Example
const [user, setUser] = useState(null);

<Popover>
  <PopoverTrigger>User Menu</PopoverTrigger>
  <PopoverContent>
    {user ? (
      <UserProfile user={user} />
    ) : (
      <LoginForm onLogin={setUser} />
    )}
  </PopoverContent>
</Popover>

Props

Popover

PropTypeDefaultDescription
openbooleanControlled open state
defaultOpenbooleanfalseDefault open state
onOpenChange(open: boolean) => voidCallback when open state changes

PopoverTrigger

PropTypeDefaultDescription
asChildbooleanfalseRender as child element instead of button
classNamestring''Additional CSS classes

PopoverContent

PropTypeDefaultDescription
side'top' | 'right' | 'bottom' | 'left''bottom'Preferred side to display popover
align'start' | 'center' | 'end''center'Alignment relative to trigger
sideOffsetnumber8Distance from trigger in pixels
alignOffsetnumber0Alignment offset in pixels
avoidCollisionsbooleantrueWhether to flip position to avoid viewport edges
classNamestring''Additional CSS classes
onEscapeKeyDown(event: KeyboardEvent) => voidCallback when Escape key is pressed
onPointerDownOutside(event: PointerEvent) => voidCallback when clicking outside

The Popover component also accepts all standard HTML attributes for their respective elements.