Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | import type { PointerEvent, ReactNode, RefObject } from "react";
import { ResizeHandles } from "@/components/CanvasComponent/resizeHandles";
import type { ResizeHandle } from "@/lib/geometry";
import type { CanvasComponent as CanvasComponentModel } from "@/types/canvas";
interface CanvasComponentViewProps {
rootRef: RefObject<HTMLDivElement | null>;
component: CanvasComponentModel;
isSelected: boolean;
isDragging: boolean;
isResizing: boolean;
preview: ReactNode;
onMovePointerDown: (event: PointerEvent<HTMLDivElement>) => boolean;
onPointerMove: (event: PointerEvent<HTMLDivElement>) => void;
onPointerFinish: (event: PointerEvent<HTMLDivElement>) => boolean;
onResizeHandlePointerDown: (
event: PointerEvent<HTMLButtonElement>,
handle: ResizeHandle,
) => boolean;
onSelect: (id: string) => void;
children?: ReactNode;
}
export function CanvasComponentView({
rootRef,
component,
isSelected,
isDragging,
isResizing,
preview,
onMovePointerDown,
onPointerMove,
onPointerFinish,
onResizeHandlePointerDown,
onSelect,
children,
}: CanvasComponentViewProps) {
const capturePointer = (pointerId: number) => {
rootRef.current?.setPointerCapture(pointerId);
};
const releasePointer = (pointerId: number) => {
if (rootRef.current?.hasPointerCapture(pointerId)) {
rootRef.current.releasePointerCapture(pointerId);
}
};
const handleActivate = () => {
onSelect(component.id);
};
return (
<div
ref={rootRef}
role="button"
tabIndex={0}
data-canvas-component="true"
data-dragging={isDragging ? "true" : "false"}
data-resizing={isResizing ? "true" : "false"}
aria-label={`${component.type} component`}
onPointerDown={(event) => {
if (onMovePointerDown(event)) {
capturePointer(event.pointerId);
}
}}
onPointerMove={onPointerMove}
onPointerUp={(event) => {
if (onPointerFinish(event)) {
releasePointer(event.pointerId);
}
}}
onPointerCancel={(event) => {
if (onPointerFinish(event)) {
releasePointer(event.pointerId);
}
}}
onClick={handleActivate}
onKeyUp={(event) => {
if (event.key === "Enter" || event.key === " ") {
handleActivate();
}
}}
className={`absolute touch-none select-none border-none bg-transparent p-0 text-left outline-none ${
isSelected ? "ring-1 ring-(--canvas-selection)" : ""
}`}
style={{
left: component.x,
top: component.y,
width: component.width,
height: component.height,
}}
>
<div className="relative h-full w-full overflow-hidden">
{preview}
{children}
</div>
<ResizeHandles
isSelected={isSelected}
componentType={component.type}
onHandlePointerDown={(event, handle) => {
if (onResizeHandlePointerDown(event, handle)) {
capturePointer(event.pointerId);
}
}}
/>
</div>
);
}
|