Skip to content

fix(ag-p03): address open review issues — ARIA regressions, focus trap, resize lock, branch event, aria-current#857

Merged
ashleyshaw merged 5 commits into
developfrom
copilot/finalize-pr-856
Jun 6, 2026
Merged

fix(ag-p03): address open review issues — ARIA regressions, focus trap, resize lock, branch event, aria-current#857
ashleyshaw merged 5 commits into
developfrom
copilot/finalize-pr-856

Conversation

Copilot AI commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Linked issues

Closes #855

Changelog

Added

  • website/src/components/Header.astro — full sticky header with Browse/Resources mega-dropdowns, mobile-actions cluster (theme -> search -> burger order), right-side slide-in drawer with all spec-required sections (BROWSE, COOK & LEARN, RESOURCES, INSTALL SOURCE, EXTERNAL).
  • website/src/scripts/theme-toggle.js — JS-injected single icon (moon in light mode, sun in dark mode); all .theme-toggle-btn buttons sync simultaneously; uses ag-theme localStorage key.
  • website/src/scripts/header.js — scroll-shrink via IntersectionObserver sentinel (64px -> 52px after 60px scroll), dropdown open/close with keyboard support, burger/drawer toggle, branch toggle with ag-branch key, search palette event dispatch, Cmd/Ctrl+K shortcut.
  • website/src/scripts/header.js — accessibility and behaviour fixes for Escape handling, focus trap, inert background locking, resize cleanup, and branch-change events.
  • eslint.config.cjs — browser globals block for website/src/scripts/**/*.js.

Changed

  • website/src/layouts/AwesomeGithubLayout.astro — switched from AwesomeGithubNav to the new spec-compliant Header component; removed inline theme-toggle delegation script (now handled by theme-toggle.js).

Fixed

  • Theme toggle was rendering both moon and sun SVGs with CSS display:none toggling. Fixed to JS-inject a single icon per the v2 spec.
  • Mobile header was missing the dedicated theme icon button. Added the 3-icon cluster in correct order: theme -> search -> burger.
  • Branch toggle was using github_branch localStorage key. Corrected to ag-branch per spec.
  • Removed a stray closing brace in theme-toggle.js that caused a syntax error and build failure.
  • Dropdown Escape handling now resets aria-expanded and returns focus to the trigger.
  • Drawer open/close now applies inert to background content and closes on desktop resize to avoid trapped focus and scroll lock.
  • Added aria-current="page" to active Cookbook and Learn links and made active-link detection base-path aware.

Risk Assessment

Risk Level: Low

Potential Impact: UI-only change to the site header and its client-side JS. No data, no API, no auth. Worst case is a header that renders incorrectly, which would be immediately visible.

Mitigation Steps:

  • Astro build verified clean.
  • Keyboard, drawer, and theme behaviours reviewed after the review fixes.
  • Changes are isolated to the website header/layout/scripts.

How to Test

Prerequisites

  • Node 20+, run npm ci inside website/

Test Steps

  1. Build: npx astro build - expect a clean build.
  2. Desktop (>1024px): Verify Browse dropdown opens on click, closes on outside click and Escape. Verify Resources dropdown behaves the same. Verify only one icon is visible on theme toggle.
  3. Mobile (<=1024px): Resize to 768px. Verify primary nav is hidden, the three icon buttons appear in the right order, and the drawer opens/closes correctly.
  4. Accessibility: Tab through the nav, open dropdowns, press Escape, and confirm focus returns to the trigger. Open the drawer and confirm background content is not tabbable.
  5. Resize: Open the drawer, resize to desktop width, and confirm it auto-closes without leaving scroll lock behind.

Expected Results

  • Nav remains translucent and blurred.
  • Brand icon swaps correctly with theme.
  • Search hint shows Cmd/Ctrl+K on desktop.
  • No console errors on load or interaction.

Edge Cases to Verify

  • Both themes tested.
  • Mobile and desktop breakpoint behaviour.
  • Keyboard navigation and focus return.
  • No hardcoded colour values outside documented exceptions.

Checklist (Global DoD / PR)

  • All AC met and demonstrated
  • Tests added/updated (unit/E2E as appropriate)
  • Accessibility checklist completed (where relevant):
    • Semantic HTML and heading order verified
    • Keyboard navigation and visible focus states verified
    • ARIA used only where needed
    • Contrast and non-colour cues reviewed (WCAG 2.2 AA)
  • Docs/readme/changelog updated (if user-facing)
  • Frontmatter updated where applicable (last_updated and version)
  • I have reviewed and applied the downstream override policy (or linked an approved exception)
  • Security checklist completed (where relevant)
    • Untrusted input validated and sanitised
    • Output escaped for its rendering context
    • Privileged actions enforce nonce and capability checks
    • No secrets/sensitive data introduced; OWASP risks reviewed
  • Code/design reviews approved
  • CI green; linked issues closed; release notes prepared (if shipping)
  • Risk assessment completed above
  • Testing instructions provided above

claude and others added 4 commits June 6, 2026 15:39
- src/components/Header.astro: full sticky nav, Browse/Resources dropdowns,
  mobile-actions cluster (theme → search → burger), right-side drawer
- src/scripts/theme-toggle.js: JS-injected single icon (moon/sun), all
  .theme-toggle-btn buttons sync; storage key ag-theme
- src/scripts/header.js: scroll-shrink sentinel, dropdown open/close,
  burger/drawer, branch toggle (ag-branch key), search dispatch, ⌘K
- AwesomeGithubLayout.astro: switches from AwesomeGithubNav to Header

Closes #855
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Ash Shaw <ashley@lightspeedwp.agency>
…e, branch event, aria-current

- theme-toggle.js: remove stray closing brace (ESLint parse error)
- header.js: reset aria-expanded + focus trigger on Escape key in dropdowns
- header.js: add focusout handler to close dropdown when focus leaves wrapper
- header.js: apply inert to background elements when drawer opens (WCAG 2.1.2)
- header.js: add matchMedia listener to call closeDrawer() on resize >=1025px
- header.js: dispatch ag:branch-changed CustomEvent on branch toggle
- Header.astro: add isActive() helper and aria-current='page' on Cookbook/Learn links
- eslint.config.cjs: add browser globals config block for website/src/scripts/
…ase-aware isActive

- header.js: use child.id comparisons in focus trap rather than object identity
- Header.astro: strip BASE_URL prefix from pathname before isActive comparison so active link detection works under any deployment subpath
Copilot AI changed the title [WIP] Update instruction files and finalize PR 856 fix(ag-p03): address open review issues — ARIA regressions, focus trap, resize lock, branch event, aria-current Jun 6, 2026
Copilot AI requested a review from ashleyshaw June 6, 2026 15:48
@ashleyshaw ashleyshaw marked this pull request as ready for review June 6, 2026 16:13
@ashleyshaw ashleyshaw requested a review from Copilot June 6, 2026 16:13
@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

✅ Template check passed after update. Thanks for fixing the PR description.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 38657358ba

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

});

/* ── Branch toggle ──────────────────────────── */
const BRANCH_KEY = "ag-branch";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restore shared branch storage key

The new header branch control persists ag-branch, but the catalogue detail page that updates the VS Code/raw/GitHub install links still reads and writes github_branch (website/src/pages/c/[type]/[slug].astro lines 254 and 275), and there is no listener for ag:branch-changed. In practice, selecting develop in the global header before opening an item detail page is ignored, so those install links remain on main until the separate per-page branch toggle is used.

Useful? React with 👍 / 👎.

Comment on lines +44 to +50
trigger.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
parent.classList.remove("open");
trigger.setAttribute("aria-expanded", "false");
trigger.focus();
}
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Handle Escape while focus is inside dropdown menus

Escape is only handled on the dropdown trigger, so once keyboard focus has moved into a menu item, pressing Escape leaves the dropdown open and aria-expanded stuck on true. I checked the header dropdown wiring in this file: the only document-level Escape handler is for the mobile drawer, so this path is not covered for the Browse/Resources menu contents.

Useful? React with 👍 / 👎.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the Awesome GitHub website header implementation to address previously raised accessibility and functional issues, moving header behaviours into dedicated browser scripts and aligning linting with browser globals.

Changes:

  • Added a new Header Astro component and corresponding client-side scripts for dropdowns, drawer, branch toggle, search trigger wiring, and theme toggle icon sync.
  • Updated the main layout to use the new header and removed the previous inline event-delegation script.
  • Extended ESLint flat config to treat website/src/scripts/**/*.js as browser code with appropriate globals.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
website/src/scripts/theme-toggle.js Implements theme toggle behaviour and icon/ARIA sync across all toggle buttons.
website/src/scripts/header.js Implements header interactions (dropdowns, drawer, branch toggle, search wiring, scroll shrink).
website/src/layouts/AwesomeGithubLayout.astro Switches layout header to the new Header component and removes inline JS delegation.
website/src/components/Header.astro Introduces the new header markup, styles, and module imports for browser scripts.
eslint.config.cjs Adds a browser-script ESLint config block for website/src/scripts/**/*.js.

Comment on lines +103 to +105
burger?.addEventListener("click", openDrawer);
drawerClose?.addEventListener("click", closeDrawer);
drawerScrim?.addEventListener("click", closeDrawer);
Comment on lines +76 to +81
function openDrawer() {
document.body.classList.add("drawer-open");
burger?.setAttribute("aria-expanded", "true");
burger?.setAttribute("aria-label", "Close menu");
drawer?.setAttribute("aria-hidden", "false");
drawer?.removeAttribute("inert");
Comment on lines +90 to +94
document.body.classList.remove("drawer-open");
burger?.setAttribute("aria-expanded", "false");
burger?.setAttribute("aria-label", "Open menu");
drawer?.setAttribute("aria-hidden", "true");
drawer?.setAttribute("inert", "");
Comment on lines +44 to +50
trigger.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
parent.classList.remove("open");
trigger.setAttribute("aria-expanded", "false");
trigger.focus();
}
});
Comment on lines +149 to +157
/* ── Search palette wiring ──────────────────── */
document
.getElementById("search-btn-mobile")
?.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("ag:open-search"));
});
document.querySelector(".search-trigger")?.addEventListener("click", () => {
document.dispatchEvent(new CustomEvent("ag:open-search"));
});
Comment on lines +252 to +256
/* Wire drawer search button to same event */
document.addEventListener('DOMContentLoaded', () => {
document.getElementById('search-btn-drawer')?.addEventListener('click', () => {
document.dispatchEvent(new CustomEvent('ag:open-search'));
});
Comment on lines +38 to +40
try {
localStorage.setItem("ag-theme", next);
} catch (e) {}
Comment on lines +123 to +127
try {
return localStorage.getItem(BRANCH_KEY) || "main";
} catch (e) {
return "main";
}
Comment on lines +134 to +136
try {
localStorage.setItem(BRANCH_KEY, b);
} catch (e) {}

@ashleyshaw ashleyshaw left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Reviewed the review-fix branch. The syntax, ARIA, focus, inert, resize, and active-link changes line up with the reported issues.

@ashleyshaw ashleyshaw merged commit 6d9909f into develop Jun 6, 2026
7 of 8 checks passed
@ashleyshaw ashleyshaw deleted the copilot/finalize-pr-856 branch June 6, 2026 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Phase 03] Header: nav, dropdowns, theme toggle, mobile

4 participants