| name | create-mockup |
| description | UIモックアップを作成するスキル。ユーザーが「モックアップを作りたい」「新しいページを作って」「UIデザインを実装したい」「サイトの画面を作りたい」「LP/トップページを作って」「デザインを実装して」などと言った場合は必ずこのスキルを使う。サイト種別・デザインテイスト・ページ種別の3つをヒアリングしてから、このプロジェクトのCLAUDE.md仕様に沿って実装する。Figma URLがない状態でUIを作る場合に特に有効。 |
create-mockup — UIモックアップ作成スキル
ユーザーの要件をヒアリングして、プロジェクトの技術スタック(React 19 + TypeScript + Tailwind CSS v4 + TanStack Router)に沿ったUIモックアップを実装する。
Step 1: サイト・アプリの種類を確認する
まず、何を作りたいか聞く。一問一答で進めると UX がいいので、最初の質問はこれだけでいい:
「どんなサイト・アプリの画面を作りたいですか?(例:ECサイト、コーポレートサイト、ダッシュボード、LP、ブログ、SaaSアプリなど)」
ユーザーの回答から用途・ターゲットユーザー・コンテンツの大まかなイメージを把握する。
Step 2: デザインテイストを確認する
次にデザインの方向性を確認する。以下の観点でまとめて質問すると効率的:
「デザインのイメージを教えてください:
- カラー: ブランドカラーや使いたい色はありますか?(なければ「おまかせ」でも可)
- テイスト: モダン・ミニマル・ナチュラル・ビビッド・クラシックなど、雰囲気のイメージは?
- 参考サイトや気になるデザインがあれば教えてください(なくてもOK)」
ユーザーが「おまかせ」と言った場合は、Step 1 で聞いたサイト種別に合わせて適切なカラーとテイストを自分で決めて、決定内容をユーザーに一言伝えてから進む。
カラーを決めたら @theme に定義する
ユーザーまたは自分で決めたカラーは src/index.css の @theme ブロックに追加する。例:
@theme {
--color-primary: #2C4A7C;
--color-secondary: #F4A261;
--color-accent: #E76F51;
--color-base: #FAF7F2;
}
Tailwind CSS v4 なので tailwind.config.js は使わない。
Step 3: ページ種別と優先順位を確認する
どのページを作るか確認する:
「どのページを作りますか?複数ある場合は優先順位も教えてください。
- トップページ(ヒーロー・特徴・CTA など複数セクション)
- 商品一覧 / 詳細ページ
- 記事一覧 / 詳細ページ
- フォーム(お問い合わせ・サインアップ など)
- その他(具体的に)」
ページが複数ある場合は1ページずつ実装し、完成したら次を聞くスタイルにする。
Step 4: 実装前のクリーンアップ
新規モックアップを作成する前に、スターターのボイラープレートをクリアする。
src/routes/__root.tsx の確認・整理
スターターには <div className="p-2"> などのラッパーが含まれていることがある。これが残っていると、ヒーローセクションの全幅表示などに意図しないマージン・パディングが生じる。
実装前に __root.tsx を読み込み、<Outlet /> の周囲に余分なラッパーや padding があれば除去する:
import { createRootRoute, Outlet } from '@tanstack/react-router'
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
const RootLayout = () => (
<>
<Outlet />
<TanStackRouterDevtools position="bottom-right" />
</>
)
export const Route = createRootRoute({ component: RootLayout })
ヘッダー・フッターをグローバルに配置する場合はここに追加してよい。ただし <Outlet /> を直接囲む div に padding/margin を与えないこと。
Step 5: 実装する
ファイル配置のルール
| 種類 | 配置先 |
|---|
| ページコンポーネント(ルート) | src/routes/ |
| 再利用可能なUIコンポーネント | src/components/ |
| カラー・テーマ定義 | src/index.css の @theme ブロック |
ルートは src/routes/ に置くだけで自動登録される(TanStack Router が routeTree.gen.ts を自動生成するため手動編集不要)。
ルートファイルの命名規則
TanStack Router のファイルベースルーティング規則に従う:
| URL | ファイルパス |
|---|
/ | src/routes/index.tsx |
/about | src/routes/about.tsx |
/products | src/routes/products/index.tsx または src/routes/products.tsx |
/products/:id | src/routes/products/$productId.tsx |
/dashboard | src/routes/dashboard.tsx |
/blog/:slug | src/routes/blog/$slug.tsx |
既存ファイルの上書きについて: このスキルは新規モックアップ作成用なので、index.tsx を含む既存ファイルへの上書きは問題ない。
コンポーネントの分割方針
できるだけ細かく分割して再利用しやすくする。ルートファイルはページ全体の骨格だけを持ち、実際の UI は全てコンポーネントに切り出す。
分割の目安:
- セクション単位(
HeroSection, FeatureSection, CtaSection)
- 繰り返し要素(
ProductCard, KpiCard, ArticleCard)
- 独立して機能するUI部品(
FilterBar, SortDropdown, Pagination)
- ナビゲーション・ヘッダー・フッター
悪い例(避ける): products.tsx 1ファイルに全JSXを書く
良い例: products.tsx が ProductGrid, ProductCard, FilterBar をインポートして組み合わせる
関連コンポーネントが複数あるときはサブディレクトリにまとめる(例: src/components/dashboard/)。
コンポーネントの書き方
プロジェクトには3つのスタイリングアプローチがある。用途に合わせて選ぶ:
シンプルな条件付きスタイル → cn() 関数
import { cn } from '@/lib/utils'
function Badge({ active, className }: { active?: boolean; className?: string }) {
return (
<span className={cn('px-2 py-1 rounded text-sm', active && 'bg-primary text-white', className)}>
...
</span>
)
}
単一要素のバリアント → CVA
import { cva, type VariantProps } from 'class-variance-authority'
import { cn } from '@/lib/utils'
const button = cva('px-4 py-2 rounded font-medium transition', {
variants: {
intent: { primary: 'bg-primary text-white hover:opacity-90', ghost: 'border border-primary text-primary' },
size: { sm: 'text-sm', md: 'text-base', lg: 'text-lg px-6 py-3' },
},
defaultVariants: { intent: 'primary', size: 'md' },
})
複数要素のバリアント → tailwind-variants
import { tv, type VariantProps } from 'tailwind-variants'
const card = tv({
slots: { base: 'rounded-xl overflow-hidden', image: 'w-full object-cover', content: 'p-6' },
variants: { tone: { light: { base: 'bg-white shadow-sm' }, dark: { base: 'bg-gray-900 text-white' } } },
})
必ず守るルール
ヒーローセクションのサンプル構造(参考)
import { createFileRoute } from '@tanstack/react-router'
import { HeroSection } from '@/components/HeroSection'
import { FeatureSection } from '@/components/FeatureSection'
import { CtaSection } from '@/components/CtaSection'
export const Route = createFileRoute('/')({
component: HomePage,
})
function HomePage() {
return (
<main>
<HeroSection />
<FeatureSection />
<CtaSection />
</main>
)
}
Step 6: 実装後の確認
実装が終わったら以下の順で確認する:
1. クラス重複・命名衝突チェック(必須)
各コンポーネントで同じクラスが複数回指定されていないか確認する。
チェック観点:
- クラスの重複: 同じ
className 内に同じクラス名が2回以上ある(例: text-surface text-surface)
- サイズ vs カラーの衝突:
@theme で定義した色名と Tailwind 組み込みユーティリティ名が被っていないか(Step 2 の命名規則を参照)
- 意味の競合:
text-sm と text-base のようにフォントサイズ系クラスが同じ要素に複数ある
2. 型チェック・ビルド確認
<pm> run check
<pm> run build
TypeScript エラーや Vite のビルドエラーがないことを確認する。
3. 開発サーバーの起動
ビルドが成功したら、開発サーバーをバックグラウンドで起動する。Vite は他のポートが使用中の場合、5174・5175… と自動でポートを変えるため、起動後に実際のポートを取得してユーザーに伝えること。
手順:
run_in_background: true でサーバーを起動し、出力ファイルのパスを控える
- 2〜3秒待ってから出力ファイルを Read する
Local: http://localhost:XXXX/ の行からポート番号を取得する
- そのURLをユーザーに案内する
grep -oE 'localhost:[0-9]+' <出力ファイルパス> | head -1
4. 報告と次の工程選択
ユーザーに完成を報告し、AskUserQuestion ツールで次のアクションを選択してもらう:
次に何をしますか?
1. Figma にキャプチャとして取り込む
→ ブラウザのレンダリング結果をそのまま Figma に画像として移植(generate_figma_design)
2. Figma ノードとして生成する(/figma:figma-use)
→ コンポーネント・変数・オートレイアウトを持つデザインシステムとして作成
3. Tailwind 変数を Figma Variables に移植する(/tailwind-to-figma)
→ src/index.css の @theme トークンを Figma の Variables として登録
4. このままで終了
選択に応じて対応するスキルを呼び出す:
- 1 を選択 → 以下の手順で
generate_figma_design MCP ツールを直接呼ぶ(スキル経由にしない):
- Step 6.3 で起動した開発サーバーの URL(例:
http://localhost:5173)を使用する
- まず
outputMode なしで generate_figma_design を呼び、取り込み先の選択肢を表示する
- ユーザーが選択したら
outputMode とURLを指定して再度呼ぶ
- 返却された
captureId を使い、5秒おきに最大10回ポーリングして完了を待つ
- 注意:
/figma:figma-generate-design スキルは呼ばない。use_figma も呼ばない。純粋なキャプチャのみ。
- 2 を選択 →
/figma:figma-use スキルを起動
- 3 を選択 →
/tailwind-to-figma スキルを起動
- 4 を選択 → 「お疲れ様でした!」と伝えて終了
よくある落とし穴
routeTree.gen.ts は自動生成されるため 絶対に手動編集しない
- Tailwind v4 は
@theme でカスタムトークンを定義(JS設定ファイル不要)
--color-base は使わない: text-base(font-size: 1rem)と衝突する。--color-surface など別名を使う
- パスエイリアスは
@/ で src/ を指す(vite.config.ts と tsconfig.app.json 両方で設定済み)
- コンポーネントは named export で書く(default export は TanStack Router のルートコンポーネント以外では使わない)
- 大文字テキスト: HTML に直接
ABOUT と書かず <span className="uppercase">About</span> にする(スクリーンリーダー対策)
- ナビゲーション:
nav > ul > li > a の構造を必ず使う。TanStack Router の <Link> を <li> の中に入れる