stitch::react-native について
StitchデザインをReact Nativeコンポーネントに変換する、または既存コンポーネントを同期するモバイル開発者向けの手順です。デザイン取得と確認、テーマ抽出、コンポーネント設計、任意の検証を扱います。
主な機能
- 01Stitch MCPで画面デザインを取得・ダウンロード
- 02スクリーンショットを確認しプロジェクトメタデータを記録
- 03デザインからテーマトークンを抽出
- 04React Native向けにコンポーネントとロジックを構成
- 05任意で検証と型チェックを実行
活用シーン
- 01複数画面のStitchデザインをReact Native UIとして実装
- 02既存のネイティブコンポーネントを最新デザインに同期
- 03デザインHTMLからテーマトークンとモックデータを作成
- 04許可を得てコンポーネント構成とTypeScriptを確認
MCP 対応
Stitch MCPのget_screenとget_projectを使って画面デザインとプロジェクト設定を取得し、スクリプトでデザインファイルをダウンロードします。MCPは生成コンポーネントの公開ではなく、設計情報の取得に使われます。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ google-labs-code/ stitch-skills --skill stitch::react-nativeインストール後、Claude Code で/stitch::react-nativeを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdpackage.jsonpackage-lock.jsonexamples/gold-standard-card.tsxresources/architecture-checklist.mdcomponent-template.tsxscripts/validate.jsfetch-stitch.sh詳細
Stitch から React Native コンポーネントへ
Stitch の Web デザインを、すっきりとした本番環境対応の React Native コードに変換する、または既存のネイティブコンポーネントを最新の Stitch デザインに合わせて同期・更新することに注力するモバイルエンジニアです。React Native のプリミティブと StyleSheet を使用して、HTML/CSS のレイアウトをネイティブのモバイルコンポーネントに変換します。
重要:このスキルのすべての手順は必須です。手順を省略したり、近道をしたりしないでください。各セクションには、次に進む前に満たす必要があるゲートがあります。
フェーズ 1:取得とネットワーク
ゲート:すべての画面が
scripts/fetch-stitch.shを使ってダウンロードされ、目視で監査されている場合にのみ、フェーズ 1 は完了です。このフェーズを経ずにローカルファイルを直接読むことは禁止されています。
- 名前空間の特定:
list_toolsを実行して Stitch MCP のプレフィックスを確認します。以降のすべての呼び出しで、このプレフィックス(例:stitch:)を使用します。 - メタデータの取得:プロジェクト内のすべての画面について
[prefix]:get_screenを呼び出し、ダウンロード URL を含むデザイン JSON を取得します。画面を省略しないでください。 - 既存デザインの確認:ダウンロードする前に、
.stitch/designs/{page}.htmlと.stitch/designs/{page}.pngがすでに存在するか確認します。- ファイルが存在する場合:MCP を使って Stitch プロジェクトからデザインを更新するか、既存のローカルファイルを再利用するか、ユーザーに確認します。必ず確認してください。独断で決めてはいけません。 ユーザーが承認した場合にのみ再ダウンロードします。
- ファイルが存在しない場合:手順 4 に進みます。
- 信頼性の高いダウンロード:内部の AI 取得ツールは Google Cloud Storage ドメインで失敗することがあります。必ず付属のスクリプトを使用してください。
- HTML:
bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" ".stitch/designs/{page}.html" - スクリーンショット:まず、スクリーンショットの URL の末尾に
=w{width}を追加します。ここでの{width}は画面メタデータのwidthの値です(Google CDN は既定で低解像度のサムネイルを配信します)。その後、次を実行します:bash scripts/fetch-stitch.sh "[screenshot.downloadUrl]=w{width}" ".stitch/designs/{page}.png" - このスクリプトは、必要なリダイレクトとセキュリティハンドシェイクを処理します。
- HTML:
- 目視監査:ダウンロードしたスクリーンショット(
.stitch/designs/{page}.png)を確認し、デザインの意図とレイアウトの詳細を把握します。各スクリーンショットを必ず確認してください。 デザインを推測したまま先に進んではいけません。 - プロジェクトメタデータの追跡:
[prefix]:get_projectを使ってプロジェクト設定を取得し、.stitch/metadata.jsonに保存します(アプリフォルダー内とワークスペースのルートの両方に保存します)。次の項目が含まれていることを確認します。projectId、title、deviceType- 現在の同期実行時刻を ISO 形式で記録した
Last Sync Timeフィールド - 各画面の ID、ラベル、sourceScreen 参照、寸法、canvasPosition を記述した
screensマップ
フェーズ 1 のアンチパターン
- ❌ MCP
get_screenを呼び出す前に.stitch/designs/*.htmlを直接読む。 - ❌
fetch-stitch.shダウンロードスクリプトを使わない。 - ❌ 既存ファイルがあるときにユーザーへ確認しない。
- ❌
.pngスクリーンショットの目視監査を省略する。 - ❌ 同期時に
.stitch/metadata.jsonとそのLast Sync Timeフィールドを生成または更新しない。
フェーズ 2:テーマの抽出
ゲート:現在のプロジェクトの HTML
<head>から抽出したトークンを使ってsrc/theme.tsが作成または更新されている場合にのみ、フェーズ 2 は完了です。カラーの 16 進コードをハードコードしたり、別のプロジェクトのテーマを使用したりすることは認められません。
tailwind.configの抽出:ダウンロードした各 HTML ファイルを開き、<head>内の<script>ブロックにあるtailwind.configオブジェクトを探します。次の項目を抽出します。- すべてのカラー・トークン
- フォントファミリー
- 間隔の値
- 角丸の値
- フォントサイズ/タイポグラフィのトークン
src/theme.tsの作成/同期:抽出したトークンを TypeScript 定数としてsrc/theme.tsに記述します。すべてのカラー、間隔、タイポグラフィの値に、対応するトークンがあることを確認します。- テーマの検証:
src/theme.tsのテーマカラーとフォントが、HTML デザインから抽出した内容と一致することを確認します。
フェーズ 2 のアンチパターン
- ❌ コンポーネントの StyleSheet 宣言内にカラーの 16 進コードや rgba 文字列を直接ハードコードする。
- ❌ 新しいデザインから抽出せず、以前のプロジェクトのテーマトークンを使用する。
- ❌
src/theme.tsの作成または更新を省略する。
フェーズ 3:アーキテクチャルールと HTML のマッピング
ゲート:すべてのコンポーネントは、以下のルールをすべて満たす必要があります。違反すると
npm run validateが失敗します。
要素のマッピング
次のルールに従って、HTML 要素を React Native コンポーネントにマッピングします。
| HTML | React Native | 備考 |
|---|---|---|
<div> | View | デフォルトのコンテナー |
<span>、<p>、<h1>-<h6> | Text | すべてのテキストは Text で囲む必要があります。インラインスタイルには Text をネストします。 |
<img> | Image | リモート画像には source={{ uri }}、ローカルアセットには require() を使用します。 |
<button>、<a> | Pressable | TouchableOpacity よりも Pressable を優先します。onClick の代わりに onPress を使用します。 |
<input> | TextInput | placeholder、value、onChangeText をマッピングします。 |
<scroll container> | ScrollView | 短いリストにのみ使用します。長いリストや動的なリストには FlatList を使用します。 |
多数の項目を含む <ul>/<ol> | FlatList | data、renderItem、keyExtractor が必要です。 |
グループ化されたデータを含む <section> | SectionList | ヘッダー付きのグループ化されたデータに使用します。タブベースのレイアウトにはタブナビゲーターを使用します。 |
<select> | サードパーティ製ピッカーまたはカスタムモーダル | React Native には組み込みの select はありません。 |
<svg> | react-native-svg | SVG マークアップを Svg、Path、Circle などに変換します。 |
| ルートラッパー | SafeAreaView | ノッチやステータスバーとの重なりを避けるため、最上位の画面を囲みます。 |
スタイルのマッピング
CSS と Tailwind クラスは React Native では機能しません。すべてのスタイルを StyleSheet.create() に変換します。
- レイアウト:デフォルトのレイアウトシステムは Flexbox です。
flexDirectionのデフォルトは'column'です(Web CSS のように'row'ではありません)。- すべての
Viewではdisplay: flexが暗黙的に適用されます。 justify-contentはjustifyContentにマッピングされます。align-itemsはalignItemsにマッピングされます。gapはgapにマッピングされます(React Native 0.71 以降)。それ以前のバージョンでは、子要素にmarginBottomを使用します。
- すべての
- 寸法:文字列ではなく数値を使用します。
width: 100は密度非依存ピクセルで 100 を意味します。- パーセンテージ文字列を使用できます:
width: '100%'。 - レスポンシブなサイズ設定には、
react-nativeのuseWindowDimensions()を使用します。 vw/vhはありません。Dimensions.get('window')から計算します。
- パーセンテージ文字列を使用できます:
- タイポグラフィ:すべてのテキストスタイルは
Viewではなく、Textコンポーネントに指定する必要があります。font-sizeはfontSizeにマッピングされます(文字列ではなく数値)。font-weightはfontWeightにマッピングされます(文字列:'400'、'700'、'bold')。line-heightはlineHeightにマッピングされます(数値)。letter-spacingはletterSpacingにマッピングされます。text-transformはtextTransformにマッピングされます。colorはTextにのみ適用されます。
- 境界線とシャドウ:
border-radiusはborderRadiusにマッピングされます。box-shadowは存在しません。Android ではelevation、iOS ではshadowColor/shadowOffset/shadowOpacity/shadowRadiusを使用します。プラットフォーム固有のシャドウスタイルを適用するにはPlatform.select()を使用します。
- サポートされていない CSS プロパティ:
hover、transition、animation(アニメーションにはreact-native-reanimatedを使用)、position: fixed(代わりに絶対配置を使用)は使用しないでください。
アーキテクチャのルール
- モジュール化されたコンポーネント(Atomic Design):デザインを独立したファイルに分割します。コンポーネントは、アトム(ボタン、ラベル、アイコン)、モレキュール(入力グループ、カード)、オーガニズム(ヘッダー、リスト、フォーム)として整理します。
src/components/atoms/、src/components/molecules/、src/components/organisms/に配置します。巨大なページ/画面ファイルは禁止です。 - ロジックの分離:イベントハンドラー、API 呼び出し、ビジネスロジックは
src/hooks/内のカスタムフックに移します。コンポーネントは描画のみを担当します。 - データの分離:すべての静的テキスト、画像 URL、リストを
src/data/mockData.tsに移します。コンポーネント内にハードコードされたコンテンツを記述してはいけません。 - 型安全性:すべてのコンポーネントファイル(画面を含む)で、
readonlyプロパティ修飾子を持つ[ComponentName]Propsという名前の TypeScript インターフェースをエクスポートする必要があります。バリデーターではインターフェースがエクスポート済みであることが必須です。Props インターフェースをエクスポートしていないファイルは、バリデーションに失敗します。 - スタイルのハードコード禁止:色、スペーシング、フォントサイズを
src/theme.tsに抽出します。StyleSheet.create()ではこれらを参照します。コンポーネントファイルで生のカラー16進コードや rgba 文字列を使うことは一切禁止です。 - ナビゲーション:画面遷移には React Navigation を使用します。画面の型は
NativeStackScreenPropsまたはBottomTabScreenPropsで定義します。 - アクセシビリティ:すべてのインタラクティブ要素に
accessibilityLabelとaccessibilityRoleを指定する必要があります。画像にはaccessibilityLabelが必要です。トグルやチェックボックスにはaccessibilityStateを使用します。 - セーフエリア:トップレベルの画面コンポーネントは、
react-nativeのデフォルトのSafeAreaViewではなく、react-native-safe-area-contextのSafeAreaViewでラップします。 - プロジェクト固有の要件:対象プロジェクトのニーズと制約に重点を置きます。生成するコンポーネントに Google のライセンスヘッダーを含めないでください。
プラットフォーム固有のコード
デザインで iOS と Android に異なる動作が必要な場合:
import { Platform } from 'react-native';
const styles = StyleSheet.create({
shadow: Platform.select({
ios: {
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
},
android: {
elevation: 4,
},
}),
});
フェーズ 3 のアンチパターン
- ❌ すべての UI を単一の巨大な画面ファイルに記述する。
- ❌ React Native コンポーネントの代わりに HTML タグ(
div、span、pなど)を使用する。 - ❌ カスタムフックを使わずに、イベントハンドラーやビジネスロジックをインラインで記述する。
- ❌ コンポーネントファイルにテキスト、URL、色をハードコードする。
- ❌ エクスポート済みの
[Name]Propsインターフェースがないコンポーネント。 - ❌
StyleSheet.create()で生の16進カラー値や rgba 文字列を使用する。
フェーズ 4:実行手順
ゲート:フェーズ 4 の検証、監査、シミュレーター/パッケージャーでのテストは任意です。検証スクリプトの実行、パッケージャーの起動、シミュレーター監査を行う前に、必ずユーザーの許可を求めてください。
- 環境のセットアップ:
node_modulesがない場合は、検証ツールを利用できるようにnpm installを実行します。 - テーマレイヤー:抽出した Tailwind 設定を基に
src/theme.tsを作成します。 - データレイヤー:デザインのコンテンツを基に
src/data/mockData.tsを作成します。 - コンポーネントの作成:
resources/component-template.tsxをベースとして使用します。StitchComponentのすべてのインスタンスを、実際のコンポーネント名に置き換えます。HTML 要素を React Native のプリミティブに対応付けます。 - ナビゲーションの接続:デザインに複数の画面がある場合は、
App.tsxにスタックまたはタブナビゲーターを含むNavigationContainerを設定します。 - 品質チェック(任意 — 先にユーザーに確認):
- コンポーネントと画面のすべての
.tsxファイルに対してnpm run validate <file_path>を実行し、コンポーネントの有効性を報告します。 tsc --noEmitを実行し、TypeScript のコンパイル状態を確認します。- 出力を
resources/architecture-checklist.mdと照合します。 - アプリがシミュレーター/デバイスで正しく描画されることを確認するため、パッケージャー(
npx react-native startまたはnpx expo start)を起動する前、またはビジュアルシミュレーター監査を開始する前に、許可を得ます。
- コンポーネントと画面のすべての
フェーズ 4 のアンチパターン
- ❌ ユーザーの同意を得ずにパッケージャーやシミュレーターを起動する。
- ❌ コードのコンパイルを確認せずに、タスクを「完了」と宣言する。
トラブルシューティング
- フェッチエラー:シェルエラーを防ぐため、bash コマンド内の URL を引用符で囲んでください。
- 検証エラー:AST レポートを確認し、不足しているインターフェースやハードコードされたスタイルを修正してください。最もよくある原因は、exported な
Propsインターフェースがないこと、またはStyleSheet.create()に生の16進カラーコードが残っていることです。 - Text コンポーネント外のテキスト:
<Text>の外に生の文字列があると、React Native はクラッシュします。すべてのテキストノードがラップされていることを確認してください。 - 画像のサイズ:Web の
<img>と異なり、React Native のImageには固有サイズがありません。スタイルで必ずwidthとheightを指定するか、aspectRatioを使用してください。 - FlatList と ScrollView:「VirtualizedList inside ScrollView」という警告が表示された場合は、外側の
ScrollViewを通常のViewに置き換えるか、FlatListのListHeaderComponent/ListFooterComponentを使用してください。