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>.

Editable example

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.

Editable example

Title#

Render a title using the title prop.

Editable example

Footer#

Render a footer using the title prop.

Editable example

Action buttons#

Editable example

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.

Editable example

Or you can display a close button:

Editable example

Render within a portal#

You can render the popover within a React Portal.

Editable example

Setting initial focus#

You can specify an initial element to put focus on using the unstable_initialFocusRef prop.

Editable example

Setting final focus#

You can specify an element focus on when the popover closes using the unstable_finalFocusRef prop.

Editable example

Restricting closure#

You can retrict closure (via click & esc) by using the hideOnEsc and hideOnClickOutside props.

Editable example

Animation#

To enable animation on your popover. You will have to set the animated flag on <Popover.State>

Fade#

Editable example

Slide#

Editable example

Expand#

Editable example

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.

Editable example

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#

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 a Portal 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 a Portal 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 a Portal 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 a Portal 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 a Portal 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 a Portal 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
Copyright © 2021 Jake Moxey