UNPKG

chakra-ui

Version:

Responsive and accessible React UI components built with React and Emotion

153 lines (140 loc) 5.53 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; /** @jsx jsx */ import { jsx } from "@emotion/core"; import Portal from "@reach/portal"; import { oneOf } from "prop-types"; import { cloneElement, useEffect, useRef, Fragment } from "react"; import FocusLock from "react-focus-lock"; import { Manager, Popper, Reference } from "react-popper"; import { PopoverTransition, PopoverContent, PopoverCloseButton } from "./components"; import { assignRef, genId } from "../utils"; import { useUIMode } from "../ThemeProvider"; import Box from "../Box"; import useDisclosure from "../useDisclosure"; var Popover = function Popover(_ref) { var controlledIsOpen = _ref.isOpen, defaultOpen = _ref.defaultOpen, _ref$maxWidth = _ref.maxWidth, maxWidth = _ref$maxWidth === void 0 ? "xs" : _ref$maxWidth, trigger = _ref.trigger, gutter = _ref.gutter, placement = _ref.placement, children = _ref.children, showArrow = _ref.showArrow, showCloseButton = _ref.showCloseButton, initialFocusRef = _ref.initialFocusRef, _ref$usePortal = _ref.usePortal, usePortal = _ref$usePortal === void 0 ? true : _ref$usePortal, onOpenChange = _ref.onOpenChange, _ref$trapFocus = _ref.trapFocus, trapFocus = _ref$trapFocus === void 0 ? false : _ref$trapFocus, closeOnBlur = _ref.closeOnBlur, _ref$closeOnEsc = _ref.closeOnEsc, closeOnEsc = _ref$closeOnEsc === void 0 ? true : _ref$closeOnEsc, rest = _objectWithoutProperties(_ref, ["isOpen", "defaultOpen", "maxWidth", "trigger", "gutter", "placement", "children", "showArrow", "showCloseButton", "initialFocusRef", "usePortal", "onOpenChange", "trapFocus", "closeOnBlur", "closeOnEsc"]); var _useDisclosure = useDisclosure(defaultOpen), isOpen = _useDisclosure.isOpen, onClose = _useDisclosure.onClose, onToggle = _useDisclosure.onToggle; var triggerRef = useRef(); var popperRef = useRef(); useEffect(function () { onOpenChange && onOpenChange(); }, [isOpen, onOpenChange]); var handleClick = function handleClick() { onToggle(); }; /* Close on outside click and blur for the Menu */ var handleBlur = function handleBlur(event) { if (!trapFocus && isOpen && popperRef.current && triggerRef.current && !popperRef.current.contains(event.relatedTarget) && !triggerRef.current.contains(event.relatedTarget)) { closeOnBlur && onClose(); } }; var _useUIMode = useUIMode(), mode = _useUIMode.mode; var _bgColor = mode === "light" ? "white" : "gray.700"; var _color = mode === "light" ? "gray.900" : "whiteAlpha.900"; var bg = rest.bg || rest.background || rest.backgroundColor || _bgColor; var color = rest.color || _color; var popoverId = genId("popper"); var Wrapper = usePortal ? Portal : Fragment; return jsx(Manager, null, jsx(Reference, null, function (_ref2) { var referenceRef = _ref2.ref; return cloneElement(trigger, { "aria-haspopup": "true", "aria-controls": popoverId, ref: function ref(node) { triggerRef.current = node; assignRef(referenceRef, node); }, onClick: function onClick(event) { handleClick(); trigger.props.onClick && trigger.props.onClick(event); } }); }), jsx(Wrapper, null, jsx(Popper, { placement: placement }, function (_ref3) { var _ref4 = _ref3.ref, popperStyle = _ref3.style, placement = _ref3.placement, arrowProps = _ref3.arrowProps; return jsx(PopoverTransition, { duration: 100, isOpen: isOpen }, function (styles) { return jsx(FocusLock, { returnFocus: true, onActivation: function onActivation() { if (initialFocusRef && initialFocusRef.current) { initialFocusRef.current.focus(); } } }, jsx(PopoverContent, _extends({ ref: function ref(node) { popperRef.current = node; assignRef(_ref4, node); }, bg: bg, color: color, maxWidth: maxWidth, "data-placement": placement, borderRadius: "lg", boxShadow: "lg", id: popoverId, "aria-hidden": isOpen }, rest, { tabIndex: "-1", onBlur: handleBlur, css: _extends({}, popperStyle, { transform: "".concat(popperStyle.transform, " scale(").concat(styles.scale, ")"), opacity: styles.opacity }), onKeyDown: function onKeyDown(event) { event.stopPropagation(); if (event.key === "Escape" && closeOnEsc) { onClose && onClose(); } } }), showCloseButton && jsx(PopoverCloseButton, { onClick: onClose }), typeof children === "function" ? children({ isOpen: isOpen, onClose: onClose }) : children, showArrow && jsx(Box, { borderColor: bg, "data-arrow": "", ref: arrowProps.ref, css: arrowProps.style }))); }); }))); }; export var placementOptions = ["left", "right", "bottom", "auto", "top", "right-end", "right-start", "left-end", "left-start", "bottom-end", "bottom-start", "top-end", "top-start", "auto-start", "auto-end"]; process.env.NODE_ENV !== "production" ? Popover.propTypes = { interaction: oneOf(["hover", "click"]), placement: oneOf(placementOptions) } : void 0; export default Popover; export * from "./components";