From 6caebde908c14d7af694ffa3735a55011adae8db Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Sat, 23 Aug 2025 11:10:06 +0330 Subject: [PATCH] row action add props top and left --- src/components/RowActionsDropdown.tsx | 75 ++++++++++++++++++--------- src/shared/Header.tsx | 5 ++ 2 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/components/RowActionsDropdown.tsx b/src/components/RowActionsDropdown.tsx index f4d253e..2a672c2 100644 --- a/src/components/RowActionsDropdown.tsx +++ b/src/components/RowActionsDropdown.tsx @@ -14,11 +14,23 @@ interface RowActionsDropdownProps { actions: RowActionItem[]; className?: string; trigger?: React.ReactNode; + topOffset?: number; + leftOffset?: number; + topOffsetMobile?: number; + leftOffsetMobile?: number; } -const RowActionsDropdown: React.FC = ({ actions, className = '', trigger }) => { +const RowActionsDropdown: React.FC = ({ + actions, + className = '', + trigger, + topOffset = 0, + leftOffset = 0, + topOffsetMobile = 0, + leftOffsetMobile = 0 +}) => { const [isOpen, setIsOpen] = useState(false) - const [position, setPosition] = useState({ top: 0, left: 0 }) + const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0 }) const dropdownRef = useRef(null) const buttonRef = useRef(null) @@ -35,31 +47,46 @@ const RowActionsDropdown: React.FC = ({ actions, classN } }, []) + const calculatePosition = (rect: DOMRect) => { + const isMobile = window.innerWidth < 768 + const dropdownWidth = isMobile ? 140 : 150 + const dropdownHeight = actions.length * (isMobile ? 36 : 40) + + // انتخاب offset بر اساس سایز صفحه + const currentTopOffset = isMobile ? topOffsetMobile : topOffset + const currentLeftOffset = isMobile ? leftOffsetMobile : leftOffset + + let left = rect.left + window.scrollX - dropdownWidth + rect.width + currentLeftOffset + let top = rect.bottom + window.scrollY + currentTopOffset + + if (left + dropdownWidth > window.innerWidth) { + left = rect.left + window.scrollX - dropdownWidth + currentLeftOffset + } + + if (left < 0) { + left = isMobile ? 20 : 40 + } + + if (top + dropdownHeight > window.innerHeight + window.scrollY) { + top = rect.top + window.scrollY - dropdownHeight + currentTopOffset + } + + // اطمینان از اینکه dropdown از صفحه خارج نشود + if (left < 0) left = 20 + if (left + dropdownWidth > window.innerWidth) left = window.innerWidth - dropdownWidth - 20 + if (top < 0) top = 20 + if (top + dropdownHeight > window.innerHeight) top = window.innerHeight - dropdownHeight - 20 + + return { top, left } + } + const handleToggle = (e: React.MouseEvent) => { e.stopPropagation() if (!isOpen && buttonRef.current) { const rect = buttonRef.current.getBoundingClientRect() - const isMobile = window.innerWidth < 768 - const dropdownWidth = isMobile ? 140 : 150 - const dropdownHeight = actions.length * (isMobile ? 36 : 40) - - let left = rect.left + window.scrollX - dropdownWidth + rect.width - let top = rect.bottom + window.scrollY - - if (left + dropdownWidth > window.innerWidth) { - left = rect.left + window.scrollX - dropdownWidth - } - - if (left < 0) { - left = isMobile ? 20 : 40 - } - - if (top + dropdownHeight > window.innerHeight + window.scrollY) { - top = rect.top + window.scrollY - dropdownHeight - } - - setPosition({ top, left }) + const calculatedPosition = calculatePosition(rect) + setDropdownPosition(calculatedPosition) } setIsOpen(!isOpen) @@ -78,8 +105,8 @@ const RowActionsDropdown: React.FC = ({ actions, classN ref={dropdownRef} className="fixed py-3 md:py-3 bg-white dark:bg-[#252526] rounded-xl md:rounded-2xl shadow-lg z-[5] min-w-[140px] md:min-w-[150px] border border-gray-200 dark:border-[#3e3e42]" style={{ - top: `${position.top}px`, - left: `${position.left}px`, + top: `${dropdownPosition.top}px`, + left: `${dropdownPosition.left}px`, }} > {actions.map((action, index) => ( diff --git a/src/shared/Header.tsx b/src/shared/Header.tsx index e961cf2..61e2284 100644 --- a/src/shared/Header.tsx +++ b/src/shared/Header.tsx @@ -285,6 +285,11 @@ const Header: FC = () => { }, ]} trigger={} + topOffset={20} + leftOffset={70} + topOffsetMobile={10} + leftOffsetMobile={60} + />