@@ -11,7 +11,7 @@ import { vTooltip, VueButton, VueDialog, VueInput } from '@vue/devtools-ui'
11
11
import { useElementSize , useEventListener , useToggle , watchDebounced } from ' @vueuse/core'
12
12
import { flatten , groupBy } from ' lodash-es'
13
13
import { Pane , Splitpanes } from ' splitpanes'
14
- import { computed , onUnmounted , ref , watch , watchEffect } from ' vue'
14
+ import { computed , nextTick , onUnmounted , ref , watch , watchEffect } from ' vue'
15
15
import SelectiveList from ' ~/components/basic/SelectiveList.vue'
16
16
import RootStateViewer from ' ~/components/state/RootStateViewer.vue'
17
17
import ComponentTree from ' ~/components/tree/TreeViewer.vue'
@@ -283,32 +283,40 @@ useEventListener('keydown', (event) => {
283
283
if (! activeComponentId .value )
284
284
return
285
285
286
- switch (event .key ) {
287
- case ' ArrowRight' :
288
- handleArrowRight ()
289
- break
290
- case ' ArrowLeft' :
291
- handleArrowLeft ()
292
- break
293
- case ' ArrowDown' :
294
- handleArrowDown ()
295
- event .preventDefault ()
296
- break
297
- case ' ArrowUp' :
298
- handleArrowUp ()
299
- event .preventDefault ()
300
- break
301
- case ' ' :
302
- case ' Enter' : {
303
- handleEnter ()
304
- event .preventDefault ()
305
- break
286
+ nextTick (() => {
287
+ switch (event .key ) {
288
+ case ' ArrowRight' :{
289
+ handleArrowRight ()
290
+ break
291
+ }
292
+ case ' ArrowLeft' : {
293
+ handleArrowLeft ()
294
+ break
295
+ }
296
+ case ' ArrowDown' : {
297
+ handleArrowDown ()
298
+ event .preventDefault ()
299
+ return false
300
+ }
301
+ case ' ArrowUp' : {
302
+ handleArrowUp ()
303
+ event .preventDefault ()
304
+ break
305
+ }
306
+ case ' ' :
307
+ case ' Enter' : {
308
+ handleEnter ()
309
+ break
310
+ }
306
311
}
307
- }
312
+ })
308
313
})
309
314
310
315
function handleArrowRight() {
311
- if (! expandedTreeNodes .value .includes (activeComponentId .value )) {
316
+ const isPresentInExpandedNodes = expandedTreeNodes .value .includes (activeComponentId .value )
317
+ const hasChildren = flattenedTreeNodes .value .find (item => item .id === activeComponentId .value )?.children ?.length
318
+
319
+ if (! isPresentInExpandedNodes && hasChildren ) {
312
320
expandedTreeNodes .value .push (activeComponentId .value )
313
321
}
314
322
}
@@ -330,25 +338,23 @@ function handleArrowDown() {
330
338
return false
331
339
}
332
340
else {
333
- const listIndex = treeNodeLinkedList .value .findIndex (arr => arr .includes (activeComponentId .value ))
334
- const nextTree = treeNodeLinkedList .value [listIndex + 1 ]
335
- if (nextTree ) {
336
- activeComponentId .value = nextTree [1 ]
337
- }
341
+ activeComponentId .value = getNearestNextNode ()
338
342
}
339
343
}
340
344
341
345
function handleArrowUp() {
342
- const isSubTreeRoot = treeNodeLinkedList .value .some (chain => chain [1 ] === activeComponentId .value )
346
+ const activeId = activeComponentId .value
347
+ const list = treeNodeLinkedList .value .find (item => item .includes (activeId ))
348
+ if (! list )
349
+ return
343
350
344
- if (isSubTreeRoot ) {
345
- activeComponentId .value = getPrevExpandedNode ()
346
- }
347
- else {
348
- const currentIndex = flattenedTreeNodesIds .value .indexOf (activeComponentId .value )
349
- if (currentIndex > 0 ) {
350
- activeComponentId .value = flattenedTreeNodesIds .value [currentIndex - 1 ]
351
- }
351
+ const activeItemListIndex = list .indexOf (activeId )
352
+ const activeItemParentIndex = activeItemListIndex > 0 ? activeItemListIndex - 1 : 0
353
+ const parentId = list [activeItemParentIndex ]
354
+
355
+ const element = getNearestPreviousNode (parentId )
356
+ if (element ) {
357
+ activeComponentId .value = element .id
352
358
}
353
359
}
354
360
@@ -363,13 +369,51 @@ function handleEnter() {
363
369
else expandedTreeNodes .value .splice (index , 1 )
364
370
}
365
371
366
- function getPrevExpandedNode() {
367
- const list = treeNodeLinkedList .value
368
- const listIndex = list .findIndex ((chain : string []) => chain .includes (activeComponentId .value ))
369
- if (listIndex > 0 ) {
370
- return list [listIndex - 1 ].find (id => ! expandedTreeNodes .value .includes (id )) || list [listIndex - 1 ][1 ]
372
+ function getNearestPreviousNode(parentId : string ) {
373
+ const parentNode = flattenedTreeNodes .value .find (item => item .id === parentId )
374
+ if (! parentNode || ! parentNode .children ?.length )
375
+ return parentNode
376
+
377
+ if (parentNode .children .length === 1 )
378
+ return parentNode
379
+
380
+ const indexInSiblings = parentNode ?.children ?.findIndex (item => item .id === activeComponentId .value )
381
+
382
+ if (indexInSiblings <= 0 )
383
+ return parentNode
384
+
385
+ let prevSiblingNode = parentNode .children [indexInSiblings - 1 ]
386
+
387
+ while (prevSiblingNode
388
+ && expandedTreeNodes .value .includes (prevSiblingNode .id )
389
+ && prevSiblingNode .children ?.length ) {
390
+ const lastChildNode = prevSiblingNode .children [prevSiblingNode .children .length - 1 ]
391
+ const next = getNearestPreviousNode (lastChildNode .id )
392
+
393
+ if (! next || next .id === prevSiblingNode .id )
394
+ break
395
+ prevSiblingNode = next
371
396
}
372
- return list [listIndex ][0 ]
397
+
398
+ return prevSiblingNode || parentNode
399
+ }
400
+
401
+ function getNearestNextNode() {
402
+ const linkedListTree = treeNodeLinkedList .value
403
+ const activeItemListIndex = [... linkedListTree ]
404
+ .map ((arr , index ) => ({ arr , index }))
405
+ .reverse ()
406
+ .find (({ arr }) => arr ?.includes (activeComponentId .value ))
407
+ ?.index as number
408
+
409
+ if (activeItemListIndex === - 1 )
410
+ return activeComponentId .value
411
+ const arr1 = linkedListTree [activeItemListIndex ]
412
+ const arr2 = linkedListTree [activeItemListIndex + 1 ]
413
+
414
+ const cloesestNodeIndex = arr2 ?.findIndex ((val , index ) => val !== arr1 [index ]) ?? - 1
415
+
416
+ return cloesestNodeIndex !== - 1 ? arr2 [cloesestNodeIndex ] : activeComponentId .value
373
417
}
374
418
375
419
function scrollToComponent() {
0 commit comments