1import { css } from '@emotion/react';
2import { spacing, theme } from '@expo/styleguide';
3
4import { EnumDefinitionData, EnumValueData } from '~/components/plugins/api/APIDataTypes';
5import { APISectionDeprecationNote } from '~/components/plugins/api/APISectionDeprecationNote';
6import { APISectionPlatformTags } from '~/components/plugins/api/APISectionPlatformTags';
7import {
8  CommentTextBlock,
9  getTagNamesList,
10  STYLES_APIBOX,
11  STYLES_APIBOX_NESTED,
12  H3Code,
13} from '~/components/plugins/api/APISectionUtils';
14import { H2, H4, CODE } from '~/ui/components/Text';
15
16export type APISectionEnumsProps = {
17  data: EnumDefinitionData[];
18};
19
20const sortByValue = (a: EnumValueData, b: EnumValueData) => {
21  if (a.type && a.type.value !== undefined && b.type && b.type.value !== undefined) {
22    if (typeof a.type.value === 'string' && typeof b.type.value === 'string') {
23      return a.type.value.localeCompare(b.type.value);
24    } else if (typeof a.type.value === 'number' && typeof b.type.value === 'number') {
25      return (a.type.value ?? Number.MIN_VALUE) - (b.type.value ?? Number.MIN_VALUE);
26    }
27  }
28  return 0;
29};
30
31const renderEnumValue = (value: any) => (typeof value === 'string' ? `"${value}"` : value);
32
33const renderEnum = ({ name, children, comment }: EnumDefinitionData): JSX.Element => (
34  <div key={`enum-definition-${name}`} css={[STYLES_APIBOX, enumContentStyles]}>
35    <APISectionDeprecationNote comment={comment} />
36    <APISectionPlatformTags comment={comment} prefix="Only for:" />
37    <H3Code tags={getTagNamesList(comment)}>
38      <CODE>{name}</CODE>
39    </H3Code>
40    <CommentTextBlock comment={comment} includePlatforms={false} />
41    {children.sort(sortByValue).map((enumValue: EnumValueData) => (
42      <div css={[STYLES_APIBOX, STYLES_APIBOX_NESTED]} key={enumValue.name}>
43        <APISectionPlatformTags comment={enumValue.comment} prefix="Only for:" />
44        <H4 css={enumValueNameStyle}>
45          <CODE>{enumValue.name}</CODE>
46        </H4>
47        <CODE css={enumValueStyles}>
48          {`${name}.${enumValue.name} = ${renderEnumValue(enumValue.type.value)}`}
49        </CODE>
50        <CommentTextBlock comment={enumValue.comment} includePlatforms={false} />
51      </div>
52    ))}
53  </div>
54);
55
56const APISectionEnums = ({ data }: APISectionEnumsProps) =>
57  data?.length ? (
58    <>
59      <H2 key="enums-header">Enums</H2>
60      {data.map(renderEnum)}
61    </>
62  ) : null;
63
64const enumValueNameStyle = css({
65  h4: {
66    marginTop: 0,
67  },
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[4],
76});
77
78const enumContentStyles = css({
79  paddingBottom: 0,
80});
81
82export default APISectionEnums;
83