expo-ui について
Expoの`@expo/ui/swift-ui`とmodifier APIでiOS画面を構築するエージェント向けのリファレンススキルです。Hostの設定、レイアウト、コントロール、iOS 26の構成を優先度別のルールでまとめています。
主な機能
- 018カテゴリにわたる53のルール
- 02Hostとmodifierの使用指針
- 03レイアウトと入力コントロールのパターン
- 04iOS 26の画面構成ガイド
活用シーン
- 01ネイティブSwiftUIビューでの画面構築
- 02React NativeプリミティブからSwiftUIコンポーネントへの移行
- 03`@expo/ui/swift-ui`コードのレビューやデバッグ
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill expo-uiインストール後、Claude Code で/expo-uiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
AGENTS.mdgotchas.mdmetadata.jsonREADME.mdassets/templates/_template.mdreferences/_sections.mddisplay-chart-data-points.mddisplay-gauge-current-value-label.mddisplay-image-system-name.mddisplay-label-icon-vs-title.mddisplay-progress-indeterminate.mddisplay-text-markdown.mdhig-confirmation-dialog-destructive.mdhig-glass-effect-container.mdhig-no-glass-on-glass.mdhig-no-stacked-modals.mdhig-popover-iphone-fallback.mdhig-sheet-detents-partial.mdhig-tint-only-for-brand.mdhost-color-scheme-explicit.mdhost-ignore-safe-area.mdhost-match-contents.mdhost-viewport-size-for-form.mdhost-wrap-all-swiftui-roots.mdinput-button-role-for-destructive.mdinput-button-systemimage.mdinput-date-picker-range.mdinput-picker-style-via-modifier.mdinput-securefield-for-passwords.mdinput-stepper-bounded.md詳細
Expo @expo/ui SwiftUI のベストプラクティス
@expo/ui/swift-ui と @expo/ui/swift-ui/modifiers のライブラリリファレンスです。Expo のネイティブ UI ブリッジにおける iOS 向けの機能を扱います。iOS 26 以前でネイティブ SwiftUI ビューを表示する Expo アプリを構築するエージェント向けに、カスケードの影響度に基づいて優先順位付けされた、8 カテゴリ・53 個のルールをまとめています。
適用する場面
次のような場合に、これらのガイドラインを参照してください。
@expo/ui/swift-uiを使って新しい画面を構築する場合 — 適切なコンテナー(Form、List、ScrollView)を選び、Host で正しくラップして、モディファイアを適用します- React Native のプリミティブ(View、Text、TouchableOpacity)からネイティブの SwiftUI コンポーネントへ移行する場合
- iOS 26 の機能(Liquid Glass マテリアル、GlassEffectContainer、新しいシートの detent 動作)を対象にする場合
@expo/ui/swift-uiまたは@expo/ui/swift-ui/modifiersからインポートするコードをレビューする場合- 「SwiftUI ビューが表示されない/サイズが違う/スタイルが無視される」といった問題をデバッグする場合 — 通常は Host またはモディファイアに原因があります
- HIG のモダリティガイダンスに従って、Alert、ConfirmationDialog、BottomSheet、Popover などの表示サーフェスを組み合わせる場合
useNativeStateと worklet への書き込みを使って、TextField、Toggle、Picker、Slider などの制御された入力を作成する場合
このスキルを使用しない場面
- Android Jetpack Compose — このスキルの対象は iOS SwiftUI のみです。
@expo/ui/jetpack-composeには独自の規約があります - ユニバーサル(クロスプラットフォーム)コンポーネント —
@expo/uiが公開するコンポーネントは少数です。このスキルの対象はプラットフォーム固有の iOS 向け機能です - ナビゲーションのルーティング — スタック/タブのルーティングには
expo-routerとexpo-router/unstable-native-tabsを使用してください。このスキルが扱うのは UI の構成のみです - iOS 17 より前のフォールバック — ほとんどのルールは iOS 17 以降を前提としています。Liquid Glass のルールには iOS 26 が必要です
優先度別のルールカテゴリ
| 優先度 | カテゴリ | 影響度 | プレフィックス |
|---|---|---|---|
| 1 | セットアップと Host の境界 | CRITICAL | host- |
| 2 | iOS 26 HIG の構成ルール | CRITICAL | hig- |
| 3 | モディファイアシステム | CRITICAL | mod- |
| 4 | レイアウトコンポーネント | HIGH | layout- |
| 5 | 入力とコントロール | HIGH | input- |
| 6 | ナビゲーションとオーバーレイ | HIGH | nav- |
| 7 | 表示とフィードバック | MEDIUM-HIGH | display- |
| 8 | 状態と横断的なパターン | MEDIUM | state- |
クイックリファレンス
1. セットアップと Host の境界(CRITICAL)
host-wrap-all-swiftui-roots— SwiftUI のすべてのサブツリーを Host でラップしますhost-match-contents— matchContents を使って、Host のサイズを SwiftUI コンテンツに合わせますhost-viewport-size-for-form— Form と List には useViewportSizeMeasurement を使用しますhost-color-scheme-explicit— システム設定を上書きする場合は、colorScheme を明示的に渡しますhost-ignore-safe-area— ignoreSafeArea は全面表示のサーフェスにのみ使用します
2. iOS 26 HIG の構成ルール(CRITICAL)
hig-glass-effect-container— ガラス表現の兄弟要素を GlassEffectContainer 内にまとめますhig-no-glass-on-glass— ガラスのサーフェス内に glassEffect をネストしないようにしますhig-no-stacked-modals— 別のシートを表示する前に、現在のシートを解決しますhig-popover-iphone-fallback— iPhone では Popover を使わず、BottomSheet を使用しますhig-sheet-detents-partial— Liquid Glass の外観にするため、部分的な detent を含めますhig-confirmation-dialog-destructive— ConfirmationDialog と destructive ロールを組み合わせますhig-tint-only-for-brand— tint はブランドのサーフェスに限定し、破壊的な操作には使いません
3. モディファイアシステム(重要)
mod-prop-not-style— モディファイアは RN のスタイルではなく、modifiersプロパティを通して適用しますmod-composition-order— モディファイアの順序には意味があります。それぞれが前のモディファイアをラップしますmod-import-from-modifiers-subpath—@expo/ui/swift-ui/modifiersからインポートしますmod-frame-vs-fixedsize— frame はサイズを提案し、fixedSize は flex の対象から外しますmod-padding-vs-frame— 内側の余白には padding、外側の境界には frame を使いますmod-presentation-on-sheet-content— Presentation モディファイアはシートのコンテンツに適用しますmod-disabled-prop— disabled モディファイアを使い、条件付きでレンダリングしないようにしますmod-animation-wraps-trigger— withAnimation で、状態に応じて変化するプロパティをラップします
4. レイアウトコンポーネント(高)
layout-hstack-vs-vstack— コンテンツの流れに合わせてスタックの方向を選びますlayout-lazy-stack-for-long-lists— 長いリストには ScrollView 内で LazyVStack を使いますlayout-form-for-settings— Form は iOS のグループ化された外観を自動的に適用しますlayout-section-with-header-footer— Section の header/footer スロットを使いますlayout-scrollview-axes— 横方向または 2D のスクロールでは axes を明示的に設定しますlayout-grid-vs-stack— 列を揃えるコンテンツには Grid を使います
5. 入力とコントロール(高)
input-button-role-for-destructive— 削除ボタンには role='destructive' を設定しますinput-button-systemimage— ボタンのアイコンには systemImage の SF Symbol を使いますinput-textfield-observable-state— TextField には React の state ではなく useNativeState を使いますinput-securefield-for-passwords— パスワードには TextField ではなく SecureField を使いますinput-toggle-on-async— 即時の切り替えには SyncToggle、非同期処理には Toggle を使いますinput-picker-style-via-modifier— pickerStyle モディファイアで外観を選択しますinput-date-picker-range— range で選択可能な日付を制限しますinput-stepper-bounded— Stepper に最小値と最大値を指定します
6. ナビゲーションとオーバーレイ(高)
nav-alert-for-critical-only— ブロックを伴う通知にのみ Alert を使いますnav-context-menu-vs-swipe— 各行には ContextMenu または SwipeActions のどちらかを使い、両方は使いませんnav-bottom-sheet-via-group— BottomSheet のコンテンツを Group でラップしますnav-share-link-system— システムの共有シートには ShareLink を使いますnav-tabview-style-modifier— tabViewStyle モディファイアで外観を選択しますnav-disclosure-group-collapsible— 折りたたみ可能なセクションには DisclosureGroup を使いますnav-link-not-button-for-urls— URL には Link、アプリ内の操作には Button を使いますnav-menu-primary-action— onPrimaryAction でタップと長押しを区別します
7. 表示とフィードバック(MEDIUM-HIGH)
display-text-markdown— インラインのリッチテキストを有効にするには、markdownEnabled を有効にしますdisplay-image-system-name— uiImage よりも systemName の SF Symbols を優先しますdisplay-chart-data-points— ChartDataPoint 配列でネイティブの軸を設定しますdisplay-gauge-current-value-label— アクセシビリティのために currentValueLabel を指定しますdisplay-progress-indeterminate— value が未定義の場合はスピナー、0 の場合は停止したバーになりますdisplay-label-icon-vs-title— SF Symbols には systemImage を、カスタムアイコンには icon スロットを使用します
8. 状態と横断的なパターン(MEDIUM)
state-use-native-state-for-fields— ブリッジされたすべての入力に useNativeState を使用しますstate-worklet-writes— worklet から ObservableState を更新しますstate-controlled-via-selection-prop— selection と defaultSelection のどちらか一方を使用し、両方は使いませんstate-platform-check-pre-26— iOS 26 専用の機能は、バージョンチェックでガードしますstate-textfield-ref-imperative— フォーカスと選択範囲の操作には TextFieldRef を使用します
使用方法
詳しい説明とコード例については、各リファレンスファイルをお読みください。
各ルールファイルには、次の内容が含まれます。
- SwiftUI ブリッジで重要となる理由の簡単な説明
- 現実的なドメインに基づく誤ったコード例
- 誤った例からの差分を最小限にした正しいコード例
- 該当する場合:代替アプローチ、使用すべきでないケース、警告の注記、信頼できる参照 URL
注意点
gotchas.md を参照してください。実際の使用で問題点が明らかになったら、項目を追加します。
関連スキル
- Android Jetpack Compose コンポーネントについては、対応するスキルで
@expo/ui/jetpack-composeを対象にします - ナビゲーションのルーティング(スタック、タブ)には、
expo-routerを直接使用します - フォーム検証ライブラリについては、
react-hook-formスキルを参照してください
コメント
Markdown 対応