Skip to content

feat(shell): a nav item with a URL is a real link - #33

Merged
omercelikdev merged 1 commit into
mainfrom
feat/shell-nav-href
Aug 9, 2026
Merged

feat(shell): a nav item with a URL is a real link#33
omercelikdev merged 1 commit into
mainfrom
feat/shell-nav-href

Conversation

@omercelikdev

Copy link
Copy Markdown
Contributor

The fifth and last gap qorpe/mockifyr#323 is blocked on.

The rail renders every item as <button onClick={item.onSelect}>. That navigates, and throws away everything the browser gives an anchor for free:

  • ⌘-click and middle-click into a second tab
  • the context menu's open in new tab and copy link address
  • a link announced as a link, not as a button that happens to move you

An operator watching a journal in one tab while editing stubs in another is the ordinary case in a console, so this is not a small loss. Mockifyr's rail is NavLink today, and M4 would have downgraded it — trading ~690 lines of duplication for navigation you cannot open twice is a bad trade.

onSelect still fires on click, so a router preventDefaults and pushes state exactly as before.

Nothing existing changes

Without href the item is still a button. The class string is shared between both elements deliberately — whether an item navigates should never be a visual question — and the tests assert that an inactive link and an inactive button carry byte-identical classes.

The visual gate is the proof: not one of the 63 baselines moved. The gallery demo now renders one item as a link, and the rendering is pixel-identical.

Gates

tests 188 passed, 28 on AppShell (3 new)
coverage (G5) 97.66 / 92.36 / 94.59 / 97.66
docs (G2) · pin (G6) · typecheck clean
standard-sync (G7) §7.2 gains the rule the component now enforces
visual (G4) zero baselines changed

One test premise of mine was wrong on the way and worth recording: I first compared a link against a button while the link was the active item, so the classes differed for a legitimate reason. The implementation was right; the comparison was not.

The rail rendered every item as <button onClick={onSelect}>. That navigates and
throws away everything the browser gives an anchor for free: cmd-click and
middle-click into a second tab, the context menu's "open in new tab" and "copy
link address", and a link announced as a link rather than a button that happens
to move you.

An operator watching a journal in one tab while editing in another is the
ordinary case in a console, so it is not a small loss. Mockifyr's rail is
NavLink today and M4 would have downgraded it.

onSelect still fires, so a router preventDefaults and pushes state as before.
Without href the item is still a button with the same classes — the class string
is shared between both elements deliberately, so whether an item navigates is
never a visual question. The visual gate proves it: not one baseline moved.

Refs qorpe/mockifyr#323.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@omercelikdev
omercelikdev merged commit 6e2eadd into main Aug 9, 2026
2 checks passed
@omercelikdev
omercelikdev deleted the feat/shell-nav-href branch August 9, 2026 22:17
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.

1 participant