fix(docs): standardize missing accessibility and UX features#51
Conversation
Add prefers-reduced-motion CSS media queries, Firefox scrollbar support, window.__docsSlug for route-based deep links, scrollspy nav auto-scroll, and mobile menu close on nav click to match standardized pattern
📝 WalkthroughWalkthroughThe documentation page's navigation and scrolling behavior is enhanced with server-injected slug data and updated client-side logic. Simultaneously, global CSS rules add prefers-reduced-motion accessibility support and site-wide scrollbar styling. ChangesDocumentation Page Navigation & Scroll Behavior
Sequence DiagramsequenceDiagram
participant Server as Astro Server
participant Browser as Browser
participant DOM as Page DOM
participant Nav as Navigation Menu
Server->>Browser: Render docs page with inline script
Note over Server: window.__docsSlug, window.__isRoot injected
Browser->>DOM: Auto-scroll to requestedSlug or URL hash
activate DOM
DOM->>Browser: Section is now in view
deactivate DOM
Browser->>Nav: Initialize scrollspy listener
Note over Browser: Track active section via IntersectionObserver
loop As user scrolls
DOM->>Nav: Section enters/exits viewport
Nav->>Nav: Update active nav item highlight
Nav->>Nav: scrollIntoView() active nav item
end
alt User clicks nav item (small screen)
Nav->>Browser: Click handler fires
Browser->>Nav: Close mobile sidebar (aria-expanded = false)
end
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~25 minutes The changes involve understanding server-to-client data flow via script injection, client-side scrollspy logic with UI synchronization, and mobile interaction handling. The scrollbar and motion-preference CSS additions are straightforward but require verification of cross-browser compatibility. Possibly Related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Review rate limit: 9/10 reviews remaining, refill in 6 minutes. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (3)
docs/src/pages/docs/[...slug].astro (2)
190-198: 💤 Low valueConsider extracting the close-menu logic to avoid duplication.
This duplicates the
closeMenu()function defined at lines 142-146. SincecloseMenuis scoped inside theifblock, it's not accessible here. You could hoistcloseMenuto the outer DOMContentLoaded scope so both handlers can share it.♻️ Suggested refactor
const prefersReducedMotion = !window.matchMedia('(prefers-reduced-motion: no-preference)').matches; + function closeMenu() { + if (sidebar && overlay && menuToggle) { + sidebar.classList.remove('open'); + overlay.classList.remove('open'); + menuToggle.setAttribute('aria-expanded', 'false'); + } + } + /* Mobile menu toggle */ if (menuToggle && sidebar && overlay) { - function closeMenu() { - sidebar.classList.remove('open'); - overlay.classList.remove('open'); - menuToggle.setAttribute('aria-expanded', 'false'); - } menuToggle.addEventListener('click', function () {Then at lines 190-198:
navItems.forEach(function (item) { item.addEventListener('click', function () { - if (window.innerWidth <= 768 && menuToggle && sidebar && overlay) { - sidebar.classList.remove('open'); - overlay.classList.remove('open'); - menuToggle.setAttribute('aria-expanded', 'false'); - } + if (window.innerWidth <= 768) { + closeMenu(); + } }); });🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/src/pages/docs/`[...slug].astro around lines 190 - 198, The click handler for navItems duplicates the menu-closing logic currently implemented in the inner closeMenu function; move (hoist) the closeMenu function out of the inner if block into the outer DOMContentLoaded scope so both the original toggle handler and the navItems.forEach listener can call closeMenu(); update the navItems.forEach callback to call closeMenu() instead of repeating sidebar.classList.remove('open'), overlay.classList.remove('open') and menuToggle.setAttribute(...), and ensure closeMenu references the same menuToggle, sidebar and overlay variables defined in the outer scope.
177-181: 💤 Low valueNav auto-scroll may cause unexpected sidebar movement during fast scrolling.
When the user scrolls quickly through sections, each intersection fires
scrollIntoViewon the active nav item. Whileblock: 'nearest'minimizes movement, rapid section changes could still cause noticeable sidebar jitter.Consider debouncing the scrollIntoView call or only triggering it after scroll settles:
♻️ Optional debounce approach
+ let scrollTimeout; if (isRoot && sections.length > 1) { const observer = new IntersectionObserver( function (entries) { entries.forEach(function (entry) { if (entry.isIntersecting) { navItems.forEach(function (item) { var isActive = item.getAttribute('data-nav-id') === entry.target.id; item.classList.toggle('active', isActive); if (isActive) { - item.scrollIntoView({ behavior: prefersReducedMotion ? 'auto' : 'smooth', block: 'nearest' }); + clearTimeout(scrollTimeout); + scrollTimeout = setTimeout(function () { + item.scrollIntoView({ behavior: prefersReducedMotion ? 'auto' : 'smooth', block: 'nearest' }); + }, 150); } }); } }); },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/src/pages/docs/`[...slug].astro around lines 177 - 181, The sidebar jitter is caused by calling item.scrollIntoView on every intersection change; modify the logic around the isActive check to debounce/throttle those calls: introduce a short-lived timer (or use requestAnimationFrame + a short timeout) associated with the nav item or a module-level variable and only call item.scrollIntoView when the active state has persisted for a small delay (e.g., 100–200ms) or when scrolling has settled; keep the prefersReducedMotion check and only debounce when motion is allowed, and reference the existing symbols (item, isActive, item.scrollIntoView, prefersReducedMotion, entry.target.id / data-nav-id) so the change is localized to this intersection callback.docs/src/styles/docs.css (1)
369-397: 💤 Low valueConsider consolidating duplicate scrollbar rules.
These scrollbar styles largely duplicate
globals.css(lines 34-65). The difference is this file uses CSS variables (var(--rust-orange),var(--bg-deep)) while globals uses hardcoded hex values. If both files are loaded, these rules will override globals.css due to cascade order.If this duplication is intentional for docs-specific scoping, consider adding a brief comment explaining why. Otherwise, updating
globals.cssto use the CSS variables would eliminate the duplication.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@docs/src/styles/docs.css` around lines 369 - 397, The scrollbar rules in docs/src/styles/docs.css (selectors html, ::-webkit-scrollbar, ::-webkit-scrollbar-track, ::-webkit-scrollbar-thumb, ::-webkit-scrollbar-thumb:hover, ::-webkit-scrollbar-corner) duplicate globals.css but use CSS variables; either remove this duplication by moving these rules into globals.css and replace the hardcoded hexes there with var(--rust-orange)/var(--bg-deep), or if the docs override is intentional, add a brief clarifying comment above these rules stating they intentionally override globals for the docs build (or scope them to a docs-specific container/class) so the cascade behavior is explicit.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@docs/src/pages/docs/`[...slug].astro:
- Around line 190-198: The click handler for navItems duplicates the
menu-closing logic currently implemented in the inner closeMenu function; move
(hoist) the closeMenu function out of the inner if block into the outer
DOMContentLoaded scope so both the original toggle handler and the
navItems.forEach listener can call closeMenu(); update the navItems.forEach
callback to call closeMenu() instead of repeating
sidebar.classList.remove('open'), overlay.classList.remove('open') and
menuToggle.setAttribute(...), and ensure closeMenu references the same
menuToggle, sidebar and overlay variables defined in the outer scope.
- Around line 177-181: The sidebar jitter is caused by calling
item.scrollIntoView on every intersection change; modify the logic around the
isActive check to debounce/throttle those calls: introduce a short-lived timer
(or use requestAnimationFrame + a short timeout) associated with the nav item or
a module-level variable and only call item.scrollIntoView when the active state
has persisted for a small delay (e.g., 100–200ms) or when scrolling has settled;
keep the prefersReducedMotion check and only debounce when motion is allowed,
and reference the existing symbols (item, isActive, item.scrollIntoView,
prefersReducedMotion, entry.target.id / data-nav-id) so the change is localized
to this intersection callback.
In `@docs/src/styles/docs.css`:
- Around line 369-397: The scrollbar rules in docs/src/styles/docs.css
(selectors html, ::-webkit-scrollbar, ::-webkit-scrollbar-track,
::-webkit-scrollbar-thumb, ::-webkit-scrollbar-thumb:hover,
::-webkit-scrollbar-corner) duplicate globals.css but use CSS variables; either
remove this duplication by moving these rules into globals.css and replace the
hardcoded hexes there with var(--rust-orange)/var(--bg-deep), or if the docs
override is intentional, add a brief clarifying comment above these rules
stating they intentionally override globals for the docs build (or scope them to
a docs-specific container/class) so the cascade behavior is explicit.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 07c600e3-6cd5-4125-a573-d94028f56937
📒 Files selected for processing (2)
docs/src/pages/docs/[...slug].astrodocs/src/styles/docs.css
Summary
prefers-reduced-motionCSS media queries (no-preference+reduce) for accessibility compliancescrollbar-color,scrollbar-width) — was Webkit-onlywindow.__docsSlugviadefine:varsfor route-based deep link auto-scrollblock: 'nearest')Changes
docs/src/styles/docs.css: +43 lines (reduced motion, global scrollbar)docs/src/pages/docs/[...slug].astro: +31/-13 lines (auto-scroll, scrollspy, mobile menu)Verification
npm run build✓tsc --noEmit✓ (pre-existing tsconfig deprecation warning only)Summary by CodeRabbit