spb/company-atlas
Public
Python 66.3%
TypeScript 22.7%
JavaScript 8.6%
HTML 1.4%
CSS 0.7%
1'use client';2import { createContext, type ReactNode, useCallback, useContext, useEffect, useMemo, useState } from 'react';34const Ctx = createContext<{ open: boolean; setOpen: (v: boolean) => void }>({ open: false, setOpen: () => undefined });56/** Global ⌘K / "/" search dialog state. */7export function SearchProvider({ children }: { children: ReactNode }) {8 const [open, setOpen] = useState(false);9 useEffect(() => {10 const onKey = (e: KeyboardEvent) => {11 const target = e.target as HTMLElement | null;12 const typing = target && (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.tagName === 'SELECT' || target.isContentEditable);13 if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') {14 e.preventDefault();15 setOpen((o) => !o);16 } else if (e.key === '/' && !typing && !e.metaKey && !e.ctrlKey) {17 e.preventDefault();18 setOpen(true);19 }20 };21 window.addEventListener('keydown', onKey);22 return () => window.removeEventListener('keydown', onKey);23 }, []);24 const value = useMemo(() => ({ open, setOpen }), [open]);25 return <Ctx.Provider value={value}>{children}</Ctx.Provider>;26}2728export function useSearch() {29 return useContext(Ctx);30}31export function useOpenSearch() {32 const { setOpen } = useContext(Ctx);33 return useCallback(() => setOpen(true), [setOpen]);34}35