68 lines
1.9 KiB
TypeScript
68 lines
1.9 KiB
TypeScript
|
|
/**
|
||
|
|
* ResizeHandle - Visual drag handle for resizable panels
|
||
|
|
*
|
||
|
|
* A thin vertical bar that can be dragged to resize panels.
|
||
|
|
* Shows visual feedback on hover and during drag.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { memo } from 'react';
|
||
|
|
|
||
|
|
interface ResizeHandleProps {
|
||
|
|
/** Mouse down handler to start dragging */
|
||
|
|
onMouseDown: (e: React.MouseEvent) => void;
|
||
|
|
/** Double click handler to reset size */
|
||
|
|
onDoubleClick?: () => void;
|
||
|
|
/** Whether panel is currently being dragged */
|
||
|
|
isDragging?: boolean;
|
||
|
|
/** Position of the handle ('left' or 'right' edge of the panel) */
|
||
|
|
position?: 'left' | 'right';
|
||
|
|
}
|
||
|
|
|
||
|
|
function ResizeHandleComponent({
|
||
|
|
onMouseDown,
|
||
|
|
onDoubleClick,
|
||
|
|
isDragging = false,
|
||
|
|
position = 'right',
|
||
|
|
}: ResizeHandleProps) {
|
||
|
|
return (
|
||
|
|
<div
|
||
|
|
className={`
|
||
|
|
absolute top-0 bottom-0 w-1 z-30
|
||
|
|
cursor-col-resize
|
||
|
|
transition-colors duration-150
|
||
|
|
${position === 'right' ? 'right-0' : 'left-0'}
|
||
|
|
${isDragging
|
||
|
|
? 'bg-primary-500'
|
||
|
|
: 'bg-transparent hover:bg-primary-500/50'
|
||
|
|
}
|
||
|
|
`}
|
||
|
|
onMouseDown={onMouseDown}
|
||
|
|
onDoubleClick={onDoubleClick}
|
||
|
|
title="Drag to resize, double-click to reset"
|
||
|
|
>
|
||
|
|
{/* Wider hit area for easier grabbing */}
|
||
|
|
<div
|
||
|
|
className={`
|
||
|
|
absolute top-0 bottom-0 w-3
|
||
|
|
${position === 'right' ? '-left-1' : '-right-1'}
|
||
|
|
`}
|
||
|
|
/>
|
||
|
|
|
||
|
|
{/* Visual indicator dots (shown on hover via CSS) */}
|
||
|
|
<div className={`
|
||
|
|
absolute top-1/2 -translate-y-1/2
|
||
|
|
${position === 'right' ? '-left-0.5' : '-right-0.5'}
|
||
|
|
flex flex-col gap-1 opacity-0 hover:opacity-100 transition-opacity
|
||
|
|
${isDragging ? 'opacity-100' : ''}
|
||
|
|
`}>
|
||
|
|
<div className="w-1 h-1 rounded-full bg-dark-400" />
|
||
|
|
<div className="w-1 h-1 rounded-full bg-dark-400" />
|
||
|
|
<div className="w-1 h-1 rounded-full bg-dark-400" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
export const ResizeHandle = memo(ResizeHandleComponent);
|
||
|
|
export default ResizeHandle;
|