Popover
An overlay that displays additional information or options when triggered.
An overlay that displays additional information or options when triggered.
To set up the popover correctly, you’ll need to understand its anatomy and how we name its parts.
Each part includes a
data-part
attribute to help identify them in the DOM.
Learn how to use the Popover
component in your project. Let’s take a look at
the most basic example:
import { Popover } from '@ark-ui/react'
export const Basic = () => (
<Popover.Root>
<Popover.Trigger>
Click Me <Popover.Indicator>{'>'}</Popover.Indicator>
</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
)
import { Popover } from '@ark-ui/solid'
export const Basic = () => (
<Popover.Root>
<Popover.Trigger>
Click Me <Popover.Indicator>{'>'}</Popover.Indicator>
</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
)
<script setup lang="ts">
import { Popover } from '@ark-ui/vue'
</script>
<template>
<Popover.Root>
<Popover.Trigger>
Click Me
<Popover.Indicator>{{ '>' }}</Popover.Indicator>
</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
</template>
By default, the popover is rendered in the same DOM hierarchy as the trigger. To
render the popover within a portal, set the portalled
prop to true
.
Note: This requires that you render the component within a
Portal
based on the framework you use.
import { Popover, Portal } from '@ark-ui/react'
export const Portalled = () => (
<Popover.Root portalled>
<Popover.Trigger>
Click Me <Popover.Indicator>{'>'}</Popover.Indicator>
</Popover.Trigger>
<Portal>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
</Popover.Content>
</Popover.Positioner>
</Portal>
</Popover.Root>
)
import { Portal } from 'solid-js/web'
import { Popover } from '@ark-ui/solid'
export const Portalled = () => (
<Popover.Root portalled>
<Popover.Trigger>
Click Me <Popover.Indicator>{'>'}</Popover.Indicator>
</Popover.Trigger>
<Portal>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
</Popover.Content>
</Popover.Positioner>
</Portal>
</Popover.Root>
)
<script setup lang="ts">
import { Popover } from '@ark-ui/vue'
</script>
<template>
<Popover.Root portalled>
<Popover.Trigger>
Click Me
<Popover.Indicator>{{ '>' }}</Popover.Indicator>
</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
</template>
To render an arrow within the popover, render the component Popover.Arrow
and
Popover.ArrowTip
as children of Popover.Positioner
.
import { Popover } from '@ark-ui/react'
export const Arrow = () => (
<Popover.Root>
<Popover.Trigger>Click Me</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<Popover.Arrow>
<Popover.ArrowTip />
</Popover.Arrow>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
<Popover.CloseTrigger>Close</Popover.CloseTrigger>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
)
import { Popover } from '@ark-ui/solid'
export const Arrow = () => (
<Popover.Root>
<Popover.Trigger>Click Me</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<Popover.Arrow>
<Popover.ArrowTip />
</Popover.Arrow>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
<Popover.CloseTrigger>Close</Popover.CloseTrigger>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
)
<script setup lang="ts">
import { Popover } from '@ark-ui/vue'
</script>
<template>
<Popover.Root>
<Popover.Trigger>Click Me</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<Popover.Arrow>
<Popover.ArrowTip />
</Popover.Arrow>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
<Popover.CloseTrigger>Close</Popover.CloseTrigger>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
</template>
When the popover is opened or closed, we invoke the onOpenChange
callback.
Story not found
Story not found
Story not found
Use the isOpen
prop to control the open state of the popover.
import { useState } from 'react'
import { Popover } from '@ark-ui/react'
export const Controlled = () => {
const [isOpen, setIsOpen] = useState(false)
return (
<>
<button type="button" onClick={() => setIsOpen(!isOpen)}>
Toggle
</button>
<Popover.Root open={isOpen}>
<Popover.Anchor>Anchor</Popover.Anchor>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
<Popover.CloseTrigger>Close</Popover.CloseTrigger>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
</>
)
}
import { createSignal } from 'solid-js'
import { Popover } from '@ark-ui/solid'
export const Controlled = () => {
const [isOpen, setIsOpen] = createSignal(false)
return (
<>
<button type="button" onClick={() => setIsOpen(!isOpen())}>
Toggle
</button>
<Popover.Root open={isOpen()}>
<Popover.Anchor>Anchor</Popover.Anchor>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
<Popover.CloseTrigger>Close</Popover.CloseTrigger>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
</>
)
}
<script setup lang="ts">
import { ref } from 'vue'
import { Popover } from '@ark-ui/vue'
const open = ref(false)
</script>
<template>
<Fragment>
<button @click="() => (open = !open)">toggle</button>
<Popover.Root v-model:open="open">
<Popover.Anchor>Anchor</Popover.Anchor>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
<Popover.CloseTrigger>Close</Popover.CloseTrigger>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
</Fragment>
</template>
The popover is designed to close on blur and when the esc key is pressed.
To prevent it from closing on blur (clicking or focusing outside), pass the
closeOnInteractOutside
prop and set it to false
.
To prevent it from closing when the esc key is pressed, pass the
closeOnEsc
prop and set it to false
.
Story not found
Story not found
Story not found
To change the placement of the popover, set the positioning
prop.
import { Popover } from '@ark-ui/react'
export const Positioning = () => (
<Popover.Root
positioning={{ placement: 'left-start', gutter: 16, offset: { mainAxis: 12, crossAxis: 12 } }}
>
<Popover.Trigger>Click Me</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
<Popover.CloseTrigger>Close</Popover.CloseTrigger>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
)
import { Popover } from '@ark-ui/solid'
export const Positioning = () => (
<Popover.Root
positioning={{ placement: 'left-start', gutter: 16, offset: { mainAxis: 12, crossAxis: 12 } }}
>
<Popover.Trigger>Click Me</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
<Popover.CloseTrigger>Close</Popover.CloseTrigger>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
)
<script setup lang="ts">
import { Popover } from '@ark-ui/vue'
</script>
<template>
<Popover.Root
:positioning="{
placement: 'left-start',
gutter: 16,
offset: { mainAxis: 12, crossAxis: 12 },
}"
>
<Popover.Trigger>Click Me</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
<Popover.CloseTrigger>Close</Popover.CloseTrigger>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
</template>
In some cases, you might want the popover to be modal. This means that it’ll:
To make the popover modal, set the modal
prop to true
. When modal={true}
,
we set the portalled
attribute to true
as well.
import { Popover } from '@ark-ui/react'
export const Modal = () => (
<Popover.Root modal>
<Popover.Trigger>Click Me</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
<Popover.CloseTrigger>Close</Popover.CloseTrigger>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
)
import { Popover } from '@ark-ui/solid'
export const Modal = () => (
<Popover.Root modal>
<Popover.Trigger>Click Me</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
<Popover.CloseTrigger>Close</Popover.CloseTrigger>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
)
<script setup lang="ts">
import { Popover } from '@ark-ui/vue'
</script>
<template>
<Popover.Root modal>
<Popover.Trigger>Click Me</Popover.Trigger>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
<Popover.CloseTrigger>Close</Popover.CloseTrigger>
</Popover.Content>
</Popover.Positioner>
</Popover.Root>
</template>
Prop | Type | Default |
---|---|---|
autoFocus Whether to automatically set focus on the first focusable
content within the popover when opened. | boolean | |
closeOnEsc Whether to close the popover when the escape key is pressed. | boolean | |
closeOnInteractOutside Whether to close the popover when the user clicks outside of the popover. | boolean | |
defaultOpen The initial open state of the popover when it is first rendered.
Use when you do not need to control its open state. | boolean | |
id The unique identifier of the machine. | string | |
ids The ids of the elements in the popover. Useful for composition. | Partial<{
anchor: string
trigger: string
content: string
title: string
description: string
closeTrigger: string
positioner: string
arrow: string
}> | |
initialFocusEl The element to focus on when the popover is opened. | HTMLElement | (() => MaybeElement) | |
lazyMount Whether to enable lazy mounting | boolean | false |
modal 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 | boolean | false |
onEscapeKeyDown Function called when the escape key is pressed | (event: KeyboardEvent) => void | |
onExitComplete Function called when the animation ends in the closed state. | () => void | |
onFocusOutside Function called when the focus is moved outside the component | (event: FocusOutsideEvent) => void | |
onInteractOutside Function called when an interaction happens outside the component | (event: InteractOutsideEvent) => void | |
onOpenChange Function invoked when the popover opens or closes | (details: OpenChangeDetails) => void | |
onPointerDownOutside Function called when the pointer is pressed down outside the component | (event: PointerDownOutsideEvent) => void | |
open Whether the popover is open | boolean | |
portalled Whether the popover is rendered in a portal | boolean | true |
positioning The user provided options used to position the popover content | PositioningOptions | |
present Whether the node is present (controlled by the user) | boolean | |
unmountOnExit Whether to unmount on exit. | boolean | false |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |
Prop | Type | Default |
---|---|---|
asChild Render as a different element type. | boolean |