Skip to content

Implement global skip links#18499

Open
gcamacho079 wants to merge 15 commits into6.xfrom
a11y/bypass-blocks
Open

Implement global skip links#18499
gcamacho079 wants to merge 15 commits into6.xfrom
a11y/bypass-blocks

Conversation

@gcamacho079
Copy link
Contributor

@gcamacho079 gcamacho079 commented Mar 2, 2026

Description

Re-implements skip links with a few updates/improvements

  • The AppLayout has a single skip link by default, but IndexLayout pushes additional skip links via an additionalSkipLinks prop.
  • Changes the “Skip to left sidebar” skip link to “Skip to secondary navigation”. This feels like it’s clearer.
  • Moves the Breadcrumb navigation out of the #main container, so it can be bypassed via the “Skip to main” link.

To test

  • Non-index pages should have a single skip link (“Skip to main”)
  • Index pages should have two additional skip links (“Skip to secondary navigation”, “Skip to content”)
  • The “Skip to main” link should bypass all repeated content, so it should take users past the breadcrumbs as well
  • All navigation regions should have unique labels (“Primary”, “Secondary”, “Breadcrumb”)

Related issues

Resolves ACC-29

@gcamacho079 gcamacho079 added the accessibility 👤 features related to accessibility label Mar 2, 2026
@linear
Copy link

linear bot commented Mar 2, 2026

@gcamacho079 gcamacho079 requested a review from Copilot March 3, 2026 16:09
@gcamacho079 gcamacho079 marked this pull request as ready for review March 3, 2026 16:09
Copy link

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

Implements global “skip links” for improved keyboard/accessibility navigation across the CP, with index pages contributing additional skip targets and breadcrumb navigation moved outside the main landmark so it can be bypassed.

Changes:

  • Add global skip-link rendering in AppLayout, with IndexLayout injecting extra skip links for secondary nav/content.
  • Add/adjust ARIA landmark labels (Primary/Secondary/Breadcrumbs) and move breadcrumbs outside #main.
  • Update skip-link styling and add missing translations.

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
resources/translations/en/app.php Adds translation strings for “Secondary” and “Skip to secondary navigation”.
resources/js/pages/SettingsSitesIndex.vue Removes extra <nav> wrapper in interior-nav slot (avoids nested nav now that layout provides it).
resources/js/layout/IndexLayout.vue Adds secondary-nav/content skip-link targets and wraps interior nav in a labeled <nav> with focus target IDs.
resources/js/layout/AppLayout.vue Introduces global skip links, adds additionalSkipLinks prop, and moves breadcrumbs outside the main container.
resources/js/components/CpSidebar.vue Adds an aria-label (“Primary”) to the main sidebar navigation landmark.
resources/js/components/Breadcrumbs.vue Wraps breadcrumbs list in a labeled <nav> landmark (“Breadcrumbs”).
resources/build/legacy.js Bundled output updated (import symbol changes).
resources/build/assets/cp.css Bundled CSS updated to reflect skip-link styling changes.
resources/build/assets/AppLayout.css Bundled CSS updated for AppLayout scope hash changes.
resources/build/Updater.js Bundled output updated (import symbol changes).
resources/build/SettingsSitesIndex.js Bundled output updated for SettingsSitesIndex changes.
resources/build/SettingsSitesEdit.js Bundled output updated (import symbol changes).
resources/build/SettingsIndexPage.js Bundled output updated (import symbol changes).
resources/build/SettingsGeneralPage.js Bundled output updated (import symbol changes).
resources/build/Install.js Bundled output updated (import symbol changes).
resources/build/IndexLayout.js Bundled output updated for IndexLayout changes.
resources/build/DeleteSiteModal.vue_vue_type_script_setup_true_lang.js Bundled output updated (import symbol changes).
resources/build/CpQueueIndicator.js Bundled output updated (internal symbol changes).
resources/build/CalloutReadOnly.vue_vue_type_script_setup_true_lang.js Bundled output updated (import symbol changes).
resources/build/AppLayout.js Bundled output updated, but currently contains debug/placeholder content that doesn’t match source.
packages/craftcms-cp/src/styles/cp.css Updates .skip-link styling and adds .skip-link--global positioning variables.

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

fullWidth?: boolean;
additionalSkipLinks?: Array<{label: string; url: string;}>;
}>(),
{fullWidth: false, crumbs: () => []}
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

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

withDefaults() is providing a default for crumbs, but crumbs is not a defined prop in defineProps<...>() (crumbs comes from page.props). This will at minimum confuse the props contract and can cause TS macro/type errors. Remove the crumbs default (or add a crumbs prop if that was intended).

Suggested change
{fullWidth: false, crumbs: () => []}
{fullWidth: false}

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done! 👍🏼

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

accessibility 👤 features related to accessibility

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants