import { useRef, useEffect, useState, useCallback } from '@wordpress/element'; import SizeIcon from 'blockbite-icons/dist/Size'; import useMousePosition from './useMousePosition'; import { getNewDesignClasses, getMergedDesignList, } from '@components/DesignPanel/Helpers'; import { BiteStyleProps } from '@components/DesignPanel/types'; import has from 'lodash/has'; export type mousePositionProps = { x: number; y: number; }; export type AreaResizeProps = { currentResponsive: string; flexStyle: BiteStyleProps[]; setAttributes: (attributes: any) => void; }; export default function AreaBlock({ flexStyle, setAttributes, }: AreaResizeProps) { const ref = useRef(null); const resizeHandleRef = useRef(null); const [isResizing, setIsResizing] = useState(false); const [position, setPosition] = useState({ h: 100, // Start with a minimum height of 100px y: null, }); const [initialPosition, setInitialPosition] = useState({ y: null, h: 100, // Start with minimum height for reference }); const mousePosition = useMousePosition(); /* Initialize block position */ useEffect(() => { const { parentHeight } = getParentCoordinates(); // get the current height from the design list const currentBlock = flexStyle.find((style) => style.id === 'flexheight'); let currentHeight = 0; // if default set it as a flexStyle if (has(currentBlock, 'value')) { // parse number out of min-h-[640px] const height = currentBlock.value.match(/\d+/); currentHeight = height ? parseInt(height[0]) : 100; } else { currentHeight = 50; } if (currentHeight < parentHeight) { currentHeight = parentHeight; } update(currentHeight); setPosition({ h: currentHeight, y: 0, }); }, []); /* Update block height on mouse move if resizing */ useEffect(() => { if (isResizing) { handleResize(mousePosition); } }, [mousePosition.y]); const handleMouseUp = useCallback(() => { setIsResizing(false); }, []); useEffect(() => { if (isResizing) { document.addEventListener('mouseup', handleMouseUp); } else { document.removeEventListener('mouseup', handleMouseUp); } return () => { document.removeEventListener('mouseup', handleMouseUp); }; }, [isResizing, handleMouseUp]); const setHandleResize = useCallback( (e: React.MouseEvent) => { // Only handle left mouse button if (e.button !== 0) return; const { parentTop } = getParentCoordinates(); setInitialPosition({ y: mousePosition.y - parentTop, h: position.h, }); setIsResizing(true); }, [mousePosition.y] ); const handleResize = (mousePosition: mousePositionProps) => { const { parentTop } = getParentCoordinates(); // Only get parentTop for offset const mouseY = mousePosition.y - parentTop; // Calculate the new height, ensuring only a minimum of 100px const newHeight = Math.max( initialPosition.h + (mouseY - initialPosition.y), 100 ); setPosition((prev) => ({ ...prev, h: newHeight, })); update(newHeight); }; const getParentCoordinates = () => { return { parentHeight: ref.current?.parentElement?.offsetHeight || 0, parentTop: ref.current?.parentElement?.getBoundingClientRect().top || 0, }; }; const update = (newHeight: number) => { // only update the height in the design list for desktop const newList = [ { id: 'flexheight', value: `[${Math.round(newHeight)}px]`, screen: 'xl', }, ]; const newDesign = getMergedDesignList(newList, flexStyle); // Get the new class const newClass = getNewDesignClasses(newDesign); setAttributes({ flexStyle: newDesign, flexClass: newClass, }); }; return (
{/* Drag handle button positioned at the bottom center */}
); }