DashboardGridCommands
위젯 CRUD, 배치 변경, 초기화와 직렬화를 위한 20개 React 상태 명령.
사용 위치와 공통 계약
섹션 제목: “사용 위치와 공통 계약”useDashboardGrid()가 반환한 grid.commands에서 호출합니다. 변경 명령은 React reducer에 상태 전이를 요청하며 Promise를 반환하지 않습니다. 같은 이벤트에서 setter 직후 serializer를 호출하면 이전 렌더의 값일 수 있습니다. 갱신 결과는 다음 렌더 또는 onLayoutMutation의 snapshot에서 읽습니다. 이전 렌더의 commands 객체를 별도로 저장하지 마십시오.
존재하지 않는 ID로 일부 명령을 호출하면 시각적 변화가 없어도 새로운 state 객체와 이벤트가 만들어질 수 있습니다. mutation 이벤트는 reducer가 반환한 상태 객체의 변경을 기준으로 하며, 저장 성공이나 geometry 변화만을 의미하지 않습니다.
전체 메서드 — 20개
섹션 제목: “전체 메서드 — 20개”addWidget
섹션 제목: “addWidget”addWidget: (widget: DashboardWidget<TData>) => void;widget 전체 정의를 추가합니다. 새 ID는 빈 공간을 찾아 배치합니다. 같은 ID가 있으면 기존 위젯을 전달한 전체 정의로 교체하므로 부분 수정에는 updateWidget을 사용합니다. 반환값은 void, mutation kind는 widget:add입니다.
insertWidgetAt
섹션 제목: “insertWidgetAt”insertWidgetAt: (widget: DashboardWidget<TData>, targetLayout: DashboardWidgetLayout, targetSnapshot: DashboardLayoutSnapshot) => void;외부 드롭에서 전달된 위젯·목표 위치·전체 목표 snapshot을 함께 반영합니다. 중복 ID 또는 유효하지 않은 목표 배치는 상태를 유지합니다. 반환값은 void이므로 성공 여부를 반환값으로 판정할 수 없습니다. 결과 객체가 필요하면 공개 core 함수 insertDashboardWidgetAtLayout을 사용합니다. 성공한 상태 전이의 kind는 widget:add입니다.
updateWidget
섹션 제목: “updateWidget”updateWidget: (id: DashboardWidgetId, patch: Partial<DashboardWidget<TData>>) => void;ID에 해당하는 위젯에 patch를 얕게 병합합니다. 위젯 ID는 유지합니다. data는 깊게 병합하지 않으며 patch.layout을 전달하면 전체 layout 정의가 필요합니다. 일치하는 ID가 없으면 추가하지 않습니다. 반환값 void, kind widget:update.
updateWidgetLayout
섹션 제목: “updateWidgetLayout”updateWidgetLayout: (id: DashboardWidgetId, patch: Partial<Omit<DashboardWidgetLayout, "id">>) => void;기존 layout에 x, y, w, h 등의 부분 값을 병합하고 현재 열 수 기준으로 정규화합니다. ID는 변경하지 않습니다. 일치하는 ID가 없으면 추가하지 않습니다. 반환값 void, kind widget:update.
removeWidget
섹션 제목: “removeWidget”removeWidget: (id: DashboardWidgetId) => void;위젯과 해당 ID의 이전 배치·열별 배치 캐시를 제거합니다. 없는 ID를 제거해도 다른 위젯을 제거하지 않습니다. 반환값 void, kind widget:remove.
clearWidgets
섹션 제목: “clearWidgets”clearWidgets: () => void;모든 위젯과 복원용 이전 배치를 비웁니다. 열 수는 유지합니다. 반환값 void, kind widgets:clear.
maximizeWidget
섹션 제목: “maximizeWidget”maximizeWidget: (id: DashboardWidgetId) => void;현재 위치를 복원용으로 보관하고 최대화 상태로 전환합니다. 위치는 (0, 0), 너비는 전체 열, 높이는 기존 높이와 3 중 큰 값으로 시작해 제약 조건을 적용합니다. ID가 없으면 상태를 유지합니다. 반환값 void, kind widget:update.
minimizeWidget
섹션 제목: “minimizeWidget”minimizeWidget: (id: DashboardWidgetId) => void;복원할 위치를 보관하고 최소화 상태와 높이 1을 요청합니다. 최종 크기는 layout 제약을 따릅니다. ID가 없으면 상태를 유지합니다. 반환값 void, kind widget:update.
restoreWidget
섹션 제목: “restoreWidget”restoreWidget: (id: DashboardWidgetId) => void;최대화·최소화 플래그를 해제하고 보관된 배치를 복원한 뒤 해당 복원 기록을 제거합니다. 기록이 없으면 현재 배치를 유지하고 플래그만 해제합니다. ID가 없으면 상태를 유지합니다. 반환값 void, kind widget:update.
autoArrangeWidgets
섹션 제목: “autoArrangeWidgets”autoArrangeWidgets: () => void;위젯 배열 순서대로 왼쪽부터 채우고 공간이 부족하면 다음 행으로 배치합니다. 엔진의 compact()와 배치 규칙이 다릅니다. 반환값 void, kind layout:arrange.
fitWidgetsToColumns
섹션 제목: “fitWidgetsToColumns”fitWidgetsToColumns: () => void;같은 y의 위젯을 한 행으로 묶습니다. 빈 열 공간이 있는 행에서 너비를 나누어 전체 열을 채웁니다. 이미 찬 행은 유지합니다. 반환값 void, kind layout:fill.
fitWidgetToColumns
섹션 제목: “fitWidgetToColumns”fitWidgetToColumns: (id: DashboardWidgetId) => void;대상과 같은 y에 있는 행의 남은 너비를 대상 위젯에 주고 해당 행의 x 위치를 다시 정렬합니다. ID가 없거나 남은 너비가 없으면 상태를 유지합니다. 반환값 void, kind layout:fill.
setColumns
섹션 제목: “setColumns”setColumns: (columns: number) => void;열 수를 변경합니다. 유한수는 반올림하여 1–12로 제한하고 비유한수는 12로 처리합니다. 기존 열의 배치를 보관하고 대상 열의 캐시가 있으면 복원합니다. 같은 열 수이면 상태를 유지합니다. 반환값 void, kind columns:change.
applyLayoutSnapshot
섹션 제목: “applyLayoutSnapshot”applyLayoutSnapshot: (snapshot: DashboardLayoutSnapshot) => void;snapshot.columns와 ID별 geometry를 기존 위젯에 적용합니다. 위젯의 제목·data·목록 구성은 유지하며 snapshot에만 있는 ID를 추가하지 않습니다. onLayoutCommit에 연결하여 엔진 배치를 React 상태에 반영합니다. 반환값 void, kind layout:commit.
resetLayout
섹션 제목: “resetLayout”resetLayout: (snapshot?: DashboardLayoutSnapshot | DashboardStateSnapshotInput<TData>) => void;인자를 생략하면 최초 마운트 시 입력으로 전체 상태를 재생성합니다. snapshot을 주면 해당 값으로 교체합니다. geometry snapshot만 주면 제목·data를 복원할 수 없으므로 전체 복원에는 state snapshot을 사용합니다. refreshVersion도 0으로 초기화합니다. 반환값 void, kind layout:reset.
restoreLayout
섹션 제목: “restoreLayout”restoreLayout: (snapshot: DashboardStateSnapshotInput<TData>) => void;전달한 전체 state snapshot으로 현재 위젯·열·복원 배치·열별 캐시를 재생성합니다. 인자는 필수이며 기본 초기 상태로 돌아가는 호출이 아닙니다. 반환값 void, kind layout:restore.
refreshLayout
섹션 제목: “refreshLayout”refreshLayout: () => void;refreshVersion을 1 증가시킵니다. 이를 컴포넌트의 refreshKey에 연결해야 엔진 refresh로 이어집니다. 반환값 void, 이 명령에는 layout mutation 이벤트가 없습니다.
serializeLayout
섹션 제목: “serializeLayout”serializeLayout: () => DashboardLayoutSnapshot;현재 렌더가 보유한 열 수와 각 위젯의 geometry를 새 배열·객체로 반환합니다. 제목·data·최대화 복원 기록은 포함하지 않습니다. 조회는 상태를 변경하지 않습니다.
serializeState
섹션 제목: “serializeState”serializeState: () => DashboardStateSnapshot<TData>;현재 렌더의 위젯 정의·열 수·이전 배치·열별 캐시를 반환합니다. layout 구조는 복사하지만 data 내부 객체까지 깊게 복사하지 않습니다. JSON 문자열이나 저장 완료 결과가 아니며 저장과 데이터 직렬화는 소비자 책임입니다.
예제 조작
섹션 제목: “예제 조작”위젯을 추가하거나 A를 삭제한 뒤 현재 React 상태를 확인하십시오. compact는 ref에서 실행하고 onLayoutCommit으로 commands에 연결합니다. 저장·복원 예제는 배치 저장 가이드에 있습니다.
실행 예제
섹션 제목: “실행 예제”import { useRef, useState } from 'react';import { DashboardGrid, useDashboardGrid, type DashboardGridHandle } from 'comins-grid-layout';import 'gridstack/dist/gridstack.min.css';import 'comins-grid-layout/styles.css';
export default function GridApiDemo({ lang = 'ko' }: { lang?: string }) { const ko = lang === 'ko'; const handle = useRef<DashboardGridHandle>(null); const sequence = useRef(0); const [inspection, setInspection] = useState(''); const grid = useDashboardGrid({ initialColumns: 12, initialWidgets: [ { id: 'first', title: 'A', layout: { id: 'first', x: 0, y: 0, w: 4, h: 2 } }, { id: 'second', title: 'B', layout: { id: 'second', x: 6, y: 0, w: 4, h: 2 } }, ] }); return <div className="demo grid-demo" data-demo="grid-api"> <div className="demo-toolbar"> <button onClick={() => { const id = `added-${++sequence.current}`; grid.commands.addWidget({ id, title: id, layout: { id, x: 0, y: 0, w: 3, h: 2 } }); }}>{ko ? '위젯 추가' : 'Add widget'}</button> <button onClick={() => grid.commands.resizeWidget('first', { w: 8, h: 3 })}>{ko ? 'A 크기 8×3' : 'Resize A to 8×3'}</button> <button onClick={() => grid.commands.restoreWidget('first')}>{ko ? 'A 크기 복원' : 'Restore A size'}</button> <button onClick={() => grid.commands.removeWidget('first')}>{ko ? 'A 삭제' : 'Remove A'}</button> <button onClick={() => { const snapshot = handle.current?.compact('list'); setInspection(snapshot ? JSON.stringify(snapshot, null, 2) : (ko ? '그리드 준비 중' : 'Grid is initializing')); }}>compact('list')</button> <button onClick={() => { const ref = handle.current; const probe = { x: 0, y: 20, w: 2, h: 1 }; setInspection(JSON.stringify({ columns: ref?.getColumnCount() ?? null, rows: ref?.getRowCount() ?? null, float: ref?.getFloat() ?? null, empty: ref?.isAreaEmpty(probe) ?? null, fits: ref?.willItFit(probe) ?? null }, null, 2)); }}>{ko ? '그리드 조회' : 'Inspect grid'}</button> <button onClick={() => { grid.commands.resetLayout(); setInspection(''); }}>{ko ? '초기화' : 'Reset'}</button> </div> <DashboardGrid ref={handle} widgets={grid.widgets} columns={grid.columns} refreshKey={grid.refreshVersion} onLayoutCommit={grid.commands.applyLayoutSnapshot} editable movable resizable showControls={false} engineOptions={{ cellHeight: 60, margin: 6, animate: false }} renderWidget={widget => <div className="widget-content">{widget.title}</div>} /> <p role="status">{ko ? '위젯 수' : 'Widget count'}: <span data-widget-count>{grid.widgets.length}</span></p> <details open><summary>{ko ? '현재 React 상태' : 'Current React state'}</summary> <pre data-grid-state>{JSON.stringify(grid.commands.serializeLayout(), null, 2)}</pre> </details> {inspection && <pre data-grid-inspection aria-live="polite">{inspection}</pre>} </div>;}아래 npm 선언과 고정 소스 snapshot을 대조했습니다. snapshot은 공개 artifact의 provenance에 기록된 커밋입니다.
comins-grid-layout/dist/core/controller-types.d.ts- npm 0.3.0 · Source snapshot
resizeWidget
섹션 제목: “resizeWidget”resizeWidget: (id: DashboardWidgetId, size: Pick<DashboardWidgetLayout, "w" | "h">) => void;그리드 단위 W/H를 지정합니다. 열 수와 min/max 제약을 적용하며 첫 크기 변경 전 배치를 보존합니다. 연속 변경 후 restoreWidget은 최초 배치로 돌아옵니다. 기존 maximize/minimize는 deprecated 호환 명령으로 유지되며 기본 버튼은 제공하지 않습니다.