| name | mui |
| description | MUI(Material UI) 컴포넌트 라이브러리 사용 규칙. import 패턴, sx prop, styled(), ThemeProvider. |
MUI (Material UI) 컨벤션
Import 패턴
import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';
import Box from '@mui/material/Box';
import SearchIcon from '@mui/icons-material/Search';
import CloseIcon from '@mui/icons-material/Close';
import { Button, TextField, Box } from '@mui/material';
sx prop 사용
sx prop은 MUI 컴포넌트에 인라인 스타일을 적용하는 방법이다.
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
function OrderCard() {
return (
<Box
sx={{
padding: 2, // theme.spacing(2) = 16px
marginBottom: 1,
backgroundColor: 'background.paper',
borderRadius: 1,
boxShadow: 1,
'&:hover': {
boxShadow: 3,
},
}}
>
<Typography
variant="h6"
sx={{
color: 'text.primary',
fontWeight: 'bold',
}}
>
주문 제목
</Typography>
</Box>
);
}
<Box
sx={{
width: {
xs: '100%',
sm: '50%',
md: '33%',
},
fontSize: { xs: 14, md: 16 },
}}
/>
styled() API
복잡한 스타일이나 재사용 컴포넌트에는 styled()를 사용한다.
import { styled } from '@mui/material/styles';
import Button from '@mui/material/Button';
import Box from '@mui/material/Box';
const StyledButton = styled(Button)(({ theme }) => ({
borderRadius: theme.spacing(3),
padding: theme.spacing(1, 3),
textTransform: 'none',
'&:hover': {
backgroundColor: theme.palette.primary.dark,
},
}));
const CardContainer = styled(Box)(({ theme }) => ({
padding: theme.spacing(2),
borderRadius: theme.shape.borderRadius,
backgroundColor: theme.palette.background.paper,
[theme.breakpoints.down('sm')]: {
padding: theme.spacing(1),
},
}));
interface StatusBadgeProps {
status: 'active' | 'inactive' | 'pending';
}
const StatusBadge = styled(Box, {
shouldForwardProp: (prop) => prop !== 'status',
})<StatusBadgeProps>(({ theme, status }) => ({
display: 'inline-flex',
borderRadius: theme.spacing(1),
padding: theme.spacing(0.5, 1),
backgroundColor:
status === 'active' ? theme.palette.success.light
: status === 'inactive' ? theme.palette.error.light
: theme.palette.warning.light,
}));
ThemeProvider & createTheme
import { createTheme } from '@mui/material/styles';
export const theme = createTheme({
palette: {
primary: {
main: '#1976d2',
light: '#42a5f5',
dark: '#1565c0',
},
secondary: {
main: '#dc004e',
},
background: {
default: '#f5f5f5',
paper: '#ffffff',
},
},
typography: {
fontFamily: '"Pretendard", "Roboto", sans-serif',
h1: {
fontSize: '2rem',
fontWeight: 700,
},
},
shape: {
borderRadius: 8,
},
spacing: 8,
});
import { ThemeProvider } from '@mui/material/styles';
import CssBaseline from '@mui/material/CssBaseline';
import { theme } from '@/theme';
function App() {
return (
<ThemeProvider theme={theme}>
<CssBaseline /> {/* 브라우저 기본 스타일 초기화 */}
<AppRoutes />
</ThemeProvider>
);
}
주요 컴포넌트 패턴
Grid 레이아웃
import Grid from '@mui/material/Grid';
function OrderList() {
return (
<Grid container spacing={2}>
{orders.map((order) => (
<Grid item xs={12} sm={6} md={4} key={order.id}>
<OrderCard order={order} />
</Grid>
))}
</Grid>
);
}
Form 패턴
import TextField from '@mui/material/TextField';
import FormControl from '@mui/material/FormControl';
import InputLabel from '@mui/material/InputLabel';
import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
function OrderForm() {
return (
<Box component="form" sx={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
<TextField
label="주문명"
variant="outlined"
required
error={!!errors.name}
helperText={errors.name?.message}
{...register('name')}
/>
<FormControl fullWidth>
<InputLabel>상태</InputLabel>
<Select label="상태" value={status} onChange={handleChange}>
<MenuItem value="pending">대기중</MenuItem>
<MenuItem value="active">진행중</MenuItem>
</Select>
</FormControl>
</Box>
);
}
useTheme 훅
import { useTheme } from '@mui/material/styles';
import useMediaQuery from '@mui/material/useMediaQuery';
function ResponsiveComponent() {
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
return (
<div style={{ padding: isMobile ? theme.spacing(1) : theme.spacing(3) }}>
{isMobile ? '모바일 뷰' : '데스크탑 뷰'}
</div>
);
}
체크리스트