1import { css } from '@emotion/react';
2import { Button, shadows, theme } from '@expo/styleguide';
3import { spacing } from '@expo/styleguide-base';
4import { SearchSmIcon } from '@expo/styleguide-icons';
5import { Dispatch, SetStateAction, useEffect, useState } from 'react';
6
7import { isAppleDevice } from './utils';
8
9import { CALLOUT, KBD } from '~/ui/components/Text';
10
11type Props = {
12  setOpen: Dispatch<SetStateAction<boolean>>;
13};
14
15export const CommandMenuTrigger = ({ setOpen }: Props) => {
16  const [isMac, setIsMac] = useState<boolean | null>(null);
17
18  useEffect(() => {
19    setIsMac(typeof navigator !== 'undefined' && isAppleDevice());
20  }, []);
21
22  useEffect(() => {
23    if (isMac !== null) {
24      const keyDownListener = (e: KeyboardEvent) => {
25        if (e.key === 'k' && (isMac ? e.metaKey : e.ctrlKey)) {
26          e.preventDefault();
27          setOpen(open => !open);
28        }
29      };
30      document.addEventListener('keydown', keyDownListener, false);
31      return () => document.removeEventListener('keydown', keyDownListener);
32    }
33  }, [isMac]);
34
35  return (
36    <Button theme="secondary" css={buttonStyle} onClick={() => setOpen(true)}>
37      <SearchSmIcon />
38      <CALLOUT theme="secondary" crawlable={false}>
39        Search
40      </CALLOUT>
41      {isMac !== null && (
42        <div className="ml-auto max-lg-gutters:hidden">
43          <KBD>{isMac ? '⌘' : 'Ctrl'}</KBD> <KBD>K</KBD>
44        </div>
45      )}
46    </Button>
47  );
48};
49
50const buttonStyle = css({
51  backgroundColor: theme.background.default,
52  padding: `0 ${spacing[3]}px 0 ${spacing[2.5]}px`,
53  borderColor: theme.border.default,
54  boxShadow: shadows.xs,
55  marginBottom: spacing[2.5],
56  minHeight: spacing[10],
57  display: 'flex',
58
59  '&:focus': {
60    boxShadow: shadows.xs,
61  },
62
63  '> span': {
64    width: '100%',
65    gap: spacing[2],
66    alignItems: 'center',
67  },
68
69  kbd: {
70    height: 20,
71    lineHeight: '19px',
72  },
73});
74