@@ -26,7 +26,7 @@ function isNodeActive(node: StorybookFileTree): boolean {
2626
2727// Build route object for a story
2828function getStoryRoute(node : StorybookFileTree ): RouteLocationRaw {
29- if (node .type === ' story' ) {
29+ if (node .type === ' story' && node . storyId ) {
3030 return {
3131 name: ' stories' ,
3232 params: { path: props .basePath },
@@ -36,7 +36,7 @@ function getStoryRoute(node: StorybookFileTree): RouteLocationRaw {
3636 // For directories - navigate to first story in that directory
3737 if (node .type === ' directory' ) {
3838 const firstStory = getFirstStoryInDirectory (node )
39- if (firstStory ) {
39+ if (firstStory ?. storyId ) {
4040 return {
4141 name: ' stories' ,
4242 params: { path: props .basePath },
@@ -69,6 +69,48 @@ function getNodeIcon(node: StorybookFileTree): string {
6969
7070const { toggleDir, isExpanded, autoExpandAncestors } = useStoryTreeState (props .baseUrl )
7171
72+ const storyRefs = shallowReactive (new Map <string , HTMLElement >())
73+
74+ function setStoryRef(storyId : string | null ) {
75+ return (el : Element | { $el? : Element } | null ) => {
76+ if (! storyId ) return
77+ if (! el ) {
78+ storyRefs .delete (storyId )
79+ return
80+ }
81+ const target = ' $el' in el ? el .$el : el
82+ if (target instanceof HTMLElement ) storyRefs .set (storyId , target )
83+ }
84+ }
85+
86+ function findStoryPath(tree : StorybookFileTree [], storyId : string ): string | null {
87+ for (const node of tree ) {
88+ if (node .type === ' story' && node .storyId === storyId ) return node .path
89+ if (node .type === ' directory' && node .children ) {
90+ const found = findStoryPath (node .children , storyId )
91+ if (found ) return found
92+ }
93+ }
94+ return null
95+ }
96+
97+ watch (
98+ [() => props .currentStoryId , () => props .tree ],
99+ ([storyId , tree ]) => {
100+ if (! storyId || ! tree .length || depth .value !== 0 ) return
101+ const storyPath = findStoryPath (tree , storyId )
102+ if (! storyPath ) return
103+ autoExpandAncestors (storyPath )
104+ nextTick (() => {
105+ const target = storyRefs .get (storyId )
106+ if (target ) {
107+ target .scrollIntoView ({ block: ' nearest' , inline: ' nearest' })
108+ }
109+ })
110+ },
111+ { immediate: true },
112+ )
113+
72114// Handle directory click - toggle expansion and navigate to first story
73115function handleDirectoryClick(node : StorybookFileTree ) {
74116 if (node .type !== ' directory' ) return
@@ -120,6 +162,7 @@ function handleDirectoryClick(node: StorybookFileTree) {
120162 block
121163 :style =" { paddingLeft: `${depth * 12 + 32}px` }"
122164 :classicon =" getNodeIcon(node)"
165+ :ref =" setStoryRef(node.storyId)"
123166 >
124167 <span class =" truncate" >{{ node.name }}</span >
125168 </LinkBase >
0 commit comments