Devie UI

The Popover component extends Base UI's Popover. It provides a floating panel that appears relative to a trigger element, useful for displaying supplementary content, tooltips with rich content, or contextual actions.

Installation

Here is the component implementation code that you can copy to your project:

// https://base-ui.com/react/components/popover
 
import { Popover as BasePopover } from "@base-ui-components/react/popover";
import clsx from "clsx";
import styles from "./Popover.module.scss";
 
// Root component
const Root = BasePopover.Root;
 
// Trigger component
interface TriggerProps extends BasePopover.Trigger.Props {
  className?: string;
}
 
function Trigger({ className, ...props }: TriggerProps) {
  return (
    <BasePopover.Trigger
      className={clsx(styles.trigger, className)}
      {...props}
    />
  );
}
 
// Portal component
const Portal = BasePopover.Portal;
 
// Backdrop component
interface BackdropProps extends BasePopover.Backdrop.Props {
  className?: string;
}
 
function Backdrop({ className, ...props }: BackdropProps) {
  return (
    <BasePopover.Backdrop
      className={clsx(styles.backdrop, className)}
      {...props}
    />
  );
}
 
// Positioner component
interface PositionerProps extends BasePopover.Positioner.Props {
  className?: string;
}
 
function Positioner({ className, ...props }: PositionerProps) {
  return (
    <BasePopover.Positioner
      className={clsx(styles.positioner, className)}
      {...props}
    />
  );
}
 
// Popup component
interface PopupProps extends BasePopover.Popup.Props {
  className?: string;
}
 
function Popup({ className, ...props }: PopupProps) {
  return (
    <BasePopover.Popup className={clsx(styles.popup, className)} {...props} />
  );
}
 
// Arrow component
interface ArrowProps extends BasePopover.Arrow.Props {
  className?: string;
}
 
function Arrow({ className, ...props }: ArrowProps) {
  return (
    <BasePopover.Arrow className={clsx(styles.arrow, className)} {...props} />
  );
}
 
// Title component
interface TitleProps extends BasePopover.Title.Props {
  className?: string;
}
 
function Title({ className, ...props }: TitleProps) {
  return (
    <BasePopover.Title className={clsx(styles.title, className)} {...props} />
  );
}
 
// Description component
interface DescriptionProps extends BasePopover.Description.Props {
  className?: string;
}
 
function Description({ className, ...props }: DescriptionProps) {
  return (
    <BasePopover.Description
      className={clsx(styles.description, className)}
      {...props}
    />
  );
}
 
// Close component
interface CloseProps extends BasePopover.Close.Props {
  className?: string;
}
 
function Close({ className, ...props }: CloseProps) {
  return (
    <BasePopover.Close className={clsx(styles.close, className)} {...props} />
  );
}
 
const Popover = {
  Root,
  Trigger,
  Portal,
  Backdrop,
  Positioner,
  Popup,
  Arrow,
  Title,
  Description,
  Close,
};
 
export type PopoverProps = React.ComponentProps<typeof BasePopover.Root>;
 
export default Popover;

Use Cases

Simple popover

A basic popover with a title, description, close button, and arrow. The popover positions itself relative to the trigger and includes smooth scale and opacity animations.

Rich content with controlled state

A more complex example showing a notifications panel with custom header, list items, and footer actions. This demonstrates using controlled state via open and onOpenChange props, custom styling via className, and structured layouts within the popup.