expo-duo

Expo / React Native アプリを iPhone Duo(Apple の折りたたみ iPhone)向けにビルド、監査、修正する際に使用します。垂直レール、セーフエリアインセット、NativeTabs、SplitView、ArrangementView、expo-hinge、予約領域、画面回転ロック、Duo の姿勢テスト(ローカルまたは EAS Workflows CI 上)をサポートします。apple-design-duo(デザインルール)および expo:eas-workflows(CI YAML)と組み合わせて使用します。

expo-duo とは?

このスキルは、Expo SDK 58 と React Native を使用して、Apple の折りたたみ iPhone(iPhone Duo)向けのアプリを構築・テストするための包括的なガイドです。主な機能として、折りたたみ状態と開いた状態に応じたレイアウトの切り替え、iOS が提供する垂直レールへのナビゲーション要素の自動配置、SafeAreaView を用いた適切なインセット処理、SplitView や ArrangementView によるデュアルペインUIの実装、expo-hinge を使用したヒンジ角度の取得、react-native-reserved-regions による折り目や隠蔽領域の検出、そして EAS Workflows を使った CI 上での Duo シミュレータテストが含まれます。このスキルは Claude Code や Cursor などの AI エージェント向けに設計されており、開発者が Duo 特有のレイアウト要件に迅速に対応し、よくある落とし穴(固定タブバー、手書きヘッダー、インセットの誤った適用など)を回避するのに役立ちます。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Andrewi89/Stride-skills/tree/HEAD/plugins/design/skills/expo-duo

Installed? Explore more 生産性&コラボレーション skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

iPhone Duo 上の Expo

出典: https://expo.dev/blog/supporting-iphone-duo (Expo SDK 58)。デザインルールは apple-design-duo にあります。このスキルは Expo および React Native の実装レイヤーです。CI パイプラインの背景: https://docs.expo.dev/tutorial/cicd/introduction/ および expo:eas-workflows スキルを参照してください。

要件

  • Expo SDK 58 (iOS 27 をターゲット) および Xcode 27.1 (iOS 27.1 ランタイムと iPhone Duo シミュレータを含む)。
  • EAS Build イメージ: sdk-58 または latest。
  • Xcode 27 は Simulator.app を Device Hub に置き換えます (Xcode > Open Developer Tool > Device Hub)。折りたたみ、回転、ヒンジ角度設定が可能な 3D Duo を備えています。

メンタルモデル

折りたたみ = コンパクト幅、開いた状態 = 通常幅。レイアウトを広げるだけで、デザインを切り替えない。両方の状態で同じ機能と状態を維持。本のような姿勢では、iOS がステータスバー、タブバー、ツールバーを一方の端の垂直レールに移動します。

4つのルール

  1. iOS にナビゲーションを描画させる。 Expo Router の Stack と NativeTabs を使用してください。カスタム JS ヘッダーと <TabList> はレールに対応しておらず(SDK 58 では最小限の互換性のみ追加)、<TabList> はレール内に配置できません。
  2. すべての画面で SafeAreaView (react-native-safe-area-context) を使用し、水平方向のインセットも含める。
  3. すべての姿勢をテストする。 折りたたみ、展開、回転、Split View。
  4. 必要な箇所のみを調整する: ArrangementView、preferredPlacement、予約領域、ヒンジ API、またはレールの無効化。

セーフエリア(ほとんどのバグが発生する場所)

  • レールは左または右に 84pt のインセット が必要です。
  • スクロールコンテンツは SafeAreaView edges={['left','right']} でラップし、ScrollView 自体にはラップしないでください(背景を端から端まで表示するため)。ScrollView に contentInsetAdjustmentBehavior="automatic" を設定してください(RN パッチ #59194 により、これだけで十分になるはずです)。
  • 水平カルーセル: 自身で端にパディングを追加します。
  • フローティングボタンとトースト: right: insets.right + 16。RTL では、left と right の両方を読み取ります。
  • NativeTabs 内では、insets.bottom はタブバーが下部にある場合のみその高さを含みます。固定のタブバーの高さを追加しないでください。
  • ルートビューではなく、コンテンツコンテナにインセットを適用します。
  • useWindowDimensions をレンダリング時に読み取ります。左側の Split View ウィンドウの幅は 469pt です。

Expo Router

  • レール内のヘッダーボタンは 1 列に積み重ねられ、Back または Close が最初に来ます。テキストのみのアイテムは水平のままです。カスタムビューは除外されます。
  • Dynamic Island の Live Activity により、ツールバーがオーバーフローして縮小される可能性があります。これに対抗しないでください。
  • <SplitView> はシステムの Split View をラップします: 折りたたみ時は 1 列、開いた時は 2 列、折りたたみを認識します。SDK 58 では実験的機能です。
  • NativeTabs の preferredPlacement: 'sidebar' | 'tabBar' | 'automatic'。ランドスケープで開いているディスプレイに適用されます。

追加 API

ニーズAPI
2ペインコンテンツ (iOS 27.1 のみ、古いバージョンでは子要素がコンテナなしでレンダリングされます)@expo/ui/swift-ui の ArrangementView、Host 内で使用し、ArrangementView.Primary と .Secondary を配置。`arrangementViewStyle('split'
折り目と隠蔽フレームnpx expo install react-native-reserved-regions、その後 useReservedRegions() で `{ kind: 'division'
ヒンジ角度と状態npx expo install expo-hinge。useHinge()、getHinge()、addHingeListener()。状態: closed、partiallyOpen、fullyOpen、unknown。SwiftUI の Modifier onHingeChange は useWorkletCallback を介して UI スレッドで実行可能。Reanimated および Android 11+ の折りたたみデバイスでも動作します。
レールの端useVerticalBarEdgeIOS() は 'leading'、'trailing'、または null を返します。Duo 検出器ではありません(開いたポートレートでは null を返します)。
レールの無効化<StatusBar verticalBarBehaviorIOS="disabled" /> (preferredVerticalBarBehavior にマッピング)。動画プレーヤーや電卓スタイルの画面でのみ使用し、画面ごとに設定を安定させてください。

画面回転

iOS 27 では、画面回転ロックはリサイズ可能なコンテキストにおけるプリファレンスです。lockAsync は拒否される可能性があり、requireFullScreen はもはやオプトアウトしません。Duo でポートレートまたはランドスケープにロックするには、姿勢変更時にアプリが画面を埋める場合にのみ機能します。

既知の制限

  • StandBy は Duo シミュレータでは利用できず、ほとんどのアプリ拡張機能は Xcode 27.1 のシミュレータでは利用できません。ウィジェットと拡張機能は実機でテストしてください。
  • expo-app-intents(アルファ版、SDK 58 も対象)は、Siri、Shortcuts、Spotlight にアクションを公開します。一部のスキーマは、そのドメインよりも新しい iOS を必要とします(.mail.openDraft は iOS 27 が必要)。レイアウトとは無関係です。

テストチェックリスト

  • 折りたたみ時: レールの下に重要なものがないこと、ボタンが反応すること。
  • 開いた時: レイアウトがデザインを切り替えないこと、レールの下に何もないこと、ポートレートのバーが上部と下部に戻ること。
  • 半開き時: 折り目に重要なものがなく、シートとポップオーバーが片側に収まること。
  • Split View 時: コンテンツがレールから離れていること(左ウィンドウの左端)。
  • 画面中央で折りたたみ中: スクロール位置、状態、アクションが保持されること。
  • 標準的な iPhone 時: 何も変わらないこと。

監査ワークフロー

  1. SDK 58 を確認し、再ビルドする。
  2. カスタムヘッダーまたはタブバー (headerShown: false と手動構築バー、TabList) を検索し、Stack と NativeTabs に移行する。
  3. ハードコードされた top、bottom、left、right のオフセット、固定のタブバーの高さ、ルートレベルのパディングを検索し、インセットに置き換える。
  4. カルーセル、FAB、トーストをセーフエリアのリストに従って確認する。
  5. 2ペイン画面を選択: SplitView または ArrangementView。
  6. 画面ごとに、カスタムレイアウトで本当に必要な場合にのみ、予約領域またはヒンジを使用するか判断する。
  7. Device Hub で検証し、その後 CI で検証する(以下参照)。

CI: Duo シミュレータで実行する

expo:eas-workflows スキルを使用してください(最初にライブスキーマを取得し、ジョブパラメータを推測しないでください)。CI/CD チュートリアルから適切な形状: PR トリガーのシミュレータビルドを sdk-58 または latest イメージ上で行い、オプションで Maestro E2E を実行し、指紋ベースでネイティブビルドと本番用の EAS Update を選択します。npx -y eas-cli@latest workflow:validate .eas/workflows/<file>.yml --non-interactive で検証してください。Workflows は有料の EAS 分を消費します。

よくある間違い

間違い修正
ScrollView にインセットをパディングするその周りを SafeAreaView で囲み、contentInsetAdjustmentBehavior="automatic" を設定
パディングに固定のタブバーの高さを使用するセーフエリアから insets.bottom を使用
useVerticalBarEdgeIOS() を Duo の検出に使用するこれはレールの端のみを示し、開いたポートレートでは null
予約領域で折り目にコンテンツを分割するArrangementView または SplitView を使用
手動で構築した JS ヘッダーまたはタブバーStack と NativeTabs を使用
right: 16 のフローティングボタンright: insets.right + 16 に変更
lockAsync が常に成功すると仮定するプリファレンスとして扱い、画面を埋める
標準的な iPhone でのみテストするDevice Hub ですべての姿勢をテスト

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

関連スキル