chore: extract useResizeHandler

This commit is contained in:
EnixCoda 2022-03-27 23:43:02 +08:00
parent 9b86021a0f
commit edc8d32aac
3 changed files with 68 additions and 63 deletions

View file

@ -1,5 +1,6 @@
import { Icon } from 'components/Icon'
import * as React from 'react'
import { ResizeState, useResizeHandler } from '../utils/hooks/useResizeHandler'
import { Size2D } from './SideBarBodyWrapper'
type Props = {
@ -10,8 +11,6 @@ type Props = {
style?: React.CSSProperties
}
type ResizeState = 'idle' | 'resizing'
export function ResizeHandler({ onResize, onResetSize, onResizeStateChange, size, style }: Props) {
const { onPointerDown } = useResizeHandler(size, onResize, { onResizeStateChange })
@ -26,63 +25,3 @@ export function ResizeHandler({ onResize, onResetSize, onResizeStateChange, size
</div>
)
}
export function useResizeHandler(
size: Size2D,
onResize: (size: Size2D) => void,
{
onResizeStateChange,
onClick,
}: Partial<{
onResizeStateChange: (state: ResizeState) => void
onClick: (e: PointerEvent) => void
}> = {},
) {
const pointerDown = React.useRef(false)
const pointerMoved = React.useRef(false)
const initialSizeRef = React.useRef([0, 0])
const baseSize = React.useRef(size)
const latestPropSize = React.useRef(size)
React.useEffect(() => {
latestPropSize.current = size
}, [size])
React.useEffect(() => {
const onPointerMove = ({ clientX, clientY }: PointerEvent) => {
if (!pointerDown.current) return
pointerMoved.current = true
const [x, y] = baseSize.current
onResize([x + clientX - initialSizeRef.current[0], y + clientY - initialSizeRef.current[1]])
}
window.addEventListener('pointermove', onPointerMove)
return () => window.removeEventListener('pointermove', onPointerMove)
}, [onResize])
React.useEffect(() => {
const onPointerUp = (e: PointerEvent) => {
if (pointerDown.current) {
pointerDown.current = false
if (!pointerMoved.current) onClick?.(e)
pointerMoved.current = false
baseSize.current = latestPropSize.current
onResizeStateChange?.('idle')
}
}
window.addEventListener('pointerup', onPointerUp)
return () => window.removeEventListener('pointerup', onPointerUp)
}, [])
const onPointerDown = React.useCallback((e: React.PointerEvent) => {
e.preventDefault() // Prevent unexpected selection when dragging in Safari
const { clientX, clientY } = e
pointerDown.current = true
initialSizeRef.current = [clientX, clientY]
baseSize.current = latestPropSize.current
onResizeStateChange?.('resizing')
}, [])
return { onPointerDown }
}

View file

@ -3,8 +3,8 @@ import { useConfigs } from 'containers/ConfigsContext'
import * as React from 'react'
import { useDebounce, useWindowSize } from 'react-use'
import { cx } from 'utils/cx'
import { useResizeHandler } from 'utils/hooks/useResizeHandler'
import { Icon } from './Icon'
import { useResizeHandler } from './ResizeHandler'
type Props = {
error?: string | null

View file

@ -0,0 +1,66 @@
import * as React from 'react';
import { Size2D } from '../../components/SideBarBodyWrapper';
export type ResizeState = 'idle' | 'resizing';
export function useResizeHandler(
size: Size2D,
onResize: (size: Size2D) => void,
{
onResizeStateChange,
onClick,
}: Partial<{
onResizeStateChange: (state: ResizeState) => void;
onClick: (e: PointerEvent) => void;
}> = {}
) {
const pointerDown = React.useRef(false);
const pointerMoved = React.useRef(false);
const initialSizeRef = React.useRef([0, 0]);
const baseSize = React.useRef(size);
const latestPropSize = React.useRef(size);
React.useEffect(() => {
latestPropSize.current = size;
}, [size]);
React.useEffect(() => {
const onPointerMove = ({ clientX, clientY }: PointerEvent) => {
if (!pointerDown.current)
return;
pointerMoved.current = true;
const [x, y] = baseSize.current;
onResize([x + clientX - initialSizeRef.current[0], y + clientY - initialSizeRef.current[1]]);
};
window.addEventListener('pointermove', onPointerMove);
return () => window.removeEventListener('pointermove', onPointerMove);
}, [onResize]);
React.useEffect(() => {
const onPointerUp = (e: PointerEvent) => {
if (pointerDown.current) {
pointerDown.current = false;
if (!pointerMoved.current)
onClick?.(e);
pointerMoved.current = false;
baseSize.current = latestPropSize.current;
onResizeStateChange?.('idle');
}
};
window.addEventListener('pointerup', onPointerUp);
return () => window.removeEventListener('pointerup', onPointerUp);
}, []);
const onPointerDown = React.useCallback((e: React.PointerEvent) => {
e.preventDefault(); // Prevent unexpected selection when dragging in Safari
const { clientX, clientY } = e;
pointerDown.current = true;
initialSizeRef.current = [clientX, clientY];
baseSize.current = latestPropSize.current;
onResizeStateChange?.('resizing');
}, []);
return { onPointerDown };
}