@atlaskit/popup
Version:
A popup displays brief content in an overlay.
71 lines (70 loc) • 2.88 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import React, { useRef, useState } from 'react';
import { useId } from '@atlaskit/ds-lib/use-id';
import { fg } from '@atlaskit/platform-feature-flags/fg';
import { Manager } from '@atlaskit/popper/manager';
import { IdContext } from './id-context';
import { EnsureIsInsidePopupContext } from './is-inside-popup-context';
import { IsOpenContext } from './is-open-context';
import { RoleContext } from './role-context';
import { SetTriggerRefContext } from './set-trigger-ref-context';
import { TriggerRefContext } from './trigger-ref-context';
import { TriggerRefObjectContext } from './trigger-ref-object-context';
/**
* __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>
* ```
*/
export var Popup = function Popup(_ref) {
var children = _ref.children,
providedId = _ref.id,
_ref$isOpen = _ref.isOpen,
isOpen = _ref$isOpen === void 0 ? false : _ref$isOpen,
role = _ref.role;
var _useState = useState(null),
_useState2 = _slicedToArray(_useState, 2),
triggerRef = _useState2[0],
setTriggerRef = _useState2[1];
// When the top-layer flag is on, we maintain a stable RefObject for the
// trigger element, provided through TriggerRefObjectContext. Unlike the
// state-based triggerRef (which causes a re-render when the trigger mounts),
// this ref has a stable identity so useAnchoredPopover's useLayoutEffect dep
// array never changes — the effect runs once on mount when the trigger element
// is already populated. PopupTrigger sets this ref directly instead of calling
// the state setter, avoiding an unnecessary re-render.
var triggerRefObject = useRef(null);
var generatedId = useId();
var id = providedId || generatedId;
return /*#__PURE__*/React.createElement(RoleContext.Provider, {
value: role
}, /*#__PURE__*/React.createElement(EnsureIsInsidePopupContext.Provider, {
value: true
}, /*#__PURE__*/React.createElement(IdContext.Provider, {
value: id
}, /*#__PURE__*/React.createElement(TriggerRefContext.Provider, {
value: triggerRef
}, /*#__PURE__*/React.createElement(SetTriggerRefContext.Provider, {
value: setTriggerRef
}, /*#__PURE__*/React.createElement(IsOpenContext.Provider, {
value: isOpen
}, fg('platform-dst-top-layer') ?
/*#__PURE__*/
// Skip Popper's <Manager> when Top Layer is being used.
React.createElement(TriggerRefObjectContext.Provider, {
value: triggerRefObject
}, children) : /*#__PURE__*/React.createElement(Manager, null, children)))))));
};