Displays rich content in a portal, triggered by a button.
import React from 'react';
import {
Popover,
PopoverTrigger,
Button,
PopoverContent,
InvisibleTextField,
} from '@minddrop/ui';
export const PopoverDemo = () => (
<div style={{ display: 'flex', alignItems: 'center' }}>
<Popover>
<PopoverTrigger>
<Button>Rename topic</Button>
</PopoverTrigger>
<PopoverContent sideOffset={-6}>
<InvisibleTextField
style={{ padding: '4px 8px' }}
label="Topic name"
placeholder="Untitled"
defaultValue="The book of tea"
size="large"
/>
</PopoverContent>
</Popover>
</div>
);
export default PopoverDemo;
Import the component from the @minddrop/ui
package.
import {
Popover,
PopoverTrigger,
PopoverContent,
PopoverClose,
} from '@minddrop/ui';
export default () => (
<Popover>
<PopoverTrigger>Popover trigger</PopoverTrigger>
<PopoverContent>
<h3>Popover content</h3>
<p>Are you sure you wanna do this?</p>
<PopoverClose>Yes</PopoverClose>
</PopoverContent>
</Popover>
);
You can anchor the content to another element if you do not want to use the trigger as the anchor.
import {
Popover,
PopoverAnchor,
PopoverTrigger,
PopoverContent,
PopoverClose,
} from '@minddrop/ui';
export default () => (
<Popover>
<PopoverAnchor>
Row as anchor <PopoverTrigger>Trigger</PopoverTrigger>
</PopoverAnchor>
<PopoverContent>
<h3>Popover content</h3>
<p>Are you sure you wanna do this?</p>
<PopoverClose>Yes</PopoverClose>
</PopoverContent>
</Popover>
);
Radix exposes a CSS custom property --radix-popover-content-transform-origin
. Use it to animate the content from its computed origin based on side
, sideOffset
, align
, alignOffset
and any collisions.
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0);
}
to {
opacity: 1;
transform: scale(1);
}
}
.popover {
transform-origin: var(--radix-popover-content-transform-origin);
animation: scaleIn 0.5s ease-out;
}
Radix exposes data-side
and data-align
attributes. Their values will change at runtime to reflect collisions. Use them to create collision and direction-aware animations.
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(0);
}
to {
opacity: 1;
transform: translateY(-10px);
}
}
.popover {
animation-duration: 0.6s;
animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
}
.popover[data-side='bottom'] {
animation: slideDown;
}
.popover[data-side='top'] {
animation: slideUp;
}
Contains all the parts of a popover.
Prop | Type | Default |
---|---|---|
defaultOpen | boolean | |
open | boolean | |
onOpenChange | function | |
modal | boolean | false |
The button that toggles the popover. By default, the PopoverContent
will position itself against the trigger.
Prop | Type | Default |
---|---|---|
asChild | boolean | true |
An optional element to position the PopoverContent
against. If this part is not used, the content will position alongside the PopoverTrigger
.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
The component that pops out when the popover is open.
Prop | Type | Default |
---|---|---|
allowPinchZoom | boolean | false |
onOpenAutoFocus | function | |
onCloseAutoFocus | function | |
onEscapeKeyDown | function | |
onPointerDownOutside | function | |
onFocusOutside | function | |
onInteractOutside | function | |
portalled | boolean | true |
forceMount | boolean | |
side | "top" | "right" | "bottom" | "left" | "bottom" |
sideOffset | number | 0 |
align | "start" | "center" | "end" | "center" |
alignOffset | number | 0 |
avoidCollisions | boolean | true |
collisionTolerance | number | 0 |
The button that closes an open popover.
Prop | Type | Default |
---|---|---|
asChild | boolean | false |
Adheres to the Dialog WAI-ARIA design pattern.
Key | Description |
---|---|
Space | Opens/closes the popover. |
Enter | Opens/closes the popover. |
Tab | Moves focus to the next focusable element |
Shift + Tab | Moves focus to the previous focusable element |
Esc | Closes the popover and moves focus to PopoverTrigger . |