Skip to content

Commit

Permalink
Merge pull request #788 from arkivanov/panels-docs
Browse files Browse the repository at this point in the history
Added docs for Child Panels
  • Loading branch information
arkivanov authored Oct 3, 2024
2 parents 5e14613 + 8884673 commit 17852c5
Show file tree
Hide file tree
Showing 12 changed files with 601 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package com.arkivanov.decompose.router.panels
import com.arkivanov.decompose.ExperimentalDecomposeApi

/**
* Determines how lifecycles of the panels within the Child Panels navigation model are changing.
* Determines how lifecycles of the child components within the Child Panels navigation model are changing.
*
* @see com.arkivanov.essenty.lifecycle.Lifecycle.State
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ fun <MC : Any, DC : Any, EC : Any> PanelsNavigator<MC, DC, EC>.navigate(
}

/**
* Activates the [Main][ChildPanels.main] component represented by the specified [main],
* Activates the [Main][ChildPanels.main] component represented by the specified [main] configuration,
* and dismisses (destroys) any currently active Main component.
*
* @param main a configuration of the Main component being activated.
Expand All @@ -76,7 +76,7 @@ fun <MC : Any, DC : Any, EC : Any> PanelsNavigator<MC, DC, EC>.activateMain(
}

/**
* Activates the [Details][ChildPanels.details] component represented by the specified [details],
* Activates the [Details][ChildPanels.details] component represented by the specified [details] configuration,
* and dismisses (destroys) any currently active Details component.
*
* @param details a configuration of the Details component being activated.
Expand Down Expand Up @@ -109,7 +109,7 @@ fun <MC : Any, DC : Any, EC : Any> PanelsNavigator<MC, DC, EC>.dismissDetails(
}

/**
* Activates the [Extra][ChildPanels.extra] component represented by the specified [extra],
* Activates the [Extra][ChildPanels.extra] component represented by the specified [extra] configuration,
* and dismisses (destroys) any currently active Extra component.
*
* @param extra a configuration of the Extra component being activated.
Expand Down
89 changes: 84 additions & 5 deletions docs/extensions/compose.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,15 @@ fun DialogContent(component: DialogComponent) {

Child Slot might not be suitable for a Navigation Drawer. This is because the Navigation Drawer can be opened by a drag gesture at any time. The corresponding component should be [always created](https://arkivanov.github.io/Decompose/component/child-components/#adding-a-child-component-manually) so that it's always ready to be rendered.

## Pager-like navigation

!!!warning
This navigation model is experimental, the API is subject to change.
## Child Pages navigation with Compose

The [Child Pages](../navigation/pages/overview.md) navigation model provides [ChildPages](https://github.com/arkivanov/Decompose/blob/master/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/pages/ChildPages.kt) as `Value<ChildPages>` that can be observed in a `Composable` component.

The Compose extension module provides the [ChildPages(...)](https://github.com/arkivanov/Decompose/blob/master/extensions-compose/src/commonMain/kotlin/com/arkivanov/decompose/extensions/compose/pages/ChildPages.kt) function which has the following features:

- It listens for the `ChildPages` changes and displays child components using `HorizontalPager` or `VerticalPager` (see the related Jetpack Compose [documentation](https://developer.android.com/jetpack/compose/layouts/pager)).
- It animates page changes if there is an `animation` spec provided.
- It animates page changes if there is a `scrollAnimation` spec provided.
- It supports displaying either just two panels (Main and Details) or three panels (Main, Details and Extra).

=== "Before version 3.2.0-alpha03"

Expand Down Expand Up @@ -267,6 +265,87 @@ The Compose extension module provides the [ChildPages(...)](https://github.com/a
}
```

## Child Panels navigation with Compose

!!!warning
This navigation model is experimental since version `3.2.0-beta01`, the API is subject to change.

The [Child Panels](../navigation/panels/overview.md) navigation model provides [ChildPanels](https://github.com/arkivanov/Decompose/blob/master/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/panels/ChildPanels.kt) as `Value<ChildPages>` that can be observed in a `Composable` component.

The experimental Compose extension module provides the [ChildPanels(...)](https://github.com/arkivanov/Decompose/blob/master/extensions-compose-experimental/src/commonMain/kotlin/com/arkivanov/decompose/extensions/compose/experimental/panels/ChildPanels.kt) function which has the following features:

- It listens for the `ChildPanels` changes and displays child components (panels) using the provided `layout`.
- It animates panel changes using the provided `animators` and `predictiveBackParams` specs.

The following arguments are supported.

- `panels` - an observable [ChildPanels] to be displayed.
- `mainChild` - a `Composable` function that displays the provided Main component.
- `detailsChild` - a `Composable` function that displays the provided Details component.
- `extraChild` - a `Composable` function that displays the provided Extra component.
- `modifier` - a `Modifier` to be applied to a wrapping container.
- `layout` - an implementation of [ChildPanelsLayout](https://github.com/arkivanov/Decompose/blob/master/extensions-compose-experimental/src/commonMain/kotlin/com/arkivanov/decompose/extensions/compose/experimental/panels/ChildPanelsLayout.kt) responsible for laying out panels. The default layout is [HorizontalChildPanelsLayout](https://github.com/arkivanov/Decompose/blob/master/extensions-compose-experimental/src/commonMain/kotlin/com/arkivanov/decompose/extensions/compose/experimental/panels/HorizontalChildPanelsLayout.kt).
- `animators` - a [ChildPanelsAnimators](https://github.com/arkivanov/Decompose/blob/master/extensions-compose-experimental/src/commonMain/kotlin/com/arkivanov/decompose/extensions/compose/experimental/panels/ChildPanelsAnimators.kt) containing panel animators for different kinds of layouts.
- `predictiveBackParams` - a function that returns `PredictiveBackParams` for the specified `ChildPanels`, or `null`. The predictive back gesture is enabled if the value returned for the specified `ChildStack` is not `null`, and disabled if the returned value is `null`. Only works if `ChildPanels.mode` is `SINGLE`. Also see the related docs below.

The default `HorizontalChildPanelsLayout` layout places child components (panels) in the following ways.

- If the `mode` is `SINGLE`, all panels are displayed in a stack. The Main panel, then the Details panel on top (if any), and finally the Extra panel (if any).
- If the `mode` is `DUAL`, the Main panel is always displayed on the left side, and then the Details and the Extra panels are displayed in a stack on the right side (next to the Main panel).
- If the `mode` is `TRIPLE`, all panels are displayed horizontally side by side.

```kotlin title="Basic example"
import androidx.compose.runtime.Composable
import com.arkivanov.decompose.extensions.compose.experimental.panels.ChildPanels

@Composable
fun PanelsContent(component: PanelsComponent) {
ChildPanels(
panels = component.panels,
mainChild = { MainContent(it.instance) },
detailsChild = { DetailsContent(it.instance) },
)
}

@Composable
fun MainContent(component: MainComponent) {
// Omitted code
}

@Composable
fun DetailsContent(component: DetailsComponent) {
// Omitted code
}
```

```kotlin title="Example with animations"
import androidx.compose.runtime.Composable
import com.arkivanov.decompose.extensions.compose.experimental.panels.ChildPanels
import com.arkivanov.decompose.extensions.compose.experimental.panels.ChildPanelsAnimators
import com.arkivanov.decompose.extensions.compose.experimental.stack.animation.PredictiveBackParams
import com.arkivanov.decompose.extensions.compose.experimental.stack.animation.fade
import com.arkivanov.decompose.extensions.compose.experimental.stack.animation.plus
import com.arkivanov.decompose.extensions.compose.experimental.stack.animation.scale
import com.arkivanov.decompose.extensions.compose.stack.animation.predictiveback.materialPredictiveBackAnimatable

@Composable
fun PanelsContent(component: PanelsComponent) {
ChildPanels(
panels = component.panels,
mainChild = { MainContent(it.instance) },
detailsChild = { DetailsContent(it.instance) },
animators = ChildPanelsAnimators(single = fade() + scale(), dual = fade() to fade()),
predictiveBackParams = { // See the docs below
PredictiveBackParams(
backHandler = component.backHandler,
onBack = component::onBackClicked,
animatable = ::materialPredictiveBackAnimatable,
)
},
)
}
```

## Animations

Decompose provides [Child Animation API](https://github.com/arkivanov/Decompose/tree/master/extensions-compose/src/commonMain/kotlin/com/arkivanov/decompose/extensions/compose/stack/animation) for Compose, as well as some predefined animation specs. To enable child animations you need to pass the `animation` argument to the `Children` function. There are predefined animators provided by Decompose.
Expand Down
1 change: 1 addition & 0 deletions docs/navigation/pages/navigation.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ All navigation in `Child Pages` is performed using the [`PagesNavigator`](https:
There is also `navigate` extension function without the `onComplete` callback, for convenience.

```kotlin title="Creating the navigation"
// In your component class
val navigation = PagesNavigation<Configuration>()
```

Expand Down
9 changes: 3 additions & 6 deletions docs/navigation/pages/overview.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
# Child Pages overview

## The Child Pages (experimental)
## The Child Pages

`Child Pages` is a navigation model for managing a list of components (pages) with one selected (active) component. The list can be empty.

!!!warning
This navigation model is experimental, the API is subject to change.

Similarly to `Child Stack`, each component has its own `Lifecycle`. By default, the currently selected page is `ACTIVE`, its two neighbours are `INACTIVE`, and the rest are `DESTROYED`. You can implement your own logic, for example with circular behaviour.

It is possible to have more than one `Child Pages` navigation model in a component, nested navigation is also supported.

The `Child Pages` navigation model consists of two main entities:
The `Child Pages` navigation model consists of three main entities:

- [Pages](https://github.com/arkivanov/Decompose/blob/master/decompose/src/commonMain/kotlin/com/arkivanov/decompose/router/pages/Pages.kt) - represents a state of the `Child Pages` navigation model. The navigation is performed by creating a new navigation state from the previous one.
- `Pages#items` - the list of child configurations, must be unique, can be empty.
Expand Down Expand Up @@ -49,7 +46,7 @@ There are three steps to initialize `Child Pages`:

### Displaying pages with Compose

`Child Pages` state can be observed and displayed in Compose by using the `Pager` `Composable` function from the Compose extensions module provided by Decompose. Please see the [related documentation](../../extensions/compose.md#pager-like-navigation) for more information.
`Child Pages` state can be observed and displayed in Compose by using the `ChildPages` `Composable` function from the Compose extensions module provided by Decompose. Please see the [related documentation](../../extensions/compose.md#child-pages-navigation-with-compose) for more information.

## Example

Expand Down
Loading

0 comments on commit 17852c5

Please sign in to comment.