swiftui-style-driven-components
Appleのデザインパターンに沿って、ButtonStyleやLabelStyleなどのスタイルプロトコルを活用し、環境設定に基づいた柔軟なコンポーネントや拡張可能なライブラリを構築、レビューするSkill。
📜 元の英語説明(参考)
Expert guidance on SwiftUI style-driven components following Apple patterns (ButtonStyle, LabelStyle). Use when: building components with style protocols, implementing configuration patterns, adding environment-based styling, creating extensible component libraries, or reviewing component architecture.
🇯🇵 日本人クリエイター向け解説
Appleのデザインパターンに沿って、ButtonStyleやLabelStyleなどのスタイルプロトコルを活用し、環境設定に基づいた柔軟なコンポーネントや拡張可能なライブラリを構築、レビューするSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o swiftui-style-driven-components.zip https://jpskill.com/download/10660.zip && unzip -o swiftui-style-driven-components.zip && rm swiftui-style-driven-components.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/10660.zip -OutFile "$d\swiftui-style-driven-components.zip"; Expand-Archive "$d\swiftui-style-driven-components.zip" -DestinationPath $d -Force; ri "$d\swiftui-style-driven-components.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
swiftui-style-driven-components.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
swiftui-style-driven-componentsフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
SwiftUI スタイル駆動コンポーネント
概要
このスキルは、スタイル駆動アーキテクチャパターンに従って SwiftUI コンポーネントを構築、レビュー、拡張するための専門的なガイダンスを提供します。このパターンは、拡張性、保守性、および Apple スタイルの API 設計を重視しており、再利用可能なコンポーネントライブラリの構築に最適です。
エージェントの行動規範
- 新しいコンポーネントを作成する前に、2つ以上の意味的に異なるスタイルが必要かどうかを確認します。そうでない場合は、スタイルプロトコルをスキップします。
- Apple のパターン(
ButtonStyle、LabelStyle)をゴールドスタンダードとして従ってください。 - 設定には、ネストされた型消去ビューを使用します(
LabelStyleConfiguration.Titleなど)。 - 設定イニシャライザを
publicとして公開しないでください。 - 型消去のために、
style.makeBodyをAnyViewでラップします。 - スタイルプロトコルには、
SendableではなくDynamicPropertyを使用します。 - 存在型(
any [Component]Style)を使用して、環境からスタイルを読み取ります。
コアアーキテクチャの原則
- プロトコル:
[Component]Style— どのようにレンダリングするかを定義します - 設定:
[Component]StyleConfiguration— 何をレンダリングするかを含みます - コンポーネント: 内部で設定を作成し、レンダリングをスタイルに委譲します
- 環境: コンポーネントを変更せずにサブツリーのスタイル設定を可能にします
スタイルプロトコルを使用する場合
スタイルプロトコルは、次の場合に使用します。
- 2つ以上の意味的に異なるビジュアルスタイルが必要な場合
- 環境ベースのスタイルカスケードが必要な場合
- 再利用可能なコンポーネントライブラリを構築する場合
- スタイルが環境アクセス(
@Environment)を必要とする場合
スタイルプロトコルは、次の場合にスキップします。
- 単一のビジュアル表現
- シンプルで静的な外観
- 1回限りの内部コンポーネント
- スタイルのカスタマイズが不要
クイック意思決定ツリー
新しいコンポーネントを構築しますか?
- 複数のスタイルが必要ですか? → いいえの場合は、スタイルプロトコルをスキップします
- 構造を作成します →
references/component-structure.mdを参照してください - プロトコルを定義します →
references/style-protocol.mdを参照してください - 設定を作成します → ネストされた型消去ビューパターン
- デフォルトスタイルを実装します → 基本的なレンダリング
- 環境キーを追加します →
references/environment-keys.mdを参照してください - 便利なアクセサを追加します →
references/common-patterns.mdを参照してください
新しいスタイルを追加しますか?
[Component]Styleに準拠する構造体を作成しますmakeBody(configuration:)を実装します- 便利なアクセサ(
.myStyle)を追加します - コンポーネントの変更は不要です!
コンポーネントアーキテクチャをレビューしますか?
- プロトコルが
DynamicProperty、@ViewBuilder @MainActorを使用しているか確認します - 設定がネストされた型消去ビューを使用しているか確認します
- 設定の init が
internalであることを確認します - コンポーネントが
style.makeBodyをAnyViewでラップしているか確認します - 環境キーが存在型(
any [Component]Style)を使用しているか検証します - 新しいスタイルでコンポーネントの変更が必要ないことを確認します
トリアージプレイブック
- コンポーネントファイル構造の作成 →
references/component-structure.md - スタイルプロトコルの定義 →
references/style-protocol.md - コンテンツを含む設定の作成 →
references/style-protocol.md - 環境キーの設定 →
references/environment-keys.md - 便利なイニシャライザの追加 →
references/common-patterns.md - パラメータ化されたスタイルまたはアダプティブスタイル →
references/common-patterns.md - デザイントークンの使用 →
references/design-system.md - スナップショットテストの作成 →
references/testing.md - プレビューの整理 →
references/previews.md - アクセシビリティ要件 →
references/accessibility.md
クイックリファレンス
コンポーネント構造
[Component]/
├── EnvironmentKeys/[Component]StyleKey.swift
├── Styles/
│ ├── [Component]Style.swift
│ ├── [Component]StyleConfiguration.swift
│ └── Default[Component]Style.swift
└── [Component].swift
パターンの概要
- スタイルプロトコル:
DynamicProperty,@ViewBuilder @MainActor func makeBody - 設定: ネストされた
struct Content: Viewとprivate let _body: () -> AnyView - 設定 Init:
internal(notpublic) - コンポーネント Body:
AnyView(style.makeBody(configuration: .init(...))) - 環境キー:
@Entry public var style: any [Component]Style = .automatic - View Modifier:
func style(_ style: some [Component]Style) -> some View
ベストプラクティス
実行すること
- スタイルプロトコルには
DynamicPropertyを使用します - 設定にはネストされた型消去ビューを使用します
- 設定イニシャライザを
internalにします style.makeBodyをAnyViewでラップします- マジックナンバーではなくデザイントークンを使用します
- 便利なアクセサ(
.compact、.outlined)を提供します
実行しないこと
- プロトコルに明示的な
Sendableを追加しないでください - 設定イニシャライザを
publicにしないでください - 設定をコンポーネントイニシャライザに渡さないでください
- コンテンツプロパティをスタイルプロトコルに配置しないでください
- 単一バリアントコンポーネントにスタイルプロトコルを使用しないでください
AnyViewを設定プロパティタイプとして直接使用しないでください
レビューチェックリスト
アーキテクチャ
- [ ] スタイルプロトコルは
DynamicPropertyを使用しています - [ ]
makeBodyは@ViewBuilder @MainActorを持っています - [ ] 設定はネストされた型消去ビューを使用しています
- [ ] 設定 init は
internalです - [ ] コンポーネントは
style.makeBodyをAnyViewでラップしています - [ ] 新しいスタイルでコンポーネントの変更は不要です
環境
- [ ]
@Entryマクロを使用しています - [ ] 存在型(
any [Component]Style)として保存します - [ ] Modifier は不透明なパラメータ(
some [Component]Style)を使用します - [ ] デフォルト値が提供されています(
.automatic)
品質
- [ ] プレビューはすべてのスタイルをカバーしています(
references/previews.mdを参照してください) - [ ] スナップショットテストが存在します(
references/testing.mdを参照してください) - [ ] アクセシビリティがサポートされています(
references/accessibility.mdを参照してください) - [ ] デザイントークンが使用されています(
references/design-system.mdを参照してください)
参照ファイル
references/component-structure.md— 新しいコンポーネントの作成、ファイル構成references/style-protocol.md— プロトコル定義、設定パターン、スタイルの追加references/environment-keys.md— 環境インジェクション、使用パターンreferences/common-patterns.md— 便利なイニシャライザ/アクセサ、パラメータ化されたスタイルreferences/testing.md— スナップショットテスト、テスト構成references/previews.md— プレビュー構造、チェックリスト- **`referen
(原文がここで切り詰められています)
📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
SwiftUI Style-Driven Components
Overview
This skill provides expert guidance on building, reviewing, and extending SwiftUI components following the style-driven architecture pattern. This pattern emphasizes extensibility, maintainability, and Apple-style API design, making it ideal for building reusable component libraries.
Agent Behavior Contract
- Before creating a new component, verify it needs 2+ meaningfully different styles. If not, skip the style protocol.
- Follow Apple's patterns (
ButtonStyle,LabelStyle) as the gold standard. - Use nested type-erased views in configuration (like
LabelStyleConfiguration.Title). - Never expose configuration initializers as
public. - Wrap
style.makeBodyinAnyViewfor type erasure. - Use
DynamicPropertyfor style protocols, notSendable. - Read styles from environment using existential type (
any [Component]Style).
Core Architecture Principles
- Protocol:
[Component]Style— defines HOW to render - Configuration:
[Component]StyleConfiguration— contains WHAT to render - Component: Creates configuration internally, delegates rendering to style
- Environment: Enables subtree styling without modifying components
When to Use Style Protocol
Use style protocol when:
- 2+ meaningfully different visual styles needed
- Environment-based style cascading desired
- Building reusable component library
- Styles need environment access (
@Environment)
Skip style protocol when:
- Single visual representation
- Simple, static appearance
- One-off internal component
- No style customization needed
Quick Decision Tree
Building a new component?
- Needs multiple styles? → If no, skip style protocol
- Create structure → See
references/component-structure.md - Define protocol → See
references/style-protocol.md - Create configuration → Nested type-erased views pattern
- Implement default style → Basic rendering
- Add environment key → See
references/environment-keys.md - Add convenience accessors → See
references/common-patterns.md
Adding a new style?
- Create struct conforming to
[Component]Style - Implement
makeBody(configuration:) - Add convenience accessor (
.myStyle) - No component changes needed!
Reviewing component architecture?
- Check protocol uses
DynamicProperty,@ViewBuilder @MainActor - Verify configuration uses nested type-erased views
- Confirm configuration init is
internal - Check component wraps
style.makeBodyinAnyView - Validate environment key uses existential (
any [Component]Style) - Ensure new styles don't require component changes
Triage Playbook
- Creating component file structure →
references/component-structure.md - Defining style protocol →
references/style-protocol.md - Creating configuration with content →
references/style-protocol.md - Setting up environment keys →
references/environment-keys.md - Adding convenience initializers →
references/common-patterns.md - Parameterized or adaptive styles →
references/common-patterns.md - Using design tokens →
references/design-system.md - Writing snapshot tests →
references/testing.md - Organizing previews →
references/previews.md - Accessibility requirements →
references/accessibility.md
Quick Reference
Component Structure
[Component]/
├── EnvironmentKeys/[Component]StyleKey.swift
├── Styles/
│ ├── [Component]Style.swift
│ ├── [Component]StyleConfiguration.swift
│ └── Default[Component]Style.swift
└── [Component].swift
Pattern Summary
- Style Protocol:
DynamicProperty,@ViewBuilder @MainActor func makeBody - Configuration: Nested
struct Content: Viewwithprivate let _body: () -> AnyView - Configuration Init:
internal(notpublic) - Component Body:
AnyView(style.makeBody(configuration: .init(...))) - Environment Key:
@Entry public var style: any [Component]Style = .automatic - View Modifier:
func style(_ style: some [Component]Style) -> some View
Best Practices
DO
- Use
DynamicPropertyfor style protocols - Use nested type-erased views in configuration
- Make configuration initializers
internal - Wrap
style.makeBodyinAnyView - Use design tokens, not magic numbers
- Provide convenience accessors (
.compact,.outlined)
DON'T
- Add explicit
Sendableto protocols - Make configuration initializers
public - Pass configuration to component initializer
- Put content properties in style protocol
- Use style protocol for single-variant components
- Use
AnyViewdirectly as configuration property type
Review Checklist
Architecture
- [ ] Style protocol uses
DynamicProperty - [ ]
makeBodyhas@ViewBuilder @MainActor - [ ] Configuration uses nested type-erased views
- [ ] Configuration init is
internal - [ ] Component wraps
style.makeBodyinAnyView - [ ] New styles don't require component changes
Environment
- [ ] Uses
@Entrymacro - [ ] Stores as existential (
any [Component]Style) - [ ] Modifier uses opaque parameter (
some [Component]Style) - [ ] Default value provided (
.automatic)
Quality
- [ ] Previews cover all styles (see
references/previews.md) - [ ] Snapshot tests exist (see
references/testing.md) - [ ] Accessibility supported (see
references/accessibility.md) - [ ] Design tokens used (see
references/design-system.md)
Reference Files
references/component-structure.md— Creating new component, file organizationreferences/style-protocol.md— Protocol definition, configuration pattern, adding stylesreferences/environment-keys.md— Environment injection, usage patternsreferences/common-patterns.md— Convenience initializers/accessors, parameterized stylesreferences/testing.md— Snapshot tests, test organizationreferences/previews.md— Preview structure, checklistreferences/design-system.md— Design tokens, typography, colorsreferences/accessibility.md— Labels, identifiers, Dynamic Type
Philosophy
Style-driven components prioritize:
- Extensibility — Add styles without modifying components
- Apple Patterns — Follow
ButtonStyle,LabelStyleconventions - Simplicity — Skip style protocol for single-variant components
- Type Safety — Generic APIs with internal type erasure
- Consistency — All components follow same patterns