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.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>
)
}
用法
¥Usage
import { Popover } from "@chakra-ui/react"
<Popover.Root>
<Popover.Trigger />
<Popover.Positioner>
<Popover.Content>
<Popover.CloseTrigger />
<Popover.Arrow>
<Popover.ArrowTip />
</Popover.Arrow>
<Popover.Body>
<Popover.Title />
</Popover.Body>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
快捷键
¥Shortcuts
Popover 为常见用例提供了快捷方式。
¥The Popover provides a shortcuts for common use cases.
箭头
¥Arrow
Popover.Arrow 默认在其内部渲染 Popover.ArrowTip 组件。
¥The Popover.Arrow renders the Popover.ArrowTip component within in by
default.
有效:
¥This works:
<Popover.Arrow>
<Popover.ArrowTip />
</Popover.Arrow>
如果你不需要自定义箭头,这可能会更简洁。
¥This might be more concise, if you don't need to customize the arrow tip.
<Popover.Arrow />
示例
¥Examples
受控
¥Controlled
使用 open 和 onOpenChange 控制弹出窗口的可见性。
¥Use the open and onOpenChange to control the visibility of the popover.
"use client"
import { Button, Popover, Portal } from "@chakra-ui/react"
import { useState } from "react"
const Demo = () => {
const [open, setOpen] = useState(false)
return (
<Popover.Root open={open} onOpenChange={(e) => setOpen(e.open)}>
<Popover.Trigger asChild>
<Button size="sm" variant="outline">
Click me
</Button>
</Popover.Trigger>
<Portal>
<Popover.Positioner>
<Popover.Content>
<Popover.Arrow />
<Popover.Body>
This is a popover with the same width as the trigger button
</Popover.Body>
</Popover.Content>
</Popover.Positioner>
</Portal>
</Popover.Root>
)
}
尺寸
¥Sizes
使用 size 属性更改弹出窗口组件的大小。
¥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 {
Button,
For,
Input,
Popover,
Portal,
Stack,
Text,
} from "@chakra-ui/react"
const Demo = () => {
return (
<Stack align="center" direction="row" gap="10">
<For each={["xs", "sm", "md", "lg"]}>
{(size) => (
<Popover.Root key={size} size={size}>
<Popover.Trigger asChild>
<Button size={size} variant="outline">
Click me
</Button>
</Popover.Trigger>
<Portal>
<Popover.Positioner>
<Popover.Content>
<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={size} />
</Popover.Body>
</Popover.Content>
</Popover.Positioner>
</Portal>
</Popover.Root>
)}
</For>
</Stack>
)
}
延迟加载
¥Lazy Mount
使用 lazyMounted 和/或 unmountOnExit 属性可将弹出框内容的加载延迟到弹出框打开时。
¥Use the lazyMounted and/or unmountOnExit prop to defer the mounting of the
popover content until it's opened.
import { Button, Popover, Portal, Text } from "@chakra-ui/react"
const Demo = () => {
return (
<Popover.Root lazyMount unmountOnExit>
<Popover.Trigger asChild>
<Button size="sm" variant="outline">
Click me
</Button>
</Popover.Trigger>
<Portal>
<Popover.Positioner>
<Popover.Content>
<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>
</Popover.Body>
</Popover.Content>
</Popover.Positioner>
</Portal>
</Popover.Root>
)
}
放置位置
¥Placement
使用 positioning.placement 属性配置底层 floating-ui 定位逻辑。
¥Use the positioning.placement prop to configure the underlying floating-ui
positioning logic.
import { Button, Popover, Portal } from "@chakra-ui/react"
const Demo = () => {
return (
<Popover.Root positioning={{ placement: "bottom-end" }}>
<Popover.Trigger asChild>
<Button size="sm" variant="outline">
Click me
</Button>
</Popover.Trigger>
<Portal>
<Popover.Positioner>
<Popover.Content>
<Popover.Arrow />
<Popover.Body>Some content</Popover.Body>
</Popover.Content>
</Popover.Positioner>
</Portal>
</Popover.Root>
)
}
偏移
¥Offset
使用 positioning.offset 属性调整弹出框内容的位置。
¥Use the positioning.offset prop to adjust the position of the popover content.
import { Button, Popover, Portal } from "@chakra-ui/react"
const Demo = () => {
return (
<Popover.Root positioning={{ offset: { crossAxis: 0, mainAxis: 0 } }}>
<Popover.Trigger asChild>
<Button size="sm" variant="outline">
Open
</Button>
</Popover.Trigger>
<Portal>
<Popover.Positioner>
<Popover.Content>
<Popover.Body>
This popover has a custom offset from its trigger
</Popover.Body>
</Popover.Content>
</Popover.Positioner>
</Portal>
</Popover.Root>
)
}
宽度相同
¥Same Width
使用 positioning.sameWidth 属性使弹出窗口内容与触发器宽度相同。
¥Use the positioning.sameWidth prop to make the popover content the same width
as the trigger.
import { Button, Popover, Portal } from "@chakra-ui/react"
const Demo = () => {
return (
<Popover.Root positioning={{ sameWidth: true }}>
<Popover.Trigger asChild>
<Button size="sm" variant="outline" minW="xs">
Click me
</Button>
</Popover.Trigger>
<Portal>
<Popover.Positioner>
<Popover.Content width="auto">
<Popover.Arrow />
<Popover.Body>
This is a popover with the same width as the trigger button
</Popover.Body>
</Popover.Content>
</Popover.Positioner>
</Portal>
</Popover.Root>
)
}
嵌套弹出框
¥Nested Popover
在弹出框内嵌套诸如弹出框、选择框、菜单等叠加元素时,请在这些元素上设置 portalled=false。
¥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 { Button, 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.Body>
<Text mb="4">
Naruto is a Japanese manga series written and illustrated by
Masashi Kishimoto.
</Text>
<Popover.Root>
<Popover.Trigger asChild>
<Button variant="outline" size="xs">
Open Nested Popover
</Button>
</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<Popover.Arrow />
<Popover.Body>Some nested popover content</Popover.Body>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
</Popover.Body>
</Popover.Content>
</Popover.Positioner>
</Portal>
</Popover.Root>
)
}
初始焦点
¥Initial Focus
使用 initialFocusEl 属性设置弹出内容的初始焦点。
¥Use the initialFocusEl prop to set the initial focus of the popover content.
"use client"
import { Box, Button, Group, Popover, Portal } from "@chakra-ui/react"
import { useRef } from "react"
const Demo = () => {
const ref = useRef<HTMLButtonElement | null>(null)
return (
<Popover.Root initialFocusEl={() => ref.current}>
<Popover.Trigger asChild>
<Button size="sm" variant="outline">
Click me
</Button>
</Popover.Trigger>
<Portal>
<Popover.Positioner>
<Popover.Content>
<Popover.Header>Manage Your Channels</Popover.Header>
<Popover.Arrow />
<Popover.Body>
This is a popover with the same width as the trigger button
</Popover.Body>
<Popover.Footer>
<Box fontSize="sm" flex="1">
Step 2 of 4
</Box>
<Group>
<Button size="sm" ref={ref}>
Prev
</Button>
<Button size="sm">Next</Button>
</Group>
</Popover.Footer>
<Popover.CloseTrigger />
</Popover.Content>
</Popover.Positioner>
</Portal>
</Popover.Root>
)
}
表单
¥Form
这是一个带有表单的弹出窗口示例。
¥Here's an example of a popover with a form inside.
import {
Button,
Field,
Input,
Popover,
Portal,
Stack,
Textarea,
} 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.Body>
<Stack gap="4">
<Field.Root>
<Field.Label>Width</Field.Label>
<Input placeholder="40px" />
</Field.Root>
<Field.Root>
<Field.Label>Height</Field.Label>
<Input placeholder="32px" />
</Field.Root>
<Field.Root>
<Field.Label>Comments</Field.Label>
<Textarea placeholder="Start typing..." />
</Field.Root>
</Stack>
</Popover.Body>
<Popover.CloseTrigger />
</Popover.Content>
</Popover.Positioner>
</Portal>
</Popover.Root>
)
}
自定义背景
¥Custom Background
使用 --popover-bg CSS 变量更改弹出内容及其箭头的背景颜色。
¥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 { 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 css={{ "--popover-bg": "lightblue" }}>
<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 bg="bg" placeholder="Your fav. character" size="sm" />
</Popover.Body>
</Popover.Content>
</Popover.Positioner>
</Portal>
</Popover.Root>
)
}
在对话框中
¥Within Dialog
要在 Dialog 中使用 Popover,你需要避免将 Popover.Positioner 传送到文档正文。
¥To use the Popover within a Dialog, you need to avoid portalling the
Popover.Positioner to the document's body.
-<Portal>
<Popover.Positioner>
<Popover.Content>
{/* ... */}
</Popover.Content>
</Popover.Positioner>
-</Portal>
如果你已在 Dialog 上设置了 scrollBehavior="inside",则需要:
¥If you have set scrollBehavior="inside" on the Dialog, you need to:
-
将弹出框定位设置为
fixed,以避免弹出框被对话框裁剪。 -
将
hideWhenDetached设置为true,以便在触发器滚动出视图时隐藏弹出窗口。
<Popover.Root positioning={{ strategy: "fixed", hideWhenDetached: true }}>
{/* ... */}
</Popover.Root>
"use client"
import {
Button,
CloseButton,
Dialog,
Popover,
Portal,
Text,
} from "@chakra-ui/react"
const Demo = () => {
return (
<Dialog.Root>
<Dialog.Trigger asChild>
<Button variant="outline">Open Dialog</Button>
</Dialog.Trigger>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.CloseTrigger asChild>
<CloseButton />
</Dialog.CloseTrigger>
<Dialog.Header>
<Dialog.Title>Popover in Dialog</Dialog.Title>
</Dialog.Header>
<Dialog.Body>
<DialogPopover />
</Dialog.Body>
<Dialog.Footer />
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
)
}
function DialogPopover() {
return (
<Popover.Root>
<Popover.Trigger asChild>
<Button size="sm" variant="outline">
Click me
</Button>
</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<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>
</Popover.Body>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
)
}
属性
¥Props
根元素
¥Root
| Prop | Default | Type |
|---|---|---|
autoFocus | true | booleanWhether to automatically set focus on the first focusable content within the popover when opened. |
closeOnEscape | true | booleanWhether to close the popover when the escape key is pressed. |
closeOnInteractOutside | true | booleanWhether to close the popover when the user clicks outside of the popover. |
lazyMount | false | booleanWhether to enable lazy mounting |
modal | false | booleanWhether 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 | booleanWhether the popover is portalled. This will proxy the tabbing behavior regardless of the DOM position of the popover content. |
skipAnimationOnMount | false | booleanWhether to allow the initial presence animation. |
unmountOnExit | false | booleanWhether to unmount on exit. |
colorPalette | 'gray' | 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink'The color palette of the component |
size | 'md' | 'xs' | 'sm' | 'md' | 'lg'The size of the component |
as | React.ElementTypeThe underlying element to render. | |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
unstyled | booleanWhether to remove the component's style. | |
defaultOpen | booleanThe initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | |
id | stringThe 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 | booleanWhether to synchronize the present change immediately or defer it to the next frame | |
initialFocusEl | () => HTMLElement | nullThe element to focus on when the popover is opened. | |
onEscapeKeyDown | (event: KeyboardEvent) => voidFunction called when the escape key is pressed | |
onExitComplete | VoidFunctionFunction called when the animation ends in the closed state | |
onFocusOutside | (event: FocusOutsideEvent) => voidFunction called when the focus is moved outside the component | |
onInteractOutside | (event: InteractOutsideEvent) => voidFunction called when an interaction happens outside the component | |
onOpenChange | (details: OpenChangeDetails) => voidFunction invoked when the popover opens or closes | |
onPointerDownOutside | (event: PointerDownOutsideEvent) => voidFunction called when the pointer is pressed down outside the component | |
open | booleanThe controlled open state of the popover | |
persistentElements | (() => Element | null)[]Returns the persistent elements that: - should not have pointer-events disabled - should not trigger the dismiss event | |
positioning | PositioningOptionsThe user provided options used to position the popover content | |
present | booleanWhether the node is present (controlled by the user) |