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