mui
MUI(Material UI) 컴포넌트 라이브러리 사용 규칙. import 패턴, sx prop, styled(), ThemeProvider.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
MUI(Material UI) 컴포넌트 라이브러리 사용 규칙. import 패턴, sx prop, styled(), ThemeProvider.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
세션 핸드오프. 컨텍스트가 차기 전에 중요 맥락을 progress.md에 문서화하고 새 세션 킥오프 프롬프트를 클립보드에 복사한다. "핸드오프", "세션 정리하고 넘기자", "컨텍스트 정리", "이어갈 준비" 등의 요청에 사용.
MD 파일 또는 텍스트로 작업을 정의하면, 분석 → 디자인 확인 → 구현 → 검증 → 커밋 → PR까지 전체 플로우를 수행한다. "이거 만들어줘", "기능 구현해줘", "작업 시작하자", "이 티켓 진행해줘" 등 코드 작업 착수 발화에 사용.
Claude + OpenAI Codex 협업 스킬. MCP 서버 설정 시에만 사용 가능.
code-forge 상태 대시보드. REFLECT flag, quality 이벤트, notepad/decisions, usage 집계를 한 번에. forge-glow 같은 외부 도구는 --json으로 파싱.
교차 모델 토론. Agent Teams / Codex CLI / self-debate 모드 선택. 설계 결정, 아키텍처 선택 시 활용. "어느 쪽이 나을까", "설계 비교해줘", "토론시켜줘", "교차 검증해줘" 등의 요청에 사용.
화면 단위 E2E 테스트 자동화. Figma/코드 기반 테스트 케이스 도출 → Playwright 코드 생성 → Forge Loop(에스컬레이션 기반 자율 실행). "E2E 돌려줘", "화면 테스트 만들어줘", "이 페이지 자동 테스트" 등의 요청에 사용.
| name | mui |
| description | MUI(Material UI) 컴포넌트 라이브러리 사용 규칙. import 패턴, sx prop, styled(), ThemeProvider. |
// ✅ 좋은 예: 트리 쉐이킹이 가능한 named import
import Button from '@mui/material/Button';
import TextField from '@mui/material/TextField';
import Box from '@mui/material/Box';
// ✅ 아이콘 import
import SearchIcon from '@mui/icons-material/Search';
import CloseIcon from '@mui/icons-material/Close';
// ❌ 나쁜 예: 배럴 import (번들 크기 증가 가능)
import { Button, TextField, Box } from '@mui/material';
sx prop은 MUI 컴포넌트에 인라인 스타일을 적용하는 방법이다.
import Box from '@mui/material/Box';
import Typography from '@mui/material/Typography';
// ✅ 간단한 스타일: sx prop 사용
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>
);
}
// 반응형 스타일 (breakpoints)
<Box
sx={{
width: {
xs: '100%', // mobile
sm: '50%', // tablet
md: '33%', // desktop
},
fontSize: { xs: 14, md: 16 },
}}
/>
복잡한 스타일이나 재사용 컴포넌트에는 styled()를 사용한다.
import { styled } from '@mui/material/styles';
import Button from '@mui/material/Button';
import Box from '@mui/material/Box';
// ✅ styled()로 커스텀 컴포넌트 생성
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),
},
}));
// Props를 받는 styled 컴포넌트
interface StatusBadgeProps {
status: 'active' | 'inactive' | 'pending';
}
const StatusBadge = styled(Box, {
shouldForwardProp: (prop) => prop !== 'status', // DOM에 전달하지 않을 prop
})<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,
}));
// src/theme/index.ts
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, // 기본 spacing 단위 (px)
});
// src/main.tsx
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>
);
}
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>
);
}
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>
);
}
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>
);
}
@mui/material/Button)sx prop 사용?styled() 사용?ThemeProvider로 theme 전역 제공?CssBaseline 포함?shouldForwardProp 사용?