Skip to content

Commit 773f59c

Browse files
committed
fix(ui): preserve root dir state when sibling dir is expanded
- Recompute expanded state after toggling or auto-expanding directories - Only auto-expand ancestors for the top-level tree - Add regression coverage for sibling directory expansion
1 parent 0164064 commit 773f59c

File tree

3 files changed

+92
-1
lines changed

3 files changed

+92
-1
lines changed

app/components/Code/FileTree.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ const { toggleDir, isExpanded, autoExpandAncestors } = useFileTreeState(props.ba
3939
watch(
4040
() => props.currentPath,
4141
path => {
42-
if (path) {
42+
if (depth.value === 0 && path) {
4343
autoExpandAncestors(path)
4444
}
4545
},

app/composables/useFileTreeState.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export function useFileTreeState(baseUrl: string) {
77
} else {
88
expanded.value.add(path)
99
}
10+
expanded.value = new Set(expanded.value)
1011
}
1112

1213
function isExpanded(path: string) {
@@ -21,6 +22,7 @@ export function useFileTreeState(baseUrl: string) {
2122
prefix = prefix ? `${prefix}/${part}` : part
2223
expanded.value.add(prefix)
2324
}
25+
expanded.value = new Set(expanded.value)
2426
}
2527

2628
return {
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import { mountSuspended } from '@nuxt/test-utils/runtime'
2+
import { describe, expect, it, vi } from 'vitest'
3+
import CodeFileTree from '~/components/Code/FileTree.vue'
4+
5+
const mockTree: PackageFileTree[] = [
6+
{
7+
name: 'distribution',
8+
type: 'directory',
9+
path: 'distribution',
10+
children: [
11+
{
12+
name: 'core',
13+
type: 'directory',
14+
path: 'distribution/core',
15+
children: [
16+
{
17+
name: 'constants.d.ts',
18+
type: 'file',
19+
path: 'distribution/core/constants.d.ts',
20+
},
21+
],
22+
},
23+
{
24+
name: 'types',
25+
type: 'directory',
26+
path: 'distribution/types',
27+
children: [
28+
{
29+
name: 'common.d.ts',
30+
type: 'file',
31+
path: 'distribution/types/common.d.ts',
32+
},
33+
],
34+
},
35+
],
36+
},
37+
]
38+
39+
function findDirButton(wrapper: Awaited<ReturnType<typeof mountCodeFileTree>>, name: string) {
40+
return wrapper.findAll('button').find(button => button.text().trim() === name)
41+
}
42+
43+
async function mountCodeFileTree() {
44+
return mountSuspended(CodeFileTree, {
45+
attachTo: document.body,
46+
props: {
47+
tree: mockTree,
48+
currentPath: 'distribution/core/constants.d.ts',
49+
baseUrl: '/package-code/ky/v/1.14.3/distribution/core/constants.d.ts?test=tree',
50+
baseRoute: {
51+
params: {
52+
packageName: 'ky',
53+
version: '1.14.3',
54+
filePath: '',
55+
},
56+
},
57+
},
58+
})
59+
}
60+
61+
describe('CodeFileTree', () => {
62+
it('keeps a collapsed sibling directory closed when another sibling expands', async () => {
63+
const wrapper = await mountCodeFileTree()
64+
65+
await vi.waitFor(() => {
66+
expect(wrapper.text()).toContain('constants.d.ts')
67+
expect(wrapper.text()).not.toContain('common.d.ts')
68+
})
69+
70+
const coreButton = findDirButton(wrapper, 'core')
71+
expect(coreButton).toBeDefined()
72+
await coreButton!.trigger('click')
73+
74+
await vi.waitFor(() => {
75+
expect(wrapper.text()).not.toContain('constants.d.ts')
76+
})
77+
78+
const typesButton = findDirButton(wrapper, 'types')
79+
expect(typesButton).toBeDefined()
80+
await typesButton!.trigger('click')
81+
82+
await vi.waitFor(() => {
83+
expect(wrapper.text()).toContain('common.d.ts')
84+
expect(wrapper.text()).not.toContain('constants.d.ts')
85+
})
86+
87+
wrapper.unmount()
88+
})
89+
})

0 commit comments

Comments
 (0)