UNPKG

@atlaskit/popup

Version:

A popup displays brief content in an overlay.

205 lines (202 loc) 8.88 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.PopupTrigger = exports.PopupContent = exports.Popup = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _react = _interopRequireWildcard(require("react")); var _tinyInvariant = _interopRequireDefault(require("tiny-invariant")); var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop")); var _useId = require("@atlaskit/ds-lib/use-id"); var _layering = require("@atlaskit/layering"); var _openLayerObserver = require("@atlaskit/layering/experimental/open-layer-observer"); var _popper = require("@atlaskit/popper"); var _portal = _interopRequireDefault(require("@atlaskit/portal")); var _popperWrapper = _interopRequireDefault(require("../popper-wrapper")); var _useAppearance = require("../use-appearance"); var _useGetMemoizedMergedTriggerRef = require("../use-get-memoized-merged-trigger-ref"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } var IsOpenContext = /*#__PURE__*/(0, _react.createContext)(false); var IdContext = /*#__PURE__*/(0, _react.createContext)(undefined); var TriggerRefContext = /*#__PURE__*/(0, _react.createContext)(null); var SetTriggerRefContext = /*#__PURE__*/(0, _react.createContext)(_noop.default); var EnsureIsInsidePopupContext = /*#__PURE__*/(0, _react.createContext)(false); // Used to ensure popup sub-components are used within a Popup // and provide a useful error message if not. var useEnsureIsInsidePopup = function useEnsureIsInsidePopup() { var context = (0, _react.useContext)(EnsureIsInsidePopupContext); (0, _tinyInvariant.default)(context, 'PopupTrigger and PopupContent components must be used within a Popup'); }; /** * __Popup__ * * Popup is a composable component that provides the context for the trigger and content components. * * Usage example: * ```jsx * <Popup> * <PopupTrigger> * {(props) => ( * <button type="button" {...props}>Click me</button> * )} * </PopupTrigger> * <PopupContent> * {(props) => <div>Hello world</div>} * </PopupContent> * </Popup> * ``` */ var Popup = exports.Popup = function Popup(_ref) { var children = _ref.children, providedId = _ref.id, _ref$isOpen = _ref.isOpen, isOpen = _ref$isOpen === void 0 ? false : _ref$isOpen; var _useState = (0, _react.useState)(null), _useState2 = (0, _slicedToArray2.default)(_useState, 2), triggerRef = _useState2[0], setTriggerRef = _useState2[1]; var generatedId = (0, _useId.useId)(); var id = providedId || generatedId; return /*#__PURE__*/_react.default.createElement(EnsureIsInsidePopupContext.Provider, { value: true }, /*#__PURE__*/_react.default.createElement(IdContext.Provider, { value: id }, /*#__PURE__*/_react.default.createElement(TriggerRefContext.Provider, { value: triggerRef }, /*#__PURE__*/_react.default.createElement(SetTriggerRefContext.Provider, { value: setTriggerRef }, /*#__PURE__*/_react.default.createElement(IsOpenContext.Provider, { value: isOpen }, /*#__PURE__*/_react.default.createElement(_popper.Manager, null, children)))))); }; /** * __Popup trigger__ * * Popup trigger is the component that renders the trigger for the popup. * * It must be a child of the Popup component. */ var PopupTrigger = exports.PopupTrigger = function PopupTrigger(_ref2) { var children = _ref2.children; useEnsureIsInsidePopup(); var isOpen = (0, _react.useContext)(IsOpenContext); var id = (0, _react.useContext)(IdContext); var setTriggerRef = (0, _react.useContext)(SetTriggerRefContext); var getMergedTriggerRef = (0, _useGetMemoizedMergedTriggerRef.useGetMemoizedMergedTriggerRef)(); return /*#__PURE__*/_react.default.createElement(_popper.Reference, null, function (_ref3) { var ref = _ref3.ref; return children({ ref: getMergedTriggerRef(ref, setTriggerRef, isOpen), 'aria-controls': id, 'aria-expanded': isOpen, 'aria-haspopup': true }); }); }; var defaultLayer = 400; /** * Disables popper.js GPU acceleration for this popup. * This means only positioning will be used, without any transforms. * * Performance will be degraded if the popup is expected to move. */ var shouldDisableGpuAccelerationModifiers = [{ name: 'computeStyles', options: { gpuAcceleration: false } }]; /** * __Popup content__ * * Popup content is the component that renders the content of the popup. * * It must be a child of the Popup component. */ var PopupContent = exports.PopupContent = function PopupContent(_ref4) { var xcss = _ref4.xcss, _ref4$appearance = _ref4.appearance, inAppearance = _ref4$appearance === void 0 ? 'default' : _ref4$appearance, children = _ref4.children, boundary = _ref4.boundary, offset = _ref4.offset, strategy = _ref4.strategy, onClose = _ref4.onClose, testId = _ref4.testId, _ref4$rootBoundary = _ref4.rootBoundary, rootBoundary = _ref4$rootBoundary === void 0 ? 'viewport' : _ref4$rootBoundary, _ref4$shouldFlip = _ref4.shouldFlip, shouldFlip = _ref4$shouldFlip === void 0 ? true : _ref4$shouldFlip, _ref4$placement = _ref4.placement, placement = _ref4$placement === void 0 ? 'auto' : _ref4$placement, fallbackPlacements = _ref4.fallbackPlacements, popupComponent = _ref4.popupComponent, _ref4$autoFocus = _ref4.autoFocus, autoFocus = _ref4$autoFocus === void 0 ? true : _ref4$autoFocus, _ref4$zIndex = _ref4.zIndex, zIndex = _ref4$zIndex === void 0 ? defaultLayer : _ref4$zIndex, _ref4$shouldUseCaptur = _ref4.shouldUseCaptureOnOutsideClick, shouldUseCaptureOnOutsideClick = _ref4$shouldUseCaptur === void 0 ? false : _ref4$shouldUseCaptur, inShouldRenderToParent = _ref4.shouldRenderToParent, _ref4$shouldDisableFo = _ref4.shouldDisableFocusLock, shouldDisableFocusLock = _ref4$shouldDisableFo === void 0 ? false : _ref4$shouldDisableFo, shouldFitContainer = _ref4.shouldFitContainer, shouldFitViewport = _ref4.shouldFitViewport, _ref4$shouldDisableGp = _ref4.shouldDisableGpuAcceleration, shouldDisableGpuAcceleration = _ref4$shouldDisableGp === void 0 ? false : _ref4$shouldDisableGp; useEnsureIsInsidePopup(); var isOpen = (0, _react.useContext)(IsOpenContext); var id = (0, _react.useContext)(IdContext); var triggerRef = (0, _react.useContext)(TriggerRefContext); var _usePopupAppearance = (0, _useAppearance.usePopupAppearance)({ appearance: inAppearance, shouldRenderToParent: inShouldRenderToParent }), appearance = _usePopupAppearance.appearance, shouldRenderToParent = _usePopupAppearance.shouldRenderToParent; var handleOpenLayerObserverCloseSignal = (0, _react.useCallback)(function () { onClose === null || onClose === void 0 || onClose(null); }, [onClose]); (0, _openLayerObserver.useNotifyOpenLayerObserver)({ isOpen: isOpen, onClose: handleOpenLayerObserverCloseSignal }); if (!isOpen) { return null; } var popperWrapper = /*#__PURE__*/_react.default.createElement(_layering.Layering, { isDisabled: false }, /*#__PURE__*/_react.default.createElement(_popperWrapper.default, { xcss: xcss, appearance: appearance, content: children, isOpen: isOpen, placement: placement, fallbackPlacements: fallbackPlacements, boundary: boundary, rootBoundary: rootBoundary, shouldFlip: shouldFlip, offset: offset, popupComponent: popupComponent, id: id, testId: testId, onClose: onClose, autoFocus: autoFocus, shouldFitContainer: shouldFitContainer, shouldUseCaptureOnOutsideClick: shouldUseCaptureOnOutsideClick, shouldRenderToParent: shouldRenderToParent, shouldDisableFocusLock: shouldDisableFocusLock, triggerRef: triggerRef, strategy: strategy, shouldFitViewport: shouldFitViewport, modifiers: shouldDisableGpuAcceleration ? shouldDisableGpuAccelerationModifiers : undefined })); if (shouldRenderToParent) { return popperWrapper; } return /*#__PURE__*/_react.default.createElement(_portal.default, { zIndex: zIndex }, popperWrapper); };