244 lines
9.4 KiB
JavaScript
244 lines
9.4 KiB
JavaScript
'use client';
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
function _export(target, all) {
|
|
for(var name in all)Object.defineProperty(target, name, {
|
|
enumerable: true,
|
|
get: all[name]
|
|
});
|
|
}
|
|
_export(exports, {
|
|
usePopoverBase_unstable: function() {
|
|
return usePopoverBase_unstable;
|
|
},
|
|
usePopover_unstable: function() {
|
|
return usePopover_unstable;
|
|
}
|
|
});
|
|
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
|
|
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
|
|
const _reactutilities = require("@fluentui/react-utilities");
|
|
const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
|
|
const _reactpositioning = require("@fluentui/react-positioning");
|
|
const _reacttabster = require("@fluentui/react-tabster");
|
|
const _index = require("../PopoverSurface/index");
|
|
const _constants = require("./constants");
|
|
const _reactmotion = require("@fluentui/react-motion");
|
|
const _PopoverSurfaceMotion = require("./PopoverSurfaceMotion");
|
|
const usePopover_unstable = (props)=>{
|
|
const { appearance, size = 'medium' } = props;
|
|
const positioning = (0, _reactpositioning.resolvePositioningShorthand)(props.positioning);
|
|
const withArrow = props.withArrow && !positioning.coverTarget;
|
|
const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)();
|
|
const handlePositionEnd = (0, _reactpositioning.usePositioningSlideDirection)({
|
|
targetDocument,
|
|
onPositioningEnd: positioning.onPositioningEnd
|
|
});
|
|
const state = usePopoverBase_unstable({
|
|
...props,
|
|
positioning: {
|
|
...positioning,
|
|
onPositioningEnd: handlePositionEnd,
|
|
// Update the offset with the arrow size only when it's available
|
|
...withArrow ? {
|
|
offset: (0, _reactpositioning.mergeArrowOffset)(positioning.offset, _index.arrowHeights[size])
|
|
} : {}
|
|
}
|
|
});
|
|
return {
|
|
components: {
|
|
surfaceMotion: _PopoverSurfaceMotion.PopoverSurfaceMotion
|
|
},
|
|
appearance,
|
|
size,
|
|
...state,
|
|
surfaceMotion: (0, _reactmotion.presenceMotionSlot)(props.surfaceMotion, {
|
|
elementType: _PopoverSurfaceMotion.PopoverSurfaceMotion,
|
|
defaultProps: {
|
|
visible: state.open,
|
|
appear: true,
|
|
unmountOnExit: true
|
|
}
|
|
})
|
|
};
|
|
};
|
|
const usePopoverBase_unstable = (props)=>{
|
|
const [contextTarget, setContextTarget] = (0, _reactpositioning.usePositioningMouseTarget)();
|
|
const initialState = {
|
|
contextTarget,
|
|
setContextTarget,
|
|
...props
|
|
};
|
|
const children = _react.Children.toArray(props.children);
|
|
if (process.env.NODE_ENV !== 'production') {
|
|
if (children.length === 0) {
|
|
// eslint-disable-next-line no-console
|
|
console.warn('Popover must contain at least one child');
|
|
}
|
|
if (children.length > 2) {
|
|
// eslint-disable-next-line no-console
|
|
console.warn('Popover must contain at most two children');
|
|
}
|
|
}
|
|
let popoverTrigger = undefined;
|
|
let popoverSurface = undefined;
|
|
if (children.length === 2) {
|
|
popoverTrigger = children[0];
|
|
popoverSurface = children[1];
|
|
} else if (children.length === 1) {
|
|
popoverSurface = children[0];
|
|
}
|
|
const [open, setOpenState] = useOpenState(initialState);
|
|
const [setOpenTimeout, clearOpenTimeout] = (0, _reactutilities.useTimeout)();
|
|
const setOpen = (0, _reactutilities.useEventCallback)((e, shouldOpen)=>{
|
|
clearOpenTimeout();
|
|
if (!(e instanceof Event) && e.persist) {
|
|
// < React 17 still uses pooled synthetic events
|
|
e.persist();
|
|
}
|
|
if (e.type === 'mouseleave') {
|
|
var _props_mouseLeaveDelay;
|
|
// FIXME leaking Node timeout type
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
setOpenTimeout(()=>{
|
|
setOpenState(e, shouldOpen);
|
|
}, (_props_mouseLeaveDelay = props.mouseLeaveDelay) !== null && _props_mouseLeaveDelay !== void 0 ? _props_mouseLeaveDelay : 500);
|
|
} else {
|
|
setOpenState(e, shouldOpen);
|
|
}
|
|
});
|
|
const toggleOpen = _react.useCallback((e)=>{
|
|
setOpen(e, !open);
|
|
}, [
|
|
setOpen,
|
|
open
|
|
]);
|
|
const positioningRefs = usePopoverRefs(initialState);
|
|
const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)();
|
|
var _props_closeOnIframeFocus;
|
|
(0, _reactutilities.useOnClickOutside)({
|
|
contains: _reactutilities.elementContains,
|
|
element: targetDocument,
|
|
callback: (ev)=>setOpen(ev, false),
|
|
refs: [
|
|
positioningRefs.triggerRef,
|
|
positioningRefs.contentRef
|
|
],
|
|
disabled: !open,
|
|
disabledFocusOnIframe: !((_props_closeOnIframeFocus = props.closeOnIframeFocus) !== null && _props_closeOnIframeFocus !== void 0 ? _props_closeOnIframeFocus : true)
|
|
});
|
|
// only close on scroll for context, or when closeOnScroll is specified
|
|
const closeOnScroll = initialState.openOnContext || initialState.closeOnScroll;
|
|
(0, _reactutilities.useOnScrollOutside)({
|
|
contains: _reactutilities.elementContains,
|
|
element: targetDocument,
|
|
callback: (ev)=>setOpen(ev, false),
|
|
refs: [
|
|
positioningRefs.triggerRef,
|
|
positioningRefs.contentRef
|
|
],
|
|
disabled: !open || !closeOnScroll
|
|
});
|
|
const { findFirstFocusable } = (0, _reacttabster.useFocusFinders)();
|
|
const activateModal = (0, _reacttabster.useActivateModal)();
|
|
_react.useEffect(()=>{
|
|
if (props.unstable_disableAutoFocus) {
|
|
return;
|
|
}
|
|
const contentElement = positioningRefs.contentRef.current;
|
|
if (open && contentElement) {
|
|
var _contentElement_getAttribute;
|
|
const shouldFocusContainer = !isNaN((_contentElement_getAttribute = contentElement.getAttribute('tabIndex')) !== null && _contentElement_getAttribute !== void 0 ? _contentElement_getAttribute : undefined);
|
|
const firstFocusable = shouldFocusContainer ? contentElement : findFirstFocusable(contentElement);
|
|
firstFocusable === null || firstFocusable === void 0 ? void 0 : firstFocusable.focus();
|
|
if (shouldFocusContainer) {
|
|
// Modal activation happens automatically when something inside the modal is focused programmatically.
|
|
// When the container is focused, we need to activate the modal manually.
|
|
activateModal(contentElement);
|
|
}
|
|
}
|
|
}, [
|
|
findFirstFocusable,
|
|
activateModal,
|
|
open,
|
|
positioningRefs.contentRef,
|
|
props.unstable_disableAutoFocus
|
|
]);
|
|
var _props_inertTrapFocus, _props_inline;
|
|
return {
|
|
...initialState,
|
|
...positioningRefs,
|
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
inertTrapFocus: (_props_inertTrapFocus = props.inertTrapFocus) !== null && _props_inertTrapFocus !== void 0 ? _props_inertTrapFocus : props.legacyTrapFocus === undefined ? false : !props.legacyTrapFocus,
|
|
popoverTrigger,
|
|
popoverSurface,
|
|
open,
|
|
setOpen,
|
|
toggleOpen,
|
|
setContextTarget,
|
|
contextTarget,
|
|
inline: (_props_inline = props.inline) !== null && _props_inline !== void 0 ? _props_inline : false
|
|
};
|
|
};
|
|
/**
|
|
* Creates and manages the Popover open state
|
|
*/ function useOpenState(state) {
|
|
'use no memo';
|
|
const onOpenChange = (0, _reactutilities.useEventCallback)((e, data)=>{
|
|
var _state_onOpenChange;
|
|
return (_state_onOpenChange = state.onOpenChange) === null || _state_onOpenChange === void 0 ? void 0 : _state_onOpenChange.call(state, e, data);
|
|
});
|
|
const [open, setOpenState] = (0, _reactutilities.useControllableState)({
|
|
state: state.open,
|
|
defaultState: state.defaultOpen,
|
|
initialState: false
|
|
});
|
|
state.open = open !== undefined ? open : state.open;
|
|
const setContextTarget = state.setContextTarget;
|
|
const setOpen = _react.useCallback((e, shouldOpen)=>{
|
|
if (shouldOpen && e.type === 'contextmenu') {
|
|
setContextTarget(e);
|
|
}
|
|
if (!shouldOpen) {
|
|
setContextTarget(undefined);
|
|
}
|
|
setOpenState(shouldOpen);
|
|
onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(e, {
|
|
open: shouldOpen
|
|
});
|
|
}, [
|
|
setOpenState,
|
|
onOpenChange,
|
|
setContextTarget
|
|
]);
|
|
return [
|
|
open,
|
|
setOpen
|
|
];
|
|
}
|
|
/**
|
|
* Creates and sets the necessary trigger, target and content refs used by Popover
|
|
*/ function usePopoverRefs(state) {
|
|
'use no memo';
|
|
const positioningOptions = {
|
|
position: 'above',
|
|
align: 'center',
|
|
arrowPadding: 2 * _constants.popoverSurfaceBorderRadius,
|
|
target: state.openOnContext ? state.contextTarget : undefined,
|
|
...(0, _reactpositioning.resolvePositioningShorthand)(state.positioning)
|
|
};
|
|
// no reason to render arrow when covering the target
|
|
if (positioningOptions.coverTarget) {
|
|
state.withArrow = false;
|
|
}
|
|
const { targetRef: triggerRef, containerRef: contentRef, arrowRef } = (0, _reactpositioning.usePositioning)(positioningOptions);
|
|
return {
|
|
triggerRef,
|
|
contentRef,
|
|
arrowRef
|
|
};
|
|
}
|