Menu fixes

Fixed: Menus in modals on iOS
Fixed: Menu not closing on outside touch on mobile
This commit is contained in:
Mark McDowall 2019-08-15 22:51:30 -07:00
parent 73e6db9a12
commit 34e0eea173
3 changed files with 34 additions and 4 deletions

View File

@ -39,6 +39,7 @@ class Menu extends Component {
this._scheduleUpdate = null; this._scheduleUpdate = null;
this._menuButtonId = getUniqueElememtId(); this._menuButtonId = getUniqueElememtId();
this._menuContentId = getUniqueElememtId();
this.state = { this.state = {
isMenuOpen: false, isMenuOpen: false,
@ -99,12 +100,14 @@ class Menu extends Component {
window.addEventListener('resize', this.onWindowResize); window.addEventListener('resize', this.onWindowResize);
window.addEventListener('scroll', this.onWindowScroll, { capture: true }); window.addEventListener('scroll', this.onWindowScroll, { capture: true });
window.addEventListener('click', this.onWindowClick); window.addEventListener('click', this.onWindowClick);
window.addEventListener('touchstart', this.onTouchStart);
} }
_removeListener() { _removeListener() {
window.removeEventListener('resize', this.onWindowResize); window.removeEventListener('resize', this.onWindowResize);
window.removeEventListener('scroll', this.onWindowScroll, { capture: true }); window.removeEventListener('scroll', this.onWindowScroll, { capture: true });
window.removeEventListener('click', this.onWindowClick); window.removeEventListener('click', this.onWindowClick);
window.removeEventListener('touchstart', this.onTouchStart);
} }
// //
@ -123,6 +126,30 @@ class Menu extends Component {
} }
} }
onTouchStart = (event) => {
const menuButton = document.getElementById(this._menuButtonId);
const menuContent = document.getElementById(this._menuContentId);
if (!menuButton || !menuContent) {
return;
}
if (event.targetTouches.length !== 1) {
return;
}
const target = event.targetTouches[0].target;
if (
!menuButton.contains(target) &&
!menuContent.contains(target) &&
this.state.isMenuOpen
) {
this.setState({ isMenuOpen: false });
this._removeListener();
}
}
onWindowResize = () => { onWindowResize = () => {
this.setMaxHeight(); this.setMaxHeight();
} }

View File

@ -12,6 +12,7 @@ class MenuContent extends Component {
const { const {
forwardedRef, forwardedRef,
className, className,
id,
children, children,
style, style,
isOpen isOpen
@ -19,6 +20,7 @@ class MenuContent extends Component {
return ( return (
<div <div
id={id}
ref={forwardedRef} ref={forwardedRef}
className={className} className={className}
style={style} style={style}
@ -38,6 +40,7 @@ class MenuContent extends Component {
MenuContent.propTypes = { MenuContent.propTypes = {
forwardedRef: PropTypes.func, forwardedRef: PropTypes.func,
className: PropTypes.string, className: PropTypes.string,
id: PropTypes.string.isRequired,
children: PropTypes.node.isRequired, children: PropTypes.node.isRequired,
style: PropTypes.object, style: PropTypes.object,
isOpen: PropTypes.bool isOpen: PropTypes.bool

View File

@ -33,6 +33,7 @@ class Modal extends Component {
this._node = document.getElementById('portal-root'); this._node = document.getElementById('portal-root');
this._backgroundRef = null; this._backgroundRef = null;
this._modalId = getUniqueElememtId(); this._modalId = getUniqueElememtId();
this._bodyScrollTop = 0;
} }
componentDidMount() { componentDidMount() {
@ -73,8 +74,8 @@ class Modal extends Component {
if (openModals.length === 1) { if (openModals.length === 1) {
if (isIOS()) { if (isIOS()) {
setScrollLock(true); setScrollLock(true);
const offset = document.body.scrollTop; const scrollTop = document.body.scrollTop;
document.body.style.top = `${offset * -1}px`; this._bodyScrollTop = scrollTop;
elementClass(document.body).add(styles.modalOpenIOS); elementClass(document.body).add(styles.modalOpenIOS);
} else { } else {
elementClass(document.body).add(styles.modalOpen); elementClass(document.body).add(styles.modalOpen);
@ -90,9 +91,8 @@ class Modal extends Component {
setScrollLock(false); setScrollLock(false);
if (isIOS()) { if (isIOS()) {
const offset = parseInt(document.body.style.top);
elementClass(document.body).remove(styles.modalOpenIOS); elementClass(document.body).remove(styles.modalOpenIOS);
document.body.scrollTop = (offset * -1); document.body.scrollTop = this._bodyScrollTop;
} else { } else {
elementClass(document.body).remove(styles.modalOpen); elementClass(document.body).remove(styles.modalOpen);
} }