import { IconButton } from "@/components/ui/button"; import { cn } from "@/lib/utils"; import { createContext, useContext, useEffect, useMemo, useCallback, useState, useRef } from "react"; // 管理所有抽屉的层级顺序 export const DrawerLayerContext = createContext<{ openOrder: string[]; registerDrawer: (id: string) => void; unregisterDrawer: (id: string) => void; bringToFront: (id: string) => void; getZIndex: (id: string) => number; }>({ openOrder: [], registerDrawer: () => {}, unregisterDrawer: () => {}, bringToFront: () => {}, getZIndex: () => 0, }); export const DrawerLayerProvider = ({ children, baseZIndex = 10, }: { children: React.ReactNode; baseZIndex?: number; }) => { const [openOrder, setOpenOrder] = useState([]); const registerDrawer = useCallback((id: string) => { setOpenOrder((prev) => (prev.includes(id) ? prev : [...prev, id])); }, []); const unregisterDrawer = useCallback((id: string) => { setOpenOrder((prev) => prev.filter((item) => item !== id)); }, []); const bringToFront = useCallback((id: string) => { setOpenOrder((prev) => { // 如果该抽屉已经在最前面,则不需要更新 if (prev.length > 0 && prev[prev.length - 1] === id) { return prev; } const filtered = prev.filter((item) => item !== id); return [...filtered, id]; }); }, []); const getZIndex = useCallback((id: string) => { const index = openOrder.indexOf(id); if (index === -1) return baseZIndex; return baseZIndex + index; }, [openOrder, baseZIndex]); const value = useMemo( () => ({ openOrder, registerDrawer, unregisterDrawer, bringToFront, getZIndex }), [openOrder, registerDrawer, unregisterDrawer, bringToFront, getZIndex] ); return {children}; }; const InlineDrawerContext = createContext<{ id: string; open: boolean; onOpenChange: (open: boolean) => void; }>({ id: "", open: false, onOpenChange: () => {}, }); export const InlineDrawer = ({ id, open, onOpenChange, timestamp, children, }: { id: string; open: boolean; onOpenChange: (open: boolean) => void; timestamp?: number; children: React.ReactNode; }) => { const { registerDrawer, unregisterDrawer, bringToFront } = useContext(DrawerLayerContext); // 当抽屉打开时注册并置顶;当关闭或卸载时移除 // 监听 timestamp 变化,确保每次重新打开时都会置顶 useEffect(() => { if (open) { registerDrawer(id); bringToFront(id); } }, [open, timestamp, id, registerDrawer, bringToFront]); useEffect(() => { return () => { unregisterDrawer(id); }; }, [id, unregisterDrawer, open]); // 当抽屉关闭时不渲染任何内容 if (!open) { return null; } return ( {children} ); }; export const InlineDrawerContent = ({ children, className, }: { children: React.ReactNode; className?: string; }) => { const { id } = useContext(InlineDrawerContext); const { getZIndex, bringToFront } = useContext(DrawerLayerContext); const zIndex = getZIndex(id); return (
bringToFront(id)} > {children}
); }; export const InlineDrawerHeader = ({ children, }: { children: React.ReactNode; }) => { const { onOpenChange } = useContext(InlineDrawerContext); return (
onOpenChange(false)} />
{children}
); } export const InlineDrawerDescription = ({ children, className, }: { children: React.ReactNode; className?: string; }) => { return
{children}
; }; export const InlineDrawerFooter = ({ children, className, }: { children: React.ReactNode; className?: string; }) => { return
{children}
; };