1import { DocsLogo, PlanEnterpriseIcon, iconSize, theme } from '@expo/styleguide';
2import { Command } from 'cmdk';
3
4import type { AlgoliaItemType } from '../types';
5import { getContentHighlightHTML, getHighlightHTML, isEASPath, openLink } from '../utils';
6import { FootnoteSection } from './FootnoteSection';
7import { FootnoteArrowIcon, GuideIcon } from './icons';
8import { contentStyle, footnoteStyle, itemIconWrapperStyle, itemStyle } from './styles';
9
10import versions from '~/public/static/constants/versions.json';
11import { CALLOUT, FOOTNOTE } from '~/ui/components/Text';
12
13const { LATEST_VERSION } = versions;
14
15type Props = {
16  item: AlgoliaItemType;
17  onSelect?: () => void;
18};
19
20const isDev = process.env.NODE_ENV === 'development';
21
22const ItemIcon = ({ url }: { url: string }) => {
23  if (url.includes('/versions/')) {
24    return <DocsLogo width={iconSize.md} color={theme.icon.secondary} />;
25  } else if (isEASPath(url)) {
26    return <PlanEnterpriseIcon color={theme.icon.secondary} />;
27  }
28  return <GuideIcon />;
29};
30
31const getFootnotePrefix = (url: string) => {
32  if (url.includes('/versions/')) {
33    return 'API Reference';
34  } else if (isEASPath(url)) {
35    return 'Expo Application Services';
36  } else {
37    return 'Guides';
38  }
39};
40
41const ItemFootnotePrefix = ({ url, isNested = false }: { url: string; isNested?: boolean }) => {
42  return isNested ? (
43    <>
44      <span css={footnoteStyle}>{getFootnotePrefix(url)}</span>
45      <FootnoteArrowIcon />
46    </>
47  ) : (
48    <FOOTNOTE css={footnoteStyle}>{getFootnotePrefix(url)}</FOOTNOTE>
49  );
50};
51
52const transformUrl = (url: string) => {
53  if (url.includes(LATEST_VERSION)) {
54    url = url.replace(LATEST_VERSION, 'latest');
55  }
56  if (isDev) {
57    url = url.replace('https://docs.expo.dev/', 'http://localhost:3002/');
58  }
59  return url;
60};
61
62export const ExpoDocsItem = ({ item, onSelect }: Props) => {
63  const { lvl0, lvl2, lvl3, lvl4, lvl6 } = item.hierarchy;
64  return (
65    <Command.Item
66      value={`expodocs-${item.objectID}`}
67      onSelect={() => {
68        openLink(transformUrl(item.url));
69        onSelect && onSelect();
70      }}>
71      <div css={itemStyle}>
72        <div css={itemIconWrapperStyle}>
73          <ItemIcon url={item.url} />
74        </div>
75        <div>
76          {lvl6 && (
77            <>
78              <CALLOUT weight="medium" {...getHighlightHTML(item, 'lvl6')} />
79              <FOOTNOTE css={footnoteStyle}>
80                <ItemFootnotePrefix url={item.url} isNested />
81                <span {...getHighlightHTML(item, 'lvl0')} />
82                <FootnoteSection item={item} levelKey="lvl2" />
83                <FootnoteSection item={item} levelKey="lvl3" />
84                <FootnoteSection item={item} levelKey="lvl4" />
85              </FOOTNOTE>
86            </>
87          )}
88          {!lvl6 && lvl4 && (
89            <>
90              <CALLOUT weight="medium" {...getHighlightHTML(item, 'lvl4')} />
91              <FOOTNOTE css={footnoteStyle}>
92                <ItemFootnotePrefix url={item.url} isNested />
93                <span {...getHighlightHTML(item, 'lvl0')} />
94                <FootnoteSection item={item} levelKey="lvl2" />
95                <FootnoteSection item={item} levelKey="lvl3" />
96              </FOOTNOTE>
97            </>
98          )}
99          {!lvl6 && !lvl4 && lvl3 && (
100            <>
101              <CALLOUT weight="medium" {...getHighlightHTML(item, 'lvl3')} />
102              <FOOTNOTE css={footnoteStyle}>
103                <ItemFootnotePrefix url={item.url} isNested />
104                <span {...getHighlightHTML(item, 'lvl0')} />
105                <FootnoteSection item={item} levelKey="lvl2" />
106              </FOOTNOTE>
107            </>
108          )}
109          {!lvl6 && !lvl4 && !lvl3 && lvl2 && (
110            <>
111              <CALLOUT weight="medium" {...getHighlightHTML(item, 'lvl2')} />
112              <FOOTNOTE css={footnoteStyle}>
113                <ItemFootnotePrefix url={item.url} isNested />
114                <span {...getHighlightHTML(item, 'lvl0')} />
115              </FOOTNOTE>
116            </>
117          )}
118          {!lvl6 && !lvl4 && !lvl3 && !lvl2 && lvl0 && (
119            <>
120              <CALLOUT weight="medium" {...getHighlightHTML(item, 'lvl0')} />
121              <ItemFootnotePrefix url={item.url} />
122            </>
123          )}
124          <FOOTNOTE theme="secondary" {...getContentHighlightHTML(item)} css={contentStyle} />
125        </div>
126      </div>
127    </Command.Item>
128  );
129};
130