Skip to content

Desktop navigation and header customization - #80

Merged
MegalithOfficial merged 19 commits into
mainfrom
nav-styles
Jul 27, 2026
Merged

Desktop navigation and header customization#80
MegalithOfficial merged 19 commits into
mainfrom
nav-styles

Conversation

@MegalithOfficial

Copy link
Copy Markdown
Contributor

Adds user-selectable navigation and header styles, and reworks the desktop
header so page chrome sits on the same grid as page content.

The app's chrome was a mobile layout stretched to desktop width: a full-bleed
title bar with ~1100px of dead space, a thumb-reach bottom pill, and a search
icon where a search field would fit. This branch makes the chrome
configurable and adds a desktop-shaped option, then aligns everything to one
content column.

Navigation

Six nav styles (bottom bar, bottom bar with labels, floating dock, sidebar,
floating sidebar, inside-header), plus side, placement, and drag-to-reorder
nav items. All configured under Settings → Customization → Navigation.

Sidebar styles anchor Settings to the bottom edge by default, which is what
stops a five-item rail from reading as an empty column. That anchor is a
default only: if you place Settings yourself in the items editor, it renders
where you put it. Same for Create.

Below 1024px, sidebar and inside-header fall back to bottom bar and floating
sidebar falls back to dock, so mobile only ever sees the three horizontal
styles.

In-page header

A fourth header style, In page, for desktop at ≥1024px. On Chats, Groups,
and Library the fixed chrome bar is replaced by a header inside the content
column: large title, a real search field that filters the list, and actions
on the same baseline. It pins to the top and condenses on scroll.

Discovery adopts the same component, replacing three hand-rolled bars
(DiscoveryPage, DiscoveryBrowsePage, and the toolbar row). Library's
filter chips move into it too. /discover/search keeps its own bar — it's a
mobile-only route with a different interaction model.

Alignment

The recurring bug was chrome and content using different containment models.
Every header now derives its position from the same CSS vars the content
container pads by (--appnav-w / --appnav-wr) and shares one column
constant, so they can't drift.

Verified against a replica of the real DOM across every var combination the
nav components publish — bottom/dock, sidebar left, sidebar right, floating
sidebar, and discovery-with-TopNav — at 1024 / 1280 / 1440 / 1920 / 2560.
Left and right edges match the cards in every cell.

The floating pill no longer stretches to the window. At 2560 it was 881px
wider than the content it sat above; it's now capped to the column and
centered, so its edges align with the cards.

Notes

  • The in-page header is opt-in and off by default. Nothing changes unless you
    select it.
  • New pageHeader.* strings are English-only; other locales fall back
    through the existing DeepPartial pattern.
  • TopNav now resets --topnav-h to 0px on unmount, so the dock and
    sidebar no longer anchor off a stale value on routes without a top nav.
  • Unrelated and untouched: ImageLibraryPage.tsx:304 passes a non-scrolling
    element to the virtualizer as getScrollElement. Surfaced while debugging
    the header, pre-existing on main.

Testing

bun run check passes. There is no test suite in this repo, so verification
was typecheck + cargo check, headless-browser geometry measurements against a
replica of the real DOM nesting, and manual passes on Linux/WebKitGTK.
Right-side sidebar has been measured but not eyeballed in a real build.

@MegalithOfficial
MegalithOfficial merged commit 6fc0f96 into main Jul 27, 2026
5 checks passed
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