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