Tiamat Utils ------------ ## Overlays `OverlaysExtension` adds a local overlay navigation stack to a Tiamat destination while keeping the host content visible underneath. It is intended for dialogs, bottom sheets, and nested modal flows that should not replace the current screen. ### Usage Attach an `OverlaysExtension` to the destination that should host a local overlay stack: ```kotlin import com.composegears.tiamat.compose.* import com.composegears.tiamat.utils.extensions.OverlaysExtension val SettingsScreen by navDestination( OverlaysExtension( destinations = arrayOf( EditProfileDialog, DeleteAccountSheet, ) ) ) { val overlays = ext() ?: error("OverlaysExtension is missing") val overlayNavController = overlays.overlayNavController() Column { Text("Settings") Button(onClick = { overlayNavController.navigate(EditProfileDialog) }) { Text("Edit profile") } } } ``` The extension creates a dedicated overlay `NavController` for the host destination. The host screen stays mounted under the overlay content. ### Overlay destinations Overlay destinations are normal `navDestination` entries, opened through the local overlay controller: ```kotlin import androidx.compose.material3.BasicAlertDialog import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ModalBottomSheet import com.composegears.tiamat.compose.back import com.composegears.tiamat.compose.navController import com.composegears.tiamat.compose.navDestination val EditProfileDialog by navDestination { val overlayNavController = navController() BasicAlertDialog( onDismissRequest = overlayNavController::back, content = { Column { Text("Edit profile") Button(onClick = overlayNavController::back) { Text("Close") } } }, ) } @OptIn(ExperimentalMaterial3Api::class) val DeleteAccountSheet by navDestination { val overlayNavController = navController() ModalBottomSheet(onDismissRequest = overlayNavController::back) { Column { Text("Delete this account?") Button(onClick = overlayNavController::back) { Text("Cancel") } } } } ``` Inside an overlay destination, `navController()` resolves to the local overlay controller. If you need the parent/root controller, use `overlayNavController.parent`. ### Closing overlays Use `back()` on the local overlay controller to dismiss the current overlay. `OverlaysExtension` creates that controller with `NavController.BackBehaviour.AllowUntilEmpty`, so back navigation removes the last overlay entry and clears the overlay layer instead of navigating the parent/root controller back. ```kotlin val overlays = ext() ?: error("OverlaysExtension is missing") val overlayNavController = overlays.overlayNavController() Button(onClick = overlayNavController::back) { Text("Close") } ``` This makes the local controller's `back()` the standard dismiss action for a modal flow in the local overlay host: it closes the current overlay without unexpectedly leaving the host destination. ### Configuration The array constructor is shorthand for `DestinationLoader.from(destinations)`. Use the primary constructor when destinations must be resolved dynamically: ```kotlin import com.composegears.tiamat.navigation.NavController val overlays = OverlaysExtension( destinationLoader = DestinationLoader.byKey { key -> overlayDestinations.firstOrNull { it.key == key } }, handleSystemBackEvents = false, overlaysNavControllerFactory = { rememberNavController( key = "settings-overlays", saveable = false, backBehaviour = NavController.BackBehaviour.AllowUntilEmpty, ) }, ) ``` - Set `handleSystemBackEvents = false` when the containing UI owns system-back handling. - Use `overlaysNavControllerFactory` to customize creation of the local controller; keep `backBehaviour = NavController.BackBehaviour.AllowUntilEmpty` so closing the last overlay clears the overlay stack instead of bubbling to the parent controller. The default controller is saveable, uses the key `OverlaysExtensionNavController`, and already applies that back behaviour. ### Notes - `OverlaysExtension` is attached to the host destination; it does not replace the destination. - Overlay destinations can open other overlays or root screens without losing the host content beneath them. - `ext()?.overlayNavController()` is the usual access point from inside a host destination.