자동 배치와 열별 레이아웃 복원
자동 배치·행 너비 채우기·특정 위젯 확장과 6열/12열 전환을 비교하는 예제.
조작 순서
섹션 제목: “조작 순서”아래 비교는 각 동작 전에 초기화한 상태를 기준으로 합니다. float: true를 사용하여 처음의 세로 여백을 유지합니다.
| 조작 | 기대 결과 |
|---|---|
| 자동 배치 | 배열 순서 A → B → C로 같은 첫 행에 배치합니다. 너비는 각각 3, 3, 4입니다. |
| 행 너비 채우기 | 같은 y의 A와 B를 각 6칸으로, 단독 행의 C를 12칸으로 채웁니다. |
| A에 남은 너비 주기 | 같은 행의 B 너비 3은 유지하고 A 너비를 9로 늘립니다. C는 유지합니다. |
| 6열 → 배치 조작 → 12열 | 12열에서 마지막으로 사용했던 배치를 복원합니다. |
| 다시 6열 | 6열에서 저장된 배치를 복원합니다. |
| 초기화 | 최초 12열과 A/B/C 배치로 돌아갑니다. |
메서드 선택
섹션 제목: “메서드 선택”autoArrangeWidgets는 위젯 배열 순서에 따라 행을 채웁니다. fitWidgetsToColumns는 같은 y의 위젯들을 묶어 빈 열 너비를 나누며, fitWidgetToColumns(id)는 그 행의 남은 너비를 지정 위젯에 줍니다. 엔진의 compact()와 같은 연산으로 취급하지 마십시오.
setColumns는 열별 좌표를 보관하고 이전 열 수로 돌아갈 때 해당 배치를 복원합니다. 이 예제는 명시적인 열 수 전환이며, 컨테이너 폭에 따른 자동 반응형 breakpoint 예제는 아닙니다.
React와 엔진 연결
섹션 제목: “React와 엔진 연결”widgets, columns, refreshKey를 훅 반환값에 연결하고 onLayoutCommit을 commands.applyLayoutSnapshot에 연결합니다. 드래그와 리사이즈도 아래 JSON에 반영됩니다. 초기 상태를 prop 변경으로 덮어쓰지 않으며, 초기화는 commands.resetLayout()으로 요청합니다.
표의 결과는 이 예제의 제약 없는 위젯 기준입니다. 애플리케이션의 min/max 크기 제한과 엔진 설정이 추가되면 최종 배치가 달라질 수 있습니다.
저장 범위
섹션 제목: “저장 범위”표시 JSON은 현재 열의 geometry만 보여줍니다. 열별 캐시까지 외부에 보존하려면 serializeState()로 전체 상태를 저장하고 restoreLayout()으로 복원하십시오. 이 예제는 브라우저 메모리에서 동작하며 새로고침 후 복원을 구현하지 않습니다.
관련 문서
섹션 제목: “관련 문서”상태 명령 20개 · 초기 옵션 · 엔진 compact · 배치 저장
직접 실행
섹션 제목: “직접 실행”import { DashboardGrid, useDashboardGrid } from 'comins-grid-layout';import 'gridstack/dist/gridstack.min.css';import 'comins-grid-layout/styles.css';
export default function GridArrangeDemo({ lang = 'ko' }: { lang?: string }) { const ko = lang === 'ko'; const grid = useDashboardGrid({ initialColumns: 12, initialWidgets: [ { id: 'a', title: 'A', layout: { id: 'a', x: 0, y: 0, w: 3, h: 2 } }, { id: 'b', title: 'B', layout: { id: 'b', x: 6, y: 0, w: 3, h: 2 } }, { id: 'c', title: 'C', layout: { id: 'c', x: 0, y: 3, w: 4, h: 2 } }, ] }); return <div className="demo grid-demo" data-demo="grid-arrange"> <div className="demo-toolbar"> <button onClick={grid.commands.autoArrangeWidgets}>{ko ? '자동 배치' : 'Auto arrange'}</button> <button onClick={grid.commands.fitWidgetsToColumns}>{ko ? '행 너비 채우기' : 'Fill row widths'}</button> <button onClick={() => grid.commands.fitWidgetToColumns('a')}>{ko ? 'A에 남은 너비 주기' : 'Give remaining width to A'}</button> <button onClick={() => grid.commands.setColumns(6)}>{ko ? '6열' : '6 columns'}</button> <button onClick={() => grid.commands.setColumns(12)}>{ko ? '12열' : '12 columns'}</button> <button onClick={() => grid.commands.resetLayout()}>{ko ? '초기화' : 'Reset'}</button> </div> <DashboardGrid widgets={grid.widgets} columns={grid.columns} refreshKey={grid.refreshVersion} editable movable resizable showControls={false} engineOptions={{ cellHeight: 50, margin: 6, float: true, animate: false }} onLayoutCommit={grid.commands.applyLayoutSnapshot} renderWidget={widget => <div className="widget-content">{widget.title}</div>} /> <p role="status">{ko ? '현재 열 수' : 'Current columns'}: <span data-column-count>{grid.columns}</span></p> <details open><summary>{ko ? '현재 배치' : 'Current layout'}</summary><pre data-arrange-layout>{JSON.stringify(grid.commands.serializeLayout(), null, 2)}</pre></details> </div>;}