Skip to content

Fix modal accessible name#5506

Open
jesielviana wants to merge 2 commits intoDSpace:mainfrom
LA-Referencia-Lyrasis-Project:fix-modal-accessible-name
Open

Fix modal accessible name#5506
jesielviana wants to merge 2 commits intoDSpace:mainfrom
LA-Referencia-Lyrasis-Project:fix-modal-accessible-name

Conversation

@jesielviana
Copy link
Copy Markdown
Contributor

References

Description

Fix accessibility issue where modal dialogs were missing an accessible name by ensuring all modals correctly use aria-labelledby.

Instructions for Reviewers

List of changes in this PR:

  • Added a global default for ariaLabelledBy in app.component.ts to ensure all modals have an accessible name (The goal of this approach is to avoid modifying many files in a single commit/PR, reducing review complexity and minimizing the likelihood of widespread regressions.).
  • Normalized modal templates by wrapping header text in semantic heading elements (<h4>) where necessary.
  • Added id="modal-title" to modal headings to match the global configuration.

Steps to Test:

Scenario 1: Search Results Modal

  1. Open the search results page.
  2. Click on “All of DSpace”.
  3. Inspect the modal element in the DOM or run an accessibility audit.
  4. Verify that the ngb-modal-window element (with role="dialog") correctly references the id of the <h4> element inside .modal-header.

Scenario 2: Add Entity Modal (Item/Collection/Community)

  1. Log in as a user with permission to add an Item, Collection, or Community.
  2. Click on “Add Item”, “Add Collection”, or “Add Community”.
  3. Inspect the modal element in the DOM or run an accessibility audit.
  4. Verify that the ngb-modal-window element (with role="dialog") correctly references the id of the <h4> element inside .modal-header.

Additional Notes

  • Part of the changes were initially suggested using GitHub Copilot.
  • All modifications were manually reviewed and validated to ensure correctness and consistency across the codebase.

Checklist

This checklist provides a reminder of what we are going to look for when reviewing your PR. You do not need to complete this checklist prior creating your PR (draft PRs are always welcome).
However, reviewers may request that you complete any actions in this list if you have not done so. If you are unsure about an item in the checklist, don't hesitate to ask. We're here to help!

  • My PR is created against the main branch of code (unless it is a backport or is fixing an issue specific to an older branch).
  • My PR is small in size (e.g. less than 1,000 lines of code, not including comments & specs/tests), or I have provided reasons as to why that's not possible.
  • My PR passes ESLint validation using npm run lint
  • My PR doesn't introduce circular dependencies (verified via npm run check-circ-deps)
  • My PR includes TypeDoc comments for all new (or modified) public methods and classes. It also includes TypeDoc for large or complex private methods.
  • My PR passes all specs/tests and includes new/updated specs or tests based on the Code Testing Guide.
  • My PR aligns with Accessibility guidelines if it makes changes to the user interface.
  • My PR uses i18n (internationalization) keys instead of hardcoded English text, to allow for translations.
  • My PR includes details on how to test it. I've provided clear instructions to reviewers on how to successfully test this fix or feature.
  • If my PR includes new libraries/dependencies (in package.json), I've made sure their licenses align with the DSpace BSD License based on the Licensing of Contributions documentation.
  • If my PR includes new features or configurations, I've provided basic technical documentation in the PR itself.
  • If my PR fixes an issue ticket, I've linked them together.

Copilot AI review requested due to automatic review settings April 17, 2026 12:16
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes accessibility issue #5502 by ensuring ng-bootstrap modal dialogs have an accessible name via aria-labelledby, using a global default and aligning modal header markup/IDs across templates.

Changes:

  • Set a global NgbModalConfig.ariaLabelledBy default to modal-title in AppComponent.
  • Updated many modal templates to wrap header text in a heading element and add id="modal-title".
  • Normalized a few modal header structures that previously contained only raw text.

Reviewed changes

Copilot reviewed 42 out of 42 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/app/workspaceitems-edit-page/workspaceitems-delete-page/workspaceitems-delete-page.component.html Adds id="modal-title" to modal header heading for aria-labelledby.
src/app/submission/sections/upload/file/section-upload-file.component.html Adds id="modal-title" to delete-confirm modal heading.
src/app/submission/sections/upload/file/edit/section-upload-file-edit.component.html Adds id="modal-title" to edit modal heading.
src/app/submission/sections/cc-license/submission-section-cc-licenses.component.html Adds id="modal-title" and modal-title class to modal header heading.
src/app/submission/import-external/import-external-preview/submission-import-external-preview.component.html Converts header to <h4> and adds id="modal-title" for labeling.
src/app/submission/import-external/import-external-collection/submission-import-external-collection.component.html Wraps header text in <h4 id="modal-title"> for labeling.
src/app/submission/form/footer/submission-form-footer.component.html Adds id="modal-title" to discard-confirm modal heading.
src/app/shared/subscriptions/subscription-modal/subscription-modal.component.html Adds id="modal-title" to subscription modal heading.
src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.html Wraps header text in <h4 id="modal-title"> for labeling.
src/app/shared/resource-policies/form/resource-policy-form.component.html Renames modal heading id to modal-title to align with global config.
src/app/shared/mydspace-actions/workspaceitem/workspaceitem-actions.component.html Converts title container to <h4 id="modal-title"> for labeling.
src/app/shared/mydspace-actions/claimed-task/reject/claimed-task-actions-reject.component.html Adds id="modal-title" to reject modal heading.
src/app/shared/idle-modal/idle-modal.component.html Moves idle modal header into <h4> with id idle-modal.header.
src/app/shared/form/vocabulary-treeview-modal/vocabulary-treeview-modal.component.html Adds id="modal-title" to vocabulary modal heading.
src/app/shared/form/builder/ds-dynamic-form-ui/models/relation-group/modal/dynamic-relation-group-modal.component.html Updates modal heading to <h4 id="modal-title">.
src/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.html Wraps header text in <h4 id="modal-title"> and normalizes header/body structure.
src/app/shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component.html Wraps header text in <h4 id="modal-title"> and normalizes header/body structure.
src/app/shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component.html Wraps header text in <h4 id="modal-title"> and normalizes header/body structure.
src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.html Wraps header text in <h4 id="modal-title"> for labeling.
src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.html Wraps header text in <h4 id="modal-title"> and normalizes header/body structure.
src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.html Wraps header text in <h4 id="modal-title"> and normalizes header/body structure.
src/app/shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component.html Wraps header text in <h4 id="modal-title"> and normalizes header/body structure.
src/app/shared/correction-suggestion/item-withdrawn-reinstate-modal.component.html Wraps conditional modal headers in <h4 id="modal-title"> for labeling.
src/app/shared/confirmation-modal/confirmation-modal.component.html Wraps header text in <h4 id="modal-title"> for labeling.
src/app/shared/access-control-form-container/item-access-control-select-bitstreams-modal/item-access-control-select-bitstreams-modal.component.html Adds id="modal-title" to modal heading.
src/app/profile-page/profile-claim-item-modal/profile-claim-item-modal.component.html Adds id="modal-title" and modal-title class to header heading.
src/app/process-page/overview/process-overview.component.html Adds id="modal-title"/class to delete modal heading.
src/app/process-page/detail/process-detail.component.html Adds id="modal-title"/class to delete modal heading.
src/app/notifications/qa/events/quality-assurance-events.component.html Renames modal heading ids to modal-title across QA action modals.
src/app/my-dspace-page/collection-selector/collection-selector.component.html Wraps header text in <h4 id="modal-title"> for labeling.
src/app/item-page/versions/item-versions-summary-modal/item-versions-summary-modal.component.html Wraps header text in <h4 id="modal-title"> for labeling (both branches).
src/app/item-page/versions/item-versions-delete-modal/item-versions-delete-modal.component.html Wraps header text in <h4 id="modal-title"> for labeling.
src/app/item-page/edit-item-page/virtual-metadata/virtual-metadata.component.html Wraps header text in <h4 id="modal-title"> for labeling.
src/app/item-page/edit-item-page/item-delete/item-delete.component.html Wraps modal header text in <h4 id="modal-title"> for labeling in nested templates.
src/app/external-log-in/external-log-in/external-log-in.component.html Adds id="modal-title" to login modal heading.
src/app/entity-groups/research-entities/submission/name-variant-modal/name-variant-modal.component.html Adds id="modal-title" to modal heading.
src/app/app.component.ts Sets global NgbModalConfig.ariaLabelledBy = 'modal-title' default.
src/app/admin/admin-workflow-page/admin-workflow-search-results/actions/workspace-item/supervision-order-group-selector/supervision-order-group-selector.component.html Wraps header text in <h4 id="modal-title"> for labeling.
src/app/admin/admin-notify-dashboard/admin-notify-detail-modal/admin-notify-detail-modal.component.html Adds id="modal-title" to modal heading.
src/app/admin/admin-ldn-services/ldn-services-directory/ldn-services-directory.component.html Adds id="modal-title"/class to delete modal heading.
src/app/admin/admin-ldn-services/ldn-service-form/ldn-service-form.component.html Adds id="modal-title"/class to edit/create confirmation modal headings.
src/app/admin/admin-edit-user-agreement/admin-edit-user-agreement.component.html Adds id="modal-title" to confirm modal heading.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 297 to 300
<ng-template #acceptModal let-modal>
<div class="modal-header">
<h4 class="modal-title" id="acceptModal">{{'quality-assurance.event.sure' | translate}}</h4>
<h4 class="modal-title" id="modal-title">{{'quality-assurance.event.sure' | translate}}</h4>
</div>
@lgeggleston lgeggleston added improvement accessibility 1 APPROVAL pull request only requires a single approval to merge testathon Reported by a tester during Community Testathon labels Apr 17, 2026
@lgeggleston lgeggleston moved this to 🙋 Needs Reviewers Assigned in DSpace 10.0 Release Apr 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1 APPROVAL pull request only requires a single approval to merge accessibility improvement testathon Reported by a tester during Community Testathon

Projects

Status: 🙋 Needs Reviewers Assigned

Development

Successfully merging this pull request may close these issues.

Modal dialog is missing an accessible name

3 participants