mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-04-09 18:53:38 +02:00
Sidebar filtering and improvements (#285)
This commit is contained in:
@@ -1,12 +1,22 @@
|
||||
import classNames from 'classnames';
|
||||
import type { CSSProperties, MouseEvent as ReactMouseEvent } from 'react';
|
||||
import React from 'react';
|
||||
import React, { useCallback, useRef, useState } from 'react';
|
||||
|
||||
interface ResizeBarProps {
|
||||
const START_DISTANCE = 7;
|
||||
|
||||
export interface ResizeHandleEvent {
|
||||
x: number;
|
||||
y: number;
|
||||
xStart: number;
|
||||
yStart: number;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
style?: CSSProperties;
|
||||
className?: string;
|
||||
isResizing: boolean;
|
||||
onResizeStart: (e: ReactMouseEvent<HTMLDivElement>) => void;
|
||||
onResizeStart?: () => void;
|
||||
onResizeEnd?: () => void;
|
||||
onResizeMove?: (e: ResizeHandleEvent) => void;
|
||||
onReset?: () => void;
|
||||
side: 'left' | 'right' | 'top';
|
||||
justify: 'center' | 'end' | 'start';
|
||||
@@ -17,17 +27,65 @@ export function ResizeHandle({
|
||||
justify,
|
||||
className,
|
||||
onResizeStart,
|
||||
onResizeEnd,
|
||||
onResizeMove,
|
||||
onReset,
|
||||
isResizing,
|
||||
side,
|
||||
}: ResizeBarProps) {
|
||||
}: Props) {
|
||||
const vertical = side === 'top';
|
||||
const [isResizing, setIsResizing] = useState<boolean>(false);
|
||||
const moveState = useRef<{
|
||||
move: (e: MouseEvent) => void;
|
||||
up: (e: MouseEvent) => void;
|
||||
calledStart: boolean;
|
||||
xStart: number;
|
||||
yStart: number;
|
||||
} | null>(null);
|
||||
|
||||
const handlePointerDown = useCallback(
|
||||
(e: ReactMouseEvent<HTMLDivElement>) => {
|
||||
function move(e: MouseEvent) {
|
||||
if (moveState.current == null) return;
|
||||
|
||||
const xDistance = moveState.current.xStart - e.clientX;
|
||||
const yDistance = moveState.current.yStart - e.clientY;
|
||||
const distance = Math.abs(vertical ? yDistance : xDistance);
|
||||
if (moveState.current.calledStart) {
|
||||
onResizeMove?.({
|
||||
x: e.clientX,
|
||||
y: e.clientY,
|
||||
xStart: moveState.current.xStart,
|
||||
yStart: moveState.current.yStart,
|
||||
});
|
||||
} else if (distance > START_DISTANCE) {
|
||||
onResizeStart?.();
|
||||
moveState.current.calledStart = true;
|
||||
setIsResizing(true);
|
||||
}
|
||||
}
|
||||
|
||||
function up() {
|
||||
setIsResizing(false);
|
||||
moveState.current = null;
|
||||
document.documentElement.removeEventListener('mousemove', move);
|
||||
document.documentElement.removeEventListener('mouseup', up);
|
||||
onResizeEnd?.();
|
||||
}
|
||||
|
||||
moveState.current = { calledStart: false, xStart: e.clientX, yStart: e.clientY, move, up };
|
||||
|
||||
document.documentElement.addEventListener('mousemove', move);
|
||||
document.documentElement.addEventListener('mouseup', up);
|
||||
},
|
||||
[moveState, onResizeEnd, onResizeMove, onResizeStart, vertical],
|
||||
);
|
||||
|
||||
return (
|
||||
<div
|
||||
aria-hidden
|
||||
style={style}
|
||||
onPointerDown={onResizeStart}
|
||||
onDoubleClick={onReset}
|
||||
onPointerDown={handlePointerDown}
|
||||
className={classNames(
|
||||
className,
|
||||
'group z-10 flex select-none transition-colors hover:bg-surface-active rounded-full',
|
||||
@@ -45,7 +103,8 @@ export function ResizeHandle({
|
||||
{isResizing && (
|
||||
<div
|
||||
className={classNames(
|
||||
'fixed -left-20 -right-20 -top-20 -bottom-20',
|
||||
// 'bg-[rgba(255,0,0,0.1)]', // For debugging
|
||||
'fixed -left-[100vw] -right-[100vw] -top-[100vh] -bottom-[100vh]',
|
||||
vertical && 'cursor-row-resize',
|
||||
!vertical && 'cursor-col-resize',
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user