Popover
View as MarkdownAn accessible popup anchored to a button.
<ui:popover.root>
<ui:popover.trigger asChild="{true}">
<ui:button>Open Popover</ui:button>
</ui:popover.trigger>
<ui:popover.content>
<ui:popover.title>Notifications</ui:popover.title>
<ui:popover.description>You are all caught up. Good job!</ui:popover.description>
</ui:popover.content>
</ui:popover.root>
import { mountAll } from 'fluid-primitives';
import { Popover } from 'fluid-primitives/popover';
mountAll('popover', ({ props }) => {
const popover = new Popover(props);
popover.init();
return popover;
});
Features
- Focus is managed and can be trapped within the popover
- Supports modal and non-modal modes
- Supports custom positioning with placement options
- Pressing
Escapecloses the popover - Automatically adjusts position to stay in viewport
Installation
typo3 ui:add popover
Please copy the files manually from GitHub into your project.
Read more about installing Components and Primitives.
Examples
With Close Button
Show a close button inside the popover.
<ui:popover.root>
<ui:popover.trigger asChild="{true}">
<ui:button>Open Popover</ui:button>
</ui:popover.trigger>
<ui:popover.content showCloseButton="{true}">
<ui:popover.title>Closeable</ui:popover.title>
<ui:popover.description>Click the X button to close.</ui:popover.description>
</ui:popover.content>
</ui:popover.root>
Custom Positioning
Control where the popover appears relative to the trigger.
<ui:popover.root positioning="{placement: 'right'}">
<ui:popover.trigger asChild="{true}">
<ui:button>Open Right</ui:button>
</ui:popover.trigger>
<ui:popover.content>
<ui:popover.title>Right Position</ui:popover.title>
<ui:popover.description>This popover opens to the right.</ui:popover.description>
</ui:popover.content>
</ui:popover.root>
Modal Mode
Make the popover modal to trap focus and block interaction with the rest of the page.
<ui:popover.root modal="{true}">
<ui:popover.trigger asChild="{true}">
<ui:button>Open Modal Popover</ui:button>
</ui:popover.trigger>
<ui:popover.content>
<ui:popover.title>Modal Popover</ui:popover.title>
<ui:popover.description>Focus is trapped within this popover.</ui:popover.description>
</ui:popover.content>
</ui:popover.root>
Localization
Default close trigger labels are shipped via XLF and follow the current Site Language. For per-template overrides, pass translated strings through the translations prop. Set closeTriggerLabel to {false} or an empty string to omit the aria-label.
<ui:popover.root
translations="{
closeTriggerLabel: f:translate(key: 'LLL:EXT:site_package/Resources/Private/Language/locallang.xlf:popover.close')
}"
>
...
</ui:popover.root>
API Reference
The following tables cover the available props of the Fluid Primitives. For a full list of available client side props and methods, see the Zag.js Machine API.
popover.root
Provides popover state and context for the composed parts. Renders no wrapper element.
| Name | Description | Required | Default |
|---|---|---|---|
modal | booleanWhether the popover should be modal. | No | false |
portalled | booleanWhether the popover is portalled and proxies tabbing behavior regardless of DOM position. | No | true |
autoFocus | booleanWhether to automatically set focus on the first focusable content within the popover when opened. | No | true |
restoreFocus | booleanWhether to restore focus to the element that had focus before the popover was opened. | No | true |
closeOnInteractOutside | booleanWhether to close the popover when the user clicks outside of the popover. | No | true |
closeOnEscape | booleanWhether to close the popover when the escape key is pressed. | No | true |
positioning | arrayThe user provided options used to position the popover content. | No | - |
defaultOpen | booleanThe initial open state of the popover when rendered. Use when you don't need to control the open state of the popover. | No | false |
translations | arrayLocalized popover labels. Set entries to `` to omit the corresponding `aria-label`. Use `f:translate` for per-template localization overrides when needed. | No | - |
rootId | stringThe root ID of the component, used for hydration and identification. | No | - |
ids | arrayThe IDs of of the component parts for composition. | No | [] |
controlled | booleanIf true, the component is meant to be initialized manually inside another component | No | false |
popover.trigger
Opens and closes the popover. Renders a <button> element.
| Name | Description | Required | Default |
|---|---|---|---|
value | string | No | - |
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
Rendered data attributes
| Attribute | Description |
|---|---|
data-scope | popover |
data-part | trigger |
data-placement | The placement of the trigger |
data-side | The side of the trigger that the trigger is positioned on |
data-value | The value of the item |
data-current | Present when current |
data-state | "open" | "closed" |
popover.positioner
Positions the popover content relative to the trigger. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
popover.content
Contains the popover panel content. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
Rendered data attributes
| Attribute | Description |
|---|---|
data-scope | popover |
data-part | content |
data-state | "open" | "closed" |
data-nested | popover |
data-has-nested | popover |
data-expanded | Present when expanded |
data-placement | The placement of the content |
data-side | The side of the trigger that the content is positioned on |
popover.arrow
Displays a decorative arrow for the popover. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
popover.indicator
Displays a decorative state indicator. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
Rendered data attributes
| Attribute | Description |
|---|---|
data-scope | popover |
data-part | indicator |
data-state | "open" | "closed" |
popover.title
Provides the accessible title for the popover. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
popover.description
Provides supporting descriptive text for the popover. Renders a <div> element.
| Name | Description | Required | Default |
|---|---|---|---|
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
popover.closeTrigger
Closes the popover when activated. Renders a <button> element.
| Name | Description | Required | Default |
|---|---|---|---|
asChild | booleanIf true the component uses its child only without the component template. Like Radix UI asChild or Base UI render props. | No | - |
class | stringThe CSS class(es) to be applied to the component. | No | - |
attributes | arrayAdditional attributes that should be rendered on the component where ui:attributes is used. | No | [] |
Machine JavaScript API
| Name | Type | Description |
|---|---|---|
portalled | boolean | Whether the popover is portalled. |
open | boolean | Whether the popover is open |
setOpen | (open: boolean) => void | Function to open or close the popover |
triggerValue | string | null | The trigger value |
setTriggerValue | (value: string | null) => void | Function to set the trigger value |
reposition | (options?: Partial<PositioningOptions>) => void | Function to reposition the popover |
Accessibility
| Key | Description |
|---|---|
Space | Opens/closes the popover. |
Enter | Opens/closes the popover. |
Tab | Moves focus to the next focusable element within the content. Note: If there are no focusable elements, focus is moved to the next focusable element after the trigger. |
Shift + Tab | Moves focus to the previous focusable element within the content Note: If there are no focusable elements, focus is moved to the trigger. |
Esc | Closes the popover and moves focus to the trigger. |
Anatomy
<primitives:popover.root>
<primitives:popover.trigger />
<primitives:popover.positioner>
<primitives:popover.content>
<primitives:popover.arrow />
<primitives:popover.closeTrigger />
<primitives:popover.title />
<primitives:popover.description />
</primitives:popover.content>
</primitives:popover.positioner>
</primitives:popover.root>