// This skill converts UI specifications and component requirements into production-ready React components using shadcn/ui, TypeScript, and Tailwind CSS. Use this when the user describes UI elements, layouts, or interactive components in natural language and needs them implemented as reusable React components. Optimized for the ScaffAI project's tech stack with automatic accessibility support.
| name | ui-spec-to-component |
| description | This skill converts UI specifications and component requirements into production-ready React components using shadcn/ui, TypeScript, and Tailwind CSS. Use this when the user describes UI elements, layouts, or interactive components in natural language and needs them implemented as reusable React components. Optimized for the ScaffAI project's tech stack with automatic accessibility support. |
Transform natural language UI specifications into production-ready React components with shadcn/ui integration, TypeScript type safety, Tailwind CSS styling, and built-in accessibility features.
Use this skill when:
Trigger examples:
Extract component requirements from the user's description:
Example:
Input: "プロジェクトカード、タイトル・ステータス・更新日表示、クリックで詳細へ"
Parsed:
- Component Type: Card
- Data Fields:
- title (string)
- status (enum: active/pending/completed)
- updatedAt (Date)
- Interactions:
- onClick → navigate to details
- Layout: Vertical stack with badge for status
- Accessibility: Button role, keyboard navigation
Map the UI requirements to appropriate shadcn/ui components:
Common Mappings:
Card, CardHeader, CardContentButton (with variant: default, outline, ghost, destructive)Form, FormField, Input, LabelDialog, DialogContent, DialogTriggerTable, TableHeader, TableBody, TableRowCard or native <ul>Select, SelectTrigger, SelectContentBadgeSkeletonuseToast hookReference: Load references/shadcn_components.md for complete component API and usage patterns.
Define TypeScript types for props and data:
// Component props interface
interface ComponentNameProps {
// Data props
title: string;
status: 'active' | 'pending' | 'completed';
updatedAt: Date;
// Event handlers
onClick?: () => void;
// Optional styling
className?: string;
}
// Data model (if needed)
interface DataModel {
id: string;
// ... other fields
}
Create a TypeScript React component with:
Template structure:
import * as React from 'react';
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
/**
* コンポーネントの説明(日本語)
*
* @param props - コンポーネントのプロパティ
* @returns JSX.Element
*/
interface ComponentNameProps {
title: string;
status: 'active' | 'pending' | 'completed';
updatedAt: Date;
onClick?: () => void;
className?: string;
}
export function ComponentName({
title,
status,
updatedAt,
onClick,
className,
}: ComponentNameProps) {
// ステータスバッジの色を決定
const statusVariant = {
active: 'default',
pending: 'secondary',
completed: 'outline',
}[status] as 'default' | 'secondary' | 'outline';
// 更新日のフォーマット
const formattedDate = new Intl.DateTimeFormat('ja-JP', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
}).format(updatedAt);
return (
<Card
className={cn('cursor-pointer hover:shadow-lg transition-shadow', className)}
onClick={onClick}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
onClick?.();
}
}}
>
<CardHeader>
<CardTitle className="flex items-center justify-between">
<span>{title}</span>
<Badge variant={statusVariant}>
{status === 'active' && '稼働中'}
{status === 'pending' && '保留中'}
{status === 'completed' && '完了'}
</Badge>
</CardTitle>
</CardHeader>
<CardContent>
<p className="text-sm text-muted-foreground">
更新日: {formattedDate}
</p>
</CardContent>
</Card>
);
}
Ensure WCAG compliance:
role, aria-label, aria-describedby when neededAccessibility Checklist:
Use Tailwind CSS responsive prefixes:
<div className="
grid grid-cols-1 // Mobile: 1 column
sm:grid-cols-2 // Small: 2 columns
md:grid-cols-3 // Medium: 3 columns
lg:grid-cols-4 // Large: 4 columns
gap-4 // Consistent spacing
">
{/* Cards */}
</div>
Breakpoints:
sm: 640pxmd: 768pxlg: 1024pxxl: 1280px2xl: 1536pxProvide a complete usage example:
// pages/projects.tsx
import { ComponentName } from '@/components/ComponentName';
import { useRouter } from 'next/navigation';
export default function ProjectsPage() {
const router = useRouter();
const projects = [
{
id: '1',
title: 'プロジェクトA',
status: 'active' as const,
updatedAt: new Date('2025-10-22'),
},
// ... more projects
];
return (
<div className="container mx-auto p-6">
<h1 className="text-2xl font-bold mb-6">プロジェクト一覧</h1>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
{projects.map((project) => (
<ComponentName
key={project.id}
title={project.title}
status={project.status}
updatedAt={project.updatedAt}
onClick={() => router.push(`/projects/${project.id}`)}
/>
))}
</div>
</div>
);
}
Provide the complete implementation in the following structure:
## 📋 コンポーネント仕様
[UI要件の要約]
## 🎨 使用するshadcn/uiコンポーネント
- [コンポーネント1]
- [コンポーネント2]
## 📘 TypeScript型定義
\`\`\`typescript
[インターフェース定義]
\`\`\`
## ⚛️ Reactコンポーネント実装
\`\`\`tsx
[完全なコンポーネントコード]
\`\`\`
## ♿ アクセシビリティ対応
- [実装された機能1]
- [実装された機能2]
## 📱 レスポンシブ対応
- モバイル: [説明]
- タブレット: [説明]
- デスクトップ: [説明]
## 📝 使用例
\`\`\`tsx
[実際の使用例コード]
\`\`\`
## 🎯 追加実装の提案(オプション)
- [拡張機能の提案1]
- [拡張機能の提案2]
Input: "プロジェクトカード、名前・ステータス・更新日・クリックで詳細"
Output: Card component with Badge, formatted date, onClick handler
Input: "作図ツールパネル、線・矩形・円・テキストボタン、選択中のツールをハイライト"
Output: Toolbar with Button group, active state management
Input: "見積入力フォーム、項目名・数量・単価、合計を自動計算"
Output: Form with Input fields, auto-calculated total, validation
Input: "確認ダイアログ、削除確認メッセージ・キャンセル・削除ボタン"
Output: Dialog component with danger variant button
This skill is designed for the ScaffAI project structure:
frontend/components/ or frontend/app/(protected)/[page]/components/frontend/components/ui/shared/types/frontend/tailwind.config.tsWhen implementing complex components, load the shadcn/ui reference:
Read references/shadcn_components.md for:
- Complete component API
- Import statements
- Usage patterns
- Variant options
This ensures accurate shadcn/ui component usage without guessing APIs.