1import { mergeClasses } from '@expo/styleguide'; 2import { Command } from 'cmdk'; 3import { PropsWithChildren, useState } from 'react'; 4 5import { openLink } from '../utils'; 6 7import { Tag } from '~/ui/components/Tag'; 8 9type Props = PropsWithChildren<{ 10 url: string; 11 onSelect?: () => void; 12 isExternalLink?: boolean; 13 isNested?: boolean; 14 // Props forwarded to Command.Item 15 className?: string; 16 value?: string; 17}>; 18 19/** 20 * Wrapper for Command.Item that adds copy link on right/ middle click + visual copy indicator. 21 */ 22export const CommandItemBase = ({ 23 children, 24 url, 25 isExternalLink, 26 isNested, 27 onSelect, 28 className, 29 value, 30}: Props) => { 31 const [copyDone, setCopyDone] = useState(false); 32 33 const copyUrl = () => { 34 navigator.clipboard?.writeText(url); 35 setCopyDone(true); 36 setTimeout(() => setCopyDone(false), 1500); 37 }; 38 39 return ( 40 <Command.Item 41 className={mergeClasses('relative', className)} 42 value={value} 43 data-nested={isNested ? true : undefined} 44 onMouseUp={event => { 45 // note(Keith): middle click (typical *nix copy shortcut) 46 // right click (works with Mac trackpads) 47 // onAuxClick is not supported in Safari 48 if (event.button === 1 || event.button === 2) { 49 copyUrl(); 50 } 51 }} 52 onSelect={() => { 53 openLink(url, isExternalLink); 54 onSelect && onSelect(); 55 }} 56 onContextMenu={event => { 57 event.preventDefault(); 58 }}> 59 {children} 60 {copyDone && ( 61 <Tag 62 name="Copied!" 63 className="absolute right-2.5 top-[calc(50%-13px)] !m-0 !border-secondary !bg-default" 64 /> 65 )} 66 </Command.Item> 67 ); 68}; 69