11<script lang="ts">
2+ import Vue from ' vue'
23import { ref , computed , watch , defineComponent } from ' @vue/composition-api'
34import scrollIntoView from ' scroll-into-view-if-needed'
5+ import { onKeyDown } from ' @front/util/keyboard'
46import { useCurrentInspector } from ' ./composable'
57
68const DEFAULT_EXPAND_DEPTH = 2
@@ -20,13 +22,23 @@ export default defineComponent({
2022 }
2123 },
2224
23- setup (props ) {
25+ setup (props , { emit } ) {
2426 const {
2527 currentInspector : inspector,
2628 selectNode
2729 } = useCurrentInspector ()
2830
29- const expanded = ref (props .depth < DEFAULT_EXPAND_DEPTH )
31+ const expanded = computed ({
32+ get : () => !! inspector .value .expandedMap [props .node .id ],
33+ set : value => {
34+ Vue .set (inspector .value .expandedMap , props .node .id , value )
35+ }
36+ })
37+
38+ // Init expanded
39+ if (props .node .expanded == null ) {
40+ expanded .value = inspector .value .expandedMap [props .node .id ] ?? props .depth < DEFAULT_EXPAND_DEPTH
41+ }
3042
3143 function toggle () {
3244 expanded .value = ! expanded .value
@@ -67,12 +79,77 @@ export default defineComponent({
6779 watch (selected , () => autoScroll ())
6880 watch (toggleEl , () => autoScroll ())
6981
82+ // Keyboard
83+
84+ onKeyDown (event => {
85+ if (selected .value ) {
86+ requestAnimationFrame (() => {
87+ switch (event .key ) {
88+ case ' ArrowRight' : {
89+ if (! expanded .value ) {
90+ toggle ()
91+ }
92+ break
93+ }
94+ case ' ArrowLeft' : {
95+ if (expanded .value ) {
96+ toggle ()
97+ }
98+ break
99+ }
100+ case ' ArrowDown' : {
101+ if (expanded .value && props .node .children .length ) {
102+ // Select first child
103+ selectNode (props .node .children [0 ])
104+ } else {
105+ emit (' select-next-sibling' )
106+ }
107+ break
108+ }
109+ case ' ArrowUp' : {
110+ emit (' select-previous-sibling' )
111+ }
112+ }
113+ })
114+ }
115+ })
116+
117+ function selectNextSibling (index ) {
118+ if (index + 1 >= props .node .children .length ) {
119+ emit (' select-next-sibling' )
120+ } else {
121+ selectNode (props .node .children [index + 1 ])
122+ }
123+ }
124+
125+ function selectPreviousSibling (index ) {
126+ if (index === 0 || ! props .node .children .length ) {
127+ if (selected .value ) {
128+ emit (' select-previous-sibling' )
129+ } else {
130+ select ()
131+ }
132+ } else {
133+ let child = props .node .children [index - 1 ]
134+ while (child ) {
135+ if (child .children .length && child .expanded ) {
136+ child = child .children [child .children .length - 1 ]
137+ } else {
138+ selectNode (child )
139+ child = null
140+ }
141+ }
142+ }
143+ }
144+
70145 return {
71146 expanded ,
72147 toggle ,
73148 select ,
74149 selected ,
75- toggleEl
150+ toggleEl ,
151+ selectNextSibling ,
152+ selectPreviousSibling
76153 }
77154 }
78155})
@@ -130,10 +207,12 @@ export default defineComponent({
130207
131208 <div v-if =" expanded && node.children" >
132209 <CustomInspectorNode
133- v-for =" child in node .children "
210+ v-for =" ( child , index ) in node .children "
134211 :key =" child .id "
135212 :node =" child "
136213 :depth =" depth + 1 "
214+ @select-next-sibling =" selectNextSibling (index )"
215+ @select-previous-sibling =" selectPreviousSibling (index )"
137216 />
138217 </div >
139218 </div >
0 commit comments