UI
Popover
Displays rich content in a portal, triggered by a button.
import { Button } from "@/components/Button"import { Popover, PopoverContent, PopoverTrigger } from "@/components/Popover"
export const PopoverHero = () => ( <div className="flex justify-center"> <Popover> <PopoverTrigger asChild> <Button variant="primary">Open</Button> </PopoverTrigger> <PopoverContent className="p-4"> <div className="flex flex-col gap-4"> <div className="space-y-1"> <p className="text-sm font-medium text-gray-700 dark:text-gray-300">Billed to:</p> <p className="text-gray-800 dark:text-gray-200">ForDailyUseCo Ltd.</p> </div> <div className="space-y-1"> <div className="flex items-center"> <p className="text-sm font-medium text-gray-700 dark:text-gray-300">Spent by:</p> </div> <p className="text-gray-800 dark:text-gray-200">ForDailyUseCo Ltd.</p> </div> </div> </PopoverContent> </Popover> </div>);
Installation
npm install @radix-ui/react-popover
- Copy and paste the code into your project’s component directory. Do not forget to update the import paths.
// Tremor Popover [v0.0.3] import React from "react"import * as PopoverPrimitives from "@radix-ui/react-popover" import { cx } from "@/lib/utils" const Popover = ( props: React.ComponentPropsWithoutRef<typeof PopoverPrimitives.Root>,) => { return <PopoverPrimitives.Root {...props} />} Popover.displayName = "Popover" const PopoverTrigger = React.forwardRef< React.ElementRef<typeof PopoverPrimitives.Trigger>, React.ComponentPropsWithoutRef<typeof PopoverPrimitives.Trigger>>((props, forwardedRef) => { return <PopoverPrimitives.Trigger ref={forwardedRef} {...props} />}) PopoverTrigger.displayName = "PopoverTrigger" const PopoverAnchor = React.forwardRef< React.ElementRef<typeof PopoverPrimitives.Anchor>, React.ComponentPropsWithoutRef<typeof PopoverPrimitives.Anchor>>((props, forwardedRef) => { return <PopoverPrimitives.Anchor ref={forwardedRef} {...props} />}) PopoverAnchor.displayName = "PopoverAnchor" const PopoverClose = React.forwardRef< React.ElementRef<typeof PopoverPrimitives.Close>, React.ComponentPropsWithoutRef<typeof PopoverPrimitives.Close>>((props, forwardedRef) => { return <PopoverPrimitives.Close ref={forwardedRef} {...props} />}) PopoverClose.displayName = "PopoverClose" type ContentProps = React.ComponentPropsWithoutRef< typeof PopoverPrimitives.Content> const PopoverContent = React.forwardRef< React.ElementRef<typeof PopoverPrimitives.Content>, ContentProps>( ( { className, sideOffset = 10, side = "bottom", align = "center", collisionPadding, avoidCollisions = true, ...props }: ContentProps, forwardedRef, ) => { return ( <PopoverPrimitives.Portal> <PopoverPrimitives.Content ref={forwardedRef} sideOffset={sideOffset} side={side} align={align} collisionPadding={collisionPadding} avoidCollisions={avoidCollisions} className={cx( // base "max-h-[var(--radix-popper-available-height)] min-w-60 overflow-hidden rounded-md border p-2.5 text-sm shadow-md", // border color "border-gray-200 dark:border-gray-800", // text color "text-gray-900 dark:text-gray-50", // background color "bg-white dark:bg-gray-950", // transition "will-change-[transform,opacity]", "data-[state=closed]:animate-hide", "data-[state=open]:data-[side=bottom]:animate-slideDownAndFade data-[state=open]:data-[side=left]:animate-slideLeftAndFade data-[state=open]:data-[side=right]:animate-slideRightAndFade data-[state=open]:data-[side=top]:animate-slideUpAndFade", className, )} tremor-id="tremor-raw" // https://github.com/radix-ui/primitives/issues/1159 onWheel={(event) => { event.stopPropagation() const isScrollingDown = event.deltaY > 0 if (isScrollingDown) { event.currentTarget.dispatchEvent( new KeyboardEvent("keydown", { key: "ArrowDown" }), ) } else { event.currentTarget.dispatchEvent( new KeyboardEvent("keydown", { key: "ArrowUp" }), ) } }} {...props} /> </PopoverPrimitives.Portal> ) },)PopoverContent.displayName = "PopoverContent" export { Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger }
import type { Config } from 'tailwindcss';export default { // ... theme: { extend: { keyframes: { hide: { from: { opacity: "1" }, to: { opacity: "0" }, }, slideDownAndFade: { from: { opacity: "0", transform: "translateY(-6px)" }, to: { opacity: "1", transform: "translateY(0)" }, }, slideLeftAndFade: { from: { opacity: "0", transform: "translateX(6px)" }, to: { opacity: "1", transform: "translateX(0)" }, }, slideUpAndFade: { from: { opacity: "0", transform: "translateY(6px)" }, to: { opacity: "1", transform: "translateY(0)" }, }, slideRightAndFade: { from: { opacity: "0", transform: "translateX(-6px)" }, to: { opacity: "1", transform: "translateX(0)" }, }, }, animation: { hide: "hide 150ms cubic-bezier(0.16, 1, 0.3, 1)", slideDownAndFade: "slideDownAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)", slideLeftAndFade: "slideLeftAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)", slideUpAndFade: "slideUpAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)", slideRightAndFade: "slideRightAndFade 150ms cubic-bezier(0.16, 1, 0.3, 1)", }, }, }, // ...} satisfies Config;
Example
import { Button } from "@/components/Button"import { Popover, PopoverContent, PopoverTrigger } from "@/components/Popover"
export const PopoverExample = () => ( <div className="flex justify-center"> <Popover> <PopoverTrigger asChild> <Button variant="primary">Open</Button> </PopoverTrigger> <PopoverContent className="p-4"> <div className="flex flex-col gap-4"> <div className="space-y-1"> <p className="text-sm font-medium text-gray-700 dark:text-gray-300">Billed to:</p> <p className="text-gray-800 dark:text-gray-200">ForDailyUseCo Ltd.</p> </div> <div className="space-y-1"> <div className="flex items-center"> <p className="text-sm font-medium text-gray-700 dark:text-gray-300">Spent by:</p> </div> <p className="text-gray-800 dark:text-gray-200">ForDailyUseCo Ltd.</p> </div> </div> </PopoverContent> </Popover> </div>);
API Reference: Popover
This component uses the Radix UI API.
API Reference: PopoverAnchor
This component uses the Radix UI API.
API Reference: PopoverClose
This component uses the Radix UI API.
API Reference: PopoverContent
This component uses the Radix UI API.
- align
- Preferred alignment against the anchor.
"center" | "start" | "end"
Default: "center"
- side
- Placement of the tooltip relative to the trigger.
"bottom" | "left" | "top" | "right"
Default: "bottom"
- sideOffset
- Distance from anchor.
number
Default: 10
API Reference: PopoverTrigger
This component uses the Radix UI API.