1import { css } from '@emotion/react';
2import { spacing, theme } from '@expo/styleguide';
3import React from 'react';
4
5import { InlineCode } from '~/components/base/code';
6import { H2, H3Code, H4Code } from '~/components/plugins/Headings';
7import { EnumDefinitionData, EnumValueData } from '~/components/plugins/api/APIDataTypes';
8import { PlatformTags } from '~/components/plugins/api/APISectionPlatformTags';
9import { CommentTextBlock, STYLES_APIBOX } from '~/components/plugins/api/APISectionUtils';
10
11export type APISectionEnumsProps = {
12  data: EnumDefinitionData[];
13};
14
15const sortByValue = (a: EnumValueData, b: EnumValueData) => {
16  if (a.defaultValue && b.defaultValue) {
17    if (a.defaultValue.includes(`'`) && b.defaultValue.includes(`'`)) {
18      return a.defaultValue.localeCompare(b.defaultValue);
19    } else {
20      return parseInt(a.defaultValue, 10) - parseInt(b.defaultValue, 10);
21    }
22  }
23  return 0;
24};
25
26const renderEnum = ({ name, children, comment }: EnumDefinitionData): JSX.Element => (
27  <div key={`enum-definition-${name}`} css={[STYLES_APIBOX, enumContentStyles]}>
28    <H3Code>
29      <InlineCode>{name}</InlineCode>
30    </H3Code>
31    <CommentTextBlock comment={comment} />
32    {children.sort(sortByValue).map((enumValue: EnumValueData) => (
33      <div css={[STYLES_APIBOX, enumContainerStyle]} key={enumValue.name}>
34        <PlatformTags comment={enumValue.comment} prefix="Only for:" firstElement />
35        <div css={enumValueNameStyle}>
36          <H4Code>
37            <InlineCode>{enumValue.name}</InlineCode>
38          </H4Code>
39        </div>
40        <InlineCode customCss={enumValueStyles}>
41          {name}.{enumValue.name}
42          {enumValue?.defaultValue ? ` = ${enumValue?.defaultValue}` : ''}
43        </InlineCode>
44        <CommentTextBlock comment={enumValue.comment} includePlatforms={false} />
45      </div>
46    ))}
47  </div>
48);
49
50const APISectionEnums = ({ data }: APISectionEnumsProps) =>
51  data?.length ? (
52    <>
53      <H2 key="enums-header">Enums</H2>
54      {data.map(renderEnum)}
55    </>
56  ) : null;
57
58const enumContainerStyle = css({
59  boxShadow: 'none',
60  marginBottom: spacing[3],
61});
62
63const enumValueNameStyle = css({
64  marginTop: spacing[3],
65});
66
67const enumValueStyles = css({
68  display: 'inline-block',
69  padding: `0 ${spacing[2]}px`,
70  color: theme.text.secondary,
71  fontSize: '75%',
72  marginBottom: spacing[3],
73});
74
75const enumContentStyles = css({
76  '& blockquote': {
77    margin: `${spacing[2]}px 0`,
78  },
79
80  '& ul': {
81    marginBottom: 0,
82  },
83});
84
85export default APISectionEnums;
86