Naruto is a Japanese manga series written and illustrated by Masashi Kishimoto.
import { Input, Text } from "@chakra-ui/react"
import { Button } from "@/components/ui/button"
import {
PopoverArrow,
PopoverBody,
PopoverContent,
PopoverRoot,
PopoverTitle,
PopoverTrigger,
} from "@/components/ui/popover"
const Demo = () => {
return (
<PopoverRoot>
<PopoverTrigger asChild>
<Button size="sm" variant="outline">
Click me
</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverBody>
<PopoverTitle fontWeight="medium">Naruto Form</PopoverTitle>
<Text my="4">
Naruto is a Japanese manga series written and illustrated by Masashi
Kishimoto.
</Text>
<Input placeholder="Your fav. character" size="sm" />
</PopoverBody>
</PopoverContent>
</PopoverRoot>
)
}
Setup
If you don't already have the snippet, run the following command to add the
popover
snippet
npx @chakra-ui/cli snippet add popover
The snippet includes component compositions based on the Popover
component.
Usage
import {
PopoverBody,
PopoverContent,
PopoverRoot,
PopoverTitle,
PopoverTrigger,
} from "@/components/ui/popover"
<PopoverRoot>
<PopoverTrigger />
<PopoverContent>
<PopoverBody>
<PopoverTitle />
</PopoverBody>
</PopoverContent>
</PopoverRoot>
Examples
Controlled
Use the open
and onOpenChange
to control the visibility of the popover.
"use client"
import { Button } from "@/components/ui/button"
import {
PopoverArrow,
PopoverBody,
PopoverContent,
PopoverRoot,
PopoverTrigger,
} from "@/components/ui/popover"
import { useState } from "react"
const Demo = () => {
const [open, setOpen] = useState(false)
return (
<PopoverRoot open={open} onOpenChange={(e) => setOpen(e.open)}>
<PopoverTrigger asChild>
<Button size="sm" variant="outline">
Click me
</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverBody>
This is a popover with the same width as the trigger button
</PopoverBody>
</PopoverContent>
</PopoverRoot>
)
}
Sizes
Use the size
prop to change the size of the popover component.
Naruto is a Japanese manga series written and illustrated by Masashi Kishimoto.
Naruto is a Japanese manga series written and illustrated by Masashi Kishimoto.
Naruto is a Japanese manga series written and illustrated by Masashi Kishimoto.
Naruto is a Japanese manga series written and illustrated by Masashi Kishimoto.
import { For, Input, Stack, Text } from "@chakra-ui/react"
import { Button } from "@/components/ui/button"
import {
PopoverArrow,
PopoverBody,
PopoverContent,
PopoverRoot,
PopoverTitle,
PopoverTrigger,
} from "@/components/ui/popover"
const Demo = () => {
return (
<Stack align="center" direction="row" gap="10">
<For each={["xs", "sm", "md", "lg"]}>
{(size) => (
<PopoverRoot key={size} size={size}>
<PopoverTrigger asChild>
<Button size={size} variant="outline">
Click me
</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverBody>
<PopoverTitle fontWeight="medium">Naruto Form</PopoverTitle>
<Text my="4">
Naruto is a Japanese manga series written and illustrated by
Masashi Kishimoto.
</Text>
<Input placeholder="Your fav. character" size={size} />
</PopoverBody>
</PopoverContent>
</PopoverRoot>
)}
</For>
</Stack>
)
}
Lazy Mount
Use the lazyMounted
and/or unmountOnExit
prop to defer the mounting of the
popover content until it's opened.
import { Text } from "@chakra-ui/react"
import { Button } from "@/components/ui/button"
import {
PopoverArrow,
PopoverBody,
PopoverContent,
PopoverRoot,
PopoverTitle,
PopoverTrigger,
} from "@/components/ui/popover"
const Demo = () => {
return (
<PopoverRoot lazyMount unmountOnExit>
<PopoverTrigger asChild>
<Button size="sm" variant="outline">
Click me
</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverBody>
<PopoverTitle fontWeight="medium">Naruto Form</PopoverTitle>
<Text my="4">
Naruto is a Japanese manga series written and illustrated by Masashi
Kishimoto.
</Text>
</PopoverBody>
</PopoverContent>
</PopoverRoot>
)
}
Placement
Use the positioning.placement
prop to configure the underlying floating-ui
positioning logic.
import { Button } from "@/components/ui/button"
import {
PopoverArrow,
PopoverBody,
PopoverContent,
PopoverRoot,
PopoverTrigger,
} from "@/components/ui/popover"
const Demo = () => {
return (
<PopoverRoot positioning={{ placement: "bottom-end" }}>
<PopoverTrigger asChild>
<Button size="sm" variant="outline">
Click me
</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverBody>Some content</PopoverBody>
</PopoverContent>
</PopoverRoot>
)
}
Offset
Use the positioning.offset
prop to adjust the position of the popover content.
import { Button } from "@/components/ui/button"
import {
PopoverBody,
PopoverContent,
PopoverRoot,
PopoverTrigger,
} from "@/components/ui/popover"
const Demo = () => {
return (
<PopoverRoot positioning={{ offset: { crossAxis: 0, mainAxis: 0 } }}>
<PopoverTrigger asChild>
<Button size="sm" variant="outline">
Open
</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverBody>
This is a popover with the same width as the trigger button
</PopoverBody>
</PopoverContent>
</PopoverRoot>
)
}
Same Width
Use the positioning.sameWidth
prop to make the popover content the same width
as the trigger.
import { Button } from "@/components/ui/button"
import {
PopoverArrow,
PopoverBody,
PopoverContent,
PopoverRoot,
PopoverTrigger,
} from "@/components/ui/popover"
const Demo = () => {
return (
<PopoverRoot positioning={{ sameWidth: true }}>
<PopoverTrigger asChild>
<Button size="sm" variant="outline" minW="xs">
Click me
</Button>
</PopoverTrigger>
<PopoverContent width="auto">
<PopoverArrow />
<PopoverBody>
This is a popover with the same width as the trigger button
</PopoverBody>
</PopoverContent>
</PopoverRoot>
)
}
Nested Popover
When nesting overlay elements like popover, select, menu, inside of the popover,
set portalled=false
on them.
Here's an example of a popover inside another popover.
Naruto is a Japanese manga series written and illustrated by Masashi Kishimoto.
import { Text } from "@chakra-ui/react"
import { Button } from "@/components/ui/button"
import {
PopoverArrow,
PopoverBody,
PopoverContent,
PopoverRoot,
PopoverTrigger,
} from "@/components/ui/popover"
const Demo = () => {
return (
<PopoverRoot>
<PopoverTrigger asChild>
<Button size="sm" variant="outline">
Click me
</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverBody>
<Text mb="4">
Naruto is a Japanese manga series written and illustrated by Masashi
Kishimoto.
</Text>
<PopoverRoot>
<PopoverTrigger asChild>
<Button variant="outline" size="xs">
Open Nested Popover
</Button>
</PopoverTrigger>
<PopoverContent portalled={false}>
<PopoverArrow />
<PopoverBody>Some nested popover content</PopoverBody>
</PopoverContent>
</PopoverRoot>
</PopoverBody>
</PopoverContent>
</PopoverRoot>
)
}
Initial Focus
Use the initialFocusEl
prop to set the initial focus of the popover content.
"use client"
import { Box, Group } from "@chakra-ui/react"
import { Button } from "@/components/ui/button"
import {
PopoverArrow,
PopoverBody,
PopoverCloseTrigger,
PopoverContent,
PopoverFooter,
PopoverHeader,
PopoverRoot,
PopoverTrigger,
} from "@/components/ui/popover"
import { useRef } from "react"
const Demo = () => {
const ref = useRef<HTMLButtonElement>(null)
return (
<PopoverRoot initialFocusEl={() => ref.current}>
<PopoverTrigger asChild>
<Button size="sm" variant="outline">
Click me
</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverHeader>Manage Your Channels</PopoverHeader>
<PopoverArrow />
<PopoverBody>
This is a popover with the same width as the trigger button
</PopoverBody>
<PopoverFooter>
<Box fontSize="sm" flex="1">
Step 2 of 4
</Box>
<Group>
<Button size="sm" ref={ref}>
Prev
</Button>
<Button size="sm">Next</Button>
</Group>
</PopoverFooter>
<PopoverCloseTrigger />
</PopoverContent>
</PopoverRoot>
)
}
Form
Here's an example of a popover with a form inside.
import { Input, Stack, Textarea } from "@chakra-ui/react"
import { Button } from "@/components/ui/button"
import { Field } from "@/components/ui/field"
import {
PopoverArrow,
PopoverBody,
PopoverCloseTrigger,
PopoverContent,
PopoverRoot,
PopoverTrigger,
} from "@/components/ui/popover"
const Demo = () => {
return (
<PopoverRoot>
<PopoverTrigger asChild>
<Button size="sm" variant="outline">
Click me
</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverBody>
<Stack gap="4">
<Field label="Width">
<Input placeholder="40px" />
</Field>
<Field label="Height">
<Input placeholder="32px" />
</Field>
<Field label="Comments">
<Textarea placeholder="Start typing..." />
</Field>
</Stack>
</PopoverBody>
<PopoverCloseTrigger />
</PopoverContent>
</PopoverRoot>
)
}
Custom Background
Use the --popover-bg
CSS variable to change the background color of the
popover content and its arrow.
Naruto is a Japanese manga series written and illustrated by Masashi Kishimoto.
import { Input, Text } from "@chakra-ui/react"
import { Button } from "@/components/ui/button"
import {
PopoverArrow,
PopoverBody,
PopoverContent,
PopoverRoot,
PopoverTitle,
PopoverTrigger,
} from "@/components/ui/popover"
const Demo = () => {
return (
<PopoverRoot>
<PopoverTrigger asChild>
<Button size="sm" variant="outline">
Click me
</Button>
</PopoverTrigger>
<PopoverContent css={{ "--popover-bg": "lightblue" }}>
<PopoverArrow />
<PopoverBody>
<PopoverTitle fontWeight="medium">Naruto Form</PopoverTitle>
<Text my="4">
Naruto is a Japanese manga series written and illustrated by Masashi
Kishimoto.
</Text>
<Input bg="bg" placeholder="Your fav. character" size="sm" />
</PopoverBody>
</PopoverContent>
</PopoverRoot>
)
}
Without Snippet
If you don't want to use the snippet, you can use the Popover
component from
the @chakra-ui/react
package.
Naruto is a Japanese manga series written and illustrated by Masashi Kishimoto.
import { Button, Input, Popover, Portal, Text } from "@chakra-ui/react"
const Demo = () => {
return (
<Popover.Root>
<Popover.Trigger asChild>
<Button size="sm" variant="outline">
Click me
</Button>
</Popover.Trigger>
<Portal>
<Popover.Positioner>
<Popover.Content>
<Popover.Arrow>
<Popover.ArrowTip />
</Popover.Arrow>
<Popover.Body>
<Popover.Title fontWeight="medium">Naruto Form</Popover.Title>
<Text my="4">
Naruto is a Japanese manga series written and illustrated by
Masashi Kishimoto.
</Text>
<Input placeholder="Your fav. character" size="sm" />
</Popover.Body>
</Popover.Content>
</Popover.Positioner>
</Portal>
</Popover.Root>
)
}
Props
Root
Prop | Default | Type |
---|---|---|
autoFocus | true | boolean Whether to automatically set focus on the first focusable content within the popover when opened. |
closeOnEscape | true | boolean Whether to close the popover when the escape key is pressed. |
closeOnInteractOutside | true | boolean Whether to close the popover when the user clicks outside of the popover. |
lazyMount | false | boolean Whether to enable lazy mounting |
modal | false | boolean Whether the popover should be modal. When set to `true`: - interaction with outside elements will be disabled - only popover content will be visible to screen readers - scrolling is blocked - focus is trapped within the popover |
portalled | true | boolean Whether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. |
unmountOnExit | false | boolean Whether to unmount on exit. |
colorPalette | 'gray' | 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink' | 'accent' The color palette of the component |
size | 'md' | 'xs' | 'sm' | 'md' | 'lg' The size of the component |
defaultOpen | boolean The initial open state of the popover when it is first rendered. Use when you do not need to control its open state. | |
id | string The unique identifier of the machine. | |
ids | Partial<{
anchor: string
trigger: string
content: string
title: string
description: string
closeTrigger: string
positioner: string
arrow: string
}> The ids of the elements in the popover. Useful for composition. | |
immediate | boolean Whether to synchronize the present change immediately or defer it to the next frame | |
initialFocusEl | () => HTMLElement | null The element to focus on when the popover is opened. | |
onEscapeKeyDown | (event: KeyboardEvent) => void Function called when the escape key is pressed | |
onExitComplete | () => void Function called when the animation ends in the closed state | |
onFocusOutside | (event: FocusOutsideEvent) => void Function called when the focus is moved outside the component | |
onInteractOutside | (event: InteractOutsideEvent) => void Function called when an interaction happens outside the component | |
onOpenChange | (details: OpenChangeDetails) => void Function invoked when the popover opens or closes | |
onPointerDownOutside | (event: PointerDownOutsideEvent) => void Function called when the pointer is pressed down outside the component | |
open | boolean Whether the popover is open | |
persistentElements | (() => Element | null)[] Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | |
positioning | PositioningOptions The user provided options used to position the popover content | |
present | boolean Whether the node is present (controlled by the user) | |
as | React.ElementType The underlying element to render. | |
asChild | boolean Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
unstyled | boolean Whether to remove the component's style. |