위젯이 여러 개 들어간 대시보드를 구성하면서, 위젯의 크기를 조절하고 위치를 옮길 수 있는 옵션을 찾다가 react-grid-layout이라는 라이브러리를 발견해서 적용했다.
react-grid-layout은 리액트를 위한 그리드 레이아웃 시스템입니다. 반응성이 뛰어나고 breakpoint를 지원합니다. breakpoint layout은 사용자가 제공하거나 자동으로 생성될 수 있습니다. 드래그와 크기 조정이 가능합니다. static 위젯을 설정해서 특정 위젯의 위치를 고정할 수도 있습니다.
npm으로 package를 설치한다.
npm install react-grid-layout
index.js 파일에 css를 import 한다. 이걸 안해주면 디자인 적용이 제대로 되지 않는다. 파일에 아래 코드를 추가해준다.
import 'react-grid-layout/css/styles.css'
import 'react-resizable/css/styles.css'
react-grid-layout에서 사용되는 layout의 형태이다. grid layout은 각 그리드의 key 값을 사용해서 해당 x, y 좌표에 w, h 크기로 그리드를 배치해준다.
i
는 각 그리드의 key
값이고, key 옵션에 맞게 그리드가 해당 위치에 해당 사이즈로 그려진다.
나는 반복문을 사용해서 layout 배열을 구성해서 아래처럼 별도로 적어두지 않았지만, 이해를 돕기 위해 layout의 형태를 써둔다.
const layout = [
{ i: "key값1", x: 0, y: 0, w: 1, h: 1 },
{ i: "key값2", x: 1, y: 0, w: 1, h: 1 },
{ i: "key값3", x: 2, y: 0, w: 1, h: 1 },
{ i: "key값4", x: 3, y: 0, w: 1, h: 1 },
{ i: "key값5", x: 4, y: 0, w: 1, h: 1 }
];
실제로 화면에 적용하는 코드이다.
ResponsiveGridLayout에 있는 breakpoints와 cols도 state에 넣어서 사용했는데, onBreakPointChange를 적용하려고 하니 에러가 나서 직접 사용했다. 이유는 잘모르지만 직접 적어주는게 맞는 것 같다.
onLayoutChange
에 있는 layout과 layouts의 차이점은 layout
은 breakpoint에 상관 없이 현재 layout 배열
하나만 반환하고, layouts
는 각 breakpoint에 따른 layout 배열들
을 반환한다. 필요에 따라 선택해서 사용하면 된다.
// react-grid-layout library 가져오기
import { Responsive, WidthProvider } from 'react-grid-layout'
// responsive grid 생성
const ResponsiveGridLayout = WidthProvider(Responsive)
const DashboardDetailView = () => {
// responsive grid에 필요한 state
const [state, setState] = useState({
breakpoints: 'lg',
layouts: { lg: [] },
})
// grid-layout 변경 시 사용
const onLayoutChange = (layout, layouts) => {
// console.log('layouts', layouts, layout)
setState((state) => ({
...state,
layouts: layouts,
}))
}
// breakpoint 변경
const onBreakPointChange = (breakpoint) => {
// console.log(breakpoint) // lg or md or sm or xs or xxs
setState((state) => ({
...state,
breakpoints: breakpoint,
}))
}
return (
<ResponsiveGridLayout
layouts={state.layouts}
breakpoints={{
lg: 1200,
md: 996,
sm: 768,
xs: 480,
xxs: 0,
}}
cols={{ lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }}
rowHeight={150}
width={1000}
onLayoutChange={onLayoutChange}
onBreakpointChange={onBreakPointChange}
isResizable={true}
>
{widgetList.map((widget, index) => (
<Grid item key={widget.widgetId}>
<WidgetCard
// title={widget.widgetTitle}
widgetInfo={widget}
getWidgetData={getWidgetData}
>
<WidgetComponent widgetInfo={widget} />
</WidgetCard>
</Grid>
))}
</ResponsiveGridLayout>
)
}
그리드의 크기를 조절할 수 있고, 그리드를 움직일 수 있다.
참조
https://www.npmjs.com/package/react-grid-layout
https://codesandbox.io/s/182lw48lo7?file=/src/components/DataEdit.js
https://codesandbox.io/s/5wy3rz5z1x?module=%2Fsrc%2FShowcaseLayout.js
https://isamatov.com/react-grid-layout-tutorial/
https://github.com/react-grid-layout/react-grid-layout