mcpField
S
stitch-react-components

stitch-react-components

github.com/gabelul開発4756 回インストール14 週間前に更新
リポジトリ

stitch-react-components について

Stitchのデザイン、ローカルHTML、URLを、Viteや通常のReactプロジェクト向けのモジュール化されたコンポーネントに変換するスキルです。デザイントークンの抽出、テーマ設定、構成を案内し、Next.jsは対象外です。

主な機能

  1. 01HTMLデザインをReactコンポーネントに変換
  2. 02Stitch、ローカルファイル、URLに対応
  3. 03デザイントークン抽出とダークモード対応
  4. 04コンポーネント、データ、共有型を整理
  5. 05HTMLダウンロード用スクリプトを提供

活用シーン

  1. 01ViteのReactアプリでStitch画面を再構築
  2. 02ローカルHTMLデザインをReactコンポーネントに変換
  3. 03ウェブページのデザインを通常のReactプロジェクトに移植

MCP 対応

Stitch画面を入力にする場合、Stitch MCPで関連ツールを探し、画面のメタデータを取得します。それ以外のHTMLソースではStitch MCPは不要です。

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/gabelul/stitch-kit --skill stitch-react-components

インストール後、Claude Code で/stitch-react-componentsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
tailwind-to-react.md
resources/
architecture-checklist.md
component-template.tsx
scripts/
fetch-stitch.sh

詳細

Stitch → Vite / React コンポーネント

制約: ユーザーが「Stitch」とReact(Vite、CRA、またはNext.jsを使わない「React app」)に明示的に言及した場合のみ、このスキルを使用してください。

Stitchのモバイル/デスクトップデザインを、Vite + TypeScriptを使用したクリーンでモジュール化されたReactコンポーネントに変換するフロントエンドエンジニアです。このスキルの対象は通常のReactアプリであり、Next.js App Routerは対象外です。Next.jsの場合は、代わりにstitch-nextjs-componentsを使用してください。

このスキルとNext.jsの使い分け

シナリオ使用するもの
ユーザーが「React app」「Vite」「CRA」と言うstitch-react-components
ユーザーが「Next.js」「App Router」「SSR」と言うstitch-nextjs-components
ユーザーが後からshadcn/uiコンポーネントの追加を希望するstitch-react-components → 続けてstitch-shadcn-ui
ユーザーがサーバーサイドレンダリングまたはファイルベースのルーティングを希望するstitch-nextjs-components

前提条件

HTMLソース。以下のいずれかを使用できます。

  • Stitchの画面 — Stitch MCPへのアクセスと、生成済みの画面が必要です
  • ローカルHTMLファイル — Stitchアカウントは不要です
  • URL — Stitchアカウントは不要です

また、以下が必要です。

  • Node.js + npm/pnpm
  • Vite + Reactプロジェクトの初期化:npm create vite@latest my-app -- --template react-ts

ステップ1:ソースを解決する

以降の処理では、すべて1つのファイルtemp/source.htmlを読み込みます。ユーザーから渡されたものに合う方法でHTMLをそこに取得してから、ステップ2に進んでください。マークアップの取得元にかかわらず、このスキルの残りの手順は同じです。

Stitchの画面から取得する場合:

  1. 名前空間を確認する — list_toolsを使ってStitch MCPのプレフィックスを見つけます
  2. メタデータを取得する — 数値のprojectIdとscreenIdを指定して[prefix]:get_screenを呼び出します
  3. HTMLをダウンロードする — GCS URLには、信頼性の高いダウンローダーが必要です。
    bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html"
    
  4. 見た目を確認する — 書き換える前にscreenshot.downloadUrlを確認してください。フル解像度で取得するには、そのURLに=s0を追加します。URLをそのまま使うと、APIが報告するwidth/heightに関係なく、512pxのサムネイルが返されます。

ローカルHTMLファイルから取得する場合:

mkdir -p temp && cp "path/to/design.html" temp/source.html

URLから取得する場合:

bash scripts/fetch-stitch.sh "https://example.com/page" "temp/source.html"

スクリプトの名前にかかわらず、これは汎用の堅牢なダウンローダーです。リダイレクトに従い、一時的なエラーを再試行し、gzipを処理し、結果が空の場合は明確に失敗します。URLがStitchを指しているかどうかは問いません。

スクリーンショットから取得する場合: アップロードする方法はありません。Stitch MCP APIには画像アップロード用のツールがありません。stitch-mcp-generate-screen-from-textを使ってテキストプロンプトからデザインを再現するか、HTMLを手動で記述して上記のローカルファイルの方法を使ってください。

APIキーが必要なのはStitch経由の場合のみです。ローカルファイルまたはURLの変換には、Googleアカウントは必要ありません。

ステップ2:プロジェクト構成

src/
├── components/           ← One file per component
│   └── [Name].tsx
├── data/
│   └── mockData.ts       ← Static content (never in components)
├── theme/
│   ├── tokens.ts         ← Design token constants
│   └── useTheme.ts       ← Dark mode hook
├── types/
│   └── index.ts          ← Shared TypeScript types
├── App.tsx               ← Root component
└── main.tsx              ← Entry point

ステップ3:デザイントークンを抽出する

HTMLに実際に含まれている情報をもとに、以下の順序でトークンを特定します。

  1. <head>内のインラインtailwind.config(Stitchが出力するもの)— 存在する場合はそのまま使用します。
  2. CSSカスタムプロパティ(:root { --color-primary: ... })— 手書きHTMLやテンプレートHTMLでよく使われます。
  3. リンクされた、またはインラインのスタイルシート — 宣言された色、フォントファミリー、角丸、間隔を解析します。
  4. 最後の手段 — マークアップ内で最も頻繁に使われる計算済みの値(背景の基調色、テキスト色、アクセントカラー、見出し/本文のフォント、角丸)からトークンを導き出し、推定した内容をユーザーに伝えて修正できるようにします。

URL経由の方法では、単一のHTMLレスポンスだけをダウンロードします。外部リンクされたスタイルシートは取得できないことがあります。上記の方法でトークンを特定できない場合は、配色を作り出すのではなく、その旨を伝えてください。

// src/theme/tokens.ts
export const lightTokens = {
  background: '#FFFFFF',
  surface:    '#F4F4F5',
  primary:    '#6366F1',
  primaryFg:  '#FFFFFF',
  text:       '#09090B',
  textMuted:  '#71717A',
  border:     '#E4E4E7',
} as const

export const darkTokens = {
  background: '#09090B',
  surface:    '#18181B',
  primary:    '#818CF8',
  primaryFg:  '#09090B',
  text:       '#FAFAFA',
  textMuted:  '#A1A1AA',
  border:     '#27272A',
} as const

export type ThemeTokens = typeof lightTokens
// src/theme/useTheme.ts
import { useEffect, useState } from 'react'
import { lightTokens, darkTokens, type ThemeTokens } from './tokens'

/**
 * Returns current theme tokens based on system color scheme.
 * Listens for system-level dark/light mode changes.
 */
export function useTheme(): ThemeTokens {
  const [isDark, setIsDark] = useState(
    () => window.matchMedia('(prefers-color-scheme: dark)').matches
  )

  useEffect(() => {
    const mq = window.matchMedia('(prefers-color-scheme: dark)')
    const handler = (e: MediaQueryListEvent) => setIsDark(e.matches)
    mq.addEventListener('change', handler)
    return () => mq.removeEventListener('change', handler)
  }, [])

  return isDark ? darkTokens : lightTokens
}

ステップ4:コンポーネント変換ルール

レイアウトのマッピング
HTML/CSS→ React / Tailwind
display:flex; flex-direction:column<div className="flex flex-col gap-4">
display:flex; flex-direction:row<div className="flex items-center gap-2">
justify-content:space-between<div className="flex justify-between">
display:grid; grid-template-columns:1fr 1fr<div className="grid grid-cols-2 gap-4">
overflow-y:scroll<div className="overflow-y-auto">
長いリストitems.map(item => <Card key={item.id} {...item} />)
<img><img src="..." alt="..." className="object-cover">
Tailwind クラスのマッピング

カスタムトークンを参照しない場合は、ソース HTML の Tailwind クラスを JSX で直接使用します。カスタムトークンは CSS 変数にマッピングします。

// Source HTML: bg-primary → CSS variable → Tailwind arbitrary value
// OR: use inline style with token value

// Option A — Tailwind arbitrary value (if custom tokens in tailwind.config)
<div className="bg-[--color-primary] text-[--color-primaryFg]">

// Option B — inline style with useTheme()
const theme = useTheme()
<div style={{ backgroundColor: theme.primary, color: theme.primaryFg }}>
コンポーネントのテンプレート
// src/components/StitchComponent.tsx

/**
 * Props for StitchComponent — all data via props, never fetched inside.
 */
interface StitchComponentProps {
  /** Primary heading text */
  title: string
  /** Supporting description — optional */
  description?: string
  /** Primary action callback */
  onAction?: () => void
}

/**
 * StitchComponent — [describe purpose in one sentence]
 */
export function StitchComponent({
  title,
  description,
  onAction,
}: Readonly<StitchComponentProps>) {
  const theme = useTheme()

  return (
    <div
      className="rounded-xl border p-4 gap-2 flex flex-col"
      style={{
        backgroundColor: theme.surface,
        borderColor: theme.border,
      }}
    >
      <h3 className="text-base font-semibold" style={{ color: theme.text }}>
        {title}
      </h3>

      {description ? (
        <p className="text-sm" style={{ color: theme.textMuted }}>
          {description}
        </p>
      ) : null}

      {onAction ? (
        <button
          onClick={onAction}
          className="rounded-lg px-4 py-2 text-sm font-medium transition-opacity hover:opacity-90"
          style={{ backgroundColor: theme.primary, color: theme.primaryFg }}
          type="button"
        >
          Action
        </button>
      ) : null}
    </div>
  )
}

ステップ 5:アーキテクチャのルール

  • ファイルごとにコンポーネントを 1 つ — 単一ファイルにコードを詰め込まない
  • 静的データは src/data/mockData.ts に配置 — JSX にハードコードしない
  • 共有型は src/types/index.ts に配置
  • すべてのコンポーネントに Readonly<ComponentNameProps> インターフェースを用意する
  • 16 進数カラーをハードコードしない — useTheme() または CSS 変数を使用する
  • any 型を使用しない

ステップ 6:shadcn/ui との統合

デザインを基本的な React コンポーネントに変換した後、shadcn/ui を重ねて適用できます。

npx shadcn@latest init    # Set up shadcn in your Vite project
npx shadcn@latest add button card input dialog

次に、stitch-shadcn-ui スキルを使用して、デザイントークンを維持しながら生の HTML 要素を shadcn コンポーネントに置き換えます。

トラブルシューティング

問題解決方法
Tailwind クラスが適用されないtailwind.config.js の content に ./src/**/*.{ts,tsx} が含まれているか確認します
ダークモードが切り替わらないuseTheme() がコンポーネントのレベルで呼び出されており、外部に引き上げられていないことを確認します
画像が表示されない明示的に width と height を追加するか、className="w-full h-auto" を使用します
props の型エラーReadonly<> でラップされていること、および必須の props がすべて指定されていることを確認します

参考資料

  • resources/component-template.tsx — コンポーネントのひな形
  • resources/architecture-checklist.md — リリース前のチェックリスト
  • references/tailwind-to-react.md — トークンとクラスのマッピングガイド(ソース HTML → React/Tailwind)
  • scripts/fetch-stitch.sh — GCS HTML を確実にダウンロードするスクリプト
  • stitch-shadcn-ui — 基本変換後に shadcn/ui コンポーネントを追加する
  • docs/tailwind-reference.md — Tailwind ユーティリティクラスの検索

コメント