UNPKG

@yandex/ui

Version:

Yandex UI components

51 lines (50 loc) 3.04 kB
import { __assign, __read, __rest } from "tslib"; import React, { useState, cloneElement, useRef, useCallback, Children } from 'react'; import { mergeRefs } from '../lib/mergeRefs'; import { forkFn } from '../lib/forkFn'; import { useUniqId } from '../useUniqId'; import { Tooltip } from './Tooltip'; /** * Компонент используется для создания всплывающих подсказок. * * @param {TooltipStatefulProps} props Свойства компонента. */ export var TooltipStateful = function (_a) { var _b; var children = _a.children, content = _a.content, _c = _a.defaultVisible, defaultVisible = _c === void 0 ? false : _c, // eslint-disable-next-line react-hooks/rules-of-hooks _d = _a.id, // eslint-disable-next-line react-hooks/rules-of-hooks id = _d === void 0 ? useUniqId('tooltip') : _d, _e = _a.trigger, trigger = _e === void 0 ? 'hover' : _e, props = __rest(_a, ["children", "content", "defaultVisible", "id", "trigger"]); var _f = __read(useState(defaultVisible), 2), visible = _f[0], setVisible = _f[1]; var anchorRef = useRef(null); var child = Children.only(children); // В дальнейшем данный код можно вынести куда-то выше и использовать по аналогии с Popup и Modal. var triggers = Array.isArray(trigger) ? trigger : [trigger]; var handlers = triggers.reduce(function (acc, trigger) { switch (trigger) { case 'click': acc.onClick = forkFn(child.props.onClick, function () { return setVisible(!visible); }); break; case 'focus': acc.onFocus = forkFn(child.props.onFocus, function () { return setVisible(true); }); acc.onBlur = forkFn(child.props.onBlur, function () { return setVisible(false); }); break; case 'hover': acc.onMouseEnter = forkFn(child.props.onMouseEnter, function () { return setVisible(true); }); acc.onMouseLeave = forkFn(child.props.onMouseLeave, function () { return setVisible(false); }); break; } return acc; }, {}); var onClose = useCallback(function () { setVisible(false); }, []); // Определяем тип ссылки в зависимости от типа потомка, // нативные элементы реализуют ref, лего-компоненты должны реализовывать innerRef. var refKey = typeof child.type === 'string' ? 'ref' : 'innerRef'; var ref = child.props[refKey] === undefined ? anchorRef : mergeRefs(child.props[refKey], anchorRef); return (React.createElement(React.Fragment, null, cloneElement(child, __assign(__assign({}, handlers), (_b = {}, _b[refKey] = ref, _b['aria-describedby'] = id, _b))), React.createElement(Tooltip, __assign({}, props, { id: id, visible: visible, anchor: anchorRef, onClose: onClose }), content))); };