svelte-components について
Svelte開発者向けのコンポーネント規約をまとめたスキルです。構成、Svelte runes、プロパティ、操作方法に加え、UIの視覚確認とキーボードアクセシビリティの検証を扱います。
主な機能
- 01コンポーネントの命名と配置
- 02Svelte runesとプロパティの指針
- 03shadcn-svelteのコンポーネント規約
- 04イベントとスニペットのパターン
- 05視覚とキーボード操作の確認
活用シーン
- 01一貫性のあるSvelteコンポーネントの構築
- 02コンポーネント構成と状態の確認
- 03UIの見た目と操作の検証
MCP 対応
このスキルは、UI開発時にChrome MCPでスナップショットやスクリーンショットを取得し、表示、操作状態、レスポンシブレイアウトを確認するよう案内します。
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ exceptionless/ exceptionless --skill svelte-componentsインストール後、Claude Code で/svelte-componentsを入力して読み込まれたか確認します。
詳細
Svelte コンポーネント
ドキュメント: svelte.dev | API リファレンスには
context7を使用してください
Chrome MCP による視覚的な検証
UI を変更した場合は、必ず Chrome MCP を使って視覚的に検証してください。
- コンポーネントを変更した後、Chrome MCP でスナップショットまたはスクリーンショットを撮影します
- コンポーネントが正しくレンダリングされ、想定されたデザインと一致していることを確認します
- 該当する場合は、インタラクティブな状態(ホバー、フォーカス、無効)をテストします
- さまざまなビューポートサイズでレスポンシブな動作を確認します
- 検証には
/nextサイトパスを使用してください
この視覚的な検証ループにより、自動テストでは見逃す可能性のあるスタイルの問題、レイアウトの問題、アクセシビリティの後退を検出できます。
ファイルの整理
命名規則
- すべてのコンポーネントファイルに kebab-case を使用します。:
stack-status-badge.svelte、user-profile-card.svelte - API コントローラーに合わせて、機能スライスと同じ場所に配置します
ディレクトリー構成
src/lib/features/
├── organizations/ # Matches OrganizationController
│ ├── components/
│ │ ├── organization-card.svelte
│ │ └── organization-switcher.svelte
│ ├── api.svelte.ts
│ ├── models.ts
│ └── schemas.ts
├── stacks/ # Matches StackController
│ └── components/
│ └── stack-status-badge.svelte
└── shared/ # Shared across features
└── components/
├── data-table/
├── navigation/
└── typography/
shadcn-svelte コンポーネントを必ず使用する
ボタン、入力欄、フォーム要素にはネイティブ HTML を使用しないでください。
<script lang="ts">
import { Button } from '$comp/ui/button';
import { Input } from '$comp/ui/input';
import * as Card from '$comp/ui/card';
</script>
<Card.Root>
<Card.Header>
<Card.Title>Settings</Card.Title>
</Card.Header>
<Card.Content>
<Input placeholder="Enter value" />
</Card.Content>
<Card.Footer>
<Button>Save</Button>
</Card.Footer>
</Card.Root>
<button class="...">Save</button>
<input type="text" />
Runes
$state — リアクティブな状態
<script lang="ts">
let count = $state(0);
let user = $state<User | null>(null);
let items = $state<string[]>([]);
</script>
$derived — 計算値
<script lang="ts">
let count = $state(0);
let doubled = $derived(count * 2);
let isEven = $derived(count % 2 === 0);
// Complex derived
let summary = $derived.by(() => {
return items.filter(i => i.active).map(i => i.name).join(', ');
});
</script>
$effect — 副作用
<script lang="ts">
let searchTerm = $state('');
$effect(() => {
console.log('Search term changed:', searchTerm);
return () => console.log('Cleaning up');
});
</script>
Props
<script lang="ts">
interface Props {
name: string;
count?: number;
onUpdate?: (value: number) => void;
children?: import('svelte').Snippet;
}
let { name, count = 0, onUpdate, children }: Props = $props();
</script>
イベント処理
on:click ではなく onclick を使用します。
<Button onclick={() => handleClick()}>Click me</Button>
<Input oninput={(e) => (value = e.currentTarget.value)} />
Snippets(コンテンツの投影)
<slot> を snippets に置き換えます。src/Exceptionless.Web/ClientApp/src/routes/(auth)/login/+page.svelte より:
<form.Subscribe selector={(state) => state.errors}>
{#snippet children(errors)}
<ErrorMessage message={getFormErrorMessages(errors)}></ErrorMessage>
{/snippet}
</form.Subscribe>
<form.Field name="email">
{#snippet children(field)}
<Field.Field data-invalid={ariaInvalid(field)}>
<Field.Label for={field.name}>Email</Field.Label>
<Input
id={field.name}
value={field.state.value}
oninput={(e) => field.handleChange(e.currentTarget.value)}
/>
<Field.Error errors={mapFieldErrors(field.state.meta.errors)} />
</Field.Field>
{/snippet}
</form.Field>
クラスのマージ
条件付きクラスには配列構文を使用します。
<div class={['flex items-center', expanded && 'bg-muted', className]}>
Content
</div>
<Button class={['w-full', isActive && 'bg-primary']}>Save</Button>
キーボードアクセシビリティ
すべてのインタラクティブなコンポーネントは、キーボードで操作できる必要があります。
Buttonコンポーネントを使用します(フォーカス処理が自動的に行われます)- カスタム操作に
tabindexとキーボードハンドラーが設定されていることを確認します - キーボードのみでのナビゲーションをテストします
WCAG のガイドラインについては、アクセシビリティを参照してください。
インポート
<script lang="ts">
// Use $app/state instead of $app/stores
import { page } from '$app/state';
// Access page data
let currentPath = $derived(page.url.pathname);
</script>
参考資料
- shadcn-svelte — UI コンポーネントのパターンとトリガー snippets
- アクセシビリティ — WCAG のガイドラインとキーボードナビゲーション
コメント
Markdown 対応