1- import { useEffect , useState } from 'react' ;
2- import { View } from 'react-native' ;
3- import useSWR from 'swr ' ;
1+ import { type PropsWithChildren , type ReactElement , useEffect , useState } from 'react' ;
2+ import { type StyleProp , View } from 'react-native' ;
3+ import { type Style } from 'twrnc ' ;
44
5- import { H6 } from '~/common/styleguide' ;
5+ import { H6Section } from '~/common/styleguide' ;
66import { Button } from '~/components/Button' ;
77import { Arrow } from '~/components/Icons' ;
8- import { type PeerDependencyData } from '~/types' ;
9- import { TimeRange } from '~/util/datetime' ;
108import tw from '~/util/tailwind' ;
119
12- import DependencyRow from './DependencyRow' ;
1310import EntityCounter from './EntityCounter' ;
1411
15- type Props = {
12+ type Props = PropsWithChildren < {
1613 title : string ;
17- data ?: Record < string , string | PeerDependencyData > | null ;
18- checkExistence ?: boolean ;
19- } ;
14+ count ?: number ;
15+ rightSlot ?: ReactElement ;
16+ headerStyle ?: StyleProp < Style > ;
17+ } > ;
2018
21- export default function CollapsibleSection ( { title, data, checkExistence } : Props ) {
19+ export default function CollapsibleSection ( {
20+ title,
21+ count,
22+ rightSlot,
23+ headerStyle,
24+ children,
25+ } : Props ) {
2226 const sectionKey = sanitizeTitle ( title ) ;
2327 const key = `@ReactNativeDirectory:PackageSectionCollapsed:${ sectionKey } ` ;
24- const noData = ! data || Object . keys ( data ) . length === 0 ;
2528
2629 const [ collapsed , setCollapsed ] = useState < boolean > ( Boolean ( window . localStorage . getItem ( key ) ) ) ;
2730
28- const { data : checkData } = useSWR (
29- checkExistence && ! noData
30- ? `/api/library?name=${ Object . keys ( data ) . join ( ',' ) } &check=true`
31- : null ,
32- ( url : string ) => fetch ( url ) . then ( res => res . json ( ) ) ,
33- {
34- dedupingInterval : TimeRange . HOUR * 1000 ,
35- revalidateOnFocus : false ,
36- }
37- ) ;
38-
3931 useEffect ( ( ) => {
4032 setCollapsed ( window . localStorage . getItem ( key ) === 'true' ) ;
4133 } , [ key ] ) ;
4234
43- if ( noData ) {
44- return null ;
45- }
46-
4735 async function toggleSection ( ) {
4836 const nextState = ! collapsed ;
4937 setCollapsed ( nextState ) ;
@@ -53,10 +41,11 @@ export default function CollapsibleSection({ title, data, checkExistence }: Prop
5341 return (
5442 < >
5543 < View style = { tw `flex-row items-center justify-between gap-1.5` } >
56- < H6 style = { tw `flex items-center gap-1.5 text-[16px] text-secondary` } >
44+ < H6Section style = { [ tw `flex items-center gap-1.5` , headerStyle ] } >
5745 { title }
58- < EntityCounter count = { Object . keys ( data ) . length } />
59- </ H6 >
46+ { count && < EntityCounter count = { count } /> }
47+ </ H6Section >
48+ { ! collapsed ? rightSlot : undefined }
6049 < Button
6150 onPress = { toggleSection }
6251 style = { tw `bg-palette-gray2 p-1 dark:bg-palette-gray7` }
@@ -65,20 +54,7 @@ export default function CollapsibleSection({ title, data, checkExistence }: Prop
6554 < Arrow style = { [ tw `h-3 w-4 text-icon` , collapsed ? tw `rotate-90` : tw `rotate-270` ] } />
6655 </ Button >
6756 </ View >
68- { ! collapsed && (
69- < View >
70- { Object . entries ( data )
71- . sort ( ( [ aName ] , [ bName ] ) => aName . localeCompare ( bName ) )
72- . map ( ( [ name , depData ] ) => (
73- < DependencyRow
74- key = { `${ sectionKey } -${ name } ` }
75- name = { name }
76- data = { depData }
77- packageExists = { checkData ?. [ name ] }
78- />
79- ) ) }
80- </ View >
81- ) }
57+ { ! collapsed && < View > { children } </ View > }
8258 </ >
8359 ) ;
8460}
0 commit comments