Popover
<cw-popover> | CwPopover
Popovers display rich content anchored to a trigger, positioned with floating-ui and rendered via the native Popover API’s top layer — a good fit for content that doesn’t belong in a tooltip (hover-only) or a dropdown (menu-focused).
Popovers consist of a trigger and a panel. Activating the trigger shows the panel, anchored to it; clicking outside the panel or pressing Escape closes it again.
Popovers are a good fit for content that doesn’t belong in a tooltip (hover-only, not meant for rich or interactive content) or a dropdown (built around a menu). Forms, previews, and other rich content anchored to a trigger are all good candidates.
<cw-popover> <cw-button slot="trigger">Toggle</cw-button> This is a popover. </cw-popover>
import CwButton from '@cordwainer/cw-elements/dist/react/button'; import CwPopover from '@cordwainer/cw-elements/dist/react/popover'; const App = () => ( <CwPopover> <CwButton slot="trigger">Toggle</CwButton> This is a popover. </CwPopover> );
Examples
Placement
The preferred placement of the popover can be set with the placement attribute. Note that the
actual position may vary to ensure the popover remains in the viewport.
<cw-popover placement="top-start"> <cw-button slot="trigger">Toggle</cw-button> This is a popover. </cw-popover>
import CwButton from '@cordwainer/cw-elements/dist/react/button'; import CwPopover from '@cordwainer/cw-elements/dist/react/popover'; const App = () => ( <CwPopover placement="top-start"> <CwButton slot="trigger">Toggle</CwButton> This is a popover. </CwPopover> );
Distance and Skidding
The distance from the panel to the trigger, and its offset along the trigger, can be customized with the
distance and skidding attributes, respectively. Both are specified in pixels.
<cw-popover distance="20" skidding="20"> <cw-button slot="trigger">Toggle</cw-button> This is a popover. </cw-popover>
import CwButton from '@cordwainer/cw-elements/dist/react/button'; import CwPopover from '@cordwainer/cw-elements/dist/react/popover'; const App = () => ( <CwPopover distance={20} skidding={20}> <CwButton slot="trigger">Toggle</CwButton> This is a popover. </CwPopover> );
Arrow
Add the arrow attribute to display an arrow pointing at the trigger. Its size and color can be
customized with the --arrow-size and --arrow-color custom properties, or via
::part(arrow).
<cw-popover arrow> <cw-button slot="trigger">Toggle</cw-button> This is a popover. </cw-popover>
import CwButton from '@cordwainer/cw-elements/dist/react/button'; import CwPopover from '@cordwainer/cw-elements/dist/react/popover'; const App = () => ( <CwPopover arrow> <CwButton slot="trigger">Toggle</CwButton> This is a popover. </CwPopover> );
Disabled
Add the disabled attribute to prevent the popover from opening.
<cw-popover disabled> <cw-button slot="trigger">Toggle</cw-button> This is a popover. </cw-popover>
import CwButton from '@cordwainer/cw-elements/dist/react/button'; import CwPopover from '@cordwainer/cw-elements/dist/react/popover'; const App = () => ( <CwPopover disabled> <CwButton slot="trigger">Toggle</CwButton> This is a popover. </CwPopover> );
Controlling Open State
Use the open attribute, or the show() and hide() methods, to control
the popover’s open state from JavaScript.
<cw-popover class="popover-manual"> <cw-button slot="trigger">Toggle</cw-button> This is a popover. </cw-popover> <script> const popover = document.querySelector('.popover-manual'); popover.addEventListener('cw-after-show', () => console.log('shown')); popover.addEventListener('cw-after-hide', () => console.log('hidden')); </script>
import CwButton from '@cordwainer/cw-elements/dist/react/button'; import CwPopover from '@cordwainer/cw-elements/dist/react/popover'; const App = () => ( <CwPopover onCwAfterShow={() => console.log('shown')} onCwAfterHide={() => console.log('hidden')}> <CwButton slot="trigger">Toggle</CwButton> This is a popover. </CwPopover> );
Importing
If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.
To import this component from the CDN using a script tag:
<script type="module" src="https://cdn.jsdelivr.net/npm/@cordwainer/cw-elements@1.5.2/cdn/components/popover/popover.js"></script>
To import this component from the CDN using a JavaScript import:
import 'https://cdn.jsdelivr.net/npm/@cordwainer/cw-elements@1.5.2/cdn/components/popover/popover.js';
To import this component using a bundler:
import '@cordwainer/cw-elements/dist/components/popover/popover.js';
To import this component as a React component:
import CwPopover from '@cordwainer/cw-elements/dist/react/popover';
Slots
| Name | Description |
|---|---|
| (default) | The popover’s content. |
trigger
|
The element that anchors and toggles the popover, usually a <cw-button>. |
Learn more about using slots.
Properties
| Name | Description | Reflects | Type | Default |
|---|---|---|---|---|
open
|
Indicates whether or not the popover is open. You can toggle this attribute to show and hide the
popover, or you can use the show() and hide() methods. Clicking outside
the popover or pressing Escape closes it too.
|
|
boolean
|
false
|
placement
|
The preferred placement of the popover. Note that the actual placement may vary as needed to keep the popover inside of the viewport. |
|
'top' | 'top-start' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-end' | 'right' |
'right-start' | 'right-end' | 'left' | 'left-start' | 'left-end'
|
'top'
|
disabled
|
Disables the popover so it can’t be opened. |
|
boolean
|
false
|
distance
|
The distance in pixels from which to offset the popover away from its trigger. |
number
|
0
|
|
skidding
|
The distance in pixels from which to offset the popover along its trigger. |
number
|
0
|
|
arrow
|
Attaches an arrow to the popover, pointing at the trigger. The arrow’s size and color can be
customized using the --arrow-size and --arrow-color custom properties, or
via ::part(arrow).
|
|
boolean
|
false
|
updateComplete |
A read-only promise that resolves when the component has finished updating. |
Learn more about attributes and properties.
Events
| Name | React Event | Description | Event Detail |
|---|---|---|---|
cw-show |
onCwShow |
Emitted when the popover opens. | - |
cw-after-show |
onCwAfterShow |
Emitted after the popover opens and all animations are complete. | - |
cw-hide |
onCwHide |
Emitted when the popover closes, whether via hide()/toggling open, or
dismissed natively (clicking outside, pressing Escape).
|
- |
cw-after-hide |
onCwAfterHide |
Emitted after the popover closes and all animations are complete. | - |
Learn more about events.
Methods
| Name | Description | Arguments |
|---|---|---|
show() |
Shows the popover. | - |
hide() |
Hides the popover. | - |
reposition() |
Instructs the popover to recalculate and update its position. Useful if the trigger’s size or position changes. | - |
Learn more about methods.
Custom Properties
| Name | Description | Default |
|---|---|---|
--arrow-size |
The size of the arrow. Note that an arrow won’t be shown unless the arrow attribute is
used.
|
6px |
--arrow-color |
The color of the arrow. | var(–cw-color-neutral-0) |
Learn more about customizing CSS custom properties.
Parts
| Name | Description |
|---|---|
trigger |
The container that wraps the trigger. |
popup |
The outer popup container, the element the native Popover API and floating-ui both act on. Has no
visible styling of its own — see body for the visible box.
|
body |
The popup’s visible box (background, border, padding) wrapping its content. |
arrow |
The arrow’s container, present only when the arrow attribute is set. |
Learn more about customizing CSS parts.
Animations
| Name | Description |
|---|---|
popover.show |
The animation to use when showing the popover. |
popover.hide |
The animation to use when hiding the popover. |
Learn more about customizing animations.