@ozen-ui/kit
Version:
React component library
136 lines (135 loc) • 7.72 kB
JavaScript
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';