From 1d07cfcc3c070fbf1682ece097463cfa21b46e5e Mon Sep 17 00:00:00 2001 From: meriadec Date: Mon, 5 Feb 2018 14:41:08 +0100 Subject: [PATCH 1/2] Save/restore active element on modal open/close --- .eslintrc | 2 ++ src/components/base/Modal/index.js | 38 +++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/.eslintrc b/.eslintrc index 58a1cf34..1999f835 100644 --- a/.eslintrc +++ b/.eslintrc @@ -9,6 +9,8 @@ "__SENTRY_URL__": false, "__static": false, "window": false, + "document": false, + "HTMLDivElement": false, "ResizeObserver": false, }, "rules": { diff --git a/src/components/base/Modal/index.js b/src/components/base/Modal/index.js index f6f1aad8..9843c949 100644 --- a/src/components/base/Modal/index.js +++ b/src/components/base/Modal/index.js @@ -4,6 +4,7 @@ /* eslint-disable jsx-a11y/no-static-element-interactions */ import React, { PureComponent } from 'react' +import { findDOMNode } from 'react-dom' import { connect } from 'react-redux' import Mortal from 'react-mortal' import styled from 'styled-components' @@ -13,7 +14,7 @@ import { rgba } from 'styles/helpers' import { closeModal, isModalOpened, getModalData } from 'reducers/modals' -import Box from 'components/base/Box' +import Box, { Tabbable } from 'components/base/Box' import GrowScroll from 'components/base/GrowScroll' import Icon from 'components/base/Icon' @@ -67,7 +68,7 @@ const Backdrop = styled(Box).attrs({ position: fixed; ` -const Wrapper = styled(Box).attrs({ +const Wrapper = styled(Tabbable).attrs({ bg: 'transparent', flow: 20, mt: 100, @@ -77,6 +78,7 @@ const Wrapper = styled(Box).attrs({ transform: `translate3d(0, ${p.offset}px, 0)`, }), })` + outline: none; width: 570px; z-index: 2; ` @@ -109,6 +111,31 @@ export class Modal extends PureComponent { isOpened: false, } + componentDidUpdate(prevProps: Props) { + const didOpened = this.props.isOpened && !prevProps.isOpened + const didClose = !this.props.isOpened && prevProps.isOpened + if (didOpened) { + // Store a reference to the last active element, to restore it after + // modal close + this._lastFocusedElement = document.activeElement + + // Forced to use findDOMNode here, because innerRef is giving a proxied component + const domWrapper = findDOMNode(this._wrapper) // eslint-disable-line react/no-find-dom-node + + if (domWrapper instanceof HTMLDivElement) { + domWrapper.focus() + } + } + if (didClose) { + if (this._lastFocusedElement) { + this._lastFocusedElement.focus() + } + } + } + + _wrapper = null + _lastFocusedElement = null + render() { const { preventBackdropClick, isOpened, onClose, onHide, render, data } = this.props return ( @@ -125,7 +152,12 @@ export class Modal extends PureComponent { - e.stopPropagation()}> + e.stopPropagation()} + innerRef={n => (this._wrapper = n)} + > {render({ data, onClose })} From deb14f31b4213fe0c7f63240ff20f4abf30b0308 Mon Sep 17 00:00:00 2001 From: meriadec Date: Mon, 5 Feb 2018 15:45:50 +0100 Subject: [PATCH 2/2] Prevent annoying blink on select when content is smaller than placeholder --- src/components/base/Select/index.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/base/Select/index.js b/src/components/base/Select/index.js index 8741089f..ab9cd2f6 100644 --- a/src/components/base/Select/index.js +++ b/src/components/base/Select/index.js @@ -37,6 +37,7 @@ const Container = styled(Box).attrs({ relative: true, color: 'steel' })`` const TriggerBtn = styled(Box).attrs({ p: 2, })` + min-height: 58px; ${space}; border: 1px solid ${p => p.theme.colors.mouse}; border-radius: 3px;