Repository navigation
f-1587 enable native Ctrl/Cmd-click navigation in header - #1637
morozov-av wants to merge 6 commits into
Conversation
morozov-av
commented
Oct 28, 2026
- Render navigation elements as real links instead of buttons
- Allow Ctrl/Cmd-click, Shift-click, and middle-click to use native browser behavior
- Added tests
bnmnetp
left a comment
There was a problem hiding this comment.
Thanks for this. Making the header items real links so Ctrl/Cmd-click and middle-click work is the right fix. Below are the issues I found, most important first. Paths are under bases/rsptx/assignment_server_api/assignment_builder/, and line numbers are approximate.
Navigation behaviour
- Hrefs don't match the router outside production (
src/navUtils.ts~L115). The hrefs hardcode/assignment/instructor/..., but the router's basename comes fromVITE_BASE_URL, which is/undernpm run dev. In dev, a Ctrl-click on Grader / Assignment Builder / Accommodations opens a route that doesn't exist, while a plain click works. Could the href be built from the same base the router uses? - Disabled items can still be clicked (
src/components/shell/AppNavBar.tsx~L38). Thedisabledattribute does nothing on an<a>. A disabled item with an href still runsonClickand still navigates on middle-click or Ctrl-click, which the old disabled<button>never did.handleNavClickshould return early whenitem.disabledis set, and the anchor should also getaria-disabledand no href. - Each URL is written twice (
src/navUtils.ts~L102). Every entry has its URL inhrefand again inside itsonClick, and the two already differ for SPA routes (/assignment/instructor/graderand"grader"). If someone updates one copy and not the other, a click and a Ctrl-click go to different places. A single target per entry, withAppNavBardoing the navigation (plus a separateroutefield for SPA routes), would prevent that. - "Back to course" link can be invalid (
src/navUtils.ts~L102). Its href is/ns/books/published/${course}/index.htmlwith no check, while the label falls back tocourse || "Course". Ifcourseis empty or undefined, the link becomes/ns/books/published//index.htmlor.../undefined/..., and now that it's a real link, someone can open it. - External links are opened from script (
src/components/shell/AppNavBar.tsx~L17). A plain click on "Join our Discord" or the other Help links callspreventDefaultand thenwindow.open(_blank)withoutnoopener. The opened page keeps awindow.openerreference to the Runestone tab, and popup blockers may stop it. A nativetarget="_blank" rel="noopener"anchor for external links would avoid both problems.
Unrelated dependency changes
- TipTap code-block extension downgraded (
package.json~L71).tiptap-extension-code-block-prismchanges from^0.0.2-eto exactly0.0.2-e. In semver,0.0.2-esorts before0.0.2, so the lockfile drops from the stable release to the older pre-release. - The
vite.config.tsworkaround only applies in dev (~L59). The newoptimizeDepsinclude /needsInteropentries only affect the dev server; the production build ignores them. The dev server and the production bundle could load the extension differently, soCodeBlockPrismmight be undefined only in production. - Playwright upgrade (
package-lock.json). Playwright goes from 1.60 to 1.64.1, which requires Node 20 or later, and the lockfile drops the darwinfseventsoptional dependency.
Could #6–8 go in a separate PR, or be reverted here? Bundled with this change, they can't be rolled back separately if the editor or CI breaks.
Tests
- Modified-click tests don't check the main goal (
src/components/shell/AppNavBar.spec.tsx~L225). They only assert thatonClickwasn't called. They don't check thatpreventDefaultwasn't called, which is what keeps native Ctrl/Cmd-click working. ThealtKeycase and theevent.button !== 0case aren't tested.
Suggested before merging: #1, #2 and #4, plus splitting out #6–8.
🤖 Generated with Claude Code
|
The main test I've been trying is using right click to see what I can open up in a new window. I'm not sure what @ascholerChemeketa all had in mind with the request, or how complex this might be to implement. When I right click on something in the navbar I'm given the option to open that in a new window. But lets say I'm in the assignment building, I cannot click on the name of an assignment and open it in a new tab/window. I'm not even sure that this is a high priority unless it is some kind of a11y requirement?? Probably rendering links is important for a11y navigation. |
Thanks for review. I’ve fixed issues:
|
Good point! I agree that links within main content should support the same browser behavior as navbar. |