UNPKG

@asphalt-react/popover

Version:

Popover

579 lines (379 loc) 13.9 kB
# Popover ![npm](https://img.shields.io/npm/dt/@asphalt-react/popover?style=flat-square) [![npm version](https://badge.fury.io/js/@asphalt-react%2Fpopover.svg)](https://badge.fury.io/js/@asphalt-react%2Fpopover) Popover package offers following components: * Popover * Tooltip Popover and Tooltip require a target element that acts as a pivot for their content. They support multiple placement positions, allowing both elements to be positioned next to the target element in any direction. ## Popover Popover is an interactive floating element that displays information related to an anchor element when the element is clicked. It represents the UI element as floating above the normal flow creating the "pop out" effect. Popover can contain a range of elements from simple strings to complex React designs. Popover is a controlled component, it does not manage visibility state on it's own. ## Tooltip Tooltip component allows user to see additional context about a UI element without cluttering the interface. Tooltip provides informative text when the user hovers over, focuses on, and on mobile device taps on an element. Tooltips are often used sparingly to avoid overwhelming users. They are meant to support discovery, not replace clear design or documentation. To use an icon from `@asphalt-react/iconpack` as the target element for tooltip, wrap the icon inside an HTML element like a `div` or `span`. ## Usage ```js import React, { useState } from "react" import { Popover, Tooltip } from "@asphalt-react/popover" import { Button } from "@asphalt-react/button" const App = () => { const [open, setOpen] = useState(false) return ( <> <Popover open={open} target={<Button>Click Me</Button>} onOpenChange={setOpen} > <p> Hello there </p> </Popover> <Tooltip target={<a href="#">Hover over here</a>} > Add information here </Tooltip> </> ) } export default App ``` ## Sizes Popover & Tooltip comes in 3 sizes `small(s)`, `medium(m)` & `large(l)`. ## Building blocks 1. Popover component comes with: * BasePopover * FocusManager 2. `BasePopover` supports 3 sizes: `small(s)`, `medium(m)` & `large(l)`. 3. `FocusManager` handles the focus management for Popover content. ## Hooks ### usePopover Use the `usePopover()` hook to get all the prop getter functions and then spread them in the target & popover components. `usePopover()` takes props as parameter. React hook which returns prop getter functions. Use these functions to generate prop objects for different components in Popover. #### Arguments usePopover accepts the following props: 1. open 2. placement 3. outOfFlow 4. flip 5. size 6. bezel 7. focusTrap 8. noOffset 9. lowOffset 10. mediumOffset 11. highOffset 12. onOpenChange 13. stretch 14. returnFocus #### Getter functions #### getTargetProps() Use this function to create props for Target element of the Popover. ```jsx const { getTargetProps } = usePopover({ open: true, onOpenChange: setOpen }) <Button {...getTargetProps()}> Click me </Button> ``` #### getPopoverProps() Use this function to create props for Popover/floating component. ```jsx const { getPopoverProps } = usePopover({ open: true, onOpenChange: setOpen }) <BasePopover {...getPopoverProps()}> <p> Hello there! </p> </BasePopover> ``` #### getFocusProps() Use this function to create props for `FocusManager` component. ```jsx const { getFocusProps } = usePopover({ open: true, onOpenChange: setOpen }) <FocusManager {...getFocusProps()}> <BasePopover {...getPopoverProps()}> <p> Hello there! </p> </BasePopover> <FocusManager> ``` #### Usage ```js import { BasePopover, usePopover, FocusManager } from "@asphalt-react/popover" const App = () => { const [open, setOpen] = useState(false) const { getTargetProps, getPopoverProps, getFocusProps } = usePopover({ open, onOpenChange: setOpen, }) return ( <div> <Button {...getTargetProps()}>Click me</Button> {open && ( <FocusManager {...getFocusProps()}> <BasePopover open={open} {...getPopoverProps()}> <p> Lorem ipsum dolor sit amet </p> </BasePopover> </FocusManager> )} </div> ) } export default App ``` ## Accessibility * For popover, clicking outside the popover closes it. While in tooltip, moving the cursor away from the target element closes the tooltip. * Pressing <kbd>Esc</kbd> key closes both popover and tooltip. * Popover [traps focus](https://developers.google.com/web/fundamentals/accessibility/focus/using-tabindex#modals_and_keyboard_traps) within its content, rotating the focus among its interactive elements. * The first interactive element receives focus by default when Popover opens. * The element that serves as the tooltip container has `role="tooltip"`. * The element that triggers the tooltip has `aria-describedby`. Example of tooltip accessibility: ```jsx <Tooltip id="my-tooltip" target={<a aria-describedby="my-tooltip" href="#">Hover over here</a>} > Add information here </Tooltip> ``` [comment]: # "Popover Props" ## Props ### children React node to render inside Popover. | type | required | default | | ---- | -------- | ------- | | node | true | N/A | ### target Target node that triggers the Popover. | type | required | default | | ---- | -------- | ------- | | node | true | N/A | ### open Decides the open state for Popover. | type | required | default | | ---- | -------- | ------- | | bool | false | false | ### size Size of the Popover. | type | required | default | | ---- | -------- | ------- | | enum | false | "m" | ### bezel Adds padding on all sides. | type | required | default | | ---- | -------- | ------- | | bool | false | true | ### placement Placement of the Popover with respect to target node. Popover supports multiple placements: * `auto``auto-start``auto-end` * `top``top-start``top-end` * `bottom``bottom-start``bottom-end` * `left``left-start``left-end` * `right``right-start``right-end` | type | required | default | | ---- | -------- | -------- | | enum | false | "bottom" | ### focusOrder The order in which focus cycles. * `reference` - Target element which acts as pivot for Popover. * `floating` - Popover wrapper element. * `content` - Content inside Popover wrapper. By default it's value is \['content'] - Subsequent tabs will cycle through the tabbable contents of the Popover content. If the value is set to \['floating', 'content'] - Includes floating element in focus cycle. If the value is set to \['reference', 'content'] - Includes reference element in focus cycle. * If the value is set to \['reference', 'floating', 'content'] - tabs will cycle through the reference, floating & tabbable contents of the Popover content. | type | required | default | | ------- | -------- | ----------- | | arrayOf | false | ["content"] | ### initialFocus Element to initially focus when Popover is opened. Can be either a number or a ref. Number is decided by the tabbable index as specified by the focusOrder. | type | required | default | | ----- | -------- | ------- | | union | false | 0 | ### outOfFlow When Popover is added to a container with `position: fixed` and/or `overflow: hidden`, it creates a containing block with a stacking context which the Popover can't skip. In such scenarios, enabling `outOfFlow` will remove Popover from its parent's flow. | type | required | default | | ---- | -------- | ------- | | bool | false | false | ### flip Flips the position of the floating element if there is space constraint in order to make it visible in viewport. | type | required | default | | ---- | -------- | ------- | | bool | false | true | ### stretch Enables the Popover to stretch and fill the width of its container. By default, the Popover matches the width of its content. Strech works only in a relatively positioned container. Refer to the example below. | type | required | default | | ---- | -------- | ------- | | bool | false | false | ### shift Shifts the Popover horizontally to avoid the content from overflowing the viewport. | type | required | default | | ---- | -------- | ------- | | bool | false | true | ### focusTrap Add focus trap in the content, outside content cannot be accessed if enabled. | type | required | default | | ---- | -------- | ------- | | bool | false | true | ### lowOffset adds a low spacing between target and Popover. | type | required | default | | ---- | -------- | ------- | | bool | false | false | ### mediumOffset adds a medium spacing between target and Popover. | type | required | default | | ---- | -------- | ------- | | bool | false | false | ### highOffset adds a high spacing between target and Popover. | type | required | default | | ---- | -------- | ------- | | bool | false | false | ### noOffset removes spacing between target and Popover. | type | required | default | | ---- | -------- | ------- | | bool | false | false | ### onOpenChange callback when open state is changed. | type | required | default | | ---- | -------- | ------- | | func | false | null | ### returnFocus determines if focus should be returned to the reference element. | type | required | default | | ---- | -------- | ------- | | bool | false | true | # BasePopover [comment]: # "BasePopover Props" ## Props ### children React node to render inside Base Popover. | type | required | default | | ---- | -------- | ------- | | node | true | N/A | ### open Indicates the open state for Popover. | type | required | default | | ---- | -------- | ------- | | bool | false | false | ### size Size of the Popover. | type | required | default | | ---- | -------- | ------- | | enum | false | "m" | ### bezel Adds padding on all sides. | type | required | default | | ---- | -------- | ------- | | bool | false | true | ### stretch Enables the Popover to stretch and fill the width of its container. By default, the Popover matches the width of its content. | type | required | default | | ---- | -------- | ------- | | bool | false | false | ### anchorStyles Adds styles to position the Popover relative to the target element. | type | required | default | | ------ | -------- | ------- | | object | false | N/A | ### inverse Set to true to render BasePopover with inverse background. | type | required | default | | ---- | -------- | ------- | | bool | false | false | # FocusManager [comment]: # "FocusManager Props" ## Props ### children React node to render inside Base Popover. | type | required | default | | ---- | -------- | ------- | | node | true | N/A | ### popoverContext context object used to focus on the floating element, pass the `popoverContext` returned by the `usePopover` hook. | type | required | default | | ------ | -------- | ------- | | object | true | N/A | ### focusOrder The order in which focus cycles. * `reference` - Target element which acts as pivot for Popover. * `floating` - Popover wrapper element. * `content` - Content inside Popover wrapper. By default it's value is \['content'] - Subsequent tabs will cycle through the tabbable contents of the Popover content. If the value is set to \['floating', 'content'] - Includes floating element in focus cycle. If the value is set to \['reference', 'content'] - Includes reference element in focus cycle. * If the value is set to \['reference', 'floating', 'content'] - tabs will cycle through the reference, floating & tabbable contents of the Popover content. | type | required | default | | ------- | -------- | ----------- | | arrayOf | false | ["content"] | ### focusTrap Add focus trap in the content, outside content cannot be accessed if enabled. | type | required | default | | ---- | -------- | ------- | | bool | false | true | ### initialFocus Element to initially focus when Popover is opened. Can be either a number or a ref. Number is decided by the tabbable index as specified by the focusOrder. | type | required | default | | ----- | -------- | ------- | | union | false | 0 | ### returnFocus determines if focus should be returned to the reference element. | type | required | default | | ---- | -------- | ------- | | bool | false | true | # Tooltip [comment]: # "Tooltip Props" ## Props ### children Tooltip content receives node. | type | required | default | | ---- | -------- | ------- | | node | true | N/A | ### target Target node that triggers the Popover. | type | required | default | | ---- | -------- | ------- | | node | true | N/A | ### title Tooltip title, only receives string. | type | required | default | | ------ | -------- | ------- | | string | false | N/A | ### size Tooltip size, can be "small", "medium" or "large". | type | required | default | | ---- | -------- | ------- | | enum | false | "m" | ### arrow Set `arrow=false` to disable arrow. | type | required | default | | ---- | -------- | ------- | | bool | false | true | ### placement Placement of the Popover with respect to target node. Popover supports multiple placements: * `top``top-start``top-end` * `bottom``bottom-start``bottom-end` * `left``left-start``left-end` * `right``right-start``right-end` | type | required | default | | ---- | -------- | -------- | | enum | false | "bottom" | ### bezel Adds padding on all sides. | type | required | default | | ---- | -------- | ------- | | bool | false | true |