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
chakra 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>
)
}
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. |