From 88d8cb75e038e4391c000e3648df5efbc215c6f4 Mon Sep 17 00:00:00 2001 From: Felipe Trost Date: Mon, 18 Dec 2023 18:09:38 +0100 Subject: [PATCH 1/2] feat: Resizable element supports relative css sizes --- .../components/ResizableElement.tsx | 25 ++++++++----- .../lib/css-units-helper.ts | 35 +++++++++++++++++++ 2 files changed, 51 insertions(+), 9 deletions(-) create mode 100644 src/management-system-v2/lib/css-units-helper.ts diff --git a/src/management-system-v2/components/ResizableElement.tsx b/src/management-system-v2/components/ResizableElement.tsx index 93f33d7ee..7387dfbb8 100644 --- a/src/management-system-v2/components/ResizableElement.tsx +++ b/src/management-system-v2/components/ResizableElement.tsx @@ -1,3 +1,6 @@ +'use client'; + +import { CssSize, cssSizeToPixel } from '@/lib/css-units-helper'; import React, { useState, useEffect, @@ -5,19 +8,17 @@ import React, { CSSProperties, forwardRef, useImperativeHandle, - Dispatch, - SetStateAction, } from 'react'; type ResizableElementProps = PropsWithChildren<{ initialWidth: number; - minWidth: number; - maxWidth: number; + minWidth: CssSize; + maxWidth: CssSize; onWidthChange?: (width: number) => void; style?: CSSProperties; }>; -export type ResizableElementRefType = Dispatch>; +export type ResizableElementRefType = (size: CssSize) => void; let isResizing = false; const ResizableElement = forwardRef( @@ -27,7 +28,7 @@ const ResizableElement = forwardRef setWidth); + useImperativeHandle(ref, () => (size: CssSize) => setWidth(cssSizeToPixel(size))); const onMouseDown = (e: React.MouseEvent) => { e.stopPropagation(); @@ -35,7 +36,7 @@ const ResizableElement = forwardRef { + const onMouseUp = () => { isResizing = false; }; @@ -43,7 +44,11 @@ const ResizableElement = forwardRef minWidth && offsetRight < maxWidth) { + const minPixels = cssSizeToPixel(minWidth); + const maxPixels = cssSizeToPixel(maxWidth); + console.log({ minPixels, maxPixels, offsetRight }); + + if (offsetRight > minPixels && offsetRight < maxPixels) { setWidth(offsetRight); if (onWidthChange) onWidthChange(width); } @@ -64,7 +69,9 @@ const ResizableElement = forwardRef
Date: Mon, 18 Dec 2023 19:06:14 +0100 Subject: [PATCH 2/2] feat: touch support for resizable element --- .../components/ResizableElement.tsx | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/management-system-v2/components/ResizableElement.tsx b/src/management-system-v2/components/ResizableElement.tsx index 7387dfbb8..26d82caa1 100644 --- a/src/management-system-v2/components/ResizableElement.tsx +++ b/src/management-system-v2/components/ResizableElement.tsx @@ -30,7 +30,7 @@ const ResizableElement = forwardRef (size: CssSize) => setWidth(cssSizeToPixel(size))); - const onMouseDown = (e: React.MouseEvent) => { + const onMouseDown = (e: { stopPropagation: () => void; preventDefault: () => void }) => { e.stopPropagation(); e.preventDefault(); isResizing = true; @@ -40,13 +40,12 @@ const ResizableElement = forwardRef { + const onUserMovement = (clientX: number) => { if (isResizing) { - let offsetRight = document.body.offsetWidth - (e.clientX - document.body.offsetLeft); + let offsetRight = document.body.offsetWidth - (clientX - document.body.offsetLeft); const minPixels = cssSizeToPixel(minWidth); const maxPixels = cssSizeToPixel(maxWidth); - console.log({ minPixels, maxPixels, offsetRight }); if (offsetRight > minPixels && offsetRight < maxPixels) { setWidth(offsetRight); @@ -56,11 +55,17 @@ const ResizableElement = forwardRef { + const onMouseMove = (e: MouseEvent) => onUserMovement(e.clientX); + const onTouchMove = (e: TouchEvent) => + onUserMovement(e.touches[e.touches.length - 1].clientX); + document.addEventListener('mousemove', onMouseMove); + document.addEventListener('touchmove', onTouchMove); document.addEventListener('mouseup', onMouseUp); return () => { document.removeEventListener('mousemove', onMouseMove); + document.removeEventListener('touchmove', onTouchMove); document.removeEventListener('mouseup', onMouseUp); }; }); @@ -93,6 +98,7 @@ const ResizableElement = forwardRef {children}