feat: add Reading Pane at Bottom mail layout #262
This commit is contained in:
@@ -8,38 +8,46 @@ interface ResizeHandleProps {
|
||||
onResize: (delta: number) => void;
|
||||
onResizeEnd?: () => void;
|
||||
onDoubleClick?: () => void;
|
||||
orientation?: "vertical" | "horizontal";
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const KEYBOARD_STEP = 10;
|
||||
|
||||
export function ResizeHandle({ onResizeStart, onResize, onResizeEnd, onDoubleClick, className }: ResizeHandleProps) {
|
||||
export function ResizeHandle({ onResizeStart, onResize, onResizeEnd, onDoubleClick, orientation = "vertical", className }: ResizeHandleProps) {
|
||||
const isDragging = useRef(false);
|
||||
const startX = useRef(0);
|
||||
const startPos = useRef(0);
|
||||
const isHorizontal = orientation === "horizontal";
|
||||
|
||||
const handleMouseDown = useCallback((e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
isDragging.current = true;
|
||||
startX.current = e.clientX;
|
||||
document.body.style.cursor = "col-resize";
|
||||
startPos.current = isHorizontal ? e.clientY : e.clientX;
|
||||
document.body.style.cursor = isHorizontal ? "row-resize" : "col-resize";
|
||||
document.body.style.userSelect = "none";
|
||||
onResizeStart?.();
|
||||
}, [onResizeStart]);
|
||||
}, [onResizeStart, isHorizontal]);
|
||||
|
||||
const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
|
||||
let delta = 0;
|
||||
if (e.key === "ArrowLeft") delta = -KEYBOARD_STEP;
|
||||
else if (e.key === "ArrowRight") delta = KEYBOARD_STEP;
|
||||
else return;
|
||||
if (isHorizontal) {
|
||||
if (e.key === "ArrowUp") delta = -KEYBOARD_STEP;
|
||||
else if (e.key === "ArrowDown") delta = KEYBOARD_STEP;
|
||||
else return;
|
||||
} else {
|
||||
if (e.key === "ArrowLeft") delta = -KEYBOARD_STEP;
|
||||
else if (e.key === "ArrowRight") delta = KEYBOARD_STEP;
|
||||
else return;
|
||||
}
|
||||
e.preventDefault();
|
||||
onResize(delta);
|
||||
onResizeEnd?.();
|
||||
}, [onResize, onResizeEnd]);
|
||||
}, [onResize, onResizeEnd, isHorizontal]);
|
||||
|
||||
useEffect(() => {
|
||||
const handleMouseMove = (e: MouseEvent) => {
|
||||
if (!isDragging.current) return;
|
||||
const delta = e.clientX - startX.current;
|
||||
const delta = (isHorizontal ? e.clientY : e.clientX) - startPos.current;
|
||||
onResize(delta);
|
||||
};
|
||||
|
||||
@@ -57,24 +65,25 @@ export function ResizeHandle({ onResizeStart, onResize, onResizeEnd, onDoubleCli
|
||||
document.removeEventListener("mousemove", handleMouseMove);
|
||||
document.removeEventListener("mouseup", handleMouseUp);
|
||||
};
|
||||
}, [onResize, onResizeEnd]);
|
||||
}, [onResize, onResizeEnd, isHorizontal]);
|
||||
|
||||
return (
|
||||
<div
|
||||
role="separator"
|
||||
aria-orientation="vertical"
|
||||
aria-orientation={isHorizontal ? "horizontal" : "vertical"}
|
||||
aria-label="Resize"
|
||||
tabIndex={0}
|
||||
onMouseDown={handleMouseDown}
|
||||
onKeyDown={handleKeyDown}
|
||||
onDoubleClick={onDoubleClick}
|
||||
className={cn(
|
||||
"w-1 flex-shrink-0 cursor-col-resize hover:bg-primary/30 active:bg-primary/50 transition-colors relative group",
|
||||
"flex-shrink-0 hover:bg-primary/30 active:bg-primary/50 transition-colors relative group",
|
||||
"focus-visible:outline-none focus-visible:bg-primary/40 focus-visible:ring-2 focus-visible:ring-primary/50",
|
||||
isHorizontal ? "h-1 cursor-row-resize bg-border" : "w-1 cursor-col-resize",
|
||||
className
|
||||
)}
|
||||
>
|
||||
<div className="absolute inset-y-0 -left-1 -right-1" />
|
||||
<div className={cn("absolute", isHorizontal ? "inset-x-0 -top-1 -bottom-1" : "inset-y-0 -left-1 -right-1")} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user