@atlaskit/popup
Version:
A popup displays brief content in an overlay.
56 lines (54 loc) • 2.28 kB
JavaScript
import React, { useCallback, useContext } from 'react';
import { fg } from '@atlaskit/platform-feature-flags/fg';
import { Reference } from '@atlaskit/popper/reference';
import { useGetMemoizedMergedTriggerRefNew } from '../use-get-memoized-merged-trigger-ref-new';
import { IdContext } from './id-context';
import { IsOpenContext } from './is-open-context';
import { RoleContext } from './role-context';
import { SetTriggerRefContext } from './set-trigger-ref-context';
import { TriggerRefObjectContext } from './trigger-ref-object-context';
import { useEnsureIsInsidePopup } from './use-ensure-is-inside-popup';
/**
* __Popup trigger__
*
* Popup trigger is the component that renders the trigger for the popup.
*
* It must be a child of the Popup component.
*/
export const PopupTrigger = ({
children
}) => {
useEnsureIsInsidePopup();
const id = useContext(IdContext);
const setTriggerRef = useContext(SetTriggerRefContext);
const triggerRefObject = useContext(TriggerRefObjectContext);
const isOpen = useContext(IsOpenContext);
const getMergedTriggerRef = useGetMemoizedMergedTriggerRefNew();
const role = useContext(RoleContext);
// Stable ref callback — avoids creating a new function instance on every render,
// which would cause React to detach and reattach the ref unnecessarily.
// triggerRefObject is a MutableRefObject (from useRef) so its identity never changes,
// meaning this callback is effectively created once per mount.
const triggerRef = useCallback(node => {
triggerRefObject.current = node;
}, [triggerRefObject]);
const ariaHasPopup = role === 'dialog' ? 'dialog' : true;
// When the top-layer flag is on, bypass Popper's <Reference> entirely.
// We only need to set triggerRefObject.current — no Popper ref merging needed.
if (fg('platform-dst-top-layer')) {
return /*#__PURE__*/React.createElement(React.Fragment, null, children({
ref: triggerRef,
'aria-controls': id,
'aria-expanded': isOpen,
'aria-haspopup': ariaHasPopup
}));
}
return /*#__PURE__*/React.createElement(Reference, null, ({
ref
}) => children({
ref: getMergedTriggerRef(ref, setTriggerRef),
'aria-controls': id,
'aria-expanded': isOpen,
'aria-haspopup': ariaHasPopup
}));
};