Material UI
#
Find similar titles
- 최초 작성자
- 최근 업데이트
Structured data
- Category
- Programming
Table of Contents
Material UI for React #
Material UI는 Google의 Material Design을 구현하는 React 오픈소스 라이브러리이다. install 즉시 디자인을 구현할 수 있는 여러 컬렉션을 포함하고 있으며, 기본적으로 제공하는 컬렉션 외에도 커스터마이징이 자유롭다는 큰 이점을 가지고 있는 라이브러리이다. React를 초기 구성할 때 디자인 키트를 가장 간단하게 구현할 수 있으며, 추후 디자이너가 프로젝트에 합류하게 되었을 때 호환성 및 변경의 자유로움으로 인해 React Project에서 많이 사용되고 있다.
Material UI의 장점 #
- 빠른 트러블 슈팅: 2,500명 이상의 오픈소스 기여자가 컴포넌트를 위해 수많은 시간을 투자했다. 그로 인해 Material UI 키트의 사용자가 비즈니스 로직에 더욱 집중할 수 있도록 도와준다.
- 기본적인 디자인의 아름다움:모든 Material UI 컴포넌트가 가장 높은 형식 및 기능 표준을 충족하고 있으며, 여러 가지 커스터마이징 옵션을 제공하기 위해 필요에 따라 공식 사양에서 벗어날 수 있도록 Material Design 구현에 대해 더욱 세심한 기능을 제공하고 있다. 아름다운 고유한 디자인을 유지하며 프로젝트의 디자인을 추가하여 더욱 프로젝트가 아름다울 수 있도록 도와준다.
- 높은 커스터마이징 호환성: 라이브러리에는 광범위하고 직관적인 커스터마이징 기능이 포함되어 있다. 스토어의 등록된 템플릿은 커스터마이징을 통해 끝없이 발전할 수 있다는 것을 직접적으로 보여주고 있다.
- 협업: 개발자가 아닌 디자이너의 진입 장벽을 줄여 팀이 더욱 효과적으로 협업할 수 있도록 도움을 준다. 테마를 갈아 끼우는 것만으로도 전체적인 CSS를 변경할 수 있는 것이 가장 큰 장점이다. 디자인 키트는 워크플로를 간소화하고 디자이너와 개발자 간의 일관성을 높여준다.
- 활성화된 커뮤니티 & 수천 개의 프로젝트: React의 역사와 함께 장기적으로 이어져 온 라이브러리이다. 그로 인해 Material UI는 React 생태계에서 가장 큰 커뮤니티를 보유하고 있고 수천 개의 프로젝트를 통해 수많은 예제, 신뢰를 얻을 수 있다.
Material UI의 목표 #
위에 기술된 장점은 React 개발자들의 선택을 받기에 충분했고, 그로 인해 UI 키트 중 메이저한 라이브러리 중 하나가 되었다. Material UI의 목표는 높은 커스터마이징과 디자이너의 낮은 진입 장벽을 통해 React 프로젝트들이 각각 뚜렷한 개성을 가지기 위함에 있다. 이는 Bootstrap과의 차별성을 두기 위함도 있는데, Bootstrap도 마찬가지로 디자인에 있어 개발자가 더욱 쉽고 빠르게 개발할 수 있음에 동일한 장점을 가지고 있다. 하지만 Bootstrap의 가장 큰 단점 중 하나로 커스터마이징이 자유롭지 못해 디자이너, 개발자 모두가 불편함을 감수해야 하며, 그로 인해 CSS 규칙이 파괴되는 경우도 종종 있다. 추가로 클래스를 통해 제어하는 영역 또한 굉장히 작게 쪼개져 있어 한 태그에 클래스가 10개 이상이 들어가는 경우도 발생하곤 한다. 무분별한 클래스 사용으로 인한 코드의 복잡도 증가, 사용하지 않는 기능들이 절반 이상인 JS파일, 기존 스타일의 재정의가 어려워 결국 처음부터 다시 스타일을 적용해야 하는 불편함이라는 단점을 가지고 있지만 무엇보다 가장 큰 단점은 UI의 한계이다. Bootstrap을 사용한 프로젝트는 서로 비슷한 UI를 가지고 있으며, 프로젝트의 개성을 부수는 프레임워크라고 생각하는 사람도 있다. 이는 Material UI와는 완전히 상반된 모습이다. 물론 서로 다른 장단점을 가지고 있겠지만 Bootstrap과는 다른 목표를 가지고 있다는 것을 알 수 있다.
Material UI 시작 #
우선 타 라이브러리의 시작과 동일하게 패키지를 다운받아야 한다.
npm install @mui/material @emotion/react @emotion/styled
yarn add @mui/material @emotion/react @emotion/styled
npm 혹은 yarn 패키지 매니저를 사용하여 다운받을 수 있다.
npm install @mui/material @mui/styled-engine-sc styled-components
yarn add @mui/material @mui/styled-engine-sc styled-components
styled 문법이 아닌 예전에 사용하던 styled-components 문법을 사용하고자 한다면 위에 패키지를 받은 후 설정을 변경하여 코드 스타일을 변경할 수 있다. 엔진을 바꾸는 것이며, 기능은 동일하지만 코드만 변경되는 것이다. 이 외에도 Get Started 이곳에서 종속성, 글꼴, 아이콘 등 필요한 패키지만 받아서 사용할 수 있어 불필요한 용량을 줄일 수 있다. 이제부턴 Material UI를 사용할 수 있으며, 컴포넌트 API를 사용하여 프로젝트에 적용할 수 있다.
Component API #
Material UI의 컴포넌트의 종류는 무수히 많다. 그중 Table 컴포넌트를 사용하여 UI를 적용해보겠다.
Default Table #
import * as React from 'react';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import Paper from '@mui/material/Paper';
function createData(
name: string,
calories: number,
fat: number,
carbs: number,
protein: number,
) {
return { name, calories, fat, carbs, protein };
}
const rows = [
createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
createData('Eclair', 262, 16.0, 24, 6.0),
createData('Cupcake', 305, 3.7, 67, 4.3),
createData('Gingerbread', 356, 16.0, 49, 3.9),
];
export default function BasicTable() {
return (
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} aria-label="simple table">
<TableHead>
<TableRow>
<TableCell>Dessert (100g serving)</TableCell>
<TableCell align="right">Calories</TableCell>
<TableCell align="right">Fat (g)</TableCell>
<TableCell align="right">Carbs (g)</TableCell>
<TableCell align="right">Protein (g)</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow
key={row.name}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">{row.calories}</TableCell>
<TableCell align="right">{row.fat}</TableCell>
<TableCell align="right">{row.carbs}</TableCell>
<TableCell align="right">{row.protein}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
코드는 크게 어렵지 않지만, 기본적으로 참조하고 있는 컴포넌트가 너무 많다. 이는 커스터마이징과 연관이 있는데, Table 하나를 그리는데 필요한 Container, Table, Body, Cell, head, Row(기본 HTML Table 구조와 동일)에 대해 커스터마이징을 더욱 쉽게 하기 위함에 있다. 필요에 따라 Table 관련 컴포넌트를 한 번에 커스터마이징할 수 있으며, 기본적으로는 일부 컴포넌트만 커스터마이징할 수 있는 구조로 개발자에게 높은 자유도를 제공한다.
위와 같은 형태가 가장 기본적인 형태의 Table이며, ordering, filter, search, paging, selecting 기능 사용이 필요할 시 컴포넌트 API를 사용하여 기능을 추가해나갈 수 있다. DB와 통신하여 데이터를 적용할 수도 있다. 하지만 대용량의 데이터를 처리하게 될 경우엔 DataGrid 사용을 권장한다.
Custom Table #
import * as React from 'react';
import { styled } from '@mui/material/styles';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell, { tableCellClasses } from '@mui/material/TableCell';
import TableContainer from '@mui/material/TableContainer';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import Paper from '@mui/material/Paper';
//커스텀 영역
const StyledTableCell = styled(TableCell)(({ theme }) => ({
[`&.${tableCellClasses.head}`]: {
backgroundColor: theme.palette.common.black,
color: theme.palette.common.white,
},
[`&.${tableCellClasses.body}`]: {
fontSize: 14,
},
}));
//커스텀 영역
const StyledTableRow = styled(TableRow)(({ theme }) => ({
'&:nth-of-type(odd)': {
backgroundColor: theme.palette.action.hover,
},
}));
function createData(
name: string,
calories: number,
fat: number,
carbs: number,
protein: number,
) {
return { name, calories, fat, carbs, protein };
}
const rows = [
createData('Frozen yoghurt', 159, 6.0, 24, 4.0),
createData('Ice cream sandwich', 237, 9.0, 37, 4.3),
createData('Eclair', 262, 16.0, 24, 6.0),
createData('Cupcake', 305, 3.7, 67, 4.3),
createData('Gingerbread', 356, 16.0, 49, 3.9),
];
export default function CustomizedTables() {
return (
<TableContainer component={Paper}>
<Table sx={{ minWidth: 700 }} aria-label="customized table">
<TableHead>
<TableRow>
<StyledTableCell>Dessert (100g serving)</StyledTableCell>
<StyledTableCell align="right">Calories</StyledTableCell>
<StyledTableCell align="right">Fat (g)</StyledTableCell>
<StyledTableCell align="right">Carbs (g)</StyledTableCell>
<StyledTableCell align="right">Protein (g)</StyledTableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<StyledTableRow key={row.name}>
<StyledTableCell component="th" scope="row">
{row.name}
</StyledTableCell>
<StyledTableCell align="right">{row.calories}</StyledTableCell>
<StyledTableCell align="right">{row.fat}</StyledTableCell>
<StyledTableCell align="right">{row.carbs}</StyledTableCell>
<StyledTableCell align="right">{row.protein}</StyledTableCell>
</StyledTableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
Material UI에서 가장 중요한 커스텀 부분이다. 커스텀 또한 어렵지 않다. 코드 내 커스텀 영역 주석 부분을 자세히 살펴보자. 먼저 첫 번째 StyledTableCell 부분을 보면 styled 문법을 사용하여 Cell을 디자인하는 클래스의 스타일을 JavaScript 코드로 제어한다. Table의 head는 배경이 검정, 글씨는 흰색으로 커스텀된 것을 확인할 수 있고 body는 폰트 사이즈가 14로 커스텀된 것을 확인할 수 있다. 두 번째 StyledTableRow 부분은 row가 odd(홀수)일 때 회색 배경을 주어 스트라이프 형태로 커스텀되었다.
여기서 중요 하게 봐야하는 부분은 함수의 매개변수로 받고 있는 theme이다. theme는 위에도 기술했듯이 언제든 갈아 끼울 수 있는 것이고, 그 theme를 객체 형태로 사용하여 커스텀이 가능하다는 이점이 있다는 것이다. 처음 접하게 되면 커스터마이징부분은 어려울 수밖에 없다. 이는 Material UI뿐만이 아닌 다른 라이브러리도 마찬가지일 것이다. 하지만 적응만 된다면 풍부한 디자인을 기반으로 여러 가지 기능들을 편리하게 구현할 수 있게 될 것이다.
기본 형태는 Default Table과 동일하지만 스트라이프 형태의 Row와 검정 배경의 thead는 커스텀 styled에 의해 디자인이 변경된 것을 확인할 수 있다.
Table API와 관련된 예제는 Table API 이곳에서 참고할 수 있다.
Material UI #
React 프로젝트를 진행하다 보면 Material UI를 사용하게 되는 경우가 많다. 프론트엔드 개발자가 워크플로에 집중할 수 있도록 도와주는 좋은 키트로 여러 프로젝트의 선택을 받아냈다. 템플릿을 넘어서 Material UI 엔진을 기반으로 구현된 플러그인들도 많이 있다. 그렇다고 Material UI 사용이 강제되는 것은 아니다. 결국 선택은 개발자의 몫이며, 확실한 점은 후회하지는 않을 것이라는 점이다.