[React] Grid Layout 사용하기 (Typescript) #2
React Grid Layout
시작하기 전에
프로젝트를 진행하며, 대시보드를 위젯 형태로 꾸며야 하는 상황이 발생했다.
드래그와 드랍을 이용해 위치를 조절하고, 추가적으로 위젯의 크기를 조절 해야되기 때문에, 검색도 해보고 챗GPT 한테도 물어보고 얻은 결과는 DND 와 Resizing 에 대한 기능뿐 이었다.
DND 와 Resizing 을 직접 만져보고 더 깊숙하게 들어가던 중 react-grid-layout
모듈을 발견했다.
일주일만 일찍 발견했으면…. 좋았겠지만 이번 포스트는 해당 모듈을 이용하는 방법을 알아보려고 한다.
Grid Layout 이란?
react-grid-layout
은 리액트를 위한 그리드 레이아웃 시스템이다. 반응성이 뛰어나고 breakpoint를 지원하며 breakpoint layout은 사용자가 제공하거나 자동으로 생성될 수 있다. 드래그와 크기 조정이 가능하며 static 위젯을 설정해서 특정 위젯의 위치를 고정할 수도 있다.
layout
GridLayout 컴포넌트에는 layout이라는 props가 있다. 해당 데이터는 GridLayout에 들어갈 개별 요소들의 성질을 각각 객체에 담아 배열 형식으로 만든 것이다.
1
2
3
4
5
const layout = [
{ i: "a", x: 0, y: 0, w: 1, h: 2, static: true },
{ i: "b", x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4 },
{ i: "c", x: 4, y: 0, w: 1, h: 2 },
];
key | value type | Description | require |
---|---|---|---|
i | string | 각 요소의 id값과 일치하는 식별자값 | ✅ |
x | number | 요소가 어느 x 지점에서 시작할 것인지 | ✅ |
y | number | 요소가 어느 y 지점에서 시작할 것인지 | ✅ |
w | number | 요소가 몇칸의 넓이를 차지할 것인지 | ✅ |
h | number | 요소가 몇칸의 높이를 차지할 것인지 | ✅ |
minW | number | 요소가 최소 넓이 몇칸을 유지할 수 있는지 | |
maxW | number | 요소가 최대 넓이 몇칸을 유지할 수 있는지 | |
minH | number | 요소가 최소 높이 몇칸을 유지할 수 있는지 | |
maxH | number | 요소가 최대 높이 몇칸을 유지할 수 있는지 | |
static | boolean | 크기와 위치가 고정됨 | |
isDraggable | boolean | 드래그 가능 여부 | |
isResizable | boolean | 크기 조절 가능 여부 | |
resizeHandles | array <’s’, ‘w’ , ‘e’ , ‘n’ , ‘sw’ , ‘nw’ , ‘se’ , ‘ne’> | 사이즈 조절 핸들 위치 배열 |
static이 false인 경우 isDraggable : false , isResizable : false 로 설정값과 상관없이 덮어쓰기 된다.
모듈 설치
1
2
3
npm install react-grid-layout
npm install @types/react-grid-layout
npm install react-resizable
css
최상이 파일에서 css 파일을 import 한다.
App.tsx
1
2
import "/node_modules/react-grid-layout/css/styles.css";
import "/node_modules/react-resizable/css/styles.css";
Dashboard 생성
Dashboard.tsx
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
import { FC } from "react";
import { Responsive, WidthProvider } from "react-grid-layout";
const ResponsiveGridLayout = WidthProvider(Responsive);
const Dashboard: FC = () => {
const LAYOUTS = {
items: [
{ i: "a", x: 0, y: 0, w: 1, h: 1, minW: 0, minH: 0 },
{ i: "b", x: 0, y: 1, w: 1, h: 1, minW: 0, minH: 0 },
{ i: "c", x: 0, y: 2, w: 1, h: 1, minW: 1, minH: 1 },
{ i: "d", x: 0, y: 3, w: 1, h: 1, minW: 1, minH: 1 },
{ i: "e", x: 0, y: 4, w: 1, h: 1, minW: 1, minH: 1 },
]
};
return (
<ResponsiveGridLayout
className="layout"
layouts={LAYOUTS}
breakpoints=
cols=
>
{LAYOUTS.items.map((item) => (
<div key={item.i} className="dnd-movable-item" {...item}>
<h1>{item.i}</h1>
</div>
))}
</ResponsiveGridLayout>
);
};
export default Dashboard;
Leave a comment