styled-components
styled-components 스타일링 규칙. styled() API, ThemeProvider, createGlobalStyle, *.styled.ts 파일 분리.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
styled-components 스타일링 규칙. styled() API, ThemeProvider, createGlobalStyle, *.styled.ts 파일 분리.
التثبيت باستخدام 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 | styled-components |
| description | styled-components 스타일링 규칙. styled() API, ThemeProvider, createGlobalStyle, *.styled.ts 파일 분리. |
styled-components의 styled() API로 스타일 컴포넌트를 작성한다*.styled.ts 파일로 분리한다// ✅ 좋은 예: 기본 HTML 요소 스타일링
import styled from 'styled-components';
const Container = styled.div`
padding: 16px;
margin-bottom: 8px;
border-radius: 8px;
background-color: ${({ theme }) => theme.colors.surface};
`;
const Title = styled.h2`
font-size: 1.25rem;
font-weight: 700;
color: ${({ theme }) => theme.colors.text.primary};
`;
const Button = styled.button<{ variant?: 'primary' | 'secondary' }>`
display: inline-flex;
align-items: center;
padding: 8px 16px;
border-radius: 6px;
border: none;
cursor: pointer;
font-weight: 500;
transition: background-color 0.2s;
background-color: ${({ variant, theme }) =>
variant === 'secondary' ? theme.colors.secondary : theme.colors.primary};
color: #ffffff;
&:hover {
opacity: 0.9;
}
&:disabled {
cursor: not-allowed;
opacity: 0.5;
}
`;
// ✅ 기존 컴포넌트 확장
import { Link } from 'react-router-dom';
const StyledLink = styled(Link)`
color: ${({ theme }) => theme.colors.primary};
text-decoration: none;
&:hover {
text-decoration: underline;
}
`;
interface StatusBadgeProps {
status: 'active' | 'inactive' | 'pending';
}
const StatusBadge = styled.span<StatusBadgeProps>`
display: inline-block;
padding: 2px 8px;
border-radius: 12px;
font-size: 0.75rem;
font-weight: 500;
background-color: ${({ status, theme }) => {
switch (status) {
case 'active': return theme.colors.success.light;
case 'inactive': return theme.colors.error.light;
case 'pending': return theme.colors.warning.light;
}
}};
color: ${({ status, theme }) => {
switch (status) {
case 'active': return theme.colors.success.dark;
case 'inactive': return theme.colors.error.dark;
case 'pending': return theme.colors.warning.dark;
}
}};
`;
// components/OrderCard/index.tsx
function OrderCard({ order }: { order: Order }) {
return (
<Container>
<Title>{order.name}</Title>
<StatusBadge status={order.status}>{order.status}</StatusBadge>
</Container>
);
}
export default OrderCard;
// 파일 하단에 스타일 정의
const Container = styled.div`
padding: 16px;
border: 1px solid ${({ theme }) => theme.colors.border};
border-radius: 8px;
`;
const Title = styled.h3`
font-size: 1rem;
font-weight: 600;
`;
*.styled.ts 파일로 분리// components/OrderTable/styled.ts
import styled from 'styled-components';
export const TableContainer = styled.div`
width: 100%;
overflow-x: auto;
border-radius: 8px;
border: 1px solid ${({ theme }) => theme.colors.border};
`;
export const Table = styled.table`
width: 100%;
border-collapse: collapse;
`;
export const TableHeader = styled.thead`
background-color: ${({ theme }) => theme.colors.surfaceVariant};
`;
export const TableRow = styled.tr<{ isSelected?: boolean }>`
border-bottom: 1px solid ${({ theme }) => theme.colors.divider};
background-color: ${({ isSelected, theme }) =>
isSelected ? theme.colors.primary + '20' : 'transparent'};
&:hover {
background-color: ${({ theme }) => theme.colors.surfaceVariant};
}
`;
export const TableCell = styled.td`
padding: 12px 16px;
font-size: 0.875rem;
color: ${({ theme }) => theme.colors.text.primary};
`;
// components/OrderTable/index.tsx - named import 사용
import { TableContainer, Table, TableHeader, TableRow, TableCell } from './styled';
// styles/theme.ts
export const theme = {
colors: {
primary: '#1677ff',
secondary: '#6b7280',
surface: '#ffffff',
surfaceVariant: '#f9fafb',
border: '#e5e7eb',
divider: '#f3f4f6',
text: {
primary: '#111827',
secondary: '#6b7280',
disabled: '#9ca3af',
},
success: { light: '#dcfce7', dark: '#166534' },
error: { light: '#fee2e2', dark: '#991b1b' },
warning: { light: '#fef9c3', dark: '#854d0e' },
},
spacing: {
xs: '4px',
sm: '8px',
md: '16px',
lg: '24px',
xl: '32px',
},
borderRadius: {
sm: '4px',
md: '8px',
lg: '12px',
full: '9999px',
},
typography: {
fontFamily: '"Pretendard", system-ui, sans-serif',
},
};
export type Theme = typeof theme;
// styles/styled.d.ts
import 'styled-components';
import { Theme } from './theme';
declare module 'styled-components' {
export interface DefaultTheme extends Theme {}
}
// styles/GlobalStyle.ts
import { createGlobalStyle } from 'styled-components';
export const GlobalStyle = createGlobalStyle`
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
font-size: 16px;
}
body {
font-family: ${({ theme }) => theme.typography.fontFamily};
color: ${({ theme }) => theme.colors.text.primary};
background-color: ${({ theme }) => theme.colors.surface};
-webkit-font-smoothing: antialiased;
}
a {
color: inherit;
text-decoration: none;
}
`;
// src/main.tsx
import { ThemeProvider } from 'styled-components';
import { GlobalStyle } from '@/styles/GlobalStyle';
import { theme } from '@/styles/theme';
function App() {
return (
<ThemeProvider theme={theme}>
<GlobalStyle />
<AppRoutes />
</ThemeProvider>
);
}
import styled, { css } from 'styled-components';
// ✅ 재사용 가능한 스타일 조각
const flexCenter = css`
display: flex;
align-items: center;
justify-content: center;
`;
const truncate = css`
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
// 사용
const CenteredBox = styled.div`
${flexCenter}
padding: 16px;
`;
const EllipsisText = styled.p`
${truncate}
max-width: 200px;
`;
*.styled.ts 분리?ThemeProvider로 theme 전역 제공?styled.d.ts로 DefaultTheme 타입 확장?GlobalStyle로 전역 스타일 초기화?