Popover
An overlay that displays additional information or options when triggered.
An overlay that displays additional information or options when triggered.
Tell us what is your favorite framework and why you love to use it.
To set up the popover correctly, you’ll need to understand its anatomy and how we name its parts.
Each part includes a
data-partattribute 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'
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'
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 { ref } from 'vue'
import { Popover } from '@ark-ui/vue'
const open = ref(false)
</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
Portalbased on the framework you use.
import { Popover, Portal } from '@ark-ui/react'
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 { Popover } from '@ark-ui/solid'
import { Portal } from 'solid-js/web'
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 { ref } from 'vue'
import { Popover } from '@ark-ui/vue'
const open = ref(false)
</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'
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'
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 { ref } from 'vue'
import { Popover } from '@ark-ui/vue'
const open = ref(false)
</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.
import { Popover } from '@ark-ui/react'
const OnOpenChange = () => {
return (
<Popover.Root onOpenChange={(open) => alert(open ? 'opened' : 'closed')}>
<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'
const OnOpenChange = () => {
return (
<Popover.Root onOpenChange={(open) => alert(open ? 'opened' : 'closed')}>
<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 { ref } from 'vue'
import { Popover } from '@ark-ui/vue'
const open = ref(false)
</script>
<template>
<Popover.Root @open-change="(open) => console.log(open ? 'opened' : 'closed')">
<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>
Use the isOpen prop to control the open state of the popover.
import { Popover } from '@ark-ui/react'
import { useState } from 'react'
const Controlled = () => {
const [isOpen, setIsOpen] = useState(false)
return (
<>
<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 { Popover } from '@ark-ui/solid'
import { createSignal } from 'solid-js'
const Controlled = () => {
const [isOpen, setIsOpen] = createSignal(false)
return (
<>
<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">
<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.
import { Popover } from '@ark-ui/react'
const CloseBehavior = () => (
<Popover.Root closeOnEsc={false} closeOnInteractOutside={false}>
<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'
import { Portal } from 'solid-js/web'
const CloseBehavior = () => (
<Popover.Root closeOnEsc={false} closeOnInteractOutside={false}>
<Popover.Trigger>Click Me</Popover.Trigger>
<Portal>
<Popover.Positioner>
<Popover.Content>
<Popover.Title>Title</Popover.Title>
<Popover.Description>Description</Popover.Description>
<Popover.CloseTrigger>Close</Popover.CloseTrigger>
</Popover.Content>
</Popover.Positioner>
</Portal>
</Popover.Root>
)
<script setup lang="ts">
import { ref } from 'vue'
import { Popover } from '@ark-ui/vue'
const open = ref(false)
</script>
<template>
<Popover.Root :closeOnEsc="false" :closeOnInteractOutside="false">
<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>
To change the placement of the popover, set the positioning prop.
import { Popover } from '@ark-ui/react'
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'
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 { ref } from 'vue'
import { Popover } from '@ark-ui/vue'
const open = ref(false)
</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'
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'
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 { ref } from 'vue'
import { Popover } from '@ark-ui/vue'
const open = ref(false)
</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 |
|---|---|---|
autoFocusWhether to automatically set focus on the first focusable content within the popover when opened. | boolean | |
closeOnEscWhether to close the popover when the escape key is pressed. | boolean | |
closeOnInteractOutsideWhether to close the popover when the user clicks outside of the popover. | boolean | |
defaultOpenThe initial open state of the popover. | boolean | |
dirThe document's text/writing direction. | 'ltr' | 'rtl' | "ltr" |
getRootNodeA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | () => Node | ShadowRoot | Document | |
idThe unique identifier of the machine. | string | |
idsThe 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
}> | |
initialFocusElThe element to focus on when the popover is opened. | HTMLElement | (() => MaybeElement) | |
lazyMountWhether to enable lazy mounting | boolean | false |
modalWhether 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 |
onEscapeKeyDownFunction called when the escape key is pressed | (event: KeyboardEvent) => void | |
onExitCompleteFunction called when the animation ends in the closed state. | () => void | |
onFocusOutsideFunction called when the focus is moved outside the component | (event: FocusOutsideEvent) => void | |
onInteractOutsideFunction called when an interaction happens outside the component | (event: InteractOutsideEvent) => void | |
onOpenChangeFunction invoked when the popover opens or closes | (details: OpenChangeDetails) => void | |
onPointerDownOutsideFunction called when the pointer is pressed down outside the component | (event: PointerDownOutsideEvent) => void | |
openWhether the popover is open | boolean | |
portalledWhether the popover is rendered in a portal | boolean | true |
positioningThe user provided options used to position the popover content | PositioningOptions | |
presentWhether the node is present (controlled by the user) | boolean | |
unmountOnExitWhether to unmount on exit. | boolean | false |
| Prop | Type | Default |
|---|---|---|
asChildRender as a different element type. | boolean |
| Prop | Type | Default |
|---|---|---|
asChildRender as a different element type. | boolean |
| Prop | Type | Default |
|---|---|---|
asChildRender as a different element type. | boolean |
| Prop | Type | Default |
|---|---|---|
asChildRender as a different element type. | boolean |
| Prop | Type | Default |
|---|---|---|
asChildRender as a different element type. | boolean |
| Prop | Type | Default |
|---|---|---|
asChildRender as a different element type. | boolean |
| Prop | Type | Default |
|---|---|---|
asChildRender as a different element type. | boolean |
| Prop | Type | Default |
|---|---|---|
asChildRender as a different element type. | boolean |
| Prop | Type | Default |
|---|---|---|
asChildRender as a different element type. | boolean |
| Prop | Type | Default |
|---|---|---|
asChildRender as a different element type. | boolean |