Merge pull request #118 from akuokojnr/@akuokojnr/modal-accessibility

feat: make modal accessible
This commit is contained in:
CAKE 2020-07-27 18:13:05 -07:00 committed by GitHub
commit f24c345d11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 50 additions and 11 deletions

View File

@ -3,6 +3,8 @@ import * as Constants from "~/common/constants";
import * as SVG from "~/components/system/svg";
import * as Strings from "~/common/strings";
import FocusLock from "react-focus-lock";
import { css } from "@emotion/react";
import { Boundary } from "~/components/system/components/fragments/Boundary";
@ -46,11 +48,13 @@ export class GlobalModal extends React.Component {
componentDidMount = () => {
window.addEventListener("create-modal", this._handleCreate);
window.addEventListener("delete-modal", this._handleDelete);
window.addEventListener("keydown", this._handleDocumentKeydown);
};
componentWillUnmount = () => {
window.removeEventListener("create-modal", this._handleCreate);
window.removeEventListener("delete-modal", this._handleDelete);
window.removeEventListener("keydown", this._handleDocumentKeydown);
};
_handleCreate = (e) => {
@ -61,21 +65,46 @@ export class GlobalModal extends React.Component {
this.setState({ modal: null });
};
_handleDocumentKeydown = (e) => {
if (this.state.modal && e.keyCode === 27) {
this.setState({ modal: null });
e.stopPropagation();
}
};
_handleEnterPress = (e) => {
if (e.key === "Enter") {
this.setState({ modal: null });
}
};
render() {
if (!this.state.modal) return null;
return (
<div css={STYLES_BACKGROUND} style={this.props.backgroundStyle}>
<Boundary
enabled
onOutsideRectEvent={this._handleDelete}
isDataMenuCaptured={true}
<FocusLock>
<div
css={STYLES_BACKGROUND}
style={this.props.backgroundStyle}
role="dialog"
aria-modal="true"
aria-label={this.props.label ? this.props.label : "modal"}
>
<div css={STYLES_MODAL} style={this.props.style}>
{this.state.modal}
<SVG.Dismiss css={STYLES_CLOSE_ICON} onClick={this._handleDelete} />
</div>
</Boundary>
</div>
<Boundary
enabled
onOutsideRectEvent={this._handleDelete}
isDataMenuCaptured={true}
>
<div css={STYLES_MODAL} style={this.props.style}>
<SVG.Dismiss
css={STYLES_CLOSE_ICON}
onClick={this._handleDelete}
onKeyPress={this._handleEnterPress}
/>
{this.state.modal}
</div>
</Boundary>
</div>
</FocusLock>
);
}
}

View File

@ -7,6 +7,7 @@ export const Dismiss = (props) => (
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
tabIndex="0"
height={props.height}
style={props.style}
{...props}

View File

@ -63,6 +63,7 @@
"react": "^16.12.0",
"react-dom": "^16.12.0",
"react-draggable": "^4.4.3",
"react-focus-lock": "^2.4.1",
"react-tippy": "^1.3.4",
"regenerator-runtime": "^0.13.5",
"three": "^0.108.0",

View File

@ -190,6 +190,14 @@ import { GlobalModal, dispatchCustomEvent } from 'slate-react-system';`}
d:
"Style object used to style the modal background (color, etc.)",
},
{
id: 3,
a: "label",
b: "String",
c: "modal",
d:
"A label for the modal provide context for users with assistive technology such as screen readers.",
},
],
}}
/>