- 
                Notifications
    
You must be signed in to change notification settings  - Fork 3
 
[3067] (Feature): Create bottom sheet component #70
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Introduces a highly configurable BottomSheet component, offering flexible presentation options, gesture-based dismissal, and dynamic height adjustment. Includes comprehensive configuration options for appearance and behavior and provides SwiftUI integration with a custom modifier, router, and navigation host. Enhances user experience with smooth transitions and interactive dismissal.
Refines the bottom sheet's behavior and appearance. This includes setting an initial maximum height for content and improving the height calculation within navigation controllers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resumo (TL;DR)
- Compatibilidade de linguagem: o PR usa 
packageaccess e marcaçõesSendable, o que implica Swift 5.9+; o repositório declara Swift 5.5+ → alinhar versão mínima ou trocarpackageporinternal. ([GitHub][1]) - Concorrência: vários tipos de configuração estão anotados como 
Sendable, porém carregamUIColor/CGColor(não-Sendable). RemoverSendableou tornar@unchecked Sendablecom justificativa. ([GitHub][1]) - UI/Apresentação: garantir tudo que toca UIKit marcado com 
@MainActor(Presenter, TransitioningDelegate, PresentationController, HostingController). - Acessibilidade, adaptatividade e testes: adicionar rotas de VoiceOver e testes de gesto/altura.
 - Estilo e ACL: endurecer SwiftLint (explícito de ACL, file_length, type_body_length) e revisar 
public/package. 
Bloqueadores
- Matriz de versões (Swift 5.5 vs. 
package)
O código novo usa o nível de acessopackage(Swift 5.9+). Já o README informa “Swift 5.5+”. Duas opções seguras: 
- Elevar a versão mínima para Swift 5.9 (README e 
Package.swift) e registrar no CHANGELOG como breaking de ambiente. ([GitHub][2]) - Trocar 
package→internalonde a intenção é ocultar no módulo, mantendo compatibilidade com 5.5.
Trecho ondepackageaparece (ex.:BottomSheet+Configuration.swift). ([GitHub][1]) 
- Anotações 
Sendableem tipos com UIKit/CoreGraphics
Configuration,PullBar.AppearanceeGradientBackgroundestãoSendable, mas possuemUIColor/CGColor/CGPoint. Esses tipos não são garantidamente thread-safe. Sugestões: 
- Remover 
Sendabledos tipos puramente de UI ou - Usar 
@unchecked Sendablecom docstring explicando a razão e restringir uso a@MainActor. ([GitHub][1]) 
Exemplo seguro:
@MainActor
package extension BottomSheet {
  // Remover Sendable de tipos que guardam UIKit/CoreGraphics:
  struct Configuration {
    // ...
  }
  enum PullBar {
    struct Appearance { /* ... */ }
    struct GradientBackground { /* ... */ }
  }
}- Garantir 
@MainActorem componentes de apresentação
Marcar como@MainActorclasses/structs que orquestram UI: 
BottomSheetPresenter,BottomSheetPresentationController,BottomSheetTransitioningDelegate,BaseHostingController.
Isso previne chamadas acidentais de fora da main thread.
@MainActor
final class BottomSheetPresentationController: UIPresentationController { /* ... */ }Qualidade da API e manutenção
- ACL explícita: onde a intenção é API interna, use 
internal(oupackagese adotarem Swift 5.9 oficialmente). Publique apenas o essencial. finalpor padrão: classes que não precisam herança (e.g., controllers/handlers) marcadas comofinalpara otimização e clareza.- Nomeação e consistência: propriedades como 
indicatorLineCornerRadiusestão OK; mantenha padrão e docs breves nosinits (vocês já estão colocando bons comentários de parâmetro). ([GitHub][1]) - Disponibilidade/OS: se houver APIs iOS 15/16+ (p.ex., esquinas contínuas), proteja com 
@availablee caminhos alternativos. 
Apresentação & Interações
- Gestos x ScrollViews: como há core de transição e extensões para controladores, validar concorrência do pan com scroll interno (o histórico de commits sugere ajustes em scroll removível/pull bar). Considere exigir que o pan do sheet reconheça só quando o scroll está no topo.
 - Alturas & Safe Area: o arquivo 
UIView+CalculateHeight.swiftdeve calcular comsystemLayoutSizeFittinge respeitar safe areas/teclado. Faça cache do resultado por traitCollection para evitar thrash. - Navegação embutida: há arquivos de “NavigationController/Style” — alinhe push/pop internos do sheet com um estilo previsível (ex.: animações consistentes e altura conservada entre telas).
 - iPad e compact/regular: ofereça largura máxima e centragem em regular.
 
Nota: houve commit “remove swizzled” — ótimo movimento; manter sem swizzling. ([GitHub][1])
Acessibilidade (faça agora)
- Pull bar acessível: 
accessibilityLabel = "Arrastar para expandir ou fechar"+ trait.updatesFrequentlyquando altura muda. - Modalidade: 
accessibilityViewIsModal = truequando apresentado; suporte ao gesto “escape” do VoiceOver para dismiss. - Dinamic Type/Contrast: valide cores do gradiente e indicador com contraste adequado; respeitar tamanhos grandes.
 
SwiftUI Interop
Com BaseHostingController e os modifiers/presenters SwiftUI:
- Sincronize 
preferredContentSizecom o tamanho do conteúdo SwiftUI quando a tela muda (rotation, Dynamic Type). - Exponha um 
ViewModifierpúblico e minimalista (parece que já existeBottomSheetModifier/Presenter). Valide exemplos no sample app. ([GitHub][1]) 
Lint, formatação e CI
- SwiftLint: ative regras como 
explicit_acl,file_length,type_body_length,cyclomatic_complexity,weak_delegate,redundant_type_annotation. - SwiftFormat: garanta trailing commas em multi-linhas para diffs mais limpos.
 - CI: inclua job que falhe em violações de lint e rode testes de snapshot (se houver) em diferentes trait collections.
 
Testes sugeridos
- 
Unitários:
- Defaults de 
Configuration(gradiente, altura do pull bar, etc.). ([GitHub][1]) - Cálculo de altura (mocks de conteúdo com Auto Layout).
 
 - Defaults de 
 - 
UI Tests:
- Gestos: expandir, colapsar, dismiss interativo com scroll no topo/fundo.
 - Rotação e mudança de tamanho (iPad).
 - Acessibilidade (voz de escape, foco inicial no conteúdo do sheet).
 
 
Documentação & exemplos
- Atualize o README para incluir exemplo rápido de apresentação do BottomSheet (UIKit e SwiftUI), parâmetros de configuração (incluindo 
GradientBackgroundcom cores elocations). ([GitHub][2]) 
Mudanças concretas (exemplos rápidos)
A) Se mantiver Swift 5.5:
Trocar package → internal e remover Sendable dos tipos de UI.
// Antes
package struct Configuration: Sendable { /* ... */ }
// Depois (Swift 5.5-5.8)
internal struct Configuration { /* ... */ }B) Se migrar para Swift 5.9+:
- README: “Swift 5.9+”; 
swift-tools-version: 5.9noPackage.swift. - Manter 
package, porém removerSendablede tipos com UIKit/CoreGraphics (ou justificar@unchecked Sendableem um wrapper puro-dados separado do layer de UI). 
Pull Request
Ticket or Issue link
Description
Introduces a highly configurable BottomSheet component, offering flexible presentation options, gesture-based dismissal, and dynamic height adjustment.
Includes comprehensive configuration options for appearance and behavior and provides SwiftUI integration with a custom modifier, router, and navigation host.
Checklist
swiftlintand fixed any possible issues of my code.Screenshots or videos (if applies)