From 2abb4539572b411a23c7eb9022cc1f305c8dad4a Mon Sep 17 00:00:00 2001 From: John Chilton Date: Sat, 10 Oct 2026 20:45:06 -0400 Subject: [PATCH 1/3] Repair accessibility issues identified by component story audits --- .../packages/ui/src/components/GHeading.vue | 19 ++- client/packages/ui/src/components/GModal.vue | 1 + .../packages/ui/src/directives/vGTooltip.ts | 11 +- client/patches/vue-multiselect@3.5.0.patch | 74 ++++++++-- client/pnpm-lock.yaml | 6 +- .../BaseComponents/GHeading.test.ts | 24 ++++ .../components/BaseComponents/GModal.test.ts | 1 + .../Collections/ListCollectionCreator.test.ts | 4 +- .../ListDatasetCollectionElementView.test.ts | 45 ++++++ .../ListDatasetCollectionElementView.vue | 47 +++++-- .../Collections/common/ClickToEdit.test.ts | 35 +++++ .../Collections/common/ClickToEdit.vue | 20 ++- .../CommandPalette/CommandPalette.test.ts | 4 +- .../CommandPalette/CommandPalette.vue | 72 +++++----- client/src/components/Common/ExportForm.vue | 9 +- .../Common/Wizard/GenericWizard.test.ts | 30 ++++ .../Common/Wizard/GenericWizard.vue | 2 + .../Form/Elements/FormOptionalText.test.js | 13 ++ .../Form/Elements/FormOptionalText.vue | 9 +- .../components/Form/Elements/FormSelect.vue | 8 +- .../FormSelectMany/FormSelectMany.test.ts | 24 +++- .../FormSelectMany/FormSelectMany.vue | 133 ++++++++++++------ .../Form/Elements/FormSelection.vue | 6 +- .../Form/Elements/FormSelectionPreference.vue | 17 ++- .../Elements/MultiselectAccessibility.test.ts | 55 ++++++++ .../src/components/Form/FormElementLabel.vue | 5 +- .../src/components/Graph/ZoomControl.test.ts | 22 +++ client/src/components/Graph/ZoomControl.vue | 2 +- .../History/Export/HistoryExportWizard.vue | 9 +- .../components/Login/ChangePassword.test.ts | 11 ++ .../src/components/Login/ChangePassword.vue | 18 ++- .../ObjectStore/ConfigurationMarkdown.vue | 8 +- .../ObjectStore/ObjectStoreBadge.test.ts | 8 ++ client/src/components/ProgressBar.test.ts | 33 +++++ client/src/components/ProgressBar.vue | 8 +- .../components/ScrollList/ScrollList.test.ts | 16 +++ .../src/components/ScrollList/ScrollList.vue | 31 ++-- .../SelectionDialog/DataDialogSearch.vue | 6 +- .../SelectionDialog/SelectionDialog.test.js | 16 +++ .../SelectionDialog/SelectionDialog.vue | 28 ++-- .../SelectionField/SelectionField.vue | 6 +- .../Tool/Buttons/ToolOptionsButton.vue | 14 +- .../Tool/Buttons/ToolVersionsButton.vue | 14 +- client/src/components/Tool/ToolCard.test.js | 16 +++ .../ToolsList/ScrollToTopButton.vue | 5 +- .../InstallationSettings.test.js | 4 + .../InstallationSettings.vue | 3 +- .../DiskUsage/Quota/QuotaUsageBar.test.ts | 14 ++ .../User/DiskUsage/Quota/QuotaUsageBar.vue | 13 +- .../WorkflowInvocationState.test.ts | 14 +- .../WorkflowInvocationState.vue | 4 +- client/src/components/admin/QuotaForm.test.ts | 22 ++- client/src/components/admin/QuotaForm.vue | 34 ++++- client/src/components/admin/RoleForm.test.ts | 14 +- client/src/components/admin/RoleForm.vue | 14 +- client/src/composables/useMultiselect.ts | 18 --- client/src/directives/vGTooltip.test.ts | 36 +++++ client/src/style/scss/multiselect.scss | 15 +- 58 files changed, 923 insertions(+), 227 deletions(-) create mode 100644 client/src/components/BaseComponents/GHeading.test.ts create mode 100644 client/src/components/Collections/ListDatasetCollectionElementView.test.ts create mode 100644 client/src/components/Collections/common/ClickToEdit.test.ts create mode 100644 client/src/components/Form/Elements/MultiselectAccessibility.test.ts create mode 100644 client/src/components/Graph/ZoomControl.test.ts create mode 100644 client/src/components/ProgressBar.test.ts delete mode 100644 client/src/composables/useMultiselect.ts diff --git a/client/packages/ui/src/components/GHeading.vue b/client/packages/ui/src/components/GHeading.vue index 0db609a928f..25eab1ff26b 100644 --- a/client/packages/ui/src/components/GHeading.vue +++ b/client/packages/ui/src/components/GHeading.vue @@ -76,7 +76,15 @@ onUpdated(() => nextTick(checkClamped)); + + diff --git a/client/src/components/SelectionField/SelectionField.vue b/client/src/components/SelectionField/SelectionField.vue index 9c015ce9d06..9e5f4fb32d6 100644 --- a/client/src/components/SelectionField/SelectionField.vue +++ b/client/src/components/SelectionField/SelectionField.vue @@ -16,9 +16,9 @@ @dragleave.prevent="onDragLeave" @dragover.prevent @drop.prevent="onDrop"> - + @@ -128,3 +125,10 @@ loadToolMenuWebhooks(); + + diff --git a/client/src/components/Tool/Buttons/ToolVersionsButton.vue b/client/src/components/Tool/Buttons/ToolVersionsButton.vue index 1430a027e4f..cc471e95d83 100644 --- a/client/src/components/Tool/Buttons/ToolVersionsButton.vue +++ b/client/src/components/Tool/Buttons/ToolVersionsButton.vue @@ -3,7 +3,6 @@ import { faCheck, faCube, faCubes } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import { computed } from "vue"; -import GButton from "@/components/BaseComponents/GButton.vue"; import GDropdown from "@/components/BaseComponents/GDropdown.vue"; import GDropdownItem from "@/components/BaseComponents/GDropdownItem.vue"; @@ -26,12 +25,10 @@ const availableVersions = computed(() => [...props.versions].reverse()); variant="link" aria-label="Select Versions" class="tool-versions" - toggle-class="p-0" + toggle-class="px-2 py-1" size="sm"> [...props.versions].reverse()); + + diff --git a/client/src/components/Tool/ToolCard.test.js b/client/src/components/Tool/ToolCard.test.js index 2f25fb4d23b..46d2ddd6a40 100644 --- a/client/src/components/Tool/ToolCard.test.js +++ b/client/src/components/Tool/ToolCard.test.js @@ -124,6 +124,22 @@ describe("ToolCard", () => { expect(router.currentRoute.value.fullPath).toBe("/?tool_id=identifier&version=latest"); }); + it("offers a single focusable toggle for each tool menu", async () => { + await wrapper.setProps({ + version: "1.0", + options: { ...wrapper.props("options"), versions: ["1.0", "2.0"] }, + }); + for (const menu of [".tool-dropdown", ".tool-versions"]) { + const toggle = wrapper.get(`${menu} button.dropdown-toggle`); + expect(toggle.find("button, a, [tabindex]").exists()).toBe(false); + expect(toggle.attributes("aria-label")).toBeTruthy(); + await toggle.trigger("keydown", { key: "ArrowDown" }); + await flushPromises(); + expect(toggle.attributes("aria-expanded")).toBe("true"); + await toggle.trigger("keydown", { key: "Escape" }); + } + }); + it("does not show newer version badge for the latest lineage version", async () => { await wrapper.setProps({ version: "2.0", diff --git a/client/src/components/ToolsList/ScrollToTopButton.vue b/client/src/components/ToolsList/ScrollToTopButton.vue index 82ef04e2d6c..be157bf0345 100644 --- a/client/src/components/ToolsList/ScrollToTopButton.vue +++ b/client/src/components/ToolsList/ScrollToTopButton.vue @@ -15,7 +15,10 @@ const props = defineProps(); v-g-tooltip.hover class="back-to-top" :class="{ show: props.offset > 100 }" - :title="props.offset > 100 ? 'Scroll To Top' : ''" + title="Scroll To Top" + aria-label="Scroll to top" + :disabled="props.offset <= 100" + :tabindex="props.offset <= 100 ? -1 : 0" color="blue" @click="$emit('click')"> diff --git a/client/src/components/Toolshed/RepositoryDetails/InstallationSettings.test.js b/client/src/components/Toolshed/RepositoryDetails/InstallationSettings.test.js index 31ac94456e2..f008892eae5 100644 --- a/client/src/components/Toolshed/RepositoryDetails/InstallationSettings.test.js +++ b/client/src/components/Toolshed/RepositoryDetails/InstallationSettings.test.js @@ -52,6 +52,10 @@ describe("InstallationSettings", () => { expect(wrapper.find(".description").text()).toBe("long_description"); expect(wrapper.find(".revision").text()).toBe("owner rev. changesetRevision"); + const sectionInput = wrapper.get("#repository-target-section"); + expect(wrapper.get('label[for="repository-target-section"]').text()).toBe("Target Section:"); + expect(sectionInput.attributes("list")).toBe("sectionSelect"); + expect(wrapper.vm.installToolDependencies).toBe(true); expect(wrapper.vm.installRepositoryDependencies).toBe(true); expect(wrapper.vm.installResolverDependencies).toBe(true); diff --git a/client/src/components/Toolshed/RepositoryDetails/InstallationSettings.vue b/client/src/components/Toolshed/RepositoryDetails/InstallationSettings.vue index 1608fc82900..96413e56739 100644 --- a/client/src/components/Toolshed/RepositoryDetails/InstallationSettings.vue +++ b/client/src/components/Toolshed/RepositoryDetails/InstallationSettings.vue @@ -14,8 +14,9 @@ - +