UNPKG

@ozen-ui/kit

Version:

React component library

136 lines (135 loc) 7.72 kB
import { __assign, __read, __rest, __spreadArray } from "tslib"; import './Tooltip.css'; import React, { useRef, useMemo, useEffect, useState } from 'react'; import { useBoolean } from '../../hooks/useBoolean'; import { useControlled } from '../../hooks/useControlled'; import { useDebounceCallback } from '../../hooks/useDebounceCallback'; import { useDeprecatedProperty } from '../../hooks/useDeprecated'; import { useMultiRef } from '../../hooks/useMultiRef'; import { useThemeProps } from '../../hooks/useThemeProps'; import { cn } from '../../utils/classname'; import { polymorphicComponentWithRef } from '../../utils/polymorphicComponentWithRef'; import { Popover } from '../Popover'; import { TOOLTIP_DEFAULT_ARROW, TOOLTIP_DEFAULT_DELAY_ENTER, TOOLTIP_DEFAULT_DELAY_LEAVE, TOOLTIP_DEFAULT_DISABLED, TOOLTIP_DEFAULT_INVERSE, TOOLTIP_DEFAULT_OFFSET, TOOLTIP_DEFAULT_SHOULD_WRAP_CHILDREN, TOOLTIP_DEFAULT_SIZE, TOOLTIP_DEFAULT_TAG, TOOLTIP_DEFAULT_TRIGGER, } from './constants'; export var cnTooltip = cn('Tooltip'); export var Tooltip = polymorphicComponentWithRef(function (inProps, ref) { var props = useThemeProps({ props: inProps, name: 'Tooltip' }); var _a = props.trigger, trigger = _a === void 0 ? TOOLTIP_DEFAULT_TRIGGER : _a, _b = props.size, size = _b === void 0 ? TOOLTIP_DEFAULT_SIZE : _b, _c = props.offset, offset = _c === void 0 ? TOOLTIP_DEFAULT_OFFSET : _c, _d = props.delayEnter, delayEnter = _d === void 0 ? TOOLTIP_DEFAULT_DELAY_ENTER : _d, _e = props.delayLeave, delayLeave = _e === void 0 ? TOOLTIP_DEFAULT_DELAY_LEAVE : _e, _f = props.arrow, arrow = _f === void 0 ? TOOLTIP_DEFAULT_ARROW : _f, _g = props.shouldWrapChildren, shouldWrapChildren = _g === void 0 ? TOOLTIP_DEFAULT_SHOULD_WRAP_CHILDREN : _g, _h = props.disabled, disabled = _h === void 0 ? TOOLTIP_DEFAULT_DISABLED : _h, _j = props.inverse, inverse = _j === void 0 ? TOOLTIP_DEFAULT_INVERSE : _j, _k = props.as, as = _k === void 0 ? TOOLTIP_DEFAULT_TAG : _k, modifiersProp = props.modifiers, onMouseEnter = props.onMouseEnter, onMouseLeave = props.onMouseLeave, variant = props.variant, children = props.children, label = props.label, openProp = props.open, className = props.className, onOpen = props.onOpen, onClose = props.onClose, other = __rest(props, ["trigger", "size", "offset", "delayEnter", "delayLeave", "arrow", "shouldWrapChildren", "disabled", "inverse", "as", "modifiers", "onMouseEnter", "onMouseLeave", "variant", "children", "label", "open", "className", "onOpen", "onClose"]); useDeprecatedProperty(!!variant, 'variant', 'inverse'); var anchorRef = useRef(null); var _l = __read(useState(), 2), delay = _l[0], setDelay = _l[1]; var _m = __read(useBoolean(), 2), focused = _m[0], setFocused = _m[1]; var _o = __read(useBoolean(), 2), hovered = _o[0], setHovered = _o[1]; var modifiers = __spreadArray([ { name: 'arrow', options: { padding: size === 'xs' ? 8 : 12, }, } ], __read((modifiersProp || [])), false); var _p = __read(useControlled({ value: openProp, defaultValue: false, name: 'Tooltip', state: 'open', }), 2), openState = _p[0], setOpenState = _p[1]; var setOpen = function (open) { if (disabled && open) return; if (open) onOpen === null || onOpen === void 0 ? void 0 : onOpen(); else onClose === null || onClose === void 0 ? void 0 : onClose(); setOpenState(open); }; var _q = __read(useDebounceCallback(setOpen, delay), 2), setOpenWithDelay = _q[0], clearTimeout = _q[1]; var closeWithDelay = function () { return setOpenWithDelay(false); }; useEffect(function () { setDelay(openState ? delayLeave : delayEnter); }, [openState, delayEnter, delayLeave]); useEffect(function () { if (!disabled) return; clearTimeout(); if (openState) setOpen(false); }, [disabled, openState]); var resolveChildren = useMemo(function () { return typeof children !== 'object' || shouldWrapChildren ? (React.createElement("span", null, children)) : (children); }, [children, shouldWrapChildren]); var childrenProps = resolveChildren.props, childrenRef = resolveChildren.ref; var childrenMultiRef = useMultiRef([anchorRef, childrenRef]); var handleMouseEnter = function (e) { if (trigger === 'hover' || trigger === 'hover&focus') { setHovered.on(); setOpenWithDelay(true); } onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(e); }; var handleMouseLeave = function (e) { if (trigger === 'hover' || trigger === 'hover&focus') { setHovered.off(); if (!focused) setOpenWithDelay(false); } onMouseLeave === null || onMouseLeave === void 0 ? void 0 : onMouseLeave(e); }; var handleClick = function () { if (trigger === 'click') setOpenWithDelay(!openState); }; var handleFocus = function () { if (trigger === 'focus' || trigger === 'hover&focus') { setFocused.on(); setOpenWithDelay(true); } }; var handleBlur = function () { if (trigger === 'focus' || trigger === 'hover&focus') { setFocused.off(); if (!hovered) setOpenWithDelay(false); } }; var composeChildrenProps = useMemo(function () { var onClick = childrenProps.onClick, onFocus = childrenProps.onFocus, onBlur = childrenProps.onBlur, onMouseEnter = childrenProps.onMouseEnter, onMouseLeave = childrenProps.onMouseLeave; return { ref: childrenMultiRef, onClick: function (e) { handleClick(); onClick === null || onClick === void 0 ? void 0 : onClick(e); }, onFocus: function (e) { handleFocus(); onFocus === null || onFocus === void 0 ? void 0 : onFocus(e); }, onBlur: function (e) { handleBlur(); onBlur === null || onBlur === void 0 ? void 0 : onBlur(e); }, onMouseEnter: function (e) { handleMouseEnter(e); onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(e); }, onMouseLeave: function (e) { handleMouseLeave(e); onMouseLeave === null || onMouseLeave === void 0 ? void 0 : onMouseLeave(e); }, }; }, [ trigger, childrenProps, childrenMultiRef, handleMouseEnter, handleMouseLeave, handleClick, handleFocus, handleBlur, ]); return (React.createElement(React.Fragment, null, React.cloneElement(resolveChildren, composeChildrenProps), React.createElement(Popover, __assign({ arrow: arrow, offset: offset, background: "main", strategy: "absolute", arrowProps: { size: size }, anchorRef: anchorRef, modifiers: modifiers, as: as, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, radius: size === 'xs' ? 's' : 'l' }, (inverse && { background: 'main-inverse' }), (variant === 'dark' && { background: 'main-inverse' }), { className: cnTooltip({ size: size, variant: variant, inverse: inverse }, [className]), disableEnforceFocus: true, disableReturnFocus: true }, other, { open: openState, onClose: closeWithDelay, ref: ref }), React.createElement("div", { className: cnTooltip('Content', { size: size, variant: variant, inverse: inverse }) }, label)))); }); Tooltip.displayName = 'Tooltip';