Minor UI, fix dragging to select
This commit is contained in:
@@ -11,6 +11,32 @@ import clsx from 'clsx';
|
||||
import { ConfirmModal } from '../components/ConfirmModal';
|
||||
import { importDrawings, importLibrary } from '../utils/importUtils';
|
||||
|
||||
type Point = { x: number; y: number };
|
||||
|
||||
type SelectionBounds = {
|
||||
left: number;
|
||||
top: number;
|
||||
right: number;
|
||||
bottom: number;
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
|
||||
const getSelectionBounds = (start: Point, current: Point): SelectionBounds => {
|
||||
const left = Math.min(start.x, current.x);
|
||||
const right = Math.max(start.x, current.x);
|
||||
const top = Math.min(start.y, current.y);
|
||||
const bottom = Math.max(start.y, current.y);
|
||||
return {
|
||||
left,
|
||||
top,
|
||||
right,
|
||||
bottom,
|
||||
width: right - left,
|
||||
height: bottom - top,
|
||||
};
|
||||
};
|
||||
|
||||
const DragOverlayPortal: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||
return createPortal(children, document.body);
|
||||
};
|
||||
@@ -55,8 +81,8 @@ export const Dashboard: React.FC = () => {
|
||||
|
||||
// Drag Selection State
|
||||
const [isDragSelecting, setIsDragSelecting] = useState(false);
|
||||
const [dragStart, setDragStart] = useState<{ x: number; y: number } | null>(null);
|
||||
const [dragCurrent, setDragCurrent] = useState<{ x: number; y: number } | null>(null);
|
||||
const [dragStart, setDragStart] = useState<Point | null>(null);
|
||||
const [dragCurrent, setDragCurrent] = useState<Point | null>(null);
|
||||
const [potentialDragId, setPotentialDragId] = useState<string | null>(null);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
@@ -123,6 +149,11 @@ export const Dashboard: React.FC = () => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
const selectionBounds = React.useMemo<SelectionBounds | null>(() => {
|
||||
if (!dragStart || !dragCurrent) return null;
|
||||
return getSelectionBounds(dragStart, dragCurrent);
|
||||
}, [dragStart, dragCurrent]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isDragSelecting) return;
|
||||
|
||||
@@ -138,14 +169,9 @@ export const Dashboard: React.FC = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate selection rect
|
||||
const left = Math.min(dragStart.x, dragCurrent.x);
|
||||
const top = Math.min(dragStart.y, dragCurrent.y);
|
||||
const width = Math.abs(dragCurrent.x - dragStart.x);
|
||||
const height = Math.abs(dragCurrent.y - dragStart.y);
|
||||
const selectionRect = { left, top, right: left + width, bottom: top + height };
|
||||
const selectionRect = getSelectionBounds(dragStart, dragCurrent);
|
||||
|
||||
if (width > 5 || height > 5) {
|
||||
if (selectionRect.width > 5 || selectionRect.height > 5) {
|
||||
const newSelectedIds = new Set(selectedIds);
|
||||
drawings.forEach(drawing => {
|
||||
const card = document.getElementById(`drawing-card-${drawing.id}`);
|
||||
@@ -636,15 +662,15 @@ export const Dashboard: React.FC = () => {
|
||||
</div>
|
||||
|
||||
{/* Drag Selection Overlay */}
|
||||
{isDragSelecting && dragStart && dragCurrent && (
|
||||
{isDragSelecting && selectionBounds && (
|
||||
<DragOverlayPortal>
|
||||
<div
|
||||
className="fixed z-50 pointer-events-none border-2 border-black dark:border-neutral-500 bg-neutral-500/20 shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] dark:shadow-[2px_2px_0px_0px_rgba(255,255,255,0.2)]"
|
||||
style={{
|
||||
left: Math.min(dragStart.x, dragCurrent.x),
|
||||
top: Math.min(dragStart.y, dragCurrent.y),
|
||||
width: Math.abs(dragCurrent.x - dragStart.x),
|
||||
height: Math.abs(dragCurrent.y - dragStart.y),
|
||||
left: selectionBounds.left,
|
||||
top: selectionBounds.top,
|
||||
width: selectionBounds.width,
|
||||
height: selectionBounds.height,
|
||||
}}
|
||||
/>
|
||||
</DragOverlayPortal>
|
||||
|
||||
Reference in New Issue
Block a user