import { createContext, type ReactNode, useContext, useEffect, useState, } from 'react'; import {useId} from 'react'; type AsideType = 'search' | 'cart' | 'mobile' | 'closed'; type AsideContextValue = { type: AsideType; open: (mode: AsideType) => void; close: () => void; }; /** * A side bar component with Overlay * @example * ```jsx * * ``` */ export function Aside({ children, heading, type, }: { children?: React.ReactNode; type: AsideType; heading: React.ReactNode; }) { const {type: activeType, close} = useAside(); const expanded = type === activeType; const id = useId(); useEffect(() => { const abortController = new AbortController(); if (expanded) { document.addEventListener( 'keydown', function handler(event: KeyboardEvent) { if (event.key === 'Escape') { close(); } }, {signal: abortController.signal}, ); } return () => abortController.abort(); }, [close, expanded]); return (
{children}
); } const AsideContext = createContext(null); Aside.Provider = function AsideProvider({children}: {children: ReactNode}) { const [type, setType] = useState('closed'); return ( setType('closed'), }} > {children} ); }; export function useAside() { const aside = useContext(AsideContext); if (!aside) { throw new Error('useAside must be used within an AsideProvider'); } return aside; }