Repository navigation
Nav and card follow-ups from review - #11
Conversation
|
Review Clean, well-scoped follow-ups that match the codebase style, and the PR description explains the reasoning well. I found one edge case worth considering plus a few minor notes. Potential bug: menu can reopen on back/forward (
Clicking a nav link avoids this because if (menuOpenAt !== null && menuOpenAt !== location.key) setMenuOpenAt(null);This is the documented pattern for adjusting state during render, and it drops the stale key as soon as the location changes. Minor notes
No security or performance concerns. The reopen case is arguably non-blocking. 🤖 Generated with Claude Code |
4031506 to
6638f5b
Compare
|
Review Clean, well-scoped follow-ups. The menuOpenAt === location.key approach avoids an extra effect, and the description is clear. No blocking issues. Suggestions (non-blocking)
Tests / security / performance
🤖 Generated with Claude Code |
6638f5b to
3c59549
Compare
ReviewClean, focused follow-ups. The Potential bug: stale
|
3c59549 to
206ef3e
Compare
|
Review Clean, well-scoped follow-up. Deriving Worth a look
Conventions: Follows CLAUDE.md (Tailwind, Tests: There is no test framework, per CLAUDE.md. The Playwright plan in the description covers the main paths. I'd add two edge cases: a click on a nested element inside a hash link, and clicking the same hash link twice and then pressing Back. Security / performance: No concerns. There are no new dependencies. Nothing blocking from my side. 🤖 Generated with Claude Code |
The menu only closed when a link was clicked, so back/forward left it open. Open state is now tied to the location it was opened at (location.key), so any navigation closes it without an extra effect. Escape also returns focus to the menu button instead of leaving it on an unmounted link. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ppa5DyJCZ1CowKtz58QARN
The smooth-scroll handler wrote the hash with window.history.pushState, which
React Router never sees: location.hash went stale (nav underline lagged) and
back/forward across those entries didn't register as navigation. It now calls
navigate({ hash }), keeping the router, the active nav item and history in sync.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ppa5DyJCZ1CowKtz58QARN
Cards with a detail page had the stretched title link plus a separate Deep Dive link to the same URL, so keyboard and screen-reader users hit two stops for one destination. Deep Dive stays as a visual cue (aria-hidden text under the card overlay, so clicking it still opens the detail page). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ppa5DyJCZ1CowKtz58QARN
Replaces the inline node -e one-liner in postbuild with a small commented script that explains why GitHub Pages needs the SPA fallback. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ppa5DyJCZ1CowKtz58QARN
Above 1024px the menu is hidden by lg:hidden but stayed logically open, so it reappeared expanded (aria-expanded=true) after rotating a tablet to landscape and back. A matchMedia listener, attached only while the menu is open, closes it when the viewport crosses into lg. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ppa5DyJCZ1CowKtz58QARN
206ef3e to
ce5a601
Compare
ReviewOverall a clean set of follow-ups. Deriving open state from Edge case: stale
|
Tying open state to the location.key it was opened at had two failures: the key was never cleared, so Back then Forward to that entry reopened the menu by itself, and location.key stays 'default' across a fresh load and native fragment navigations, so those didn't close it. The menu is now a plain open flag stamped with the navigation (pathname + search + hash + key) and reset during render when that changes. Escape returns focus to the toggle only when focus was inside the menu. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ppa5DyJCZ1CowKtz58QARN
…ction links
- navigate({ hash }) dropped the query string (/?utm_source=x -> /#about); it now
passes search through.
- Repeat clicks on the current section replace instead of stacking history.
- Cmd/Ctrl/Shift/Alt and middle clicks (open in new tab) are left to the
browser, as are links to sections not on the page; anchors are found with
closest('a') and sections with getElementById (ids like '1-intro' aren't
valid CSS selectors).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ppa5DyJCZ1CowKtz58QARN
…link group-hover on the card darkened 'Deep Dive' when the pointer was on Live Demo or Repository, suggesting those clicks go to the detail page. Deep Dive keeps a fixed color; the card's group class is no longer needed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ppa5DyJCZ1CowKtz58QARN
It resolved dist/ against the working directory, so running it from anywhere but the repo root threw ENOENT. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ppa5DyJCZ1CowKtz58QARN
ReviewOverall this is a clean, well-scoped follow-up. The render-time reset of menu state (keyed on pathname+search+hash+key) is the idiomatic way to avoid an effect, and routing the hash updates through Suggestions
Nits
LGTM with the minor items above. |
The smooth-scroll handler compared pathnames only, so an external link such as https://example.com/#contact (or any target=_blank link) whose path and hash matched a homepage section would scroll locally instead of opening. It now also requires the same origin and no target other than _self. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ppa5DyJCZ1CowKtz58QARN
|
Review of PR 11 Clean set of follow-ups. The render-time state reset in Layout is idiomatic and avoids an effect, routing the hash update through navigate fixes the stale nav state, and copy-404.mjs is a good change. I didn't run the app; this is based on reading the diff. Suggestions
No security concerns. The closest('a') change, origin/pathname checks and modifier-key handling look correct. 🤖 Generated with Claude Code |
Builds on #9 (merged). Targets
main. Addresses the non-blocking review items left on #7:bc60483Menu closes on any navigation. It previously closed only on link click, so back/forward left it open. Open state is now tied to thelocation.keyit was opened at, so any router navigation closes it, with no extra effect. Per-link close handlers remain for the homepage anchor handler.bc60483Focus returns to the menu button after Escape, instead of staying on a link that just unmounted.b388c4bHomepage hash updates go through React Router. The smooth-scroll handler usedwindow.history.pushState, which the router never sees. That leftlocation.hashstale (the nav underline lagged), and back/forward across those entries wasn't treated as navigation, so item 1 couldn't fire. It now callsnavigate({ hash }); the smooth scroll is unchanged.10bc243No duplicate tab stop on project cards. "Deep Dive" was a second link to the same URL as the stretched title. It stays as visible text (aria-hidden, under the card overlay), so clicking it still opens the detail page.fcaa700postbuildscript. The inlinenode -eone-liner becomesscripts/copy-404.mjs, with a comment explaining why GitHub Pages needs the SPA fallback.Test plan
Production build served by
vite preview, driven with Playwright:npm run buildpasses and logs the 404.html copy;dist/404.htmlmatchesdist/index.htmlnpx tsc -p tsconfig.app.json --noEmitpasses;npm run lint0 errors (same 3 pre-existing warnings)aria-expanded="false", focus on the menu button/#about, menu closed, About scrolled to top; reopen menu, press browser Back → URL/, menu closed (it stayed open beforeb388c4b)#publications, nav underline on Publications, section scrolled to top/assets/projects/cytoscape; Live Demo opens the demo; no nested anchorsNot included
Other review notes on #7, left for later:
sitemap.xmllastmoddates are hardcoded;renderNavLinktakes four positional strings; the card overlay's rounded corners ignore the 2px top border (cosmetic). Links from other pages to/#aboutstill do a full page load.🤖 Generated with Claude Code
https://claude.ai/code/session_01Ppa5DyJCZ1CowKtz58QARN