@gluestack-ui/core
Version:
Universal UI components for React Native, Expo, and Next.js
116 lines • 5.09 kB
JSX
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import React, { forwardRef } from 'react';
import { useControllableState } from '@gluestack-ui/utils/hooks';
import { useKeyboardDismissable } from '@gluestack-ui/utils/aria';
import { TooltipProvider } from './context';
import { useId } from '@gluestack-ui/utils/aria';
import { Platform } from 'react-native';
import { Overlay } from '../../overlay/creator';
import { composeEventHandlers } from '@gluestack-ui/utils/common';
function Tooltip(StyledTooltip) {
return forwardRef((_a, ref) => {
var { isOpen: isOpenProp, isDisabled, defaultIsOpen = false, onClose, onOpen, openDelay = 350, closeDelay = 0, placement = 'bottom', children, closeOnClick = true, trigger, crossOffset, offset = 10, shouldOverlapWithTrigger = false, shouldFlip = true, _experimentalOverlay = false } = _a, props = __rest(_a, ["isOpen", "isDisabled", "defaultIsOpen", "onClose", "onOpen", "openDelay", "closeDelay", "placement", "children", "closeOnClick", "trigger", "crossOffset", "offset", "shouldOverlapWithTrigger", "shouldFlip", "_experimentalOverlay"]);
const [isOpen, setIsOpen] = useControllableState({
value: isOpenProp,
defaultValue: defaultIsOpen,
onChange: (value) => {
value ? onOpen && onOpen() : onClose && onClose();
},
});
const handleOpen = React.useCallback(() => {
setIsOpen(true);
}, [setIsOpen]);
const handleClose = React.useCallback(() => {
setIsOpen(false);
}, [setIsOpen]);
const enterTimeout = React.useRef();
const exitTimeout = React.useRef();
const openWithDelay = React.useCallback(() => {
if (!isDisabled) {
enterTimeout.current = setTimeout(handleOpen, openDelay);
}
}, [isDisabled, handleOpen, openDelay]);
const closeWithDelay = React.useCallback(() => {
if (enterTimeout.current) {
clearTimeout(enterTimeout.current);
}
exitTimeout.current = setTimeout(handleClose, closeDelay);
}, [closeDelay, handleClose]);
const tooltipID = useId();
React.useEffect(() => () => {
clearTimeout(enterTimeout.current);
clearTimeout(exitTimeout.current);
}, []);
const updatedTrigger = (reference) => {
return trigger({
'ref': reference,
'collapsable': false,
'onPress': composeEventHandlers(() => {
if (closeOnClick) {
closeWithDelay();
}
}),
'onFocus': composeEventHandlers(openWithDelay),
'onBlur': composeEventHandlers(closeWithDelay),
'onMouseEnter': composeEventHandlers(openWithDelay),
'onMouseLeave': composeEventHandlers(closeWithDelay),
'aria-describedby': isOpen ? tooltipID : undefined,
}, { open: isOpen });
};
const targetRef = React.useRef(null);
useKeyboardDismissable({
enabled: isOpen,
callback: () => setIsOpen(false),
});
if (_experimentalOverlay) {
return (<>
{updatedTrigger(targetRef)}
<TooltipProvider value={{
placement,
targetRef,
handleClose: handleClose,
isOpen,
crossOffset,
offset,
shouldOverlapWithTrigger,
shouldFlip,
}}>
<StyledTooltip {...props} ref={ref} role={Platform.OS === 'web' ? 'tooltip' : undefined} tabIndex={-1} id={tooltipID}>
{children}
</StyledTooltip>
</TooltipProvider>
</>);
}
return (<>
{updatedTrigger(targetRef)}
<Overlay isOpen={isOpen} onRequestClose={handleClose}>
<TooltipProvider value={{
placement,
targetRef,
handleClose: handleClose,
isOpen,
crossOffset,
offset,
shouldOverlapWithTrigger,
shouldFlip,
}}>
<StyledTooltip {...props} ref={ref} role={Platform.OS === 'web' ? 'tooltip' : undefined} focussable={false} id={tooltipID}>
{children}
</StyledTooltip>
</TooltipProvider>
</Overlay>
</>);
});
}
export { Tooltip };
//# sourceMappingURL=Tooltip.jsx.map