expo-duo

Use ao construir, auditar ou corrigir um app Expo / React Native para o iPhone Duo (iPhone dobrável da Apple), incluindo a barra vertical, insets de área segura, NativeTabs, SplitView, ArrangementView, expo-hinge, regiões reservadas, bloqueios de orientação e teste de poses do Duo localmente ou no CI do EAS Workflows. Combina com apple-design-duo (regras de design) e expo:eas-workflows (YAML de CI).

O que é expo-duo?

Este skill fornece as regras e práticas de implementação para suportar o iPhone Duo (o iPhone dobrável da Apple) em aplicações Expo SDK 58 e React Native. Ele aborda os quatro princípios fundamentais: usar navegação nativa com Expo Router Stack e NativeTabs, aplicar SafeAreaView em todas as telas incluindo insets horizontais, testar cada pose (dobrado, desdobrado, rotacionado, Split View), e ajustar apenas onde necessário usando ArrangementView, expo-hinge ou regiões reservadas. O skill detalha como lidar com a barra vertical de 84pt, orientação como preferência, e as limitações conhecidas. Ele também inclui um checklist de teste, um fluxo de auditoria e instruções de CI para rodar no simulador Duo usando o skill expo:eas-workflows. Ideal para desenvolvedores que precisam garantir que seus apps Expo funcionem corretamente no iPhone Duo, evitando erros comuns como padding fixo em ScrollViews, detecção incorreta do Duo ou uso de headers JS personalizados.

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

Installed? Explore more Produtividade e Colaboração skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Expo no iPhone Duo

Fonte: https://expo.dev/blog/supporting-iphone-duo (Expo SDK 58). As regras de design estão em apple-design-duo; este skill é a camada de implementação Expo e React Native. Contexto do pipeline de CI: https://docs.expo.dev/tutorial/cicd/introduction/ e o skill expo:eas-workflows.

Requisitos

  • Expo SDK 58 (alvo iOS 27) e Xcode 27.1 (runtime iOS 27.1 mais o simulador iPhone Duo).
  • Imagem EAS Build: sdk-58 ou latest.
  • O Xcode 27 substitui o Simulator.app pelo Device Hub (Xcode > Open Developer Tool > Device Hub). Ele possui um Duo 3D que dobra, gira e define o ângulo da dobradiça.

Modelo mental

Dobrado = largura compacta, aberto = largura regular. Deixe os layouts se alargarem, nunca mude os designs. Mesmas funcionalidades e estado em ambos. Em poses semelhantes a um livro, o iOS move a barra de status, barra de abas e barra de ferramentas para uma barra vertical em uma borda.

As quatro regras

  1. Deixe o iOS desenhar a navegação. Use Expo Router Stack e NativeTabs. Headers JS personalizados e <TabList> não são compatíveis com a barra (SDK 58 adiciona compatibilidade mínima) e <TabList> não pode ir na barra.
  2. SafeAreaView (react-native-safe-area-context) em cada tela, incluindo insets horizontais.
  3. Teste cada pose. Dobre, desdobre, gire, Split View.
  4. Ajuste apenas onde necessário: ArrangementView, preferredPlacement, regiões reservadas, APIs de dobradiça ou desabilitar a barra.

Áreas seguras (onde a maioria dos bugs está)

  • A barra precisa de um inset de 84pt à esquerda ou à direita.
  • Envolva o conteúdo de rolagem em SafeAreaView edges={['left','right']}, não no ScrollView, para que os fundos fiquem de ponta a ponta. Defina contentInsetAdjustmentBehavior="automatic" no ScrollView (o patch RN #59194 deve tornar isso suficiente sozinho).
  • Carrosséis horizontais: adicionam padding nas extremidades por conta própria.
  • Botões flutuantes e toasts: right: insets.right + 16. Em RTL, leia ambos left e right.
  • Dentro de NativeTabs, insets.bottom inclui a barra de abas apenas quando ela fica na parte inferior. Nunca adicione uma altura fixa de barra de abas.
  • Aplique padding ao contêiner de conteúdo com os insets, não à view raiz.
  • Leia useWindowDimensions no momento da renderização. A janela esquerda do Split View tem 469pt de largura.

Expo Router

  • Os botões do header na barra empilham em uma coluna, Back ou Close primeiro. Itens somente texto permanecem horizontais. Views personalizadas são excluídas.
  • Uma Atividade ao Vivo na Ilha Dinâmica pode encolher barras de ferramentas no overflow. Não lute contra isso.
  • <SplitView> envolve a visualização de divisão do sistema: uma coluna quando dobrado, duas quando aberto, ciente da dobra. Experimental no SDK 58.
  • NativeTabs preferredPlacement: 'sidebar' | 'tabBar' | 'automatic'. Aplica-se na tela aberta em paisagem.

APIs extras

NecessidadeAPI
Conteúdo de dois painéis (apenas iOS 27.1, versões mais antigas renderizam filhos sem contêiner)ArrangementView de @expo/ui/swift-ui, dentro de um Host, com ArrangementView.Primary e .Secondary. Estilize com arrangementViewStyle('split' | 'overlay'), splitArrangementLayoutSize, overlayArrangementEdge. Modificadores de @expo/ui/swift-ui/modifiers.
Quadros de dobra e oclusãonpx expo install react-native-reserved-regions, então useReservedRegions() retorna { kind: 'division' | 'occlusion', frame } em pontos. Bom para controles de jogo personalizados e grades de colunas pares. Não use para dividir conteúdo na dobra, use ArrangementView.
Ângulo e status da dobradiçanpx expo install expo-hinge. useHinge(), getHinge(), addHingeListener(). Status: closed, partiallyOpen, fullyOpen, unknown. O modificador SwiftUI onHingeChange pode rodar na thread da UI via useWorkletCallback. Funciona com Reanimated e dispositivos dobráveis Android 11+.
Borda da barrauseVerticalBarEdgeIOS() retorna 'leading', 'trailing' ou null. Não é um detector de Duo (retrato aberto retorna null).
Desabilitar a barra<StatusBar verticalBarBehaviorIOS="disabled" /> (mapeia para preferredVerticalBarBehavior). Apenas para players de vídeo ou telas tipo calculadora, e mantenha a escolha estável por tela.

Orientação

No iOS 27, os bloqueios de orientação são preferências em contextos redimensionáveis. lockAsync pode ser recusado e requireFullScreen não mais permite sair. Bloquear para retrato ou paisagem no Duo funciona apenas se o app preencher a tela durante as mudanças de pose.

Limitações conhecidas

  • StandBy não está disponível no simulador Duo, e a maioria das extensões de app não está disponível no simulador do Xcode 27.1. Teste widgets e extensões no dispositivo.
  • expo-app-intents (alpha, também SDK 58) expõe ações para Siri, Shortcuts e Spotlight. Alguns esquemas precisam de iOS mais novo que seu domínio (.mail.openDraft precisa de iOS 27). Não relacionado ao layout.

Checklist de teste

  • Dobrado: nada importante sob a barra, botões respondem.
  • Aberto: layout não muda de design, nada sob a barra, barras do retrato voltam para cima e para baixo.
  • Parcialmente aberto: nada essencial na dobra, folhas e popovers pousam em um lado.
  • Split View: conteúdo livre da barra (borda esquerda da janela esquerda).
  • Dobrando no meio da tela: posição de rolagem, estado e ações persistem.
  • iPhone padrão: nada muda.

Fluxo de auditoria

  1. Confirme SDK 58 e reconstrua.
  2. Grep por headers ou barras de abas personalizados (headerShown: false mais barras feitas à mão, TabList) e mova para Stack e NativeTabs.
  3. Grep por deslocamentos fixos de top, bottom, left, right, alturas fixas de barra de abas e padding no nível raiz. Substitua por insets.
  4. Verifique carrosséis, FABs e toasts conforme a lista de áreas seguras.
  5. Escolha telas de dois painéis: SplitView ou ArrangementView.
  6. Decida por tela sobre regiões reservadas ou dobradiça apenas se um layout personalizado realmente precisar.
  7. Verifique no Device Hub, depois no CI (abaixo).

CI: execute no simulador Duo

Use o skill expo:eas-workflows (busque o esquema ao vivo primeiro, não adivinhe parâmetros de job). Uma forma sensata do tutorial de CI/CD: build no simulador acionado por PR na imagem sdk-58 ou latest, Maestro E2E opcional, depois escolha baseada em fingerprint entre uma build nativa e um EAS Update para produção. Valide com npx -y eas-cli@latest workflow:validate .eas/workflows/<file>.yml --non-interactive. Workflows consomem minutos EAS pagos.

Erros comuns

ErroCorreção
Aplicar insets no ScrollViewSafeAreaView ao redor, contentInsetAdjustmentBehavior="automatic"
Altura fixa de barra de abas no paddingUse insets.bottom da área segura
Usar useVerticalBarEdgeIOS() para detectar DuoÉ apenas a borda da barra, nulo em retrato aberto
Dividir conteúdo na dobra com regiões reservadasArrangementView ou SplitView
Header ou barra de abas JS feita à mãoStack e NativeTabs
Botão flutuante em right: 16right: insets.right + 16
Assumir que lockAsync sempre funcionaTrate como preferência e preencha a tela
Testar apenas em um iPhone padrãoDevice Hub, cada pose

Individual skills in this repo

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

Habilidades Relacionadas