1import { css } from '@emotion/react';
2import { iconSize, spacing, typography, ChevronDownIcon } from '@expo/styleguide';
3import React, { PropsWithChildren } from 'react';
4
5import { NavigationRenderProps } from '.';
6
7import { Collapsible } from '~/ui/components/Collapsible';
8import { CALLOUT } from '~/ui/components/Text';
9import { durations } from '~/ui/foundations/durations';
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    <Collapsible
20      css={detailsStyle}
21      open={isActive || route.expanded}
22      summary={
23        <div css={summaryStyle}>
24          <ChevronDownIcon css={iconStyle} size={iconSize.small} />
25          <CALLOUT css={textStyle} tag="span">
26            {route.name}
27          </CALLOUT>
28        </div>
29      }>
30      {children}
31    </Collapsible>
32  );
33}
34
35const detailsStyle = css({
36  paddingTop: spacing[3],
37  marginBottom: spacing[3],
38});
39
40const summaryStyle = css({
41  display: 'flex',
42  flexDirection: 'row',
43  alignItems: 'center',
44  listStyle: 'none',
45  userSelect: 'none',
46  margin: `0 ${spacing[4]}px`,
47});
48
49const iconStyle = css({
50  flexShrink: 0,
51  transform: 'rotate(-90deg)',
52  transition: `transform ${durations.hover}`,
53
54  'details[open] &': { transform: 'rotate(0)' },
55});
56
57const textStyle = css({
58  ...typography.utility.weight.medium,
59  padding: spacing[1.5],
60});
61