@yandex/ui
Version:
Yandex UI components
51 lines (50 loc) • 3.04 kB
JavaScript
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)));
};