Components
Popover
Popover appears above other elements in the interface and is linked to a specific element. It is used to display additional information, interactive elements, or brief explanations without navigating away from the page.
React
const PreviewEn = () => { return ( <Popover.TriggerContext> <Popover.Trigger>Open popover</Popover.Trigger> <Popover placement='top'> The popover provides a quick message. You can use it to show the user information that is relevant to the context. </Popover> </Popover.TriggerContext> ); }; render(<PreviewEn />)
- id
- Description
id to connect the trigger with the popover - required when not using Popover.Context.
- Type
string
- placement
- Description
Placement of the popover on the trigger.
- Type
Placement- Default
top
- open
- Description
When a boolean is provided, the popover will be controlled.
- Type
boolean- Default
undefined
- variant
- Description
Change the background color of the popover.
- Type
"default" | "tinted"- Default
default
- onOpen
- Description
Callback when the popover wants to open.
- Type
() => void
- onClose
- Description
Callback when the popover wants to close.
- Type
() => void
- autoPlacement
- Description
Whether to enable auto placement.
- Type
boolean- Default
true
- asChild
- Description
Change the default rendered element for the one passed as a child, merging their props and behavior.
- Type
boolean- Default
false
| Name | Type | Default | Description |
|---|---|---|---|
| id | string | - | id to connect the trigger with the popover - required when not using Popover.Context. |
| placement | Placement | top | Placement of the popover on the trigger. |
| open | boolean | undefined | When a boolean is provided, the popover will be controlled. |
| variant | "default" | "tinted" | default | Change the background color of the popover. |
| onOpen | () => void | - | Callback when the popover wants to open. |
| onClose | () => void | - | Callback when the popover wants to close. |
| autoPlacement | boolean | true | Whether to enable auto placement. |
| asChild | boolean | false | Change the default rendered element for the one passed as a child, merging their props and behavior. |
Use
React and popovertarget
When you use Popover without Popover.TriggerContext, you connect the trigger and Popover yourself.
In this case, popovertarget is used in lowercase, so that all versions of React correctly render the attribute.
When you use @digdir/designsystemet-react we extend @types/react-dom to accept this.
Polyfill
Popover uses popover (mozilla.org).
This api is classified as Baseline: Newly available (mozilla.org) as of April 2024, when Firefox was the last browser to add it.
In some cases, you may find that users are locked to older browser versions for various reasons, and then it may be appropriate to add a Popover-Polyfill (github.com) to ensure that Popover works for everyone.
Examples
Standard
React
const PreviewEn = () => { return ( <Popover.TriggerContext> <Popover.Trigger>Open popover</Popover.Trigger> <Popover placement='top'> The popover provides a quick message. You can use it to show the user information that is relevant to the context. </Popover> </Popover.TriggerContext> ); }; render(<PreviewEn />)
Inline trigger
React
const DottedUnderlineEn = () => { return ( <Popover.TriggerContext> <Paragraph> We use <Popover.Trigger inline>design tokens</Popover.Trigger> to ensure a consistent design. </Paragraph> <Popover data-color='neutral'> <Paragraph> <strong style={{ display: 'block', }} > Design tokens </strong> Design tokens are a collection of variables that define the visual style within a design system. </Paragraph> </Popover> </Popover.TriggerContext> ); }; render(<DottedUnderlineEn />)
Controlled
You can control when the popover is opened or closed:
React
const ControlledEn = () => { const [open, setOpen] = useState(false); return ( <Popover.TriggerContext> <Popover.Trigger onClick={() => setOpen(!open)}>Delete</Popover.Trigger> <Popover open={open} onClose={() => setOpen(false)} data-color='danger'> <Paragraph>Are you sure you want to delete this?</Paragraph> <div style={{ display: 'flex', gap: 'var(--ds-size-2)', marginTop: 'var(--ds-size-2)', }} > <Button onClick={() => setOpen(false)} data-size='sm' data-color='danger' > Delete </Button> <Button data-variant='tertiary' onClick={() => setOpen(false)} data-size='sm' > Cancel </Button> </div> </Popover> </Popover.TriggerContext> ); }; render(<ControlledEn />)
Without TriggerContext
You can also use Popover without TriggerContext by using popovertarget:
React
const WithoutContextEn = () => { const [open, setOpen] = useState(false); return ( <> <Button data-color='danger' popovertarget='my-popover' onClick={() => setOpen(!open)} > Delete </Button> <Popover id='my-popover' open={open} onClose={() => setOpen(false)} data-color='danger' > <Paragraph>Are you sure you want to delete?</Paragraph> <Button onClick={() => setOpen(false)} data-size='sm' style={{ marginTop: 'var(--ds-size-2)' }} > Delete </Button> </Popover> </> ); }; render(<WithoutContextEn />)
HTML
You can use popover in plain HTML by using the popover attribute on an element and connecting it to a trigger with popovertarget.
The class name ds-popover is applied to the element that is the popover.
In React, we use floating-ui (floating-ui.com) for positioning, and this is a library that can also be used in pure JavaScript applications.
We recommend reading about popover (mozilla.org).
data-placement is used to position the arrow correctly.
This attribute is related to a plugin we have created for floating-ui.
It is portable to others who use floating-ui, and you can find the code on github.com.
Inline popover
If you want the trigger inline in text, you still have to use <button>, but you can add data-popover="inline" to get the correct styling.
CSS variables and data attributes
| Name | Value |
|---|---|
| --dsc-popover-background | var(--ds-color-surface-default) |
| --dsc-popover-border-width | var(--ds-border-width-default) |
| --dsc-popover-border-style | solid |
| --dsc-popover-border-color | var(--ds-color-border-default) |
| --dsc-popover-color | var(--ds-color-text-default) |
| --dsc-popover-arrow-size | var(--ds-size-3) |
| --dsc-popover-border-radius | var(--ds-border-radius-md) |
| --dsc-popover-max-width | 300px |
| --dsc-popover-padding | var(--ds-size-3) var(--ds-size-4) |
| --dsc-popover-box-shadow | var(--ds-shadow-md) |
| Name | Value |
|---|---|
| data-placement | top, left, right, bottom |
| data-variant | default, tinted |
| data-popover | inline |