React Popover - Flowbite

Use the popover component to show detailed information inside a pop-up box relative to the element that is being clicked or hovered based on multiple styles

Use the popover component to show detailed information inside a pop-up box relative to the element that is being clicked or hovered based on multiple styles

Get started with the popover component to show any type of content inside a pop-up box when hovering or clicking over a trigger element. There are multiple examples that you can choose from, such as showing more information about a user profile, company profile, password strength, and more.

Before using the popover component, make sure to import the component in your React project:

import { Popover } from 'flowbite-react';

Default popover#

Wrap the trigger component with the <Popover> component and pass the popover content to the content prop of the <Popover> component.

This will render the popover whenever you click the trigger component.

Edit on GitHub
import { Button, Popover } from 'flowbite-react';

function Component() {
  return (
    <Popover 
      aria-labelledby="default-popover"
      content={
        <div className="w-64 text-sm text-gray-500 dark:text-gray-400">
          <div className="border-b border-gray-200 bg-gray-100 px-3 py-2 dark:border-gray-600 dark:bg-gray-700">
            <h3 id="default-popover" className="font-semibold text-gray-900 dark:text-white">Popover title</h3>
          </div>
          <div className="px-3 py-2">
            <p>And here's some amazing content. It's very engaging. Right?</p>
          </div>
        </div>
      }
    >
      <Button>Default popover</Button>
    </Popover>
  );
}

Company profile#

This example can be used to show more information about a company profile.

Edit on GitHub
import { Button, Popover } from 'flowbite-react';

function Component() {
  return (
    <Popover
      aria-labelledby="profile-popover"
      content={
        <div className="w-64 p-3">
          <div className="mb-2 flex items-center justify-between">
            <a href="#">
              <img
                className="h-10 w-10 rounded-full"
                src="https://flowbite.com/docs/images/people/profile-picture-1.jpg"
                alt="Jese Leos"
              />
            </a>
            <div>
              <button
                type="button"
                className="rounded-lg bg-blue-700 px-3 py-1.5 text-xs font-medium text-white hover:bg-blue-800 focus:outline-none focus:ring-4 focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
              >
                Follow
              </button>
            </div>
          </div>
          <p id="profile-popover" className="text-base font-semibold leading-none text-gray-900 dark:text-white">
            <a href="#">Jese Leos</a>
          </p>
          <p className="mb-3 text-sm font-normal">
            <a href="#" className="hover:underline">
              @jeseleos
            </a>
          </p>
          <p className="mb-4 text-sm">
            Open-source contributor. Building{' '}
            <a href="#" className="text-blue-600 hover:underline dark:text-blue-500">
              flowbite.com
            </a>
            .
          </p>
          <ul className="flex text-sm">
            <li className="me-2">
              <a href="#" className="hover:underline">
                <span className="font-semibold text-gray-900 dark:text-white">799</span>
                <span>Following</span>
              </a>
            </li>
            <li>
              <a href="#" className="hover:underline">
                <span className="font-semibold text-gray-900 dark:text-white">3,758</span>
                <span>Followers</span>
              </a>
            </li>
          </ul>
        </div>
      }
    >
      <Button>Company profile</Button>
    </Popover>
  );
}

Image popover#

Use this example to trigger a popover component with detailed information and an image when hovering over a portion of highlighted text inspired by Wikipedia and other large news outlets.

Edit on GitHub

Due to its central geographic location in Southern Europe, has historically been home to myriad peoples and cultures. In addition to the various ancient peoples dispersed throughout what is now modern-day Italy, the most predominant being the Indo-European Italic peoples who gave the peninsula its name, beginning from the classical era, Phoenicians and Carthaginians founded colonies mostly in insular Italy

import { Popover } from 'flowbite-react';

function Component() {
  return (
    <p className="text-gray-500 dark:text-gray-400">
      Due to its central geographic location in Southern Europe,{' '}
      <Popover
        trigger="hover"
        content={
          <div className="w-96 text-sm text-gray-500 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-400">
            <div className="grid grid-cols-5">
              <div className="col-span-3 p-3">
                <div className="space-y-2">
                  <h3 className="font-semibold text-gray-900 dark:text-white">About Italy</h3>
                  <p>
                    Italy is located in the middle of the Mediterranean Sea, in Southern Europe it is also considered
                    part of Western Europe. A unitary parliamentary republic with Rome as its capital and largest city.
                  </p>
                  <a
                    href="#"
                    className="flex items-center font-medium text-blue-600 hover:text-blue-700 hover:underline dark:text-blue-500 dark:hover:text-blue-600"
                  >
                    Read more{' '}
                    <svg
                      className="ms-1.5 h-2 w-2 rtl:rotate-180"
                      aria-hidden="true"
                      xmlns="http://www.w3.org/2000/svg"
                      fill="none"
                      viewBox="0 0 6 10"
                    >
                      <path
                        stroke="currentColor"
                        stroke-linecap="round"
                        stroke-linejoin="round"
                        stroke-width="2"
                        d="m1 9 4-4-4-4"
                      />
                    </svg>
                  </a>
                </div>
              </div>
              <img
                src="https://flowbite.com/docs/images/popovers/italy.png"
                className="col-span-2 h-full"
                alt="Italy map"
              />
            </div>
          </div>
        }
      >
        <a href="#" className="text-blue-600 underline hover:no-underline dark:text-blue-500">
          Italy
        </a>
      </Popover>{' '}
      has historically been home to myriad peoples and cultures. In addition to the various ancient peoples dispersed
      throughout what is now modern-day Italy, the most predominant being the Indo-European Italic peoples who gave the
      peninsula its name, beginning from the classical era, Phoenicians and Carthaginians founded colonies mostly in
      insular Italy
    </p>
  );
}

Password strength#

Dynamically show the password strength progress when creating a new password positioned relative to the input element.

Edit on GitHub
'use client';

import { Button, Checkbox, Label, Popover, TextInput } from 'flowbite-react';

function Component() {
  return (
    <form className="flex max-w-md flex-col gap-4">
      <div>
        <div className="mb-2 block">
          <Label htmlFor="email1" value="Your email" />
        </div>
        <TextInput id="email1" type="email" placeholder="[email protected]" required />
      </div>
      <div>
        <div className="mb-2 block">
          <Label htmlFor="password1" value="Your password" />
        </div>
        <Popover
          trigger="hover"
          content={
            <div className="space-y-2 p-3">
              <h3 className="font-semibold text-gray-900 dark:text-white">Must have at least 6 characters</h3>
              <div className="grid grid-cols-4 gap-2">
                <div className="h-1 bg-orange-300 dark:bg-orange-400"></div>
                <div className="h-1 bg-orange-300 dark:bg-orange-400"></div>
                <div className="h-1 bg-gray-200 dark:bg-gray-600"></div>
                <div className="h-1 bg-gray-200 dark:bg-gray-600"></div>
              </div>
              <p>It’s better to have:</p>
              <ul>
                <li className="mb-1 flex items-center">
                  <svg
                    className="me-2 h-3.5 w-3.5 text-green-400 dark:text-green-500"
                    aria-hidden="true"
                    xmlns="http://www.w3.org/2000/svg"
                    fill="none"
                    viewBox="0 0 16 12"
                  >
                    <path
                      stroke="currentColor"
                      stroke-linecap="round"
                      stroke-linejoin="round"
                      stroke-width="2"
                      d="M1 5.917 5.724 10.5 15 1.5"
                    />
                  </svg>
                  Upper & lower case letters
                </li>
                <li className="mb-1 flex items-center">
                  <svg
                    className="me-2.5 h-3 w-3 text-gray-300 dark:text-gray-400"
                    aria-hidden="true"
                    xmlns="http://www.w3.org/2000/svg"
                    fill="none"
                    viewBox="0 0 14 14"
                  >
                    <path
                      stroke="currentColor"
                      stroke-linecap="round"
                      stroke-linejoin="round"
                      stroke-width="2"
                      d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"
                    />
                  </svg>
                  A symbol (#$&)
                </li>
                <li className="flex items-center">
                  <svg
                    className="me-2.5 h-3 w-3 text-gray-300 dark:text-gray-400"
                    aria-hidden="true"
                    xmlns="http://www.w3.org/2000/svg"
                    fill="none"
                    viewBox="0 0 14 14"
                  >
                    <path
                      stroke="currentColor"
                      stroke-linecap="round"
                      stroke-linejoin="round"
                      stroke-width="2"
                      d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"
                    />
                  </svg>
                  A longer password (min. 12 chars.)
                </li>
              </ul>
            </div>
          }
        >
          <TextInput id="password1" type="password" required />
        </Popover>
      </div>
      <div className="flex items-center gap-2">
        <Checkbox id="remember" />
        <Label htmlFor="remember">Remember me</Label>
      </div>
      <Button type="submit">Submit</Button>
    </form>
  );
}

Controlled#

Manages visibility via open and openOnChange props, allowing fine-tuned control over its display. Ideal for scenarios where Popover behavior needs to align with specific application logic or user interactions.

Edit on GitHub
'use client';

import { useState } from 'react';
import { BiCaretDown } from 'react-icons/bi';
import { Button, Popover, Label, TextInput  } from 'flowbite-react';

function Component() {
  const [open, setOpen] = useState(false);

  return (
    <Popover
      aria-labelledby="area-popover"
      open={open}
      onOpenChange={setOpen}
      content={
        <div className="flex w-64 flex-col gap-4 p-4 text-sm text-gray-500 dark:text-gray-400">
          <div>
            <h2 id="area-popover" className="text-base text-gray-500">Area (sqft)</h2>
            <div className="mb-2 block">
              <Label htmlFor="minsqft" value="Minimum sqft" />
            </div>
            <TextInput id="minsqft" type="number" />
          </div>
          <div>
            <div className="mb-2 block">
              <Label htmlFor="maxsqft" value="Maximum sqft" />
            </div>
            <TextInput id="maxsqft" type="number" />
          </div>
          <div className="flex gap-2">
            <Button color="gray">Reset</Button>
            <Button color="success" onClick={() => setOpen(false)}>
              Save
            </Button>
          </div>
        </div>
      }
    >
      <Button>
        Area <BiCaretDown className="ml-2" />
      </Button>
    </Popover>
  );
}

Placement#

Update the placement of the popover using the placement prop. The default placement is bottom and you can also use right, top, and left.

Edit on GitHub
import { Button, Popover } from 'flowbite-react';

function Component() {
  const content = (
    <div className="w-64 text-sm text-gray-500 dark:text-gray-400">
      <div className="border-b border-gray-200 bg-gray-100 px-3 py-2 dark:border-gray-600 dark:bg-gray-700">
        <h3 className="font-semibold text-gray-900 dark:text-white">Popover title</h3>
      </div>
      <div className="px-3 py-2">
        <p>And here's some amazing content. It's very engaging. Right?</p>
      </div>
    </div>
  );

  return (
    <div className="flex gap-2">
      <Popover content={content} placement="top">
        <Button>Popover top</Button>
      </Popover>
      <Popover content={content} placement="right">
        <Button>Popover right</Button>
      </Popover>
      <Popover content={content} placement="bottom">
        <Button>Popover bottom</Button>
      </Popover>
      <Popover content={content} placement="left">
        <Button>Popover left</Button>
      </Popover>
    </div>
  );
}

Trigger type#

Use the trigger prop to change the trigger type of the popover if you want to show the popover when clicking on the hover element instead of clicking on it.

The default trigger type is hover and you can also use click.

Edit on GitHub
'use client';

import { Button, Popover } from 'flowbite-react';

function Component() {
  const content = (
    <div className="w-64 text-sm text-gray-500 dark:text-gray-400">
      <div className="border-b border-gray-200 bg-gray-100 px-3 py-2 dark:border-gray-600 dark:bg-gray-700">
        <h3 className="font-semibold text-gray-900 dark:text-white">Popover title</h3>
      </div>
      <div className="px-3 py-2">
        <p>And here's some amazing content. It's very engaging. Right?</p>
      </div>
    </div>
  );

  return (
    <div className="flex gap-2">
      <Popover content={content} trigger="hover">
        <Button>Popover hover</Button>
      </Popover>
      <Popover content={content} trigger="click">
        <Button>Popover click</Button>
      </Popover>
    </div>
  );
}

Disable arrow#

You can disable the arrow of the popover component by passing the arrow prop with a value of false.

Edit on GitHub
import { Button, Popover } from 'flowbite-react';

function Component() {
  return (
    <Popover
      aria-labelledby="default-popover"
      content={
        <div className="w-64 text-sm text-gray-500 dark:text-gray-400">
          <div className="border-b border-gray-200 bg-gray-100 px-3 py-2 dark:border-gray-600 dark:bg-gray-700">
            <h3 id="default-popover" className="font-semibold text-gray-900 dark:text-white">Popover title</h3>
          </div>
          <div className="px-3 py-2">
            <p>And here's some amazing content. It's very engaging. Right?</p>
          </div>
        </div>
      }
      arrow={false}
    >
      <Button>No Arrow Popover</Button>
    </Popover>
  );
}

Theme#

To learn more about how to customize the appearance of components, please see the Theme docs.

{
  "base": "absolute z-20 inline-block w-max max-w-[100vw] bg-white outline-none border border-gray-200 rounded-lg shadow-sm dark:border-gray-600 dark:bg-gray-800",
  "content": "z-10 overflow-hidden rounded-[7px]",
  "arrow": {
    "base": "absolute h-2 w-2 z-0 rotate-45 mix-blend-lighten bg-white border border-gray-200 dark:border-gray-600 dark:bg-gray-800 dark:mix-blend-color",
    "placement": "-4px"
  }
}

References#