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}
}