Feature/fix tabulator stops (#1831)

Add tab stops to action to increase accessibility of SCM-Manager with keyboard only usage. Also add a focus trap for modals to ensure the actions inside the modal can be used without losing the focus.

Co-authored-by: René Pfeuffer <rene.pfeuffer@cloudogu.com>
This commit is contained in:
Eduard Heimbuch
2021-11-16 11:35:58 +01:00
committed by GitHub
parent 0530e3864f
commit dc5f7d0f23
47 changed files with 1380 additions and 118 deletions

View File

@@ -69,6 +69,8 @@ export const ConfirmAlert: FC<Props> = ({ title, message, buttons, close }) => {
className={classNames("button", "is-info", button.className, button.isLoading ? "is-loading" : "")}
key={index}
onClick={() => handleClickButton(button)}
onKeyDown={(e) => e.key === "Enter" && handleClickButton(button)}
tabIndex={0}
>
{button.label}
</button>

View File

@@ -21,11 +21,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import React, { FC } from "react";
import React, { FC, KeyboardEvent, useRef } from "react";
import classNames from "classnames";
import usePortalRootElement from "../usePortalRootElement";
import ReactDOM from "react-dom";
import styled from "styled-components";
import { useTrapFocus } from "../useTrapFocus";
type ModalSize = "S" | "M" | "L";
@@ -59,6 +60,13 @@ export const Modal: FC<Props> = ({
size,
}) => {
const portalRootElement = usePortalRootElement("modalsRoot");
const initialFocusRef = useRef(null);
const trapRef = useTrapFocus({
includeContainer: true,
initialFocus: initialFocusRef.current,
returnFocus: true,
updateNodes: false,
});
if (!portalRootElement) {
return null;
@@ -71,13 +79,19 @@ export const Modal: FC<Props> = ({
showFooter = <footer className="modal-card-foot">{footer}</footer>;
}
const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {
if (closeFunction && "Escape" === event.key) {
closeFunction();
}
};
const modalElement = (
<div className={classNames("modal", className, isActive)}>
<div className={classNames("modal", className, isActive)} ref={trapRef} onKeyDown={onKeyDown}>
<div className="modal-background" onClick={closeFunction} />
<SizedModal className="modal-card" size={size}>
<header className={classNames("modal-card-head", `has-background-${headColor}`)}>
<p className={`modal-card-title m-0 has-text-${headTextColor}`}>{title}</p>
<button className="delete" aria-label="close" onClick={closeFunction} />
<button className="delete" aria-label="close" onClick={closeFunction} ref={initialFocusRef} autoFocus />
</header>
<section className="modal-card-body">{body}</section>
{showFooter}