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 ページを確認してインストールできます。
SOC 職業分類に基づく
세션 핸드오프. 컨텍스트가 차기 전에 중요 맥락을 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 사용?