From d0cf976a541b4b96f189bea6caaaa771b553d502 Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Fri, 21 Jan 2022 14:25:19 +0100 Subject: [PATCH] Improve modal accessibility Implement initial focus for modals. Change all modals including forms to put initial focus on the first input. When Enter is pressed on any input (CTRL + Enter for Textareas), the form is submitted if it is valid. Co-authored-by: Sebastian Sdorra Co-authored-by: Eduard Heimbuch --- gradle/changelog/modal-focus.yaml | 2 + scm-ui/ui-components/.storybook/main.js | 5 +- scm-ui/ui-components/package.json | 3 +- .../src/__snapshots__/storyshots.test.ts.snap | 1376 ++++++++++++++++- scm-ui/ui-components/src/buttons/Button.tsx | 13 +- .../src/forms/PasswordConfirmation.tsx | 144 +- .../src/modals/ConfirmAlert.stories.tsx | 23 +- .../ui-components/src/modals/ConfirmAlert.tsx | 16 +- .../src/modals/CreateTagModal.tsx | 25 +- .../src/modals/FullscreenModal.tsx | 20 +- .../src/modals/Modal.stories.tsx | 64 +- scm-ui/ui-components/src/modals/Modal.tsx | 94 +- scm-ui/ui-components/src/useTrapFocus.ts | 163 -- scm-ui/ui-styles/src/components/_main.scss | 18 + .../plugins/components/PluginActionModal.tsx | 268 ++-- .../admin/plugins/components/PluginModal.tsx | 5 +- .../roles/containers/DeleteRepositoryRole.tsx | 3 +- .../src/components/HeaderDropDown.tsx | 13 +- .../src/groups/containers/DeleteGroup.tsx | 3 +- .../components/PermissionCheckbox.tsx | 75 +- .../components/BranchCommitDateCommitter.tsx | 4 +- .../repos/branches/components/BranchTable.tsx | 3 +- .../branches/containers/DeleteBranch.tsx | 3 +- .../components/NamespaceAndNameFields.tsx | 4 +- .../components/changesets/CreateTagModal.tsx | 11 +- .../src/repos/containers/ArchiveRepo.tsx | 3 +- .../src/repos/containers/DeleteRepo.tsx | 3 +- .../src/repos/containers/RenameRepository.tsx | 8 +- .../src/repos/containers/UnarchiveRepo.tsx | 3 +- .../components/DeletePermissionButton.tsx | 3 +- .../containers/AdvancedPermissionsDialog.tsx | 8 +- .../repos/sources/containers/SourcesView.tsx | 6 +- .../src/repos/tags/components/TagTable.tsx | 3 +- .../src/repos/tags/container/DeleteTag.tsx | 3 +- .../src/users/components/UserConverter.tsx | 12 +- .../src/users/containers/DeleteUser.tsx | 3 +- yarn.lock | 5 + 37 files changed, 1848 insertions(+), 570 deletions(-) create mode 100644 gradle/changelog/modal-focus.yaml delete mode 100644 scm-ui/ui-components/src/useTrapFocus.ts diff --git a/gradle/changelog/modal-focus.yaml b/gradle/changelog/modal-focus.yaml new file mode 100644 index 0000000000..c492f522d6 --- /dev/null +++ b/gradle/changelog/modal-focus.yaml @@ -0,0 +1,2 @@ +- type: added + description: initial focus, submission on pressing enter and fix trap focus for modals ([#1925](https://github.com/scm-manager/scm-manager/pull/1925)) diff --git a/scm-ui/ui-components/.storybook/main.js b/scm-ui/ui-components/.storybook/main.js index 3e196d1444..1fc137486e 100644 --- a/scm-ui/ui-components/.storybook/main.js +++ b/scm-ui/ui-components/.storybook/main.js @@ -27,11 +27,14 @@ const fs = require("fs"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); const RemoveThemesPlugin = require("./RemoveThemesPlugin"); const WorkerPlugin = require("worker-plugin"); +const ReactDOM = require("react-dom"); const root = path.resolve(".."); const themedir = path.join(root, "ui-styles", "src"); +ReactDOM.createPortal = node => node; + const themes = fs .readdirSync(themedir) .map(filename => path.parse(filename)) @@ -50,7 +53,7 @@ module.exports = { // add our themes to webpack entry points config.entry = { main: config.entry, - ...themes, + ...themes }; // create separate css files for our themes diff --git a/scm-ui/ui-components/package.json b/scm-ui/ui-components/package.json index c3e96f5f2a..918f8cf1cb 100644 --- a/scm-ui/ui-components/package.json +++ b/scm-ui/ui-components/package.json @@ -92,7 +92,8 @@ "remark-parse": "^9.0.0", "remark-rehype": "^8.0.0", "tabbable": "^5.2.1", - "unified": "^9.2.1" + "unified": "^9.2.1", + "@headlessui/react": "^1.4.3" }, "babel": { "presets": [ diff --git a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap index f5f2111693..876ccde558 100644 --- a/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap +++ b/scm-ui/ui-components/src/__snapshots__/storyshots.test.ts.snap @@ -19192,7 +19192,161 @@ exports[`Storyshots MarkdownView Xml Code Block 1`] = ` `; -exports[`Storyshots Modal/ConfirmAlert Default 1`] = `null`; +exports[`Storyshots Modal/ConfirmAlert Autofocus 1`] = ` +