Popover#
The <Popover>
component is a lightweight dialog that floats beside a disclosure (a button).
Import#
import { Popover } from 'bumbag';
Usage#
The <Popover.Disclosure>
component will act as the trigger of your popover.
To automatically handle the state of your popover, wrap the <Popover>
& <Popover.Disclosure>
components in a <Popover.State>
.
If you wish to control the state of your popover, see controlled usage.
Placement#
You can control the placement of your popover by using the placement
prop.
Title#
Render a title using the title
prop.
Footer#
Render a footer using the title
prop.
Action buttons#
Close within popover#
The <Popover.State>
component also renders children as a function (render props).
You can retrieve utilities from the popover
variable such as hide
to hide the popover.
Or you can display a close button:
Render within a portal#
You can render the popover within a React Portal.
Setting initial focus#
You can specify an initial element to put focus on using the unstable_initialFocusRef
prop.
Setting final focus#
You can specify an element focus on when the popover closes using the unstable_finalFocusRef
prop.
Restricting closure#
You can retrict closure (via click & esc) by using the hideOnEsc
and hideOnClickOutside
props.
Animation#
To enable animation on your popover. You will have to set the animated
flag on <Popover.State>
Fade#
Slide#
Expand#
Controlled usage#
If you would like more control over the state of your popover, you can use either the useState
hook, or the <Popover.State>
render props.
Accessing internal state#
Any descendant component of Popover.State
can utilise Popover.useContext
to access the internal popover state:
function Example() {const { popover } = Popover.useContext();return (<Button onClick={popover.hide}>Hide popover</Button>)}
Accessibility#
Popover
extends the accessibility features of the Modal component.
Props#
Popover Props#
footer
string | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)>) | (new (props: any) => Component<any, any, any>)>
Sets the footer component of the popover.
hasArrow
boolean
Indicates if the popover should have an arrow.
onClickClose
(event: MouseEvent<any, MouseEvent>) => void
Function to invoke when the popover is closed.
showActionButtons
boolean
Indicates if the action button should be visible.
showCloseButton
boolean
Indicates if the close button should be visible.
title
string | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)>) | (new (props: any) => Component<any, any, any>)>
Indicates if the action button should be visible.
usePortal
boolean
Indicates if the popover should be rendered in a portal.
actionButtonsProps
BoxOptions & HTMLAttributes<any> & RefAttributes<any> & { wrapElement?: (element: ReactNode) => ReactNode; } & CSSProperties & LocalBoxProps & LocalSetProps & LocalActionButtonsProps
arrowProps
BoxOptions & HTMLAttributes<any> & RefAttributes<any> & { wrapElement?: (element: ReactNode) => ReactNode; } & ... 6 more ... & { ...; }
closeButtonProps
{ unstable_system?: any; top?: string | number | { [key: string]: string }; right?: string | number | { [key: string]: string }; bottom?: string | number | { [key: string]: string }; left?: string | number | { [key: string]: string }; ... 807 more ...; ignoreGrayOverride?: boolean; }
standalone
boolean
delay
string
Delay of the animation (in s/ms).
duration
string
Duration of the animation (in s/ms).
expand
boolean | "top" | "right" | "bottom" | "left" | "center"
Will the component have an expand animation when it is toggled on/off?
fade
boolean
Will the component have a fade animation when it is toggled on/off?
slide
boolean | "top" | "right" | "bottom" | "left"
Will the component have a slide animation when it is toggled on/off?
timingFunction
string
Timing function of the animation
hideOnEsc
boolean
When enabled, user can hide the dialog by pressing Escape
.
hideOnClickOutside
boolean
When enabled, user can hide the dialog by clicking outside it.
preventBodyScroll
boolean
When enabled, user can't scroll on body when the dialog is visible. This option doesn't work if the dialog isn't modal.
11 state props
These props are returned by the state hook. You can spread them into this component (...state
) or pass them separately. You can also provide these props from your own state logic.
baseId
string
ID that will serve as a base for all the items IDs.
visible
boolean
Whether it's visible or not.
animating
boolean
Whether it's animating or not.
animated
number | boolean
If true
, animating
will be set to true
when visible
is updated.
It'll wait for stopAnimation
to be called or a CSS transition ends.
If animated
is set to a number
, stopAnimation
will be called only
after the same number of milliseconds have passed.
stopAnimation
() => void
Stops animation. It's called automatically if there's a CSS transition.
modal
boolean
Toggles Dialog's modal
state.
- Non-modal:
preventBodyScroll
doesn't work and focus is free. - Modal:
preventBodyScroll
is automatically enabled, focus is trapped within the dialog and the dialog is rendered within aPortal
by default.
hide
() => void
Changes the visible
state to false
baseId
string
Required
ID that will serve as a base for all the items IDs.
Inherits Box
props
use
string | (ComponentClass<any, any> & { useProps: any; }) | (FunctionComponent<any> & { useProps: any; })
className
string
children
string | number | boolean | {} | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)>) | (new (props: any) => Component<...>)> | ReactNodeArray | ReactPortal | ((props: BoxProps) => ReactNode)
alignX
"right" | "left" | "center"
alignY
"top" | "bottom" | "center"
variant
string
colorMode
string
disabled
boolean
overrides
{ useCSSVariables?: boolean; altitudes?: AltitudesThemeConfig; borders?: BordersThemeConfig; borderRadii?: BorderRadiiThemeConfig; ... 95 more ...; Template?: TemplateThemeConfig; }
elementRef
((instance: any) => void) | RefObject<any>
themeKey
string
Popover.Header Props#
Inherits Flex
props
Inherits Box
props
use
string | (ComponentClass<any, any> & { useProps: any; }) | (FunctionComponent<any> & { useProps: any; })
className
string
children
string | number | boolean | {} | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)>) | (new (props: any) => Component<...>)> | ReactNodeArray | ReactPortal | ((props: BoxProps) => ReactNode)
alignX
"right" | "left" | "center"
alignY
"top" | "bottom" | "center"
variant
string
colorMode
string
disabled
boolean
overrides
{ useCSSVariables?: boolean; altitudes?: AltitudesThemeConfig; borders?: BordersThemeConfig; borderRadii?: BorderRadiiThemeConfig; ... 95 more ...; Template?: TemplateThemeConfig; }
elementRef
((instance: any) => void) | RefObject<any>
themeKey
string
Popover.Title Props#
Inherits Text
props
Inherits Box
props
use
string | (ComponentClass<any, any> & { useProps: any; }) | (FunctionComponent<any> & { useProps: any; })
className
string
children
string | number | boolean | {} | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)>) | (new (props: any) => Component<...>)> | ReactNodeArray | ReactPortal | ((props: BoxProps) => ReactNode)
alignX
"right" | "left" | "center"
alignY
"top" | "bottom" | "center"
variant
string
colorMode
string
disabled
boolean
overrides
{ useCSSVariables?: boolean; altitudes?: AltitudesThemeConfig; borders?: BordersThemeConfig; borderRadii?: BorderRadiiThemeConfig; ... 95 more ...; Template?: TemplateThemeConfig; }
elementRef
((instance: any) => void) | RefObject<any>
themeKey
string
Popover.Content Props#
Inherits Box
props
use
string | (ComponentClass<any, any> & { useProps: any; }) | (FunctionComponent<any> & { useProps: any; })
className
string
children
string | number | boolean | {} | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)>) | (new (props: any) => Component<...>)> | ReactNodeArray | ReactPortal | ((props: BoxProps) => ReactNode)
alignX
"right" | "left" | "center"
alignY
"top" | "bottom" | "center"
variant
string
colorMode
string
disabled
boolean
overrides
{ useCSSVariables?: boolean; altitudes?: AltitudesThemeConfig; borders?: BordersThemeConfig; borderRadii?: BorderRadiiThemeConfig; ... 95 more ...; Template?: TemplateThemeConfig; }
elementRef
((instance: any) => void) | RefObject<any>
themeKey
string
Popover.Footer Props#
Inherits Flex
props
Inherits Box
props
use
string | (ComponentClass<any, any> & { useProps: any; }) | (FunctionComponent<any> & { useProps: any; })
className
string
children
string | number | boolean | {} | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)>) | (new (props: any) => Component<...>)> | ReactNodeArray | ReactPortal | ((props: BoxProps) => ReactNode)
alignX
"right" | "left" | "center"
alignY
"top" | "bottom" | "center"
variant
string
colorMode
string
disabled
boolean
overrides
{ useCSSVariables?: boolean; altitudes?: AltitudesThemeConfig; borders?: BordersThemeConfig; borderRadii?: BorderRadiiThemeConfig; ... 95 more ...; Template?: TemplateThemeConfig; }
elementRef
((instance: any) => void) | RefObject<any>
themeKey
string
Popover.Arrow Props#
size
string | number
Arrow's size
3 state props
These props are returned by the state hook. You can spread them into this component (...state
) or pass them separately. You can also provide these props from your own state logic.
placement
Required
"auto-start" | "auto" | "auto-end" | "top-start" | "top" | "top-end" | "right-start" | "right" | "right-end" | "bottom-end" | "bottom" | "bottom-start" | "left-end" | "left" | "left-start"
Actual placement
.
Inherits Box
props
use
string | (ComponentClass<any, any> & { useProps: any; }) | (FunctionComponent<any> & { useProps: any; })
className
string
children
string | number | boolean | {} | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)>) | (new (props: any) => Component<...>)> | ReactNodeArray | ReactPortal | ((props: BoxProps) => ReactNode)
alignX
"right" | "left" | "center"
alignY
"top" | "bottom" | "center"
variant
string
colorMode
string
disabled
boolean
overrides
{ useCSSVariables?: boolean; altitudes?: AltitudesThemeConfig; borders?: BordersThemeConfig; borderRadii?: BorderRadiiThemeConfig; ... 95 more ...; Template?: TemplateThemeConfig; }
elementRef
((instance: any) => void) | RefObject<any>
themeKey
string
Popover.Backdrop Props#
usePortal
boolean
6 state props
These props are returned by the state hook. You can spread them into this component (...state
) or pass them separately. You can also provide these props from your own state logic.
baseId
string
ID that will serve as a base for all the items IDs.
visible
boolean
Whether it's visible or not.
animating
boolean
Whether it's animating or not.
animated
number | boolean
If true
, animating
will be set to true
when visible
is updated.
It'll wait for stopAnimation
to be called or a CSS transition ends.
If animated
is set to a number
, stopAnimation
will be called only
after the same number of milliseconds have passed.
stopAnimation
() => void
Stops animation. It's called automatically if there's a CSS transition.
modal
boolean
Toggles Dialog's modal
state.
- Non-modal:
preventBodyScroll
doesn't work and focus is free. - Modal:
preventBodyScroll
is automatically enabled, focus is trapped within the dialog and the dialog is rendered within aPortal
by default.
Inherits Box
props
use
string | (ComponentClass<any, any> & { useProps: any; }) | (FunctionComponent<any> & { useProps: any; })
className
string
children
string | number | boolean | {} | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)>) | (new (props: any) => Component<...>)> | ReactNodeArray | ReactPortal | ((props: BoxProps) => ReactNode)
alignX
"right" | "left" | "center"
alignY
"top" | "bottom" | "center"
variant
string
colorMode
string
disabled
boolean
overrides
{ useCSSVariables?: boolean; altitudes?: AltitudesThemeConfig; borders?: BordersThemeConfig; borderRadii?: BorderRadiiThemeConfig; ... 95 more ...; Template?: TemplateThemeConfig; }
elementRef
((instance: any) => void) | RefObject<any>
themeKey
string
Popover.Disclosure Props#
disabled
boolean
Same as the HTML attribute.
focusable
boolean
When an element is disabled
, it may still be focusable
. It works
similarly to readOnly
on form elements. In this case, only
aria-disabled
will be set.
6 state props
These props are returned by the state hook. You can spread them into this component (...state
) or pass them separately. You can also provide these props from your own state logic.
visible
boolean
Whether it's visible or not.
baseId
string
Required
ID that will serve as a base for all the items IDs.
toggle
() => void
Required
Toggles the visible
state
toggle
() => void
Required
Toggles the visible
state
Inherits Box
props
use
string | (ComponentClass<any, any> & { useProps: any; }) | (FunctionComponent<any> & { useProps: any; })
className
string
children
string | number | boolean | {} | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)>) | (new (props: any) => Component<...>)> | ReactNodeArray | ReactPortal | ((props: BoxProps) => ReactNode)
alignX
"right" | "left" | "center"
alignY
"top" | "bottom" | "center"
variant
string
colorMode
string
overrides
{ useCSSVariables?: boolean; altitudes?: AltitudesThemeConfig; borders?: BordersThemeConfig; borderRadii?: BorderRadiiThemeConfig; ... 95 more ...; Template?: TemplateThemeConfig; }
elementRef
((instance: any) => void) | RefObject<any>
themeKey
string
State#
Popover.State API#
baseId
string
ID that will serve as a base for all the items IDs.
visible
boolean
Whether it's visible or not.
animated
number | boolean
If true
, animating
will be set to true
when visible
is updated.
It'll wait for stopAnimation
to be called or a CSS transition ends.
If animated
is set to a number
, stopAnimation
will be called only
after the same number of milliseconds have passed.
modal
boolean
Toggles Dialog's modal
state.
- Non-modal:
preventBodyScroll
doesn't work and focus is free. - Modal:
preventBodyScroll
is automatically enabled, focus is trapped within the dialog and the dialog is rendered within aPortal
by default.
placement
"auto-start" | "auto" | "auto-end" | "top-start" | "top" | "top-end" | "right-start" | "right" | "right-end" | "bottom-end" | "bottom" | "bottom-start" | "left-end" | "left" | "left-start"
Actual placement
.
gutter
number
Offset between the reference and the popover on the main axis. Should not be combined with unstable_offset
.
Popover.State Return Values#
24 values
baseId
string
Required
ID that will serve as a base for all the items IDs.
visible
boolean
Required
Whether it's visible or not.
animated
number | boolean
Required
If true
, animating
will be set to true
when visible
is updated.
It'll wait for stopAnimation
to be called or a CSS transition ends.
If animated
is set to a number
, stopAnimation
will be called only
after the same number of milliseconds have passed.
animating
boolean
Required
Whether it's animating or not.
setBaseId
(value: SetStateAction<string>) => void
Required
Sets baseId
.
show
() => void
Required
Changes the visible
state to true
hide
() => void
Required
Changes the visible
state to false
toggle
() => void
Required
Toggles the visible
state
setVisible
(value: SetStateAction<boolean>) => void
Required
Sets visible
.
setAnimated
(value: SetStateAction<number | boolean>) => void
Required
Sets animated
.
stopAnimation
() => void
Required
Stops animation. It's called automatically if there's a CSS transition.
modal
boolean
Required
Toggles Dialog's modal
state.
- Non-modal:
preventBodyScroll
doesn't work and focus is free. - Modal:
preventBodyScroll
is automatically enabled, focus is trapped within the dialog and the dialog is rendered within aPortal
by default.
setModal
(value: SetStateAction<boolean>) => void
Required
Sets modal
.
placement
Required
"auto-start" | "auto" | "auto-end" | "top-start" | "top" | "top-end" | "right-start" | "right" | "right-end" | "bottom-end" | "bottom" | "bottom-start" | "left-end" | "left" | "left-start"
Actual placement
.
place
(value: SetStateAction<Placement>) => void
Required
Change the placement
state.
Popover.useState API#
baseId
string
ID that will serve as a base for all the items IDs.
visible
boolean
Whether it's visible or not.
animated
number | boolean
If true
, animating
will be set to true
when visible
is updated.
It'll wait for stopAnimation
to be called or a CSS transition ends.
If animated
is set to a number
, stopAnimation
will be called only
after the same number of milliseconds have passed.
modal
boolean
Toggles Dialog's modal
state.
- Non-modal:
preventBodyScroll
doesn't work and focus is free. - Modal:
preventBodyScroll
is automatically enabled, focus is trapped within the dialog and the dialog is rendered within aPortal
by default.
placement
"auto-start" | "auto" | "auto-end" | "top-start" | "top" | "top-end" | "right-start" | "right" | "right-end" | "bottom-end" | "bottom" | "bottom-start" | "left-end" | "left" | "left-start"
Actual placement
.
gutter
number
Offset between the reference and the popover on the main axis. Should not be combined with unstable_offset
.
Popover.useState Return Values#
24 values
baseId
string
Required
ID that will serve as a base for all the items IDs.
visible
boolean
Required
Whether it's visible or not.
animated
number | boolean
Required
If true
, animating
will be set to true
when visible
is updated.
It'll wait for stopAnimation
to be called or a CSS transition ends.
If animated
is set to a number
, stopAnimation
will be called only
after the same number of milliseconds have passed.
animating
boolean
Required
Whether it's animating or not.
setBaseId
(value: SetStateAction<string>) => void
Required
Sets baseId
.
show
() => void
Required
Changes the visible
state to true
hide
() => void
Required
Changes the visible
state to false
toggle
() => void
Required
Toggles the visible
state
setVisible
(value: SetStateAction<boolean>) => void
Required
Sets visible
.
setAnimated
(value: SetStateAction<number | boolean>) => void
Required
Sets animated
.
stopAnimation
() => void
Required
Stops animation. It's called automatically if there's a CSS transition.
modal
boolean
Required
Toggles Dialog's modal
state.
- Non-modal:
preventBodyScroll
doesn't work and focus is free. - Modal:
preventBodyScroll
is automatically enabled, focus is trapped within the dialog and the dialog is rendered within aPortal
by default.
setModal
(value: SetStateAction<boolean>) => void
Required
Sets modal
.
placement
Required
"auto-start" | "auto" | "auto-end" | "top-start" | "top" | "top-end" | "right-start" | "right" | "right-end" | "bottom-end" | "bottom" | "bottom-start" | "left-end" | "left" | "left-start"
Actual placement
.
place
(value: SetStateAction<Placement>) => void
Required
Change the placement
state.
Theming#
Popover.styles.base
Popover.Content.styles.base
Popover.Header.styles.base
Popover.Title.styles.base
Popover.Footer.styles.base
Popover.Close.styles.base
Popover.Backdrop.styles.base
Popover.Arrow.styles.base