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