33import * as React from 'react' ;
44import { sortBy } from 'lodash-es' ;
55
6- import type { Module , Directory } from '@codesandbox/common/lib/types' ;
6+ import type {
7+ Module ,
8+ Directory as DirectoryType ,
9+ } from '@codesandbox/common/lib/types' ;
710
811import { isMainModule } from '@codesandbox/common/lib/sandbox/modules' ;
912// eslint-disable-next-line import/extensions
@@ -14,8 +17,8 @@ import File from '../File';
1417import { Container } from './elements' ;
1518
1619type Props = {
17- modules : Array < Module > ,
18- directories : Array < Directory > ,
20+ modules : Module [ ] ,
21+ directories : DirectoryType [ ] ,
1922 directoryId : ?string ,
2023 depth ?: number ,
2124 currentModule : string ,
@@ -44,28 +47,21 @@ function Files({
4447
4548 return (
4649 < Container >
47- { sortBy ( childrenDirectories , d => d . title ) . map ( d => (
48- < div key = { d . shortid } >
49- < File
50- id = { d . id }
51- shortid = { d . shortid }
52- title = { d . title }
53- type = "directory-open"
54- depth = { depth }
55- setCurrentModule = { setCurrentModule }
56- />
57- < Files
58- modules = { modules }
59- directories = { directories }
60- directoryId = { d . shortid }
61- depth = { depth + 1 }
50+ { sortBy ( childrenDirectories , directory => directory . title ) . map (
51+ directory => (
52+ < Directory
53+ key = { directory . shortid }
54+ directory = { directory }
55+ currentModuleId = { currentModule }
6256 setCurrentModule = { setCurrentModule }
63- currentModule = { currentModule }
6457 template = { template }
6558 entry = { entry }
59+ modules = { modules }
60+ directories = { directories }
61+ depth = { depth }
6662 />
67- </ div >
68- ) ) }
63+ )
64+ ) }
6965 { sortBy ( childrenModules , m => m . title ) . map ( m => (
7066 < File
7167 id = { m . id }
@@ -74,13 +70,85 @@ function Files({
7470 key = { m . shortid }
7571 type = { getType ( m . title ) }
7672 depth = { depth }
77- setCurrentModule = { setCurrentModule }
7873 active = { m . id === currentModule }
7974 alternative = { isMainModule ( m , modules , directories , entry ) }
75+ onClick = { ( ) => setCurrentModule ( m . id ) }
8076 />
8177 ) ) }
8278 </ Container >
8379 ) ;
8480}
8581
82+ /** Utils to help identify module tree */
83+
84+ const getCurrentModule = ( modules , currentModuleId ) =>
85+ modules . find ( module => module . id === currentModuleId ) ;
86+
87+ const getParentDirectory = ( directories , child ) =>
88+ directories . find ( directory => directory . shortid === child . directoryShortid ) ;
89+
90+ const getCurrentModuleTree = ( directories , currentModule ) => {
91+ const currentModuleTree = [ currentModule ] ;
92+
93+ let parentDirectory = getParentDirectory ( directories , currentModule ) ;
94+
95+ while ( parentDirectory ) {
96+ currentModuleTree . push ( parentDirectory ) ;
97+ // get parent directory of the parent directory
98+ parentDirectory = getParentDirectory ( directories , parentDirectory ) ;
99+ }
100+
101+ return currentModuleTree ;
102+ } ;
103+
104+ function Directory ( {
105+ directory,
106+ currentModuleId,
107+ setCurrentModule,
108+ template,
109+ entry,
110+ modules,
111+ directories,
112+ depth,
113+ } ) {
114+ /** directory should be open by default if currentModule is inside it */
115+ const [ open , setOpen ] = React . useState ( function ( ) {
116+ const currentModule = getCurrentModule ( modules , currentModuleId ) ;
117+ const currentModuleTree = getCurrentModuleTree ( directories , currentModule ) ;
118+
119+ let openByDefault = false ;
120+ if ( currentModuleTree . find ( module => module . id === directory . id ) ) {
121+ openByDefault = true ;
122+ }
123+ return openByDefault ;
124+ } ) ;
125+
126+ return (
127+ < div >
128+ < File
129+ id = { directory . id }
130+ shortid = { directory . shortid }
131+ title = { directory . title }
132+ type = { open ? 'directory-open' : 'directory' }
133+ depth = { depth }
134+ onClick = { ( ) => {
135+ setOpen ( ! open ) ;
136+ } }
137+ />
138+ { open ? (
139+ < Files
140+ modules = { modules }
141+ directories = { directories }
142+ directoryId = { directory . shortid }
143+ depth = { depth + 1 }
144+ currentModule = { currentModuleId }
145+ setCurrentModule = { setCurrentModule }
146+ template = { template }
147+ entry = { entry }
148+ />
149+ ) : null }
150+ </ div >
151+ ) ;
152+ }
153+
86154export default Files ;
0 commit comments