stitch-svelte-components について
Stitch の画面、HTML ファイル、URL を、Svelte 5 の runes API を使ったコンポーネントに変換するスキルです。SvelteKit と単独の Svelte 5 プロジェクト向けで、スタイル、トランジション、アクセシビリティ、開発時の確認も扱います。
主な機能
- 01HTML から Svelte コンポーネントへの変換
- 02Svelte 5 runes API の使用
- 03SvelteKit のファイルベースルーティング
- 04スコープ付き CSS とデザイントークン
- 05動きを抑える設定に配慮したトランジション
- 06アクセシビリティ確認と開発検証
活用シーン
- 01Stitch 画面から Svelte ページを作成
- 02ローカル HTML を再利用可能なコンポーネントに変換
- 03Web ページの URL から Svelte の画面を作成
MCP 対応
Stitch の画面からデザインデータと HTML を取得する場合は Stitch MCP が必要です。ローカルファイルと URL の入力には MCP は不要です。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ gabelul/ stitch-kit --skill stitch-svelte-componentsインストール後、Claude Code で/stitch-svelte-componentsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
resources/architecture-checklist.mdcomponent-template.sveltescripts/fetch-stitch.sh詳細
Stitch → Svelte 5 / SvelteKit コンポーネント
あなたは Svelte 5 のエンジニアです。HTML ソース(Stitch の画面、ローカルファイル、URL)を、イディオマティックな Svelte コンポーネントに変換します。従来の Options API ではなく、runes API($state、$props、$derived、$effect)を使用してください。コンポーネントでは、テーマ設定にカスタムプロパティを使ったスコープ付き CSS、アニメーションに Svelte 組み込みのトランジションを使用し、デフォルトでアクセシブルなマークアップを採用します。
注: Svelte を対象とする Stitch スキルはこれだけです。公式の
react-componentsスキルは Vite/React を対象としています。プロジェクトで SvelteKit を使用している場合は、このスキルを使ってください。
このスキルを使う場面
次の場合にこのスキルを使ってください。
- 対象プロジェクトが SvelteKit または単体の Svelte 5 を使用している
.svelteファイル、svelte.config.js、または+page.svelteの規約が見られる- ユーザーが
svelte、sveltekit、$state、$props、またはrunesに言及している
前提条件
HTML ソースが必要です。次のいずれかを使用できます。
- Stitch の画面 — Stitch MCP へのアクセスと生成済みの画面が必要です
- ローカル HTML ファイル — Stitch アカウントは不要です
- URL — Stitch アカウントは不要です
また、次の条件も必要です。
- 対象プロジェクトが Svelte 5(runes 有効)を使用していること —
package.jsonで"svelte": "^5"を確認してください
ステップ 1:ソースを解決する
以降の手順では、すべて temp/source.html という 1 つのファイルを読み込みます。ユーザーから渡された内容に合った方法で HTML をそこに用意し、ステップ 2 に進んでください。マークアップの取得元にかかわらず、このスキルの残りの手順は同じです。
Stitch の画面から取得する場合:
- 名前空間を特定する —
list_toolsで Stitch MCP のプレフィックスを確認します - メタデータを取得する —
[prefix]:get_screenでデザイン JSON を取得します - HTML をダウンロードする — GCS URL には信頼性の高いダウンローダーが必要です。
bash scripts/fetch-stitch.sh "[htmlCode.downloadUrl]" "temp/source.html" - 表示を監査する — 書き換える前に
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:SvelteKit のファイル規約
SvelteKit はファイルベースのルーティングを使用します。Stitch の画面を次の構成に対応付けてください。
src/
├── routes/
│ ├── +layout.svelte ← Persistent shell (nav, footer)
│ ├── +layout.ts ← Layout load function (optional)
│ ├── +page.svelte ← Route page component
│ ├── [route]/
│ │ ├── +page.svelte ← Sub-route page
│ │ └── +page.ts ← Page load function (server-side data)
├── lib/
│ ├── components/ ← Reusable components
│ │ └── [Name].svelte
│ ├── data/
│ │ └── mockData.ts ← Decoupled static content
│ └── types/
│ └── index.ts ← Shared types
static/ ← Static assets
主なルール:
- ページは
src/routes/に+page.svelteとして配置します - 再利用可能なコンポーネントは
src/lib/components/に配置します $lib/はsrc/lib/のエイリアスです。必ず使用してください
ステップ 3:Svelte 5 runes API
runes のみを使用してください。 古い export let、let x = 0 によるリアクティブ構文、または $: ラベルは使用しないでください。
Props
<script lang="ts">
interface Props {
title: string
description?: string
onAction?: () => void
}
// $props() replaces export let
const { title, description = 'Default text', onAction }: Props = $props()
</script>
リアクティブな状態
<script lang="ts">
// $state() replaces let count = 0
let count = $state(0)
let isOpen = $state(false)
// $derived() replaces $: doubled = count * 2
const doubled = $derived(count * 2)
// $effect() replaces onMount / afterUpdate for side effects
$effect(() => {
console.log('count changed:', count)
})
</script>
イベント処理
<button onclick={() => count++}>Increment</button>
<button onclick={onAction}>Custom action</button>
ステップ 4:デザイントークンを使ったスコープ付き CSS
Svelte ではデフォルトで CSS がコンポーネントのスコープに限定されるため、これを積極的に活用してください。次の順序でソースから色を特定し、:root(+layout.svelte または app.css)でカスタムプロパティに割り当てて、各コンポーネントから参照します。
<head>内のインラインのtailwind.config(Stitch が生成するもの)— 存在する場合はそのまま使用します。- ソース内にすでにある CSS カスタムプロパティ(
:root { --color-primary: ... })— 手書き HTML やテンプレート HTML でよく使われます。 - リンクされた、またはインラインのスタイルシート — 宣言されている色、フォントファミリー、角丸、間隔を解析します。
- 最後の手段 — マークアップで最も頻繁に使用されている計算済みの値(背景色、テキスト色、アクセントカラー、見出し/本文のフォント、角丸)からトークンを導き、推定した内容をユーザーに伝えて修正できるようにします。
URL ルートでダウンロードされるのは単一の HTML レスポンスのみです。外部リンクされたスタイルシートは含まれないことがあります。上記の方法でトークンを特定できない場合は、パレットを勝手に作成せず、その旨を伝えてください。
src/app.css 内(グローバル):
:root {
--color-background: #ffffff;
--color-surface: #f4f4f5;
--color-primary: /* dominant color from the source */;
--color-primary-foreground: #ffffff;
--color-text: #09090b;
--color-text-muted: #71717a;
--color-border: #e4e4e7;
}
[data-theme='dark'] {
--color-background: #09090b;
--color-surface: #18181b;
--color-primary: /* same hue, adjusted for dark bg */;
--color-primary-foreground: #09090b;
--color-text: #fafafa;
--color-text-muted: #a1a1aa;
--color-border: #27272a;
}
各コンポーネント内(スコープ付き):
<style>
.card {
background-color: var(--color-surface);
border: 1px solid var(--color-border);
color: var(--color-text);
border-radius: 0.5rem;
padding: 1.5rem;
}
.card:hover {
/* Scoped — won't leak to parent or children */
border-color: var(--color-primary);
}
</style>
ダークモードの切り替え — +layout.svelte に $state を追加します。
<script lang="ts">
let theme = $state<'light' | 'dark'>('light')
function toggleTheme() {
theme = theme === 'light' ? 'dark' : 'light'
document.documentElement.setAttribute('data-theme', theme)
}
</script>
<svelte:element this="div" data-theme={theme}>
{@render children()}
</svelte:element>
ステップ 5:組み込みのトランジションとアニメーション
Svelte には、第一級のトランジションサポートがあります。ソースデザインの動きの意図に沿って、次のように適用します。
<script lang="ts">
import { fade, fly, slide, scale } from 'svelte/transition'
import { cubicOut } from 'svelte/easing'
let show = $state(false)
</script>
<div transition:fade={{ duration: 200 }}>
Content that fades in
</div>
{#if isOpen}
<aside transition:fly={{ x: -300, duration: 300, easing: cubicOut }}>
Sidebar content
</aside>
{/if}
{#if expanded}
<div transition:slide={{ duration: 200 }}>
Expandable content
</div>
{/if}
モーションの軽減設定は必ず尊重してください:
<script lang="ts">
// Check user preference once
const prefersReducedMotion = $state(
typeof window !== 'undefined'
? window.matchMedia('(prefers-reduced-motion: reduce)').matches
: false
)
// Conditionally disable transitions
const transitionOptions = $derived(
prefersReducedMotion ? {} : { duration: 200 }
)
</script>
<div transition:fade={transitionOptions}>...</div>
ステップ 6:Svelte のアクセシビリティ
Svelte のコンパイラーは、アクセシビリティ属性が不足している場合に警告を出します。コンパイラーの警告はすべてエラーとして扱ってください。
roleと ARIA:セマンティックでない要素を使う場合はroleを追加します。必ずaria-labelまたはaria-labelledbyと併用してください。bind:this:プログラムによるフォーカス管理(モーダルのフォーカストラップなど)に使用します。- キーボードハンドラー:操作可能でない要素に
onclickハンドラーを設定する場合は、onkeydown/onkeyupも必要です。あるいは<button>を使用してください。 - スクリーンリーダー用テキスト:視覚的に隠すラベルには
class="sr-only"を使用します(app.cssで定義してください)。
<button
onclick={closeModal}
aria-label="Close dialog"
class="icon-btn"
>
<CloseIcon />
</button>
<dialog
bind:this={dialogEl}
aria-labelledby="dialog-title"
aria-modal="true"
>
<h2 id="dialog-title">{title}</h2>
</dialog>
ステップ 7:実行手順
- 環境の確認 —
node_modulesがない場合は、npm installを実行します。 - データレイヤー — デザインの内容から
src/lib/data/mockData.tsを作成します。 - コンポーネントの作成 —
resources/component-template.svelteをベースとして使用します。StitchComponentのすべての箇所を、実際のコンポーネント名に置き換えます。 - CSS トークン —
src/app.cssにカラートークンを追加します。stitch-design-systemを使用する場合は、代わりに生成されたdesign-tokens.cssをインポートします。 - 接続 —
src/routes/+page.svelteを更新し、新しいコンポーネントをインポートして使用します。$lib/components/からインポートしてください。 - 品質チェック —
resources/architecture-checklist.mdに沿って確認します。 - 開発時の検証 —
npm run devを実行します。ダークモードを切り替え、キーボード操作をテストします。
トラブルシューティング
| 問題 | 対処方法 |
|---|---|
| Runes の構文エラー | package.json で svelte: ^5 を確認してください。古い構文は Svelte 5 では無効です。 |
$props() の型エラー | <script> タグに lang="ts" を追加してください |
| CSS がスコープに限定されない | スタイルが .css のインポートではなく、<style> ブロック内にあることを確認してください |
| トランジションが再生されない | prefers-reduced-motion によって設定が空になっていないか確認してください |
$lib を解決できない | tsconfig.json に "paths": {"$lib/*": ["src/lib/*"]} があることを確認してください |
| 読み込み時にダークモードがちらつく | 同期的な <svelte:head> スクリプトで localStorage からテーマを読み取ってください |
他のスキルとの連携
- stitch-design-system — 先に実行して、CSS 変数の基盤となる
design-tokens.cssを生成します。 - stitch-animate — その後に実行して、上記の基本的なものを超える Svelte 固有のトランジションパターンを適用します。
- stitch-a11y — デザインに複雑な UI パターンがある場合は、その後に実行してアクセシビリティの完全な監査を行います。
参考資料
resources/component-template.svelte— 本番環境ですぐに使える Svelte 5 コンポーネントのボイラープレートresources/architecture-checklist.md— リリース前の品質チェックリストscripts/fetch-stitch.sh— 信頼性の高い GCS HTML ダウンローダー