From 1fefebee330ff738f7fc186ab620df96b1a9e781 Mon Sep 17 00:00:00 2001 From: kitimark Date: Thu, 6 Apr 2023 18:28:49 +0700 Subject: [PATCH 1/2] feat: resize rect by arrow key --- src/App.tsx | 1 + src/useResizeHandle.ts | 59 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 6 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index e0946ad..8538c45 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -6,6 +6,7 @@ function App() { const container = React.useRef(null); const { dragging, getDragHandlers } = useResizeHandle(container, { minWidth: "100px", + keyboardAdjustSize: 5, }); return ( diff --git a/src/useResizeHandle.ts b/src/useResizeHandle.ts index ee9f48d..934b2c3 100644 --- a/src/useResizeHandle.ts +++ b/src/useResizeHandle.ts @@ -1,12 +1,20 @@ import React from "react"; +const MULTIPLY_SIZE = 10; +const FIX_ALT_SIZE = 1; + export default function useResizeHandle( target: React.MutableRefObject, - options?: { minWidth?: string; maxWidth?: string } + options?: { + minWidth?: string; + maxWidth?: string; + keyboardAdjustSize?: number; + } ) { - const { minWidth = "0px", maxWidth = "100%" } = options || {}; + const { minWidth = "0px", maxWidth = "100%", keyboardAdjustSize = 1 } = options || {}; const [dragging, setDragging] = React.useState(false); const [dragOffset, setDragOffset] = React.useState(0); + const [focusing, setFocusing] = React.useState(false); const isTouchEvent = ( event: MouseEvent | TouchEvent ): event is TouchEvent => { @@ -37,6 +45,13 @@ export default function useResizeHandle( setDragging(true); setDragOffset(rect.width - (clientX - rect.x)); }; + const resizeTargetRect = React.useCallback((newWidth: number) => { + if (target.current) { + target.current.style.width = `clamp(${minWidth}, ${Math.floor( + newWidth + )}px, ${maxWidth})`; + } + }, [minWidth, maxWidth, target]) React.useEffect(() => { function resizeObject(event: MouseEvent | TouchEvent) { if (event.cancelable) { @@ -47,9 +62,7 @@ export default function useResizeHandle( if (target.current && dragging && clientX) { const objectRect = target.current.getBoundingClientRect(); const newWidth = clientX - objectRect.left + dragOffset; - target.current.style.width = `clamp(${minWidth}, ${Math.floor( - newWidth - )}px, ${maxWidth})`; + resizeTargetRect(newWidth) } } function stopResize() { @@ -69,12 +82,46 @@ export default function useResizeHandle( }; } return () => {}; - }, [dragOffset, dragging, getClientX, maxWidth, minWidth, target]); + }, [dragOffset, dragging, getClientX, target]); + const handleFocusStart = () => { + setFocusing(true); + } + React.useEffect(() => { + function resizeObject(event: KeyboardEvent) { + if (!target.current) return; + const objectRect = target.current.getBoundingClientRect(); + let diffSize = event.altKey ? FIX_ALT_SIZE : keyboardAdjustSize; + if (event.shiftKey) { + diffSize = diffSize * MULTIPLY_SIZE; + } + if (event.key === 'ArrowLeft') { + const newWidth = objectRect.width - diffSize; + resizeTargetRect(newWidth) + } + if (event.key === 'ArrowRight') { + const newWidth = objectRect.width + diffSize; + resizeTargetRect(newWidth) + } + } + function stopFocus() { + setFocusing(false); + } + if (focusing) { + document.addEventListener("keydown", resizeObject); + document.addEventListener("focusout", stopFocus); + return () => { + document.removeEventListener("keydown", resizeObject); + document.removeEventListener("focusout", stopFocus); + }; + } + return () => {}; + }, [focusing, target]); return { dragging, getDragHandlers: () => ({ onTouchStart: handleStart, onMouseDown: handleStart, + onFocus: handleFocusStart, }), }; } From c1a23add3e7424d99fc97521e04067673209e405 Mon Sep 17 00:00:00 2001 From: kitimark Date: Thu, 6 Apr 2023 18:31:45 +0700 Subject: [PATCH 2/2] refactoring: change keyword --- src/useResizeHandle.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/useResizeHandle.ts b/src/useResizeHandle.ts index 934b2c3..8b1ef13 100644 --- a/src/useResizeHandle.ts +++ b/src/useResizeHandle.ts @@ -90,16 +90,16 @@ export default function useResizeHandle( function resizeObject(event: KeyboardEvent) { if (!target.current) return; const objectRect = target.current.getBoundingClientRect(); - let diffSize = event.altKey ? FIX_ALT_SIZE : keyboardAdjustSize; + let adjustSize = event.altKey ? FIX_ALT_SIZE : keyboardAdjustSize; if (event.shiftKey) { - diffSize = diffSize * MULTIPLY_SIZE; + adjustSize = adjustSize * MULTIPLY_SIZE; } if (event.key === 'ArrowLeft') { - const newWidth = objectRect.width - diffSize; + const newWidth = objectRect.width - adjustSize; resizeTargetRect(newWidth) } if (event.key === 'ArrowRight') { - const newWidth = objectRect.width + diffSize; + const newWidth = objectRect.width + adjustSize; resizeTargetRect(newWidth) } }