Skip to content

fix(sidebar): align icon-less labels and stop a root link stealing the highlight - #2130

Merged
markdumay merged 2 commits into
mainfrom
fix/sidebar-root-link-and-icon-column
Aug 9, 2026
Merged

fix(sidebar): align icon-less labels and stop a root link stealing the highlight#2130
markdumay merged 2 commits into
mainfrom
fix/sidebar-root-link-and-icon-column

Conversation

@markdumay

Copy link
Copy Markdown
Collaborator

Two sidebar defects, reported against a downstream app whose menu mixes entries with and without icons and carries a link: "/" home entry.

A link to the site root resolves to the calling page

assets/link.html normalizes its destination by stripping the base URL's path from it. For a link to the site's own home that leaves the empty string, and path.Clean renders the empty string as ".". Only the empty form was caught by the emptiness guard, so "." survived into the page lookup — where it is a valid relative reference meaning "the page being rendered".

The sidebar is what makes it visible. Its markup is cached per section against the section root, so a menu entry linking to / rendered as href="/project/" on the project section, href="/monitor/" on monitor, and so on. That entry then matched the current page exactly in sidebar-active.js — where the first exact match wins — and took the highlight from the entry that owns the page.

The guard now treats "." as the site root alongside the empty string.

Entries without an icon do not line up with entries that have one

A row without an icon started its label at the padding edge while its neighbours started an icon-width further right, so the labels no longer formed a column and the odd row read as misplaced rather than as merely unadorned.

assets/sidebar.html now resolves, per sibling list, whether anything in that list carries an icon, and marks the rows that do not with sidebar-item-icon-indent; the stylesheet turns that into a reservation of the same column. The scope is the sibling list rather than the whole sidebar on purpose — a nested list of icon-less entries is aligned already, and reserving a column there would indent it away from the label it hangs under, which is the shape of every menu that puts icons on its top level only. The class is set by the template rather than derived in CSS with :has(), for the reason already documented for sidebar-nav-icon-indent.

Sites that render no icons, or icons on every row of a list, produce byte-identical markup.

Tests

Adds assertions to the template test site for both: four assets/link.html cases (root, absolute, section, anchored) and five sidebar cases (mixed list, no icons, all icons, and nested lists in both directions). The harness gains mounts for assets/link.html, assets/sidebar.html, mod-fontawesome's icon.html and the icon set, so the rows and their icons are rendered for real rather than stubbed.

Reverting both fixes turns these into 5 failures; with them, npm test is clean and the theme's own site builds unchanged.

Verification

Checked in a browser against a consuming app built with this branch:

  • every label lands on the same x, in both the collapsible and the plain sidebar — in the plain one the hanging indent stays on the icon-bearing rows only, as intended
  • the active item is correct on / (the home entry, exact), on a section root, and on an L2 page (L1 ancestor + L2 exact)
  • collapsed icon-only mode is unchanged: identical row heights, icons on one centre line, no overflow

🤖 Generated with Claude Code

markdumay and others added 2 commits August 9, 2026 15:49
Stripping the base URL's path from the destination leaves nothing behind for a
link to the site's own home, and `path.Clean` renders that empty string as ".".
Only the empty form was caught by the emptiness guard, so "." survived as a
relative page reference meaning "the page being rendered" and the lookup that
follows resolved it to the caller.

The sidebar is where this surfaces. Its markup is cached per section against the
section root, so a menu entry linking to "/" rendered as a link to the section
root, then matched the current page in the client-side active pass and took the
highlight from the entry that owns it.

Add assertions for assets/link.html to the template test site, covering the root
case plus the absolute, section and anchored links either side of it.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A menu is free to mix entries that lead with an icon and entries that do not,
and the ones without then started their label at the padding edge while their
neighbours started an icon-width further right, breaking the column of labels.

Resolve per sibling list whether anything in it carries an icon, and mark the
rows that do not with `sidebar-item-icon-indent`, which reserves the same
column. Scoped to the list rather than the whole sidebar: a nested list of
icon-less entries is aligned already, and reserving a column there would indent
it away from the label it hangs under - the shape of every menu that puts icons
on its top level only.

The class comes from the template rather than a CSS `:has()` derivation, for the
reason already documented for `sidebar-nav-icon-indent`: the collapse trail is
expanded client side, and a selector re-resolved as a subtree becomes visible
can paint the wrong value first.

Add assertions covering a mixed list, a list without icons, a list where every
row has one, and nested lists in both directions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@netlify

netlify Bot commented Aug 9, 2026

Copy link
Copy Markdown

Deploy Preview for gethinode-demo ready!

Name Link
🔨 Latest commit e40e261
🔍 Latest deploy log https://app.netlify.com/projects/gethinode-demo/deploys/6a7885c97f38410008879198
😎 Deploy Preview https://deploy-preview-2130--gethinode-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@markdumay
markdumay enabled auto-merge August 9, 2026 13:53
@markdumay
markdumay merged commit a5ed025 into main Aug 9, 2026
17 checks passed
@markdumay
markdumay deleted the fix/sidebar-root-link-and-icon-column branch August 9, 2026 13:55
@markdumay

Copy link
Copy Markdown
Collaborator Author

🎉 This PR is included in version 3.21.1 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant