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