콘텐츠로 이동
Grid Layout사용 가이드

팔레트와 그리드 전송

comins-grid-layout@0.3.0

전송은 request/commit 구조입니다. DOM drop이 typed request를 만들면 패키지는 임시 engine 이동을 rollback하고, 소비자가 React 상태를 갱신하여 승인 여부를 결정합니다.

import {
DashboardGrid,
insertDashboardWidgetAtLayout,
serializeDashboardState,
useDashboardDragIn,
useDashboardGrid,
} from "comins-grid-layout";
let sequence = 0;
export function TransferTarget() {
const target = useDashboardGrid({ initialColumns: 12 });
const paletteRef = useDashboardDragIn({
sourceId: "metric-palette",
previewLayout: { w: 2, h: 2 },
createWidget: () => {
const id = `metric-${++sequence}`;
return { id, title: "지표", layout: { id, x: 0, y: 0, w: 2, h: 2 } };
},
});
return (
<>
<button ref={paletteRef} type="button">지표 드래그</button>
<DashboardGrid
gridId="target-grid"
acceptExternalWidgets
widgets={target.widgets}
onLayoutCommit={target.commands.applyLayoutSnapshot}
onWidgetDropRequest={(request) => {
const result = insertDashboardWidgetAtLayout(
target.state,
request.widget,
request.targetLayout,
request.targetSnapshot,
);
if (result.accepted) target.commands.restoreLayout(serializeDashboardState(result.state));
}}
renderWidget={(widget) => widget.title}
/>
</>
);
}

useDashboardDragIn의 sourceId는 팔레트 출처, previewLayout은 drag geometry입니다. createWidget은 drag마다 새로운 안정 ID를 반환해야 합니다. dragOptions로 source 조작을 설정하고 disabled로 연결을 해제합니다.

Grid 간 전송에서는 source/target마다 고유 gridId를 지정합니다. source의 gridTransferMode는 move 또는 copy, target의 acceptExternalWidgets는 boolean 또는 predicate입니다. target은 onWidgetDropRequest를 처리합니다.

복사 모드에서는 원래 자리에 원본 모양을 남기고 + 윤곽선만 포인터를 따라갑니다. 이 정적 미리보기는 드래그 시작 시점의 표시용 복제이며 별도 React 위젯이나 엔진 노드가 아닙니다. 드롭·취소 시 제거됩니다. 같은 Grid 안에 놓으면 기존처럼 위치만 변경하며, 복사는 다른 Grid로 전송할 때 적용됩니다.

source와 target Grid의 컬럼 너비가 달라도 adapter는 포인터로 잡은 지점의 비율을 보존해 target 셀 좌표로 환산합니다. 최종 배치는 대상의 컬럼 경계와 기존 위젯 충돌에 따라 보정될 수 있습니다.

Grid source request는 transferDashboardWidget에 source/target 상태와 request 좌표, snapshot, widget ID, mode를 전달합니다. 승인 결과의 양쪽 상태를 serializeDashboardState 후 각 hook에 restoreLayout합니다. move는 source에서 위젯을 제거하고, copy는 source에 남깁니다. 두 모드 모두 ID를 유지하므로 target에 같은 ID가 있으면 거부됩니다. copy가 새 ID를 자동 생성하지는 않습니다.

거부 사유는 missing-widget, duplicate-id, not-transferable, invalid-layout입니다. 동일 상태 전송, locked/이동 불가/최소화/최대화 위젯, 잘못된 mode는 거부되며 양쪽 상태는 변경되지 않아야 합니다.

Playground: /examples/advanced/multi-grid/horizontal. 페이지의 배치 방향 컨트롤로 전송 계약은 유지한 채 가로/세로 Grid 배치를 비교합니다. 키보드용 전송 버튼도 같은 helper를 사용하지만 대상 Grid의 하단에 배치합니다. 드래그는 놓은 위치를 사용합니다.

React/Vue 예제의 A → B 전송 허용/차단 토글은 같은 위젯으로 허용 조건을 비교합니다. 차단 시 A → B 이동·복사는 드래그와 버튼 모두 적용되지 않으며 양쪽 목록을 유지합니다. B → A와 팔레트 추가는 계속 허용합니다. 드래그에는 acceptExternalWidgets를 사용하고 버튼도 같은 조건을 검사한 뒤 helper를 호출합니다. 신규 팔레트 위젯은 6×2로 추가되어 6컬럼 Grid A에서는 전체 너비, 12컬럼 Grid B에서는 절반 너비를 차지합니다.

외부 DOM 드롭 대상에서 consumer 제어 상태로 삭제하는 예제는 /examples/advanced/external-drop-trash에서 별도로 확인합니다.


실행 가능한 대표 예제 · 배포 기준 원본 가이드