/* Copyright 2026 Marimo. All rights reserved. */ import { act, render, renderHook } from "@testing-library/react"; import { describe, expect, it, vi } from "vitest"; import { useResizeHandle } from "../useResizeHandle"; describe("useResizeHandle", () => { it("should initialize with correct refs and style", () => { const { result } = renderHook(() => useResizeHandle({ startingWidth: 500, onResize: vi.fn(), }), ); expect(result.current.resizableDivRef.current).toBeNull(); expect(result.current.handleRefs.left.current).toBeNull(); expect(result.current.handleRefs.right.current).toBeNull(); expect(result.current.style).toEqual({ width: "500px" }); }); it("should handle contentWidth starting width", () => { const { result } = renderHook(() => useResizeHandle({ startingWidth: "contentWidth", onResize: vi.fn(), }), ); // Defaults to medium width expect(result.current.style).toEqual({ width: "var(--content-width-medium)", }); }); it("should call onResize when resizing", () => { const onResize = vi.fn(); // Create a test component that uses the hook const TestComponent = () => { const { resizableDivRef, handleRefs } = useResizeHandle({ startingWidth: 500, onResize, }); return (
); }; const { getByTestId } = render(); const resizableDiv = getByTestId("resizable-div") as HTMLDivElement; const rightHandle = getByTestId("right-handle") as HTMLDivElement; // Simulate resize act(() => { const mousedownEvent = new MouseEvent("mousedown", { clientX: 0 }); rightHandle.dispatchEvent(mousedownEvent); const mousemoveEvent = new MouseEvent("mousemove", { clientX: 100 }); document.dispatchEvent(mousemoveEvent); const mouseupEvent = new MouseEvent("mouseup"); document.dispatchEvent(mouseupEvent); }); expect(resizableDiv.style.width).toBe("600px"); // 500px + 100px movement expect(onResize).toHaveBeenCalledWith(600); // Resize left handle const leftHandle = getByTestId("left-handle") as HTMLDivElement; // Simulate resize act(() => { const mousedownEvent = new MouseEvent("mousedown", { clientX: 0 }); leftHandle.dispatchEvent(mousedownEvent); const mousemoveEvent = new MouseEvent("mousemove", { clientX: -100 }); document.dispatchEvent(mousemoveEvent); const mouseupEvent = new MouseEvent("mouseup"); document.dispatchEvent(mouseupEvent); }); expect(resizableDiv.style.width).toBe("700px"); // 600px - (-100px) movement expect(onResize).toHaveBeenCalledWith(700); }); it("should handle resizing with only left handle", () => { const onResize = vi.fn(); // Create a test component that uses the hook const TestComponent = () => { const { resizableDivRef, handleRefs } = useResizeHandle({ startingWidth: 500, onResize, }); return (
); }; const { getByTestId } = render(); const resizableDiv = getByTestId("resizable-div") as HTMLDivElement; const leftHandle = getByTestId("left-handle") as HTMLDivElement; // Simulate resize act(() => { const mousedownEvent = new MouseEvent("mousedown", { clientX: 0 }); leftHandle.dispatchEvent(mousedownEvent); const mousemoveEvent = new MouseEvent("mousemove", { clientX: -100 }); document.dispatchEvent(mousemoveEvent); const mouseupEvent = new MouseEvent("mouseup"); document.dispatchEvent(mouseupEvent); }); expect(resizableDiv.style.width).toBe("600px"); // 500px - (-100px) movement expect(onResize).toHaveBeenCalledWith(600); }); it("should handle resizing with only right handle", () => { const onResize = vi.fn(); // Create a test component that uses the hook const TestComponent = () => { const { resizableDivRef, handleRefs } = useResizeHandle({ startingWidth: 500, onResize, }); return (
); }; const { getByTestId } = render(); const resizableDiv = getByTestId("resizable-div") as HTMLDivElement; const rightHandle = getByTestId("right-handle") as HTMLDivElement; // Simulate resize act(() => { const mousedownEvent = new MouseEvent("mousedown", { clientX: 0 }); rightHandle.dispatchEvent(mousedownEvent); const mousemoveEvent = new MouseEvent("mousemove", { clientX: 100 }); document.dispatchEvent(mousemoveEvent); const mouseupEvent = new MouseEvent("mouseup"); document.dispatchEvent(mouseupEvent); }); expect(resizableDiv.style.width).toBe("600px"); // 500px + 100px movement expect(onResize).toHaveBeenCalledWith(600); }); it("should handle min and max width", () => { const onResize = vi.fn(); // Create a test component that uses the hook const TestComponent = () => { const { resizableDivRef, handleRefs } = useResizeHandle({ startingWidth: 500, minWidth: 400, maxWidth: 600, onResize, }); return (
); }; const { getByTestId } = render(); const resizableDiv = getByTestId("resizable-div") as HTMLDivElement; const rightHandle = getByTestId("right-handle") as HTMLDivElement; // Test min width act(() => { const mousedownEvent = new MouseEvent("mousedown", { clientX: 0 }); rightHandle.dispatchEvent(mousedownEvent); const mousemoveEvent = new MouseEvent("mousemove", { clientX: -200 }); // Try to resize below min document.dispatchEvent(mousemoveEvent); const mouseupEvent = new MouseEvent("mouseup"); document.dispatchEvent(mouseupEvent); }); expect(resizableDiv.style.width).toBe("400px"); // Should be clamped to min width expect(onResize).toHaveBeenCalledWith(400); // Test max width act(() => { const mousedownEvent = new MouseEvent("mousedown", { clientX: 0 }); rightHandle.dispatchEvent(mousedownEvent); const mousemoveEvent = new MouseEvent("mousemove", { clientX: 200 }); // Try to resize above max document.dispatchEvent(mousemoveEvent); const mouseupEvent = new MouseEvent("mouseup"); document.dispatchEvent(mouseupEvent); }); expect(resizableDiv.style.width).toBe("600px"); // Should be clamped to max width expect(onResize).toHaveBeenCalledWith(600); }); });