@@ -90,28 +90,30 @@ const Spacer = styled.div({
9090 width : 4 ,
9191} ) ;
9292
93- const LeafContainer = styled . div ( ( { theme : antdTheme } ) => ( {
93+ const LeafContainer = styled . div < { color : string } > ( ( { color } ) => ( {
9494 display : 'flex' ,
9595 flex : 1 ,
96- backgroundColor : antdTheme . token ?. colorPrimary ,
9796 borderRadius : 4 ,
97+ backgroundColor : color ,
9898 alignItems : 'center' ,
9999 justifyContent : 'center' ,
100100 padding : 8 ,
101101} ) ) ;
102102
103- const SelectedLeafContainer = styled . div ( {
103+ const SelectedLeafContainer = styled . div < { color : string } > ( ( { color } ) => ( {
104104 display : 'flex' ,
105105 flex : 1 ,
106106 padding : 4 ,
107107 border : 'dashed' ,
108+ borderColor : color ,
108109 borderRadius : 4 ,
109110 borderWidth : 2 ,
110- } ) ;
111+ } ) ) ;
111112
112- const LeafTitle = styled ( Typography . Text ) ( {
113+ const LeafTitle = styled ( Typography . Text ) < { isSelected ?: boolean } > ( ( { isSelected } ) => ( {
113114 color : 'white' ,
114- } ) ;
115+ textDecoration : isSelected ? 'underline' : 'none' ,
116+ } ) ) ;
115117
116118const Leaf = ( {
117119 title,
@@ -124,33 +126,41 @@ const Leaf = ({
124126} ) => {
125127 const Wrapper = isSelectedTab ? SelectedLeafContainer : React . Fragment ;
126128 return (
127- < Wrapper style = { { borderColor : color } } >
128- < LeafContainer style = { { backgroundColor : color } } >
129- < LeafTitle style = { { textDecoration : isSelectedTab ? 'underline' : 'none' } } >
130- { title }
131- </ LeafTitle >
129+ < Wrapper color = { color } >
130+ < LeafContainer color = { color } >
131+ < LeafTitle isSelected = { isSelectedTab } > { title } </ LeafTitle >
132132 </ LeafContainer >
133133 </ Wrapper >
134134 ) ;
135135} ;
136136
137- const NodeContainer = styled . div ( ( { theme : antdTheme } ) => ( {
137+ const NodeContainer = styled . div < { color : string ; isClosed ?: boolean } > ( ( { color , isClosed } ) => ( {
138138 display : 'flex' ,
139139 flexDirection : 'column' ,
140140 borderRadius : 4 ,
141141 borderWidth : 1 ,
142142 border : 'solid' ,
143- borderColor : antdTheme . token ?. colorPrimary ,
144- borderTopWidth : 0 ,
145- borderTopLeftRadius : 0 ,
146- borderTopRightRadius : 0 ,
143+ borderColor : color ,
144+ borderTopWidth : isClosed ? 1 : 0 ,
145+ borderTopLeftRadius : isClosed ? 4 : 0 ,
146+ borderTopRightRadius : isClosed ? 4 : 0 ,
147147 padding : 8 ,
148148 paddingTop : 4 ,
149+ cursor : 'pointer' ,
150+ backgroundColor : 'transparent' ,
151+ ':hover:not(:has(:hover))' : {
152+ backgroundColor : `${ color } 30` ,
153+ } ,
149154} ) ) ;
150155
151- const NodeTitle = styled ( Typography ) ( ( { theme } ) => ( {
152- color : theme . token ?. colorPrimary ,
156+ const NodeTitle = styled ( Typography ) < { color : string } > ( ( { color } ) => ( {
153157 alignSelf : 'flex-start' ,
158+ color,
159+ } ) ) ;
160+
161+ const ClosedNodeTitle = styled ( Typography ) < { color : string } > ( ( { color } ) => ( {
162+ alignSelf : 'center' ,
163+ color,
154164} ) ) ;
155165
156166const TabContainer = styled . div ( {
@@ -170,6 +180,8 @@ const Node = ({
170180 state : NavigationState ;
171181 parentColor : string ;
172182} ) => {
183+ const [ isClosed , setIsClosed ] = React . useState ( false ) ;
184+
173185 const routes = state . routes ;
174186 if ( ! routes || ! routes . length ) {
175187 return < Leaf title = { name } color = { parentColor } /> ;
@@ -179,11 +191,20 @@ const Node = ({
179191
180192 const StackWrapper = state . type === 'tab' ? TabContainer : React . Fragment ;
181193
194+ if ( isClosed ) {
195+ return < ClosedNode name = { name } color = { color } openNode = { ( ) => setIsClosed ( false ) } /> ;
196+ }
197+
182198 return (
183- < NodeContainer style = { { borderColor : color } } >
199+ < NodeContainer
200+ color = { color }
201+ onClick = { ( e ) => {
202+ setIsClosed ( true ) ;
203+ e . stopPropagation ( ) ;
204+ } } >
184205 < StackWrapper >
185206 { routes . toReversed ( ) . map ( ( route , index ) => (
186- < React . Fragment key = { index } >
207+ < React . Fragment key = { route . key } >
187208 { route . state ?. routes && route . state . routes . length ? (
188209 < Node name = { route . name } state = { route . state } parentColor = { color } />
189210 ) : (
@@ -199,50 +220,84 @@ const Node = ({
199220 </ React . Fragment >
200221 ) ) }
201222 </ StackWrapper >
202- < NodeTitle style = { { color } } > { name } </ NodeTitle >
223+ < NodeTitle color = { color } > { name } </ NodeTitle >
224+ </ NodeContainer >
225+ ) ;
226+ } ;
227+
228+ const ClosedNode = ( {
229+ name,
230+ color,
231+ openNode,
232+ } : {
233+ name : string ;
234+ color : string ;
235+ openNode : ( ) => void ;
236+ } ) => {
237+ return (
238+ < NodeContainer
239+ color = { color }
240+ style = { { borderColor : color } }
241+ onClick = { ( e ) => {
242+ openNode ( ) ;
243+ e . stopPropagation ( ) ;
244+ } }
245+ isClosed >
246+ < ClosedNodeTitle color = { color } > { name } </ ClosedNodeTitle >
203247 </ NodeContainer >
204248 ) ;
205249} ;
206250
207251const colorMap : Record < string , string > = { } ;
208- let currentHue = 0 ;
252+ let currentIndex = 0 ;
253+
254+ const colorList = [
255+ '#EF5350' ,
256+ '#EC407A' ,
257+ '#AB47BC' ,
258+ '#7E57C2' ,
259+ '#5C6BC0' ,
260+ '#42A5F5' ,
261+ '#29B6F6' ,
262+ '#26C6DA' ,
263+ '#26A69A' ,
264+ '#66BB6A' ,
265+ ] ;
209266
210267const generateColor = ( key : string ) => {
211268 if ( colorMap [ key ] ) {
212- console . log ( key ) ;
213-
214269 return colorMap [ key ] ;
215270 }
216271
217- currentHue = ( currentHue + 15 ) % 360 ;
218- const newColor = `hsl( ${ currentHue } , 70%, 50%)` ;
272+ currentIndex = ( currentIndex + 1 ) % colorList . length ;
273+ const newColor = colorList [ currentIndex ] ;
219274
220275 colorMap [ key ] = newColor ;
221276
222- console . log ( newColor ) ;
223-
224277 return newColor ;
225278} ;
226279
280+ const legendRed = '#EF5350' ;
281+
227282const Legend = ( ) => {
228283 return (
229284 < div style = { { padding : 12 } } >
230- < NodeContainer style = { { borderColor : 'hsl(0, 70%, 50%)' } } >
231- < Leaf title = "Screen" color = "hsl(0, 70%, 50%)" />
285+ < NodeContainer color = { legendRed } >
286+ < Leaf title = "Screen" color = { legendRed } />
232287 < div style = { { height : 4 } } />
233- < NodeTitle style = { { color : 'hsl(0, 70%, 50%)' } } > Stack Navigator</ NodeTitle >
288+ < NodeTitle color = { legendRed } > Stack Navigator</ NodeTitle >
234289 </ NodeContainer >
235290 < div style = { { height : 12 } } />
236- < NodeContainer style = { { borderColor : 'hsl(0, 70%, 50%)' } } >
291+ < NodeContainer color = { legendRed } >
237292 < div style = { { display : 'flex' , flexDirection : 'row' } } >
238- < Leaf title = "Unselected Tab" color = "hsl(0, 70%, 50%)" />
293+ < Leaf title = "Unselected Tab" color = { legendRed } />
239294 < div style = { { width : 4 } } />
240- < SelectedLeafContainer style = { { borderColor : 'hsl(0, 70%, 50%)' } } >
241- < Leaf title = "Selected Tab" color = "hsl(0, 70%, 50%)" />
295+ < SelectedLeafContainer color = { legendRed } >
296+ < Leaf title = "Selected Tab" color = { legendRed } />
242297 </ SelectedLeafContainer >
243298 </ div >
244299 < div style = { { height : 4 } } />
245- < NodeTitle style = { { color : 'hsl(0, 70%, 50%)' } } > Tab Navigator</ NodeTitle >
300+ < NodeTitle color = { legendRed } > Tab Navigator</ NodeTitle >
246301 </ NodeContainer >
247302 </ div >
248303 ) ;
0 commit comments