UNPKG

@yandex/ui

Version:

Yandex UI components

87 lines (86 loc) 4 kB
import { __assign, __extends, __read, __rest, __spread } from "tslib"; import React, { PureComponent, createRef } from 'react'; import { isKeyCode, Keys } from '../lib/keyboard'; import { getDisplayName } from '../lib/getDisplayName'; import { mergeAllRefs } from '../lib/mergeRefs'; import { canUseDOM } from '../lib/canUseDOM'; var POINTER_DOWN = 'pointerdown'; var POINTER_UP = 'pointerup'; if (canUseDOM()) { if (!window.PointerEvent) { POINTER_DOWN = 'mousedown'; POINTER_UP = 'mouseup'; if (!window.MouseEvent) { POINTER_UP = 'click'; } } } var defaultProps = { ignoreRefs: [], }; export var withOutsideClick = function (WrappedComponent) { var WithOutsideClick = /** @class */ (function (_super) { __extends(WithOutsideClick, _super); function WithOutsideClick() { var _this = _super !== null && _super.apply(this, arguments) || this; /** * Контейнер с ссылкой на DOM элемент оборачиваемого компонента. */ _this.targetRef = createRef(); _this.pointerDownEventSource = null; _this.onPointerDown = function (event) { _this.pointerDownEventSource = event.target; }; _this.onPointerUp = function (event) { var ignoreElements = __spread(_this.props.ignoreRefs, [_this.targetRef]); if (_this.props.onOutsideClick !== undefined && ignoreElements.every(function (element) { return (element.current !== null && !element.current.contains(_this.pointerDownEventSource) && // mouseDown не в ignoreElements !element.current.contains(event.target)); })) { _this.props.onOutsideClick(event); } _this.pointerDownEventSource = null; }; _this.onKeyDown = function (event) { if (_this.props.onEscapeKeyDown !== undefined && isKeyCode(event.keyCode, [Keys.ESC])) { _this.props.onEscapeKeyDown(event); } }; return _this; } WithOutsideClick.prototype.componentDidMount = function () { if (this.props.visible) { this.subscribeToEvents(); } }; WithOutsideClick.prototype.componentWillUnmount = function () { this.unsubscribeFromEvents(); }; WithOutsideClick.prototype.componentDidUpdate = function (prevProps) { if (!prevProps.visible && this.props.visible) { this.subscribeToEvents(); } else if (prevProps.visible && !this.props.visible) { this.unsubscribeFromEvents(); } }; WithOutsideClick.prototype.render = function () { var _a = this.props, ignoreRefs = _a.ignoreRefs, props = __rest(_a, ["ignoreRefs"]); return React.createElement(WrappedComponent, __assign({}, props, { targetRef: mergeAllRefs(this.targetRef, this.props.targetRef) })); }; WithOutsideClick.prototype.subscribeToEvents = function () { document.addEventListener(POINTER_DOWN, this.onPointerDown); document.addEventListener(POINTER_UP, this.onPointerUp); document.addEventListener('keydown', this.onKeyDown); }; WithOutsideClick.prototype.unsubscribeFromEvents = function () { document.removeEventListener(POINTER_DOWN, this.onPointerDown); document.removeEventListener(POINTER_UP, this.onPointerUp); document.removeEventListener('keydown', this.onKeyDown); }; WithOutsideClick.displayName = "withOutsideClick(" + getDisplayName(WrappedComponent) + ")"; WithOutsideClick.defaultProps = defaultProps; return WithOutsideClick; }(PureComponent)); return WithOutsideClick; };