import React, { useState, useRef, useCallback } from 'react'; export type DrawerId = string | number; export interface UseDrawerReturn { open: (id: DrawerId) => void; close: () => void; currentOpen: DrawerId | null; registerDrawer: ( id: DrawerId, options?: { upRelative?: string; direction?: string; } ) => { open: boolean; id: string; ref?: React.RefObject; }; registerAction: ( id: DrawerId, type: 'open' | 'close' ) => { onClick: () => void; ref?: React.RefObject; }; } export const useDrawer = (): UseDrawerReturn => { const [currentOpen, setCurrentOpen] = useState(null); const drawersRef = useRef< Map> >(new Map()); const buttonsRef = useRef< Map> >(new Map()); const open = useCallback((id: DrawerId) => { setCurrentOpen(id); }, []); const close = useCallback(() => { setCurrentOpen(null); }, []); const registerDrawer = useCallback( (id, options) => { const drawerId = `drawer-${id}`; if (!drawersRef.current.get(id)?.current) { drawersRef.current.set(id, React.createRef()); } return { open: currentOpen === id, id: drawerId, ref: drawersRef.current.get(id as string), ...options, }; }, [currentOpen] ); const registerAction = useCallback( (id: DrawerId, type: 'open' | 'close') => { if (!buttonsRef.current.has(id)) { buttonsRef.current.set(id, React.createRef()); } return { onClick: () => (type === 'open' ? open(id) : close()), ref: buttonsRef.current.get(id), }; }, [currentOpen] ); return { open, close, currentOpen, registerAction, registerDrawer, }; };