cashapp / redwood

Multiplatform reactive UI for Android, iOS, and web using Kotlin and Jetpack Compose
https://cashapp.github.io/redwood/0.x/docs/
Apache License 2.0
1.63k stars 70 forks source link

Generalized handling of dialogs, bottom sheets, etc. as secondary roots #1422

Open JakeWharton opened 1 year ago

JakeWharton commented 1 year ago

We need a mechanism by which we can dynamically create what I'm calling secondary roots. These are composables whose node does not render in the corresponding position in the native tree, and whose children render within one of these secondary roots rather than within the primary tree.

These will be widget-like schema objects, but not widgets because we almost certainly want them to go through a different factory. They have properties, events, and children (although perhaps only zero or one, not many). They generate interfaces similar to a widget so the binding procedure is similar.

These will be handled at the level of the entrypoint (TreehouseView for Treehouse, or forthcoming RedwoodView #1116 for Redwood) similar to how UiConfiguration #355 comes "in", or the forthcoming BackHandler #324 goes "out". The entrypoint will somehow mount these bindings to the native UI using the correct platform-specific mechanism (native dialogs, Compose UI dialogs, view controller-driven dialogs, etc.).

The playground app #1362 should have screens which show various dialogs and bottom sheets, including the ability to show multiple at once.

It's important that the enclosing app can set the policy on the behavior of multiple shown at once. Maybe it stacks, maybe it queues. We don't care.

JakeWharton commented 1 year ago

These secondary roots will get their own composition whose parent is the main composition. Need to figure out what this means for things like the Redwood protocol. Probably a monotonic compositionId which defaults to 0 (the primary root / composition) so as to be backwards compatible.

dnagler commented 1 year ago

I'm a fan of the name "secondary root", since it makes it clear that it represents its own window/"DOM". In iOS terms, It maps well to the rootViewController property on the UIWindow class.