Skip to content

Commit

Permalink
Introduced Child Slot, deprecated Child Overlay
Browse files Browse the repository at this point in the history
  • Loading branch information
arkivanov committed Apr 3, 2023
1 parent 8b91ffe commit a425fbb
Show file tree
Hide file tree
Showing 43 changed files with 968 additions and 292 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Here are some key concepts of the library, more details can be found in the docu
* [Component](https://arkivanov.github.io/Decompose/component/overview/) - every component represents a piece of logic with its own lifecycle, the UI is optional and is plugged externally
* [ComponentContext](https://arkivanov.github.io/Decompose/component/overview/#componentcontext) - every component has its own [ComponentContext], which makes components lifecycle-aware and allows state preservation, instances retaining (aka AndroidX `ViewModel`) and back button handling
* [Child Stack](https://arkivanov.github.io/Decompose/navigation/stack/overview/) - enables navigation between child components, nested navigation is also supported
* [Child Overlay](https://arkivanov.github.io/Decompose/navigation/overlay/overview/) - provides navigation for the case when either one active component presented at a time, or none
* [Child Slot](https://arkivanov.github.io/Decompose/navigation/slot/overview/) - allows only one child component at a time, or none
* [Generic Navigation](https://arkivanov.github.io/Decompose/navigation/children/overview/) - provides a way to create your own custom navigation model, when none of the predefined models fit your needs
* [Lifecycle](https://arkivanov.github.io/Decompose/component/lifecycle/) - provides a way to listen for lifecycle events in components
* [StateKeeper](https://arkivanov.github.io/Decompose/component/state-preservation/) - makes it possible to preserve state or data in a component when it gets destroyed
Expand Down
53 changes: 53 additions & 0 deletions decompose/api/android/decompose.api
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,59 @@ public final class com/arkivanov/decompose/router/overlay/ValueExtKt {
public static final fun getOverlay (Lcom/arkivanov/decompose/value/Value;)Lcom/arkivanov/decompose/Child$Created;
}

public final class com/arkivanov/decompose/router/slot/ChildSlot {
public fun <init> ()V
public fun <init> (Lcom/arkivanov/decompose/Child$Created;)V
public synthetic fun <init> (Lcom/arkivanov/decompose/Child$Created;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lcom/arkivanov/decompose/Child$Created;
public final fun copy (Lcom/arkivanov/decompose/Child$Created;)Lcom/arkivanov/decompose/router/slot/ChildSlot;
public static synthetic fun copy$default (Lcom/arkivanov/decompose/router/slot/ChildSlot;Lcom/arkivanov/decompose/Child$Created;ILjava/lang/Object;)Lcom/arkivanov/decompose/router/slot/ChildSlot;
public fun equals (Ljava/lang/Object;)Z
public final fun getChild ()Lcom/arkivanov/decompose/Child$Created;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class com/arkivanov/decompose/router/slot/ChildSlotFactoryKt {
public static final fun childSlot (Lcom/arkivanov/decompose/ComponentContext;Lcom/arkivanov/decompose/router/slot/SlotNavigationSource;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ZLkotlin/jvm/functions/Function2;)Lcom/arkivanov/decompose/value/Value;
public static final fun childSlot (Lcom/arkivanov/decompose/ComponentContext;Lcom/arkivanov/decompose/router/slot/SlotNavigationSource;Lkotlin/reflect/KClass;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ZZLkotlin/jvm/functions/Function2;)Lcom/arkivanov/decompose/value/Value;
public static synthetic fun childSlot$default (Lcom/arkivanov/decompose/ComponentContext;Lcom/arkivanov/decompose/router/slot/SlotNavigationSource;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/arkivanov/decompose/value/Value;
public static synthetic fun childSlot$default (Lcom/arkivanov/decompose/ComponentContext;Lcom/arkivanov/decompose/router/slot/SlotNavigationSource;Lkotlin/reflect/KClass;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ZZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/arkivanov/decompose/value/Value;
}

public abstract interface class com/arkivanov/decompose/router/slot/SlotNavigation : com/arkivanov/decompose/router/slot/SlotNavigationSource, com/arkivanov/decompose/router/slot/SlotNavigator {
}

public final class com/arkivanov/decompose/router/slot/SlotNavigationKt {
public static final fun SlotNavigation ()Lcom/arkivanov/decompose/router/slot/SlotNavigation;
}

public abstract interface class com/arkivanov/decompose/router/slot/SlotNavigationSource : com/arkivanov/decompose/router/children/NavigationSource {
}

public final class com/arkivanov/decompose/router/slot/SlotNavigationSource$Event {
public fun <init> (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)V
public synthetic fun <init> (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getOnComplete ()Lkotlin/jvm/functions/Function2;
public final fun getTransformer ()Lkotlin/jvm/functions/Function1;
}

public abstract interface class com/arkivanov/decompose/router/slot/SlotNavigator {
public abstract fun navigate (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)V
}

public final class com/arkivanov/decompose/router/slot/SlotNavigatorExtKt {
public static final fun activate (Lcom/arkivanov/decompose/router/slot/SlotNavigator;Ljava/lang/Object;Lkotlin/jvm/functions/Function0;)V
public static synthetic fun activate$default (Lcom/arkivanov/decompose/router/slot/SlotNavigator;Ljava/lang/Object;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V
public static final fun dismiss (Lcom/arkivanov/decompose/router/slot/SlotNavigator;Lkotlin/jvm/functions/Function1;)V
public static synthetic fun dismiss$default (Lcom/arkivanov/decompose/router/slot/SlotNavigator;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
public static final fun navigate (Lcom/arkivanov/decompose/router/slot/SlotNavigator;Lkotlin/jvm/functions/Function1;)V
}

public final class com/arkivanov/decompose/router/slot/ValueExtKt {
public static final fun getChild (Lcom/arkivanov/decompose/value/Value;)Lcom/arkivanov/decompose/Child$Created;
}

public final class com/arkivanov/decompose/router/stack/ChildStack {
public fun <init> (Lcom/arkivanov/decompose/Child$Created;Ljava/util/List;)V
public synthetic fun <init> (Lcom/arkivanov/decompose/Child$Created;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
Expand Down
53 changes: 53 additions & 0 deletions decompose/api/jvm/decompose.api
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,59 @@ public final class com/arkivanov/decompose/router/overlay/ValueExtKt {
public static final fun getOverlay (Lcom/arkivanov/decompose/value/Value;)Lcom/arkivanov/decompose/Child$Created;
}

public final class com/arkivanov/decompose/router/slot/ChildSlot {
public fun <init> ()V
public fun <init> (Lcom/arkivanov/decompose/Child$Created;)V
public synthetic fun <init> (Lcom/arkivanov/decompose/Child$Created;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun component1 ()Lcom/arkivanov/decompose/Child$Created;
public final fun copy (Lcom/arkivanov/decompose/Child$Created;)Lcom/arkivanov/decompose/router/slot/ChildSlot;
public static synthetic fun copy$default (Lcom/arkivanov/decompose/router/slot/ChildSlot;Lcom/arkivanov/decompose/Child$Created;ILjava/lang/Object;)Lcom/arkivanov/decompose/router/slot/ChildSlot;
public fun equals (Ljava/lang/Object;)Z
public final fun getChild ()Lcom/arkivanov/decompose/Child$Created;
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}

public final class com/arkivanov/decompose/router/slot/ChildSlotFactoryKt {
public static final fun childSlot (Lcom/arkivanov/decompose/ComponentContext;Lcom/arkivanov/decompose/router/slot/SlotNavigationSource;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ZLkotlin/jvm/functions/Function2;)Lcom/arkivanov/decompose/value/Value;
public static final fun childSlot (Lcom/arkivanov/decompose/ComponentContext;Lcom/arkivanov/decompose/router/slot/SlotNavigationSource;Lkotlin/reflect/KClass;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ZZLkotlin/jvm/functions/Function2;)Lcom/arkivanov/decompose/value/Value;
public static synthetic fun childSlot$default (Lcom/arkivanov/decompose/ComponentContext;Lcom/arkivanov/decompose/router/slot/SlotNavigationSource;Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function1;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/arkivanov/decompose/value/Value;
public static synthetic fun childSlot$default (Lcom/arkivanov/decompose/ComponentContext;Lcom/arkivanov/decompose/router/slot/SlotNavigationSource;Lkotlin/reflect/KClass;Ljava/lang/String;Lkotlin/jvm/functions/Function0;ZZLkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lcom/arkivanov/decompose/value/Value;
}

public abstract interface class com/arkivanov/decompose/router/slot/SlotNavigation : com/arkivanov/decompose/router/slot/SlotNavigationSource, com/arkivanov/decompose/router/slot/SlotNavigator {
}

public final class com/arkivanov/decompose/router/slot/SlotNavigationKt {
public static final fun SlotNavigation ()Lcom/arkivanov/decompose/router/slot/SlotNavigation;
}

public abstract interface class com/arkivanov/decompose/router/slot/SlotNavigationSource : com/arkivanov/decompose/router/children/NavigationSource {
}

public final class com/arkivanov/decompose/router/slot/SlotNavigationSource$Event {
public fun <init> (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)V
public synthetic fun <init> (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
public final fun getOnComplete ()Lkotlin/jvm/functions/Function2;
public final fun getTransformer ()Lkotlin/jvm/functions/Function1;
}

public abstract interface class com/arkivanov/decompose/router/slot/SlotNavigator {
public abstract fun navigate (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function2;)V
}

public final class com/arkivanov/decompose/router/slot/SlotNavigatorExtKt {
public static final fun activate (Lcom/arkivanov/decompose/router/slot/SlotNavigator;Ljava/lang/Object;Lkotlin/jvm/functions/Function0;)V
public static synthetic fun activate$default (Lcom/arkivanov/decompose/router/slot/SlotNavigator;Ljava/lang/Object;Lkotlin/jvm/functions/Function0;ILjava/lang/Object;)V
public static final fun dismiss (Lcom/arkivanov/decompose/router/slot/SlotNavigator;Lkotlin/jvm/functions/Function1;)V
public static synthetic fun dismiss$default (Lcom/arkivanov/decompose/router/slot/SlotNavigator;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)V
public static final fun navigate (Lcom/arkivanov/decompose/router/slot/SlotNavigator;Lkotlin/jvm/functions/Function1;)V
}

public final class com/arkivanov/decompose/router/slot/ValueExtKt {
public static final fun getChild (Lcom/arkivanov/decompose/value/Value;)Lcom/arkivanov/decompose/Child$Created;
}

public final class com/arkivanov/decompose/router/stack/ChildStack {
public fun <init> (Lcom/arkivanov/decompose/Child$Created;Ljava/util/List;)V
public synthetic fun <init> (Lcom/arkivanov/decompose/Child$Created;Ljava/util/List;ILkotlin/jvm/internal/DefaultConstructorMarker;)V
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import com.arkivanov.essenty.statekeeper.consume
/**
* Initialised and manages a generic list of components. This is an API for custom navigation models.
* Please consider the existing navigation models first:
* [childStack][com.arkivanov.decompose.router.stack.childStack],
* [childOverlay][com.arkivanov.decompose.router.overlay.childOverlay].
* [Child Stack][com.arkivanov.decompose.router.stack.childStack],
* [Child Slot][com.arkivanov.decompose.router.overlay.childSlot].
*
* The API is based around [NavState] and [ChildNavState] interfaces that should be implemented by
* clients. [NavState] represents a persistent state of the navigation. It also holds a navigation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ import com.arkivanov.decompose.Child
/**
* A state holder for `Child Overlay`.
*/
@Deprecated(
message = "Please use Child Slot API",
replaceWith = ReplaceWith(
expression = "ChildSlot<C, T>",
"com.arkivanov.decompose.router.slot.ChildSlot",
),
)
data class ChildOverlay<out C : Any, out T : Any>(
val overlay: Child.Created<C, T>? = null,
)
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ import kotlin.reflect.KClass
* @param childFactory a factory function that creates new child instances.
* @return an observable [Value] of [ChildOverlay].
*/
@Deprecated(
message = "Please use Child Slot API",
replaceWith = ReplaceWith(
expression = "childSlot",
"com.arkivanov.decompose.router.slot.childSlot",
),
)
fun <C : Parcelable, T : Any> ComponentContext.childOverlay(
source: OverlayNavigationSource<C>,
configurationClass: KClass<out C>,
Expand Down Expand Up @@ -59,6 +66,13 @@ fun <C : Parcelable, T : Any> ComponentContext.childOverlay(
* @param childFactory a factory function that creates new child instances.
* @return an observable [Value] of [ChildOverlay].
*/
@Deprecated(
message = "Please use Child Slot API",
replaceWith = ReplaceWith(
expression = "childSlot",
"com.arkivanov.decompose.router.slot.childSlot",
),
)
fun <C : Any, T : Any> ComponentContext.childOverlay(
source: OverlayNavigationSource<C>,
saveConfiguration: (C?) -> ParcelableContainer?,
Expand Down Expand Up @@ -90,6 +104,13 @@ fun <C : Any, T : Any> ComponentContext.childOverlay(
/**
* A convenience extension function for [ComponentContext.childOverlay].
*/
@Deprecated(
message = "Please use Child Slot API",
replaceWith = ReplaceWith(
expression = "this.childSlot(source, key, initialConfiguration, persistent, handleBackButton, childFactory)",
"com.arkivanov.decompose.router.slot.childSlot",
),
)
inline fun <reified C : Parcelable, T : Any> ComponentContext.childOverlay(
source: OverlayNavigationSource<C>,
key: String = "DefaultChildOverlay",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ interface OverlayNavigation<C : Any> : OverlayNavigator<C>, OverlayNavigationSou
* Returns a default implementation of [OverlayNavigation].
* Broadcasts navigation events to all subscribed observers.
*/
@Deprecated(
message = "Please use Child Slot API",
replaceWith = ReplaceWith(
expression = "SlotNavigation<C>()",
"com.arkivanov.decompose.router.slot.SlotNavigation",
),
)
@Suppress("FunctionName") // Factory function
fun <C : Any> OverlayNavigation(): OverlayNavigation<C> =
DefaultOverlayNavigation()
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ import com.arkivanov.decompose.router.children.NavigationSource
*
* @see OverlayNavigator
*/
@Deprecated(
message = "Please use Child Slot API",
replaceWith = ReplaceWith(
expression = "SlotNavigationSource",
"com.arkivanov.decompose.router.slot.SlotNavigationSource",
),
)
interface OverlayNavigationSource<C : Any> : NavigationSource<OverlayNavigationSource.Event<C>> {

class Event<C : Any>(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package com.arkivanov.decompose.router.overlay

@Deprecated(
message = "Please use Child Slot API",
replaceWith = ReplaceWith(
expression = "OverlayNavigator",
"com.arkivanov.decompose.router.slot.OverlayNavigator",
),
)
interface OverlayNavigator<C : Any> {

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.arkivanov.decompose.router.overlay
/**
* A convenience method for [OverlayNavigator.navigate].
*/
@Deprecated(message = "Please use Child Slot API")
fun <C : Any> OverlayNavigator<C>.navigate(transformer: (configuration: C?) -> C?) {
navigate(transformer = transformer, onComplete = { _, _ -> })
}
Expand All @@ -14,6 +15,7 @@ fun <C : Any> OverlayNavigator<C>.navigate(transformer: (configuration: C?) -> C
*
* @param onComplete called when the navigation is finished (either synchronously or asynchronously).
*/
@Deprecated(message = "Please use Child Slot API")
fun <C : Any> OverlayNavigator<C>.activate(configuration: C, onComplete: () -> Unit = {}) {
navigate(transformer = { configuration }, onComplete = { _, _ -> onComplete() })
}
Expand All @@ -24,6 +26,7 @@ fun <C : Any> OverlayNavigator<C>.activate(configuration: C, onComplete: () -> U
* @param onComplete called when the navigation is finished (either synchronously or asynchronously).
* The `isSuccess` argument is `true` if there was an active overlay, `false` otherwise.
*/
@Deprecated(message = "Please use Child Slot API")
fun <C : Any> OverlayNavigator<C>.dismiss(onComplete: (isSuccess: Boolean) -> Unit = {}) {
navigate(transformer = { null }, onComplete = { _, oldConfiguration -> onComplete(oldConfiguration != null) })
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ package com.arkivanov.decompose.router.overlay
import com.arkivanov.decompose.Child
import com.arkivanov.decompose.value.Value

@Suppress("DeprecatedCallableAddReplaceWith")
@Deprecated(message = "Please use Child Slot API")
val <C : Any, T : Any> Value<ChildOverlay<C, T>>.overlay: Child.Created<C, T>? get() = value.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.arkivanov.decompose.router.slot

import com.arkivanov.decompose.Child

/**
* A state holder for `Child Slot`.
*/
data class ChildSlot<out C : Any, out T : Any>(
val child: Child.Created<C, T>? = null,
)
Loading

0 comments on commit a425fbb

Please sign in to comment.