1import { css } from '@emotion/react'; 2import { spacing } from '@expo/styleguide-base'; 3import { ChevronDownIcon } from '@expo/styleguide-icons'; 4import type { PropsWithChildren } from 'react'; 5 6import { NavigationRenderProps } from '.'; 7 8import { Collapsible } from '~/ui/components/Collapsible'; 9import { CALLOUT } from '~/ui/components/Text'; 10import { durations } from '~/ui/foundations/durations'; 11 12type SectionListProps = PropsWithChildren<NavigationRenderProps>; 13 14export function SectionList({ route, isActive, children }: SectionListProps) { 15 if (route.type !== 'section') { 16 throw new Error(`Navigation route is not a section`); 17 } 18 19 return ( 20 <Collapsible 21 css={detailsStyle} 22 open={isActive || route.expanded} 23 summary={ 24 <div css={summaryStyle}> 25 <ChevronDownIcon className="icon-sm text-icon-default" css={iconStyle} /> 26 <CALLOUT css={textStyle} tag="span"> 27 {route.name} 28 </CALLOUT> 29 </div> 30 }> 31 {children} 32 </Collapsible> 33 ); 34} 35 36const detailsStyle = css({ 37 paddingTop: spacing[3], 38 marginBottom: spacing[3], 39}); 40 41const summaryStyle = css({ 42 display: 'flex', 43 flexDirection: 'row', 44 alignItems: 'center', 45 listStyle: 'none', 46 userSelect: 'none', 47 margin: `0 ${spacing[4]}px`, 48}); 49 50const iconStyle = css({ 51 flexShrink: 0, 52 transform: 'rotate(-90deg)', 53 transition: `transform ${durations.hover}`, 54 55 'details[open] &': { transform: 'rotate(0)' }, 56}); 57 58const textStyle = css({ 59 fontWeight: 500, 60 padding: spacing[1.5], 61}); 62