chore(rebar): Pier_T_rebar 작업 폴더 초기 구성 및 외부 의존 파일 통합
- Code\rebar_pipeline, review_pipeline, pier-program을 정션에서 실제 폴더로 전환 - Code\rhino_mcp 및 CLAUDE_rhino배경.md 추가, .mcp.json은 PYTHONPATH로 새 위치 사용 - pier-program 내부 .git 제거(이력은 backup\pier-program_20261028.bundle에 보관) - worktree 가이드 반영(CLAUDE.local.md, HANDOFF.md) - D:\Rhino-MCP 경로 참조를 새 위치로 치환 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
964a841de1
3978 files changed
+58013356
No files matched your search
@@ -0,0 +1,517 @@
|
||||
---
|
||||
name: phase-5-design-system
|
||||
classification: capability
|
||||
classification-reason: Pattern guidance may overlap with model's built-in knowledge as it improves
|
||||
deprecation-risk: medium
|
||||
description: |
|
||||
Build platform-independent design systems and consistent component libraries.
|
||||
Triggers: design system, component library, design tokens, 디자인 시스템, 컴포넌트.
|
||||
imports:
|
||||
- ${PLUGIN_ROOT}/templates/pipeline/phase-5-design-system.template.md
|
||||
hooks:
|
||||
Stop:
|
||||
- type: command
|
||||
command: "node ${HMCMKIT_PLUGIN_ROOT}/scripts/phase5-design-stop.js"
|
||||
timeout: 10000
|
||||
agents:
|
||||
default: hmcmkit:pipeline-guide
|
||||
frontend: hmcmkit:frontend-architect
|
||||
allowed-tools:
|
||||
- Read
|
||||
- Write
|
||||
- Edit
|
||||
- Glob
|
||||
- Bash
|
||||
user-invocable: false
|
||||
next-skill: phase-6-ui-integration
|
||||
pdca-phase: do
|
||||
task-template: "[Phase-5] {feature}"
|
||||
---
|
||||
|
||||
# Phase 5: Design System
|
||||
|
||||
> Build platform-independent design system
|
||||
|
||||
## Purpose
|
||||
|
||||
Build a reusable UI component library. Enable consistent design and fast development.
|
||||
|
||||
---
|
||||
|
||||
## What is a Design System?
|
||||
|
||||
### Definition
|
||||
|
||||
A design system is **a collection of reusable components and clear standards** that enables building consistent user experiences at scale.
|
||||
|
||||
### Why is it Needed? (Framework Agnostic)
|
||||
|
||||
| Problem | Design System Solution |
|
||||
|---------|----------------------|
|
||||
| Designer-developer mismatch | Single Source of Truth |
|
||||
| Duplicate component development | Reusable component library |
|
||||
| Inconsistent UI/UX | Unified design tokens and rules |
|
||||
| Increased maintenance cost | Centralized change management |
|
||||
| Delayed new member onboarding | Documented component catalog |
|
||||
|
||||
### 3 Layers of Design System
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ Design Tokens │
|
||||
│ Color, Typography, Spacing, Radius, Shadow, ... │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ Core Components │
|
||||
│ Button, Input, Card, Dialog, Avatar, Badge, ... │
|
||||
├─────────────────────────────────────────────────────┤
|
||||
│ Composite Components │
|
||||
│ Form, DataTable, Navigation, SearchBar, ... │
|
||||
└─────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Platform-specific Implementation Tools
|
||||
|
||||
| Platform | Recommended Tools | Design Token Method |
|
||||
|----------|------------------|---------------------|
|
||||
| **Web (React/Next.js)** | shadcn/ui, Radix | CSS Variables |
|
||||
| **Web (Vue)** | Vuetify, PrimeVue | CSS Variables |
|
||||
| **Flutter** | Material 3, Custom Theme | ThemeData |
|
||||
| **iOS (SwiftUI)** | Native Components | Asset Catalog, Color Set |
|
||||
| **Android (Compose)** | Material 3 | MaterialTheme |
|
||||
| **React Native** | NativeBase, Tamagui | StyleSheet + Theme |
|
||||
|
||||
---
|
||||
|
||||
## What to Do in This Phase
|
||||
|
||||
1. **Install Base Components**: Button, Input, Card, etc.
|
||||
2. **Customize**: Adjust to project style
|
||||
3. **Composite Components**: Combine multiple base components
|
||||
4. **Documentation**: Document component usage
|
||||
|
||||
## Deliverables
|
||||
|
||||
```
|
||||
components/
|
||||
└── ui/ # shadcn/ui components
|
||||
├── button.tsx
|
||||
├── input.tsx
|
||||
├── card.tsx
|
||||
└── ...
|
||||
|
||||
lib/
|
||||
└── utils.ts # Utilities (cn function, etc.)
|
||||
|
||||
docs/02-design/
|
||||
└── design-system.md # Design system specification
|
||||
```
|
||||
|
||||
## PDCA Application
|
||||
|
||||
- **Plan**: Required component list
|
||||
- **Design**: Component structure, variants design
|
||||
- **Do**: Implement/customize components
|
||||
- **Check**: Review consistency
|
||||
- **Act**: Finalize and proceed to Phase 6
|
||||
|
||||
## Level-wise Application
|
||||
|
||||
| Level | Application Method |
|
||||
|-------|-------------------|
|
||||
| Starter | Optional (simple projects may skip) |
|
||||
| Dynamic | Required |
|
||||
| Enterprise | Required (including design tokens) |
|
||||
|
||||
## shadcn/ui Installation
|
||||
|
||||
```bash
|
||||
# Initial setup
|
||||
npx shadcn@latest init
|
||||
|
||||
# Add components
|
||||
npx shadcn@latest add button
|
||||
npx shadcn@latest add input
|
||||
npx shadcn@latest add card
|
||||
```
|
||||
|
||||
## Required Component List
|
||||
|
||||
### Basic
|
||||
- Button, Input, Textarea
|
||||
- Card, Badge, Avatar
|
||||
- Dialog, Sheet, Popover
|
||||
|
||||
### Form
|
||||
- Form, Label, Select
|
||||
- Checkbox, Radio, Switch
|
||||
|
||||
### Navigation
|
||||
- Navigation Menu, Tabs
|
||||
- Breadcrumb, Pagination
|
||||
|
||||
## Custom Theme Building
|
||||
|
||||
### Design Token Override
|
||||
|
||||
shadcn/ui is CSS variable-based, so customize themes in `globals.css`.
|
||||
|
||||
```css
|
||||
/* globals.css */
|
||||
@layer base {
|
||||
:root {
|
||||
/* ===== Colors ===== */
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
--primary: 221.2 83.2% 53.3%; /* Brand main color */
|
||||
--primary-foreground: 210 40% 98%;
|
||||
--secondary: 210 40% 96.1%;
|
||||
--accent: 210 40% 96.1%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--muted: 210 40% 96.1%;
|
||||
--muted-foreground: 215.4 16.3% 46.9%;
|
||||
|
||||
/* ===== Typography ===== */
|
||||
--font-sans: 'Pretendard', sans-serif;
|
||||
--font-mono: 'JetBrains Mono', monospace;
|
||||
|
||||
/* ===== Spacing (rem units) ===== */
|
||||
--spacing-xs: 0.25rem; /* 4px */
|
||||
--spacing-sm: 0.5rem; /* 8px */
|
||||
--spacing-md: 1rem; /* 16px */
|
||||
--spacing-lg: 1.5rem; /* 24px */
|
||||
--spacing-xl: 2rem; /* 32px */
|
||||
|
||||
/* ===== Border Radius ===== */
|
||||
--radius: 0.5rem;
|
||||
--radius-sm: 0.25rem;
|
||||
--radius-lg: 0.75rem;
|
||||
--radius-full: 9999px;
|
||||
|
||||
/* ===== Shadows ===== */
|
||||
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
|
||||
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--foreground: 210 40% 98%;
|
||||
--primary: 217.2 91.2% 59.8%;
|
||||
/* ... dark mode overrides */
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Tailwind Config Extension
|
||||
|
||||
```js
|
||||
// tailwind.config.js
|
||||
module.exports = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
brand: {
|
||||
50: 'hsl(var(--brand-50))',
|
||||
500: 'hsl(var(--brand-500))',
|
||||
900: 'hsl(var(--brand-900))',
|
||||
},
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['var(--font-sans)', 'system-ui'],
|
||||
mono: ['var(--font-mono)', 'monospace'],
|
||||
},
|
||||
spacing: {
|
||||
'xs': 'var(--spacing-xs)',
|
||||
'sm': 'var(--spacing-sm)',
|
||||
'md': 'var(--spacing-md)',
|
||||
'lg': 'var(--spacing-lg)',
|
||||
'xl': 'var(--spacing-xl)',
|
||||
},
|
||||
borderRadius: {
|
||||
'sm': 'var(--radius-sm)',
|
||||
'DEFAULT': 'var(--radius)',
|
||||
'lg': 'var(--radius-lg)',
|
||||
'full': 'var(--radius-full)',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Design Token Documentation
|
||||
|
||||
Recommended to create `docs/02-design/design-tokens.md` per project:
|
||||
|
||||
| Token | Value | Purpose |
|
||||
|-------|-------|---------|
|
||||
| `--primary` | `221.2 83.2% 53.3%` | Brand main color |
|
||||
| `--radius` | `0.5rem` | Default border-radius |
|
||||
| `--font-sans` | `Pretendard` | Body font |
|
||||
|
||||
## Component Customization
|
||||
|
||||
```tsx
|
||||
// Extend default button to project style
|
||||
const Button = React.forwardRef<
|
||||
HTMLButtonElement,
|
||||
ButtonProps & { isLoading?: boolean }
|
||||
>(({ isLoading, children, ...props }, ref) => {
|
||||
return (
|
||||
<ButtonPrimitive ref={ref} {...props}>
|
||||
{isLoading ? <Spinner /> : children}
|
||||
</ButtonPrimitive>
|
||||
);
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Mobile App Design System
|
||||
|
||||
### Flutter: Custom Theme Building
|
||||
|
||||
Flutter defines design tokens through `ThemeData`.
|
||||
|
||||
```dart
|
||||
// lib/theme/app_theme.dart
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class AppTheme {
|
||||
// ===== Design Tokens =====
|
||||
|
||||
// Colors
|
||||
static const Color primary = Color(0xFF3B82F6);
|
||||
static const Color secondary = Color(0xFF64748B);
|
||||
static const Color destructive = Color(0xFFEF4444);
|
||||
static const Color background = Color(0xFFFFFFFF);
|
||||
static const Color foreground = Color(0xFF0F172A);
|
||||
|
||||
// Spacing
|
||||
static const double spacingXs = 4.0;
|
||||
static const double spacingSm = 8.0;
|
||||
static const double spacingMd = 16.0;
|
||||
static const double spacingLg = 24.0;
|
||||
static const double spacingXl = 32.0;
|
||||
|
||||
// Border Radius
|
||||
static const double radiusSm = 4.0;
|
||||
static const double radiusMd = 8.0;
|
||||
static const double radiusLg = 12.0;
|
||||
static const double radiusFull = 9999.0;
|
||||
|
||||
// ===== Theme Data =====
|
||||
|
||||
static ThemeData get lightTheme => ThemeData(
|
||||
useMaterial3: true,
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
seedColor: primary,
|
||||
brightness: Brightness.light,
|
||||
),
|
||||
fontFamily: 'Pretendard',
|
||||
|
||||
// Button Theme
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: spacingMd,
|
||||
vertical: spacingSm,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(radiusMd),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// Card Theme
|
||||
cardTheme: CardTheme(
|
||||
elevation: 2,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(radiusLg),
|
||||
),
|
||||
),
|
||||
|
||||
// Input Theme
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(radiusMd),
|
||||
),
|
||||
contentPadding: EdgeInsets.all(spacingSm),
|
||||
),
|
||||
);
|
||||
|
||||
static ThemeData get darkTheme => ThemeData(
|
||||
useMaterial3: true,
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
seedColor: primary,
|
||||
brightness: Brightness.dark,
|
||||
),
|
||||
fontFamily: 'Pretendard',
|
||||
// ... dark theme overrides
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Flutter: Reusable Components
|
||||
|
||||
```dart
|
||||
// lib/components/app_button.dart
|
||||
import 'package:flutter/material.dart';
|
||||
import '../theme/app_theme.dart';
|
||||
|
||||
enum AppButtonVariant { primary, secondary, destructive, outline }
|
||||
|
||||
class AppButton extends StatelessWidget {
|
||||
final String label;
|
||||
final VoidCallback? onPressed;
|
||||
final AppButtonVariant variant;
|
||||
final bool isLoading;
|
||||
|
||||
const AppButton({
|
||||
required this.label,
|
||||
this.onPressed,
|
||||
this.variant = AppButtonVariant.primary,
|
||||
this.isLoading = false,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ElevatedButton(
|
||||
onPressed: isLoading ? null : onPressed,
|
||||
style: _getStyle(),
|
||||
child: isLoading
|
||||
? SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: Text(label),
|
||||
);
|
||||
}
|
||||
|
||||
ButtonStyle _getStyle() {
|
||||
switch (variant) {
|
||||
case AppButtonVariant.destructive:
|
||||
return ElevatedButton.styleFrom(
|
||||
backgroundColor: AppTheme.destructive,
|
||||
);
|
||||
case AppButtonVariant.outline:
|
||||
return ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.transparent,
|
||||
side: BorderSide(color: AppTheme.primary),
|
||||
);
|
||||
default:
|
||||
return ElevatedButton.styleFrom();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Flutter: Project Structure
|
||||
|
||||
```
|
||||
lib/
|
||||
├── theme/
|
||||
│ ├── app_theme.dart # ThemeData + Design Tokens
|
||||
│ ├── app_colors.dart # Color constants
|
||||
│ ├── app_typography.dart # TextStyle definitions
|
||||
│ └── app_spacing.dart # Spacing constants
|
||||
├── components/
|
||||
│ ├── app_button.dart
|
||||
│ ├── app_input.dart
|
||||
│ ├── app_card.dart
|
||||
│ └── app_dialog.dart
|
||||
└── main.dart
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Cross-Platform Design Token Sharing
|
||||
|
||||
### Design Token JSON (Platform Independent)
|
||||
|
||||
Centrally manage tokens with Figma Tokens or Style Dictionary.
|
||||
|
||||
```json
|
||||
// tokens/design-tokens.json
|
||||
{
|
||||
"color": {
|
||||
"primary": { "value": "#3B82F6" },
|
||||
"secondary": { "value": "#64748B" },
|
||||
"destructive": { "value": "#EF4444" }
|
||||
},
|
||||
"spacing": {
|
||||
"xs": { "value": "4px" },
|
||||
"sm": { "value": "8px" },
|
||||
"md": { "value": "16px" },
|
||||
"lg": { "value": "24px" }
|
||||
},
|
||||
"radius": {
|
||||
"sm": { "value": "4px" },
|
||||
"md": { "value": "8px" },
|
||||
"lg": { "value": "12px" }
|
||||
},
|
||||
"font": {
|
||||
"family": { "value": "Pretendard" },
|
||||
"size": {
|
||||
"sm": { "value": "14px" },
|
||||
"md": { "value": "16px" },
|
||||
"lg": { "value": "18px" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Platform-specific Conversion
|
||||
|
||||
```bash
|
||||
# Generate tokens for each platform with Style Dictionary
|
||||
npx style-dictionary build
|
||||
|
||||
# Output:
|
||||
# - build/css/variables.css (Web)
|
||||
# - build/dart/app_tokens.dart (Flutter)
|
||||
# - build/swift/AppTokens.swift (iOS)
|
||||
# - build/kt/AppTokens.kt (Android)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Design System Checklist (Platform Agnostic)
|
||||
|
||||
### Required Items
|
||||
|
||||
- [ ] **Design Tokens Definition**
|
||||
- [ ] Colors (Primary, Secondary, Semantic)
|
||||
- [ ] Typography (Font Family, Sizes, Weights)
|
||||
- [ ] Spacing (xs, sm, md, lg, xl)
|
||||
- [ ] Border Radius
|
||||
- [ ] Shadows/Elevation
|
||||
|
||||
- [ ] **Core Components**
|
||||
- [ ] Button (variants: primary, secondary, outline, destructive)
|
||||
- [ ] Input/TextField
|
||||
- [ ] Card
|
||||
- [ ] Dialog/Modal
|
||||
- [ ] Avatar
|
||||
- [ ] Badge
|
||||
|
||||
- [ ] **Composite Components**
|
||||
- [ ] Form (with validation)
|
||||
- [ ] Navigation (Header, Sidebar, Bottom Nav)
|
||||
- [ ] Data Display (Table, List)
|
||||
|
||||
- [ ] **Documentation**
|
||||
- [ ] Component catalog (Storybook / Widgetbook)
|
||||
- [ ] Usage guidelines
|
||||
- [ ] Do's and Don'ts
|
||||
|
||||
---
|
||||
|
||||
## Template
|
||||
|
||||
See `templates/pipeline/phase-5-design-system.template.md`
|
||||
|
||||
## Next Phase
|
||||
|
||||
Phase 6: UI Implementation + API Integration → Components are ready, now implement actual screens
|
||||
Reference in new issue
Block a user