Basic example
In the following example you can see the button that will trigger the popover element to be shown when clicked.
import React from "react";
import {
TEPopover,
TEPopoverToggler,
TEPopoverContent,
TERipple,
} from "tw-elements-react";
export default function PopoverBasicExample(): JSX.Element {
return (
<TEPopover className="py-10 md:text-center">
<TERipple rippleColor="light">
<TEPopoverToggler className="inline-block rounded bg-danger px-7 pb-2.5 pt-3 text-sm font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_#dc4c64] transition duration-150 ease-in-out hover:bg-danger-600 hover:shadow-[0_8px_9px_-4px_rgba(220,76,100,0.3),0_4px_18px_0_rgba(220,76,100,0.2)] focus:bg-danger-600 focus:shadow-[0_8px_9px_-4px_rgba(220,76,100,0.3),0_4px_18px_0_rgba(220,76,100,0.2)] focus:outline-none focus:ring-0 active:bg-danger-700 active:shadow-[0_8px_9px_-4px_rgba(220,76,100,0.3),0_4px_18px_0_rgba(220,76,100,0.2)] dark:shadow-[0_4px_9px_-4px_rgba(220,76,100,0.5)] dark:hover:shadow-[0_8px_9px_-4px_rgba(220,76,100,0.2),0_4px_18px_0_rgba(220,76,100,0.1)] dark:focus:shadow-[0_8px_9px_-4px_rgba(220,76,100,0.2),0_4px_18px_0_rgba(220,76,100,0.1)] dark:active:shadow-[0_8px_9px_-4px_rgba(220,76,100,0.2),0_4px_18px_0_rgba(220,76,100,0.1)]">
Click to toggle popover
</TEPopoverToggler>
</TERipple>
<TEPopoverContent>
<h3 className="py-2 px-4 mb-0 shadow-[0_0px_3px_0_rgba(0,0,0,0.07)] bg-white bg-clip-padding rounded-t-lg border border-b-2 border-neutral-100 font-medium empty:hidden dark:border-x-0 dark:border-t-0 dark:border-neutral-500 dark:bg-neutral-700">
Popover title
</h3>
<div className="p-4 text-[#212529] rounded-b-lg shadow-[0_0px_3px_0_rgba(0,0,0,0.07),0_2px_2px_0_rgba(0,0,0,0.04)] bg-white bg-clip-padding border border-t-0 border-neutral-100 empty:hidden dark:text-white dark:border-0 dark:bg-neutral-700">
And here's some amazing content. It's very engaging. Right?
</div>
</TEPopoverContent>
</TEPopover>
);
}
Overview
Things to know when using the popover plugin:
- Triggering popovers on hidden elements will not work.
-
When triggered from hyperlinks that span multiple lines, popovers will be centered. Use
whitespace-nowrap
class on your<a>
elements to avoid this behavior. - Popovers must be hidden before their corresponding elements have been removed from the DOM.
- Popovers can be triggered thanks to an element inside a shadow DOM.
Four directions
Click on the buttons below to see the four popovers directions: top,
right, bottom, left
. Check API Properties to see all available options.
import React from "react";
import {
TEPopover,
TEPopoverContent,
TEPopoverToggler,
TERipple,
} from "tw-elements-react";
export default function PopoverFourDirections(): JSX.Element {
return (
<div className="flex space-x-1">
<TEPopover>
<TERipple rippleColor="light">
<TEPopoverToggler className="max-w-[160px] rounded bg-primary-100 px-6 py-2 text-xs font-medium uppercase leading-normal text-primary-700 transition duration-150 ease-in-out hover:bg-primary-accent-100 focus:bg-primary-accent-100 focus:outline-none focus:ring-0 active:bg-primary-accent-200">
Popover on top
</TEPopoverToggler>
</TERipple>
<TEPopoverContent placement="top">
<div className="p-4 text-[#212529] rounded-lg shadow-[0_0px_3px_0_rgba(0,0,0,0.07),0_2px_2px_0_rgba(0,0,0,0.04)] bg-white bg-clip-padding border border-t-0 border-neutral-100 empty:hidden dark:text-white dark:border-0 dark:bg-neutral-700">
Vivamus sagittis lacus vel augue laoreet rutrum faucibus.
</div>
</TEPopoverContent>
</TEPopover>
<TEPopover className="text-left">
<TERipple rippleColor="light">
<TEPopoverToggler className="max-w-[160px] rounded bg-primary-100 px-6 py-2 text-xs font-medium uppercase leading-normal text-primary-700 transition duration-150 ease-in-out hover:bg-primary-accent-100 focus:bg-primary-accent-100 focus:outline-none focus:ring-0 active:bg-primary-accent-200">
Popover on right
</TEPopoverToggler>
</TERipple>
<TEPopoverContent>
<div className="p-4 text-[#212529] rounded-lg shadow-[0_0px_3px_0_rgba(0,0,0,0.07),0_2px_2px_0_rgba(0,0,0,0.04)] bg-white bg-clip-padding border border-t-0 border-neutral-100 empty:hidden dark:text-white dark:border-0 dark:bg-neutral-700">
Vivamus sagittis lacus vel augue laoreet rutrum faucibus.
</div>
</TEPopoverContent>
</TEPopover>
<TEPopover>
<TERipple rippleColor="light">
<TEPopoverToggler className="max-w-[180px] rounded bg-primary-100 px-6 py-2 text-xs font-medium uppercase leading-normal text-primary-700 transition duration-150 ease-in-out hover:bg-primary-accent-100 focus:bg-primary-accent-100 focus:outline-none focus:ring-0 active:bg-primary-accent-200">
Popover on bottom
</TEPopoverToggler>
</TERipple>
<TEPopoverContent placement="bottom">
<div className="p-4 text-[#212529] rounded-lg shadow-[0_0px_3px_0_rgba(0,0,0,0.07),0_2px_2px_0_rgba(0,0,0,0.04)] bg-white bg-clip-padding border border-t-0 border-neutral-100 empty:hidden dark:text-white dark:border-0 dark:bg-neutral-700">
Vivamus sagittis lacus vel augue laoreet rutrum faucibus.
</div>
</TEPopoverContent>
</TEPopover>
<TEPopover className="text-right">
<TERipple rippleColor="light">
<TEPopoverToggler className="max-w-[160px] rounded bg-primary-100 px-6 py-2 text-xs font-medium uppercase leading-normal text-primary-700 transition duration-150 ease-in-out hover:bg-primary-accent-100 focus:bg-primary-accent-100 focus:outline-none focus:ring-0 active:bg-primary-accent-200">
Popover on left
</TEPopoverToggler>
</TERipple>
<TEPopoverContent placement="left">
<div className="p-4 text-[#212529] rounded-lg shadow-[0_0px_3px_0_rgba(0,0,0,0.07),0_2px_2px_0_rgba(0,0,0,0.04)] bg-white bg-clip-padding border border-t-0 border-neutral-100 empty:hidden dark:text-white dark:border-0 dark:bg-neutral-700">
Vivamus sagittis lacus vel augue laoreet rutrum faucibus.
</div>
</TEPopoverContent>
</TEPopover>
</div>
);
}
Dismiss on next click
Use trigger="focus"
to dismiss on the next click of a
different element than the toggle element.
import React from "react";
import {
TEPopover,
TEPopoverToggler,
TEPopoverContent,
TERipple,
} from "tw-elements-react";
export default function PopoverDismiss(): JSX.Element {
return (
<TEPopover className="py-10 md:text-center" trigger="focus">
<TERipple rippleColor="light">
<TEPopoverToggler className="inline-block rounded bg-danger px-7 pb-2.5 pt-3 text-sm font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_#dc4c64] transition duration-150 ease-in-out hover:bg-danger-600 hover:shadow-[0_8px_9px_-4px_rgba(220,76,100,0.3),0_4px_18px_0_rgba(220,76,100,0.2)] focus:bg-danger-600 focus:shadow-[0_8px_9px_-4px_rgba(220,76,100,0.3),0_4px_18px_0_rgba(220,76,100,0.2)] focus:outline-none focus:ring-0 active:bg-danger-700 active:shadow-[0_8px_9px_-4px_rgba(220,76,100,0.3),0_4px_18px_0_rgba(220,76,100,0.2)] dark:shadow-[0_4px_9px_-4px_rgba(220,76,100,0.5)] dark:hover:shadow-[0_8px_9px_-4px_rgba(220,76,100,0.2),0_4px_18px_0_rgba(220,76,100,0.1)] dark:focus:shadow-[0_8px_9px_-4px_rgba(220,76,100,0.2),0_4px_18px_0_rgba(220,76,100,0.1)] dark:active:shadow-[0_8px_9px_-4px_rgba(220,76,100,0.2),0_4px_18px_0_rgba(220,76,100,0.1)]">
Dismissible popover
</TEPopoverToggler>
</TERipple>
<TEPopoverContent>
<div className="p-4 text-[#212529] rounded-lg shadow-[0_0px_3px_0_rgba(0,0,0,0.07),0_2px_2px_0_rgba(0,0,0,0.04)] bg-white bg-clip-padding border border-t-0 border-neutral-100 empty:hidden dark:text-white dark:border-0 dark:bg-neutral-700">
Dismissible popover And here's some amazing content. It's very
engaging. Right?
</div>
</TEPopoverContent>
</TEPopover>
);
}
Disabled elements
Elements with the disabled
attribute aren’t interactive,
meaning users cannot focus, hover, or click them to trigger a popover
(or tootlip). As a workaround, you’ll want to trigger the TEPopoverToggler
from
a wrapper <div>
or <span>
,
ideally made keyboard-focusable using tabIndex={0}
, and
override the pointer-events
on the disabled element.
import React from "react";
import {
TEPopover,
TEPopoverContent,
TEPopoverToggler,
} from "tw-elements-react";
export default function PopoverDisabled(): JSX.Element {
return (
<TEPopover className="py-10 md:text-center" trigger="hover focus">
<TEPopoverToggler className="inline-block" tag="span">
<button
type="button"
className="pointer-events-none inline-block rounded bg-primary px-6 pb-2 pt-2.5 text-xs font-medium uppercase leading-normal text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-primary-600 hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-primary-600 focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-primary-700 active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] disabled:opacity-70 dark:shadow-[0_4px_9px_-4px_rgba(59,113,202,0.5)] dark:hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)] dark:active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.2),0_4px_18px_0_rgba(59,113,202,0.1)]"
disabled
>
Disabled button
</button>
</TEPopoverToggler>
<TEPopoverContent>
<div className="p-4 text-[#212529] rounded-lg shadow-[0_0px_3px_0_rgba(0,0,0,0.07),0_2px_2px_0_rgba(0,0,0,0.04)] bg-white bg-clip-padding border border-t-0 border-neutral-100 empty:hidden dark:text-white dark:border-0 dark:bg-neutral-700">
Disabled popover
</div>
</TEPopoverContent>
</TEPopover>
);
}
Related resources
If you are looking for more advanced options, try Bootstrap Popover from MDBootstrap.