"use client"; import { useState, useRef, useLayoutEffect, type ReactNode, useEffect } from "react"; import clsx from "clsx"; export function LyDropDown({ showDropDown, children, onClose }: { showDropDown: boolean; children: ReactNode; onClose: () => void; }) { const listRef = useRef(null); const rootRef = useRef(null); const [listPosition, setListPosition] = useState({ top: '0', transform: 'translate3d(0, 0%, 0)', }); useLayoutEffect(() => { if (listRef.current && rootRef.current && showDropDown) { const { height } = listRef.current.getBoundingClientRect(); // setListHeight(height); console.log('Measured tooltip height: ' + height); const triggerRect = rootRef.current.getBoundingClientRect(); if(triggerRect.bottom + height > window.innerHeight) { // 显示在上方 setListPosition({ top: '0', transform: 'translate3d(0, -100%, 0)', }); } else { // 显示在下方 setListPosition({ top: `${triggerRect.height}px`, transform: `translate3d(0, 0%, 0)` }); } } }, [showDropDown]); // 点击外部关闭 useEffect(() => { if (!showDropDown) return; function handleClickOutside(event: MouseEvent) { const target = event.target as Node; if ( rootRef.current && !rootRef.current.contains(target) ) { onClose(); } } // 放到 document 捕获阶段 document.addEventListener( "pointerdown", handleClickOutside, true ); return () => { document.removeEventListener( "pointerdown", handleClickOutside, true ); }; }, [showDropDown, onClose]); return ( <>
{ e.stopPropagation(); }} style={listPosition} > {children}
); }