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