Skip to content
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

Don't use KClass#simpleName for stack and overlay keys #228

Merged
merged 1 commit into from
Oct 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,22 @@ import kotlin.reflect.KClass
/**
* Initializes and manages component overlay. An overlay component can be either active or dismissed (destroyed).
*
* @param source a source of navigation events
* @param configurationClass a [KClass] of the component configurations
* @param key a key of the overlay, must be unique within the parent (hosting) component,
* default value is derived from the [configurationClass.simpleName].
* @param source a source of navigation events.
* @param configurationClass a [KClass] of the component configurations.
* @param key a key of the overlay, must be unique within the parent (hosting) component.
* @param initialConfiguration a component configuration that should be shown if there is
* no saved state, return `null` to show nothing.
* @param persistent determines whether the navigation state should pre preserved or not,
* default is `true`.
* @param handleBackButton determines whether the overlay should be automatically dismissed
* on back button press or not, default is `false`.
* @param childFactory a factory function that creates new child instances
* @return an observable [Value] of [ChildOverlay]
* @param childFactory a factory function that creates new child instances.
* @return an observable [Value] of [ChildOverlay].
*/
fun <C : Parcelable, T : Any> ComponentContext.childOverlay(
source: OverlayNavigationSource<C>,
configurationClass: KClass<out C>,
key: String = "ChildOverlay_${configurationClass.simpleName}",
key: String = "DefaultChildOverlay",
initialConfiguration: () -> C? = { null },
persistent: Boolean = true,
handleBackButton: Boolean = false,
Expand Down Expand Up @@ -65,7 +64,7 @@ fun <C : Parcelable, T : Any> ComponentContext.childOverlay(
*/
inline fun <reified C : Parcelable, T : Any> ComponentContext.childOverlay(
source: OverlayNavigationSource<C>,
key: String = "ChildOverlay_${C::class.simpleName}",
key: String = "DefaultChildOverlay",
noinline initialConfiguration: () -> C? = { null },
persistent: Boolean = true,
handleBackButton: Boolean = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,21 @@ import kotlin.reflect.KClass
/**
* Initializes and manages a stack of components.
*
* @param source a source of navigation events
* @param source a source of navigation events.
* @param initialStack a stack of component configurations (ordered from tail to head) that should be set
* if there is no saved state, must be not empty and unique
* @param configurationClass a [KClass] of the component configurations
* @param key a key of the stack, must be unique if there are multiple stacks in the same component,
* default value is derived from [configurationClass.simpleName].
* if there is no saved state, must be not empty and unique.
* @param configurationClass a [KClass] of the component configurations.
* @param key a key of the stack, must be unique if there are multiple stacks in the same component.
* @param handleBackButton determines whether the overlay should be automatically dismissed
* on back button press or not, default is `false`.
* @param childFactory a factory function that creates new child instances
* @return an observable [Value] of [ChildStack]
* @param childFactory a factory function that creates new child instances.
* @return an observable [Value] of [ChildStack].
*/
fun <C : Parcelable, T : Any> ComponentContext.childStack(
source: StackNavigationSource<C>,
initialStack: () -> List<C>,
configurationClass: KClass<out C>,
key: String = "ChildStack_${configurationClass.simpleName}",
key: String = "DefaultChildStack",
handleBackButton: Boolean = false,
childFactory: (configuration: C, ComponentContext) -> T,
): Value<ChildStack<C, T>> =
Expand All @@ -54,7 +53,7 @@ fun <C : Parcelable, T : Any> ComponentContext.childStack(
inline fun <reified C : Parcelable, T : Any> ComponentContext.childStack(
source: StackNavigationSource<C>,
noinline initialStack: () -> List<C>,
key: String = "ChildStack_${C::class.simpleName}",
key: String = "DefaultChildStack",
handleBackButton: Boolean = false,
noinline childFactory: (configuration: C, ComponentContext) -> T
): Value<ChildStack<C, T>> =
Expand All @@ -73,7 +72,7 @@ inline fun <reified C : Parcelable, T : Any> ComponentContext.childStack(
inline fun <reified C : Parcelable, T : Any> ComponentContext.childStack(
source: StackNavigationSource<C>,
initialConfiguration: C,
key: String = "ChildStack_${C::class.simpleName}",
key: String = "DefaultChildStack",
handleBackButton: Boolean = false,
noinline childFactory: (configuration: C, ComponentContext) -> T
): Value<ChildStack<C, T>> =
Expand Down
30 changes: 29 additions & 1 deletion docs/navigation/overlay/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ class DefaultRootComponent(
private val _dialog =
childOverlay(
source = dialogNavigation,
key = "Dialog",
// persistent = false, // Disable navigation state saving, if needed
handleBackButton = true, // Close the dialog on back button press
) { config, componentContext ->
Expand All @@ -81,3 +80,32 @@ class DefaultRootComponent(
) : Parcelable
}
```

## Multiple Child Overlays in a component

When multiple `Child Overlays` are used in one component, each such `Child Overlay` must have a unique key associated. The keys are required to be unique only within the parent (hosting) component, so it is ok for different components to have `Child Overlays` with same keys. An exception will be thrown if multiple `Child Overlays` with the same key are detected in a component.

```kotlin title="Two Child Overlays in one component"
class Root(
componentContext: ComponentContext
) : ComponentContext by componentContext {

private val topNavigation = OverlayNavigation<TopConfig>()

private val topOverlay =
childOverlay<TopConfig, TopChild>(
source = topNavigation,
key = "TopOverlay",
// Omitted code
)

private val bottomNavigation = OverlayNavigation<BottomConfig>()

private val bottomOverlay =
childOverlay<BottomConfig, BottomChild>(
source = bottomNavigation,
key = "BottomOverlay",
// Omitted code
)
}
```
33 changes: 4 additions & 29 deletions docs/navigation/stack/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The `Child Stack` navigation consists of two main entities:

### Component Configurations

Each component created and managed by the `Child Stack` has a configuration, please read the documentation about [child configurations](/Decompose/navigation/overview/#component-configurations-and-child-factories).
Each component created and managed by the `Child Stack` has a configuration, please read the documentation about [child configurations](/Decompose/navigation/overview/#component-configurations-and-child-factories).

`Child Stack` adds one additional requirement for child configurations:

Expand All @@ -26,7 +26,7 @@ Each component created and managed by the `Child Stack` has a configuration, ple
There are three steps to initialize the `Child Stack`:

- Create a new instance of `StackNavigation` and assign it to a variable or a property.
- Initialize the `Child Stack` using the `ComponentContext#childStack` extension function and pass `StackNavigation` into it along with other arguments.
- Initialize the `Child Stack` using the `ComponentContext#childStack` extension function and pass `StackNavigation` into it along with other arguments.
- The `childStack` function returns `Value<ChildStack>` that can be observed in the UI. Assign the returned `Value` to another property or a variable.

## Example
Expand Down Expand Up @@ -292,34 +292,9 @@ class RootComponent(

## Multiple Child Stacks in a component

When multiple `Child Stacks` are required in one component, each such `Child Stack` must have a unique key associated. The keys are required to be unique only within the parent (hosting) component, so it is ok for different components to have `Child Stacks` with same keys. An exception will be thrown if multiple `Child Stacks` with the same key are detected in a component.
When multiple `Child Stacks` are used in one component, each such `Child Stack` must have a unique key associated. The keys are required to be unique only within the parent (hosting) component, so it is ok for different components to have `Child Stacks` with same keys. An exception will be thrown if multiple `Child Stacks` with the same key are detected in a component.

By default, key value is derived from the `simpleName` property of the configuration class. The key must be explicitly specified if multiple `Child Stacks` use the same configuration class.

```kotlin title="Two Child Stacks with the same configuration class"
class Root(
componentContext: ComponentContext
) : ComponentContext by componentContext {

private val topNavigation = StackNavigation<TopConfig>()

private val topStack =
childStack<Config, TopChild>(
source = topNavigation,
// Omitted code
)

private val bottomNavigation = StackNavigation<BottomConfig>()

private val bottomStack =
childStack<Config, BottomChild>(
source = bottomNavigation,
// Omitted code
)
}
```

```kotlin title="Two Child Stacks with different configuration classes"
```kotlin title="Two Child Stacks in one component"
class Root(
componentContext: ComponentContext
) : ComponentContext by componentContext {
Expand Down