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