raamcosta / compose-destinations

Annotation processing library for type-safe Jetpack Compose navigation with no boilerplate.
https://composedestinations.rafaelcosta.xyz
Apache License 2.0
3.23k stars 134 forks source link

Q: Multi-module project change where modules generate their destinations #690

Open cj1098 opened 1 month ago

cj1098 commented 1 month ago

Hi! Is it possible to specify a directory every module can output their destination instead of inside their individual modules? I've tried using arg("compose-destinations.mode", "[GENERATION_MODE_FOR_MODULE]") arg("compose-destinations.moduleName", "[YOUR_MODULE_NAME")

with "destinations" and "navgraphs" but both seems to still create the destinations inside their respective modules. I want to keep our multi-module hierarchy but be able to navigate anywhere from any module without having to have certain modules depend on another just for navigation. Is this something I should't be doing? Is this currently possible?

jumaallan commented 1 month ago

@cj1098 I do the same thing where "destinations" and "navgraphs" live in their respective modules

I then have an interface like this in each module (you can add more navigation options and even pass params here)

interface OnboardingModuleNavigator {
    fun navigateToOnboardingScreen()

    fun navigateToHomeScreen()
}

the implementation then lives inside app module

class CoreFeatureNavigatorSettings(
    private val navController: NavController,
) : HomeModuleNavigator,
    OnboardingModuleNavigator {
    override fun navigateToOnboardingScreen() = navController.navigate(OnboardingScreenDestination.route)

    // implement all navs from different interfaces in different modules

then add

fun DependenciesContainerBuilder<*>.currentNavigator(): CoreFeatureNavigatorSettings {
    return CoreFeatureNavigatorSettings(navController = navController)
}

and use it like this inside MainActivity which is also inside app module

DestinationsNavHost(
                                    navController =
                                        engine.rememberNavController(
                                            bottomSheetNavigator,
                                        ),
                                    navGraph = navigationGraph.root,
                                    modifier = Modifier.padding(paddingValues = paddingValues),
                                    dependenciesContainerBuilder = {
                                        dependency(currentNavigator())
                                        dependency(hiltViewModel<NfcReadViewModel>(this@MainActivity))
                                    },
                                )

this way, modules don't need to depend on each other for navigation

pass it inside a composable like this, then invoke the navigation inside a button etc

@Destination
@Composable
fun OnboardingScreen(
    navigation: OnboardingModuleNavigator,
    modifier: Modifier = Modifier,
    viewModel: OnboardingViewModel = hiltViewModel(),
) {