UNPKG

@wix/design-system

Version:

@wix/design-system

99 lines 4.73 kB
import React, { useState, useImperativeHandle, forwardRef, useMemo, useEffect, useRef, } from 'react'; import Popover from '../Popover'; import RawText from '../Text/RawText'; import { dataHooks, TIMEOUT } from './constants'; import { ZIndex } from '../common/ZIndex'; import { st, classes } from './Tooltip.st.css.js'; import { useEventCallback } from '../common/useEventCallback/useEventCallback'; const Tooltip = forwardRef(({ onShow = () => ({}), onHide = () => ({}), size = 'medium', className, placement = 'top', exitDelay = 0, enterDelay = 0, moveArrowTo, appendTo = 'window', flip = true, fixed = false, maxWidth = 204, fluid, moveBy, disabled, children, zIndex = ZIndex.tooltip, textAlign = 'start', content = '', inline, 'aria-describedby': ariaDescribedBy, 'aria-labelledby': ariaLabelledBy, interactive = true, ...rest }, ref) => { const [shown, setShown] = useState(false); const contentRef = useRef(null); const open = useEventCallback(() => { setShown(true); onShow?.(); }); const close = useEventCallback(() => { setShown(false); onHide?.(); }); useImperativeHandle(ref, () => ({ open, close, getContentElement: () => contentRef.current, })); const isDisabled = disabled ?? false; const onFocus = useEventCallback((event, handlers) => { const focusableHOC = handlers && handlers.focus; const target = event.target; try { if (process.env.NODE_ENV !== 'test' && target instanceof Element && !target.matches(':focus-visible')) { handlers?.blur(); return; } } catch (e) { // browser does not support `matches(':focus-visible')` fallback to original focus behavior } open(); return focusableHOC ? handlers.focus() : null; }); const onBlur = useEventCallback((_event, handlers) => { const focusableHOC = handlers && handlers.blur; close(); return focusableHOC ? handlers.blur() : null; }); const handleKeyDown = useEventCallback((event) => { if (event.key === 'Escape' && shown) { close(); } }); useEffect(() => { document.addEventListener('keydown', handleKeyDown); return () => { document.removeEventListener('keydown', handleKeyDown); }; }, [handleKeyDown]); const triggerElement = useMemo(() => { if (typeof children === 'string' || !children) { return children; } if (React.isValidElement(children)) { const ariaProps = ariaLabelledBy ? { 'aria-labelledby': ariaLabelledBy } : { 'aria-describedby': ariaDescribedBy }; return React.cloneElement(children, { ...(isDisabled ? {} : { onFocus, onBlur }), ...ariaProps, }); } if (typeof children === 'function') { return children({ onFocus, onBlur, }); } return; }, [ children, isDisabled, onFocus, onBlur, ariaDescribedBy, ariaLabelledBy, ]); const contentElement = useMemo(() => { const textSize = size === 'small' ? 'tiny' : 'small'; return (React.createElement("div", { style: { textAlign } }, typeof content === 'string' ? ( // @ts-ignore React.createElement(RawText, { dataHook: dataHooks.tooltipText, size: textSize, light: true, className: classes.text, renderChildren: ({ text }) => text, renderElement: ({ element }) => element }, content)) : (content))); }, [content, textAlign, size]); return (React.createElement(Popover, { role: "tooltip", showArrow: size !== 'small', className: st(classes.root, { size, inline }, className), placement: placement, shown: isDisabled ? false : shown, onMouseEnter: isDisabled ? undefined : open, onMouseLeave: close, onClickOutside: close, onEscPress: close, "data-size": size, hideDelay: exitDelay, showDelay: enterDelay, moveBy: moveBy, moveArrowTo: moveArrowTo, appendTo: appendTo, id: ariaLabelledBy || ariaDescribedBy, flip: flip, fixed: fixed, maxWidth: maxWidth, fluid: fluid, disableClickOutsideWhenClosed: true, zIndex: zIndex, interactive: interactive, ...rest, theme: "dark", timeout: TIMEOUT }, React.createElement(Popover.Element, null, triggerElement), React.createElement(Popover.Content, null, React.createElement("div", { ref: contentRef, style: { maxWidth } }, contentElement)))); }); Tooltip.displayName = 'Tooltip'; export default Tooltip; //# sourceMappingURL=Tooltip.js.map