ant-design
Ant Design 컴포넌트 라이브러리 사용 규칙. import 패턴, ConfigProvider, theme 커스터마이징, Form/Table 패턴.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Ant Design 컴포넌트 라이브러리 사용 규칙. import 패턴, ConfigProvider, theme 커스터마이징, Form/Table 패턴.
用 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 | ant-design |
| description | Ant Design 컴포넌트 라이브러리 사용 규칙. import 패턴, ConfigProvider, theme 커스터마이징, Form/Table 패턴. |
// ✅ 좋은 예: named import
import { Button, Form, Input, Table, Space } from 'antd';
import type { FormProps, TableProps, ColumnsType } from 'antd';
// ✅ 아이콘 import (별도 패키지)
import { SearchOutlined, CloseOutlined, PlusOutlined } from '@ant-design/icons';
// src/main.tsx 또는 App.tsx
import { ConfigProvider, theme } from 'antd';
import ko_KR from 'antd/locale/ko_KR';
const { defaultAlgorithm, darkAlgorithm } = theme;
function App() {
return (
<ConfigProvider
locale={ko_KR}
theme={{
algorithm: defaultAlgorithm, // 또는 darkAlgorithm
token: {
colorPrimary: '#1677ff',
borderRadius: 8,
fontFamily: '"Pretendard", -apple-system, sans-serif',
colorBgContainer: '#ffffff',
},
components: {
Button: {
borderRadius: 6,
},
Table: {
borderRadius: 8,
},
},
}}
>
<AppRoutes />
</ConfigProvider>
);
}
import { Form, Input, Select, Button } from 'antd';
import type { FormProps } from 'antd';
interface OrderFormValues {
name: string;
status: 'pending' | 'active';
description?: string;
}
function OrderForm() {
const [form] = Form.useForm<OrderFormValues>();
const onFinish: FormProps<OrderFormValues>['onFinish'] = (values) => {
console.log('제출 값:', values);
};
const onFinishFailed: FormProps<OrderFormValues>['onFinishFailed'] = (errorInfo) => {
console.log('실패:', errorInfo);
};
return (
<Form
form={form}
layout="vertical"
onFinish={onFinish}
onFinishFailed={onFinishFailed}
initialValues={{ status: 'pending' }}
>
<Form.Item
label="주문명"
name="name"
rules={[{ required: true, message: '주문명을 입력해주세요.' }]}
>
<Input placeholder="주문명 입력" />
</Form.Item>
<Form.Item
label="상태"
name="status"
rules={[{ required: true }]}
>
<Select options={[
{ value: 'pending', label: '대기중' },
{ value: 'active', label: '진행중' },
]} />
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit">
저장
</Button>
</Form.Item>
</Form>
);
}
import { Table, Space, Button, Tag } from 'antd';
import type { TableProps, ColumnsType } from 'antd';
interface Order {
id: string;
name: string;
status: 'pending' | 'active' | 'done';
createdAt: string;
}
const columns: ColumnsType<Order> = [
{
title: '주문 ID',
dataIndex: 'id',
key: 'id',
width: 100,
},
{
title: '주문명',
dataIndex: 'name',
key: 'name',
sorter: (a, b) => a.name.localeCompare(b.name),
},
{
title: '상태',
dataIndex: 'status',
key: 'status',
render: (status: Order['status']) => {
const colorMap = { pending: 'gold', active: 'blue', done: 'green' };
const labelMap = { pending: '대기중', active: '진행중', done: '완료' };
return <Tag color={colorMap[status]}>{labelMap[status]}</Tag>;
},
filters: [
{ text: '대기중', value: 'pending' },
{ text: '진행중', value: 'active' },
],
onFilter: (value, record) => record.status === value,
},
{
title: '액션',
key: 'action',
render: (_, record) => (
<Space>
<Button size="small" onClick={() => handleEdit(record)}>수정</Button>
<Button size="small" danger onClick={() => handleDelete(record.id)}>삭제</Button>
</Space>
),
},
];
function OrderTable() {
const { data, isLoading } = useOrderQuery();
const tableProps: TableProps<Order> = {
columns,
dataSource: data?.orders,
rowKey: 'id',
loading: isLoading,
pagination: {
pageSize: 20,
showSizeChanger: true,
showTotal: (total) => `전체 ${total}건`,
},
scroll: { x: 800 },
};
return <Table {...tableProps} />;
}
import { Modal, Button } from 'antd';
import { useState } from 'react';
function OrderModal() {
const [open, setOpen] = useState(false);
return (
<>
<Button onClick={() => setOpen(true)}>주문 추가</Button>
<Modal
title="주문 추가"
open={open}
onOk={() => setOpen(false)}
onCancel={() => setOpen(false)}
footer={[
<Button key="cancel" onClick={() => setOpen(false)}>취소</Button>,
<Button key="submit" type="primary" onClick={handleSubmit}>저장</Button>,
]}
>
<OrderForm />
</Modal>
</>
);
}
import { App } from 'antd';
// ✅ App 컴포넌트 내부에서 훅 사용 (v5+)
function OrderActions() {
const { message, notification } = App.useApp();
const handleSave = async () => {
try {
await saveOrder();
message.success('저장되었습니다.');
} catch {
notification.error({
message: '저장 실패',
description: '다시 시도해주세요.',
});
}
};
return <Button onClick={handleSave}>저장</Button>;
}
// src/main.tsx - App 컴포넌트로 래핑 필수
function Root() {
return (
<ConfigProvider>
<App>
<AppRoutes />
</App>
</ConfigProvider>
);
}
import { theme } from 'antd';
function StyledComponent() {
const { token } = theme.useToken();
return (
<div
style={{
padding: token.paddingMD,
borderRadius: token.borderRadius,
backgroundColor: token.colorBgContainer,
color: token.colorText,
}}
>
내용
</div>
);
}
ConfigProvider로 locale 및 theme 설정?App 컴포넌트로 래핑해 message/notification 훅 사용?Form.useForm() 사용?rowKey 지정?@ant-design/icons에서 import?