@shopgate/engage
Version:
Shopgate's ENGAGE library.
157 lines (151 loc) • 4.45 kB
JavaScript
import _createClass from "@babel/runtime/helpers/createClass";
import _inheritsLoose from "@babel/runtime/helpers/inheritsLoose";
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import delay from 'lodash/delay';
import { connect } from 'react-redux';
import { UIEvents } from '@shopgate/engage/core/events';
import { getModalCount } from '@shopgate/engage/a11y/selectors';
import { emitScrollEvents } from '@shopgate/engage/core/streams';
import { MODAL_EVENTS } from '@shopgate/engage/components';
import { ViewContext } from "./context";
/**
* @param {Object} state State
* @returns {Object}
*/
import { jsx as _jsx } from "react/jsx-runtime";
const mapStateToProps = state => ({
modalCount: getModalCount(state)
});
/**
* The ViewProvider component.
*/
let ViewProvider = /*#__PURE__*/function (_Component) {
/**
* @param {Object} props The component props.
*/
function ViewProvider(props) {
var _this;
_this = _Component.call(this, props) || this;
_this.handleModalShow = () => {
_this.activeElement = document.activeElement;
_this.setAriaHidden(true);
};
_this.handleModalHide = () => {
if (_this.activeElement && _this.activeElement.focus) {
_this.activeElement.focus();
}
_this.setAriaHidden(false);
};
/**
* @param {number} value The new top value;
*/
_this.setTop = value => {
_this.set('top', value);
};
/**
* @param {number} value The new bottom value;
*/
_this.setBottom = value => {
_this.set('bottom', value);
};
/**
* @param {boolean} value The new aria hidden value;
*/
_this.setAriaHidden = value => {
_this.set('ariaHidden', value);
};
/**
* @param {Object} ref A React reference to the page content wrapper.
*/
_this.setContentRef = ref => {
_this.set('contentRef', ref);
// Delay to dispatch actual DOM node - implemented with CCP-2358
delay(() => emitScrollEvents(ref.current), 250);
};
/**
* @return {Object}
*/
_this.getContentRef = () => _this.state.contentRef;
/**
* Scrolls the content ref to the top.
* @param {number} [value=0] A number indicating the new scroll position of the content ref.
*/
_this.scrollTop = (value = 0) => {
const {
current
} = _this.state.contentRef;
if (current) {
current.scrollTop = value;
}
};
/**
* @param {string} property The state property to set.
* @param {*} value The value to set.
*/
_this.set = (property, value) => {
if (_this.state[property] !== value) {
_this.setState({
[property]: value
});
}
};
_this.state = {
top: 0,
bottom: 0,
contentRef: {
current: null
},
ariaHidden: props.modalCount > 0
};
// Last view active element
_this.activeElement = null;
return _this;
}
/** @inheritDoc */
_inheritsLoose(ViewProvider, _Component);
var _proto = ViewProvider.prototype;
_proto.componentDidMount = function componentDidMount() {
UIEvents.addListener(MODAL_EVENTS.SHOW, this.handleModalShow);
UIEvents.addListener(MODAL_EVENTS.HIDE, this.handleModalHide);
}
/** @inheritDoc */;
_proto.componentDidUpdate = function componentDidUpdate(prevProps) {
if (prevProps.modalCount !== this.props.modalCount) {
this.setAriaHidden(this.props.modalCount > 0);
}
}
/** @inheritDoc */;
_proto.componentWillUnmount = function componentWillUnmount() {
UIEvents.removeListener(MODAL_EVENTS.SHOW, this.handleModalShow);
UIEvents.removeListener(MODAL_EVENTS.HIDE, this.handleModalHide);
}
/**
* @returns {Object}
*/;
/**
* @returns {JSX}
*/
_proto.render = function render() {
return /*#__PURE__*/_jsx(ViewContext.Provider, {
value: this.providerContext,
children: this.props.children
});
};
return _createClass(ViewProvider, [{
key: "providerContext",
get: function () {
return {
...this.state,
set: this.set,
setTop: this.setTop,
setBottom: this.setBottom,
setAriaHidden: this.setAriaHidden,
setContentRef: this.setContentRef,
getContentRef: this.getContentRef,
scrollTop: this.scrollTop
};
}
}]);
}(Component);
export default connect(mapStateToProps)(ViewProvider);