- Remove the left tab sidebar containing tab labels and now-playing
- Render tabs as compact labels in the command bar row instead
- Move now-playing display next to the selection count in the status bar
- All tabs remain functional; clicking a tab label switches the active tab
Convert Discover, Feed, MyShows, and Settings pages from bespoke 3-column
flexbox JSX to render entirely via the shared <YaziPaneRow> parent|current|
preview primitive. Each page now supplies parent/current/preview content
accessors plus labels; the pane row handles layout, borders, focus styling,
and the muted placeholder for the blank parent slot at depth 0.
Replace Solid's children() helper in YaziPaneRow with a local normalizeContent
that hands the raw accessor to a reactive
expression. children() flattens to a stable resolved-nodes array and does not
re-resolve on truthy<->truthy root swaps (e.g. depth switching a pane's root
between a list fragment and an editor), which would freeze the previous
subtree. The insert effect from the reactive expression disposes and
remounts on element-identity change instead.
Add tests/yazi-pages-depth.test.ts covering the nav-store depth-stack
contract the pages depend on (push/pop stack growth, parent-slot data model
across root→child→grandchild→pop transitions).
Replace reactive / usage in the navigation
store with imperative functions so behavior is identical under both the
client JSX runtime and the server build used by unit tests (where
/ are no-ops).
- Centralize tab-switch side effects (root-frame seed, pane/mode/
command/visual reset) in , invoked by a single
helper used by gotoTab/nextTab/prevTab.
- Convert depthStack/currentDepth/topFrame/selectedIds from
to plain functions that recompute on every read while still tracking
underlying signals in reactive contexts.
Add the shared parent | current | preview row primitive that implements
yazi's mgr.ratio = [1, 3, 3] contract via Yoga flexGrow, so every list
tab renders an identical, layout-stable shell regardless of terminal
size.
- New YaziPaneRow component: three bordered columns grow at 1/7 : 3/7
: 3/7 with flexBasis=0 (content can never stretch its slot). The
current column carries the accent focus ring when `focused` is
truthy; parent and preview stay muted. The blank parent keeps its
1/7 slot with a muted placeholder rather than collapsing.
- PANE_RATIO.current 4 -> 3 to match yazi's [1, 3, 3].
- Add render-based tests covering the 1:3:3 ratios (incl. null
parent/preview) and the focused/unfocused accent ring behavior.
- Configure the bun test preload for the solid JSX transform.
- Extract navigation state and logic into navigation-store.ts for
testability and separation of concerns
- NavigationContext now only wraps the store as a Solid provider
- Remove SIDEBAR_PANE from the model; depth-tabs have a single
focusable content pane (center/current column)
- Split LayerGraph and page imports into layer-graph.ts so the
navigation utils stay free of JSX (unit-testable)
- Update Shell keybind dispatch: remove sidebar pane handling,
simplify swipe to fixed-pane tabs only, clarify depth-tab h/l
- Add nav-model.test.ts covering depth stack, tab/pane focus, and
selection semantics
- Changed nextPane/prevPane to use current tab's pane count instead of global TabsCount
- Added Page-specific pane counts mapping for accurate depth calculation
- Pages with 1 pane (Feed, Player) now skip depth navigation
- Fixed wrapping logic to respect each page's layout structure