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