UNPKG

@gluestack-ui/core

Version:

Universal UI components for React Native, Expo, and Next.js

116 lines 5.09 kB
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