fix(desktop): open a preview without dragging the file tree open

The preview pane shares a collapsible column with the file tree, and
`revealTreePane` un-collapses a column through that column's bound store —
which on the right is `$fileBrowserOpen`, the tree's own ⌘J toggle. So
every preview open literally called `setFileBrowserOpen(true)` and the tree
came with it.

`revealPreview` now un-collapses the column directly and leaves the toggle
alone. The tree pane's visibility binding gains `$fileBrowserOpen` to match,
since its presence was tracking only the column's collapse — without that it
would still render the moment anything opened the column.
This commit is contained in:
Brooklyn Nicholson 2026-07-27 17:55:24 -05:00
parent 003ff53fb4
commit cd25a9f405
2 changed files with 53 additions and 1 deletions

View file

@ -27,6 +27,8 @@ import {
revealTreePane,
setPaneCollapsed,
setTreePaneHidden,
setTreeSideCollapsed,
treeSideOfPane,
watchContributedPanes
} from '@/components/pane-shell/tree/store'
import { SidebarProvider } from '@/components/ui/sidebar'
@ -533,7 +535,13 @@ bindTreeSideVisibility('right', $fileBrowserOpen, setFileBrowserOpen)
// rode the rail's row and vanished with it), its zone stands on its own.
const $hasWorkspace = computed($currentCwd, cwd => Boolean(cwd.trim()))
bindPaneVisibility('files', $hasWorkspace)
// The tree pane's own presence tracks ⌘J directly, not just the column's
// collapse — otherwise revealing a preview (which opens that shared column)
// would drag the tree along with it. See revealPreview.
bindPaneVisibility(
'files',
computed([$hasWorkspace, $fileBrowserOpen], (workspace, open) => workspace && open)
)
// ⌘G — the review sidebar appears/disappears (and comes to the front).
bindPaneVisibility(
'review',
@ -596,6 +604,18 @@ registerPaneCloser('files', () =>
// the side, unhide, front — a NEW target while already visible still fronts.
const revealPreview = () => {
dockPaneBeside('preview', 'files')
// The preview shares a collapsible column with the file tree, and
// revealTreePane un-collapses a column through its bound store — here ⌘J /
// $fileBrowserOpen, which IS the tree's toggle. Going through it would open
// the tree every time a preview opened. Un-collapse the column directly and
// leave the toggle alone, so a preview can appear on its own.
const side = treeSideOfPane('preview')
if (side) {
setTreeSideCollapsed(side, false)
}
revealTreePane('preview')
}

View file

@ -127,6 +127,38 @@ describe('reactive pane unhide', () => {
expect(tree.$collapsedTreeSides.get().has('right')).toBe(false)
})
// Opening a preview used to drag the file tree open with it: the preview
// shares ⌘J's column, and `revealTreePane` un-collapses a column through its
// bound store — which for the right side IS the file-browser toggle. The
// reveal now un-collapses the column directly and leaves the toggle alone.
it('revealing a preview opens its column without flipping the file-tree toggle', async () => {
const { tree, layout } = await setupWithFiles()
const { registry } = await import('@/contrib/registry')
registry.register({
id: 'preview',
area: 'panes',
data: { placement: 'right' },
render: () => null,
title: 'preview'
})
layout.setFileBrowserOpen(false)
expect(tree.$collapsedTreeSides.get().has('right')).toBe(true)
// The revealPreview sequence from controller.tsx.
const side = tree.treeSideOfPane('files')
expect(side).toBe('right')
tree.setTreeSideCollapsed(side!, false)
tree.revealTreePane('preview')
// The column is showing…
expect(tree.$collapsedTreeSides.get().has('right')).toBe(false)
// …but the tree's own toggle never moved, so the tree stays closed.
expect(layout.$fileBrowserOpen.get()).toBe(false)
})
it('reactive unhide does not invoke the right side opener directly', async () => {
const { tree, layout } = await setupWithFiles()