'use client' import { AlertTriangle, ArrowLeft } from 'lucide-react' import type { HTMLAttributes, MouseEvent, PropsWithChildren, ReactElement, ReactNode } from 'react' import { Children, cloneElement, forwardRef, isValidElement, useEffect, useMemo } from 'react' import { ErrorBoundary } from 'react-error-boundary' import { useBreakpoint } from 'common' import useDragToClose from 'common/hooks/useDragToClose' import { Button, Command_Shadcn_, Dialog, DialogContent, cn } from 'ui' import { useCurrentPage, usePageComponent, usePopPage } from './hooks/pagesHooks' import { useQuery, useSetQuery } from './hooks/queryHooks' import { useCommandMenuSize, useCommandMenuOpen, useSetCommandMenuOpen, useSetupCommandMenuTouchEvents, } from './hooks/viewHooks' function Breadcrumb({ className }: { className?: string }) { const currPage = useCurrentPage() const popPage = usePopPage() if (!currPage) return return ( {currPage.name} ) } const CommandWrapper = forwardRef< React.ElementRef, React.ComponentPropsWithoutRef >(({ children, className, ...props }, ref) => { return ( {children} ) }) CommandWrapper.displayName = Command_Shadcn_.displayName function CommandError({ resetErrorBoundary }: { resetErrorBoundary: () => void }) { return ( Sorry, looks like we're having some issues with the command menu! Please try again in a bit. Try again? ) } function PageSwitch({ children }: PropsWithChildren) { const PageComponent = usePageComponent() return PageComponent ? : {children} } function useTouchGestures({ toggleOpen }: { toggleOpen: () => void }) { const { ref, handleTouchStart, handleTouchMove, handleTouchEnd } = useDragToClose({ onClose: toggleOpen, }) const setupTouchHandlers = useSetupCommandMenuTouchEvents() const touchHandlers = useMemo( () => ({ handleTouchStart, handleTouchMove, handleTouchEnd }), [handleTouchStart, handleTouchMove, handleTouchEnd] ) useEffect(() => { setupTouchHandlers(touchHandlers) }, [touchHandlers]) return { ref } } function CommandMenuTrigger({ children }: PropsWithChildren) { const open = useCommandMenuOpen() const setOpen = useSetCommandMenuOpen() const childFromProps = Children.only(children) as ReactElement< { onClick?: (event: MouseEvent) => void onOpen?: (open: boolean) => void } & HTMLAttributes > if (!childFromProps || !isValidElement(childFromProps)) return null const handleOpen = () => { setOpen(!open) childFromProps.props.onOpen?.(!open) } const childWithClickHandler = cloneElement(childFromProps, { onClick: handleOpen, 'aria-haspopup': 'dialog', 'aria-expanded': open, 'aria-controls': 'command-menu-dialog-content', className: cn( 'h-10 px-4 py-2', 'inline-flex items-center justify-center', 'whitespace-nowrap', 'rounded-md border border-input bg-background', 'text-sm font-medium', 'hover:bg-accent hover:text-accent-foreground', 'ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2', 'disabled:pointer-events-none disabled:opacity-50', 'transition-colors', childFromProps.props.className ), }) return childWithClickHandler } interface CommandMenuProps extends PropsWithChildren { trigger?: ReactNode } function CommandMenu({ children, trigger }: CommandMenuProps) { const open = useCommandMenuOpen() const setOpen = useSetCommandMenuOpen() const isMobile = useBreakpoint('sm') const size = useCommandMenuSize() const page = useCurrentPage() const popPage = usePopPage() const query = useQuery() const setQuery = useSetQuery() const { ref: contentRef } = useTouchGestures({ toggleOpen: () => setOpen(!open) }) return ( {trigger} isMobile && e.preventDefault()} onInteractOutside={() => setOpen(false)} onEscapeKeyDown={(e) => { e.preventDefault() return query ? setQuery('') : page ? popPage() : setOpen(false) }} size={size} className={cn( 'relative flex flex-col my-0 mx-auto rounded-t-lg overflow-y-scroll', 'h-[85dvh] mt-[15vh] md:max-h-[500px] md:mt-0 left-0 bottom-0 md:bottom-auto', '!animate-in !slide-in-from-bottom-[85%] !duration-300', 'data-[state=closed]:!animate-out data-[state=closed]:!slide-out-to-bottom', // Remove defaults set from primitive component '!slide-in-from-left-[0%] :!slide-in-from-top-[0%]', // Remove defaults set from primitive component '!slide-out-to-left-[0%] !slide-out-to-top-[0%]', 'md:data-[state=open]:!slide-in-from-bottom-[0%] md:data-[state=closed]:!slide-out-to-bottom-[0%]', 'md:data-[state=open]:!zoom-in-95 md:data-[state=closed]:!zoom-out-95' )} dialogOverlayProps={{ className: cn('overflow-hidden flex data-closed:delay-100'), }} > {children} ) } export { Breadcrumb, CommandMenu, CommandMenuTrigger, CommandWrapper }
Sorry, looks like we're having some issues with the command menu!
Please try again in a bit.