diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 9aeff4bc..1dd04743 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -13,6 +13,7 @@ import Footer from '@/site/Footer'; import { Suspense } from 'react'; import FooterClient from '@/site/FooterClient'; import NavClient from '@/site/NavClient'; +import CommandK from '@/components/CommandK'; import '../site/globals.css'; @@ -97,6 +98,7 @@ export default function RootLayout({ + ); diff --git a/src/components/CommandK.tsx b/src/components/CommandK.tsx new file mode 100644 index 00000000..a42187f2 --- /dev/null +++ b/src/components/CommandK.tsx @@ -0,0 +1,54 @@ +'use client'; + +import { Command } from 'cmdk'; +import { useEffect, useState } from 'react'; +import Modal from './Modal'; +import { clsx } from 'clsx/lite'; + +const LISTENER_KEYDOWN = 'keydown'; + +export default function CommandK() { + const [open, setOpen] = useState(false); + + useEffect(() => { + const down = (e: KeyboardEvent) => { + if (e.key === 'k' && (e.metaKey || e.ctrlKey)) { + e.preventDefault(); + setOpen((open) => !open); + } + }; + document.addEventListener(LISTENER_KEYDOWN, down); + return () => document.removeEventListener(LISTENER_KEYDOWN, down); + }, []); + + const renderItem = (item: string) => + + {item} + ; + + return ( + + setOpen(false)} fast> + + + No results found. + + {renderItem('a')} + {renderItem('b')} + + {renderItem('c')} + + + {renderItem('Apple')} + + + + ); +} diff --git a/src/components/Modal.tsx b/src/components/Modal.tsx index 289789d5..7c879bd4 100644 --- a/src/components/Modal.tsx +++ b/src/components/Modal.tsx @@ -11,10 +11,14 @@ import usePrefersReducedMotion from '@/utility/usePrefersReducedMotion'; export default function Modal({ onClosePath, + onClose, children, + fast, }: { onClosePath?: string + onClose?: () => void children: ReactNode + fast?: boolean }) { const router = useRouter(); @@ -32,10 +36,16 @@ export default function Modal({ useClickInsideOutside({ htmlElements, - onClickOutside: () => router.push( - onClosePath ?? PATH_ROOT, - { scroll: false }, - ), + onClickOutside: () => { + if (onClose) { + onClose(); + } else { + router.push( + onClosePath ?? PATH_ROOT, + { scroll: false }, + ); + } + }, }); return ( @@ -51,7 +61,7 @@ export default function Modal({ transition={{ duration: 0.3, easing: 'easeOut' }} >