From 5ff16f5757371c9d5d24df7a5f6e6933b85738e1 Mon Sep 17 00:00:00 2001 From: Jan Skrasek Date: Tue, 21 Mar 2023 15:43:25 +0100 Subject: [PATCH 1/2] add back LinearProgressIndicator's animation --- .../screens/LinearProgressIndicatorScreen.kt | 2 ++ .../ui/controls/LinearProgressIndicator.kt | 21 ++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/LinearProgressIndicatorScreen.kt b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/LinearProgressIndicatorScreen.kt index 9a95a2b44..f185aa762 100644 --- a/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/LinearProgressIndicatorScreen.kt +++ b/catalog/src/main/java/kiwi/orbit/compose/catalog/screens/LinearProgressIndicatorScreen.kt @@ -1,5 +1,6 @@ package kiwi.orbit.compose.catalog.screens +import androidx.compose.animation.core.snap import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -56,6 +57,7 @@ private fun LinearProgressIndicatorScreenInner() { var progress by rememberSaveable { mutableStateOf(0.5f) } LinearIndeterminateProgressIndicator() LinearProgressIndicator(progress) + LinearProgressIndicator(progress, progressAnimationSpec = snap()) Row( horizontalArrangement = Arrangement.spacedBy(16.dp), diff --git a/ui/src/main/java/kiwi/orbit/compose/ui/controls/LinearProgressIndicator.kt b/ui/src/main/java/kiwi/orbit/compose/ui/controls/LinearProgressIndicator.kt index 651f2aca3..fe6eebedd 100644 --- a/ui/src/main/java/kiwi/orbit/compose/ui/controls/LinearProgressIndicator.kt +++ b/ui/src/main/java/kiwi/orbit/compose/ui/controls/LinearProgressIndicator.kt @@ -1,12 +1,17 @@ package kiwi.orbit.compose.ui.controls import androidx.annotation.FloatRange +import androidx.compose.animation.core.AnimationSpec +import androidx.compose.animation.core.Spring +import androidx.compose.animation.core.SpringSpec +import androidx.compose.animation.core.animateFloatAsState import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.StrokeCap @@ -18,8 +23,10 @@ import kiwi.orbit.compose.ui.controls.internal.Preview /** * Linear progress indicator. * - * Renders progress indicator in maximum available width. - * To change the height or width, pass [modifier] with custom sizing. + * Renders progress indicator in maximum available width with animated progress change. + * + * - To change the height or width, pass [modifier] with custom sizing. + * - To disable the animation, use [androidx.compose.animation.core.snap] animation spec. */ @Composable public fun LinearProgressIndicator( @@ -27,9 +34,17 @@ public fun LinearProgressIndicator( modifier: Modifier = Modifier, color: Color = OrbitTheme.colors.primary.strong, backgroundColor: Color = OrbitTheme.colors.surface.normal, + progressAnimationSpec: AnimationSpec = SpringSpec( + dampingRatio = Spring.DampingRatioNoBouncy, + stiffness = Spring.StiffnessVeryLow, + // The default threshold is 0.01, or 1% of the overall progress range, which is quite + // large and noticeable. We purposefully choose a smaller threshold. + visibilityThreshold = 1 / 1000f, + ), ) { + val animatedProgress by animateFloatAsState(progress, progressAnimationSpec) androidx.compose.material3.LinearProgressIndicator( - progress = progress, + progress = animatedProgress, modifier = modifier.fillMaxWidth(), color = color, trackColor = backgroundColor, From c4c1285f7259b3ee241581b1a8e9ae3eabf92bcb Mon Sep 17 00:00:00 2001 From: Jan Skrasek Date: Tue, 21 Mar 2023 15:43:32 +0100 Subject: [PATCH 2/2] add LinearProgressIndicator docs --- .../10-progress-indicators/loading.mdx | 47 +++++++++++++++++++ docs/readme.md | 1 + .../controls/LinearProgressIndicatorTest.kt | 33 +++++++++++++ 3 files changed, 81 insertions(+) create mode 100644 docs/03-components/10-progress-indicators/loading.mdx create mode 100644 ui/src/test/kotlin/kiwi/orbit/compose/ui/controls/LinearProgressIndicatorTest.kt diff --git a/docs/03-components/10-progress-indicators/loading.mdx b/docs/03-components/10-progress-indicators/loading.mdx new file mode 100644 index 000000000..54c8bdb64 --- /dev/null +++ b/docs/03-components/10-progress-indicators/loading.mdx @@ -0,0 +1,47 @@ +--- +title: Android +--- + +## Overview + +Orbit Compose offers multiple components to visualize loading:: + +- [`LinearProgressIndicator`](https://kiwicom.github.io/orbit-compose/ui/kiwi.orbit.compose.ui.controls/-linear-progress-indicator.html) +- [`LinearIndeterminateProgressIndicator`](https://kiwicom.github.io/orbit-compose/ui/kiwi.orbit.compose.ui.controls/-linear-indeterminate-progress-indicator.html) + +## Usage + +Use `LinearProgressIndicator` composable and define a state a progress value. By default, all progress value changes are animated. Pass a custom animation specification via `progressAnimationSpec`. To disable animation, use `snap()` animation. + +```kotlin +@Composable +fun Example(progress: Float) { + LinearProgressIndicator( + progress = progress, + ) +} +``` + +## UI Testing + +Use semantic properties and action to set progress and read the state. + +```kotlin +composeTestRule.setContent { + LinearProgressIndicator( + progress = 0.4f, + modifier = Modifier.testTag("loader"), + ) +} + +val progressBarInfo = composeTestRule + .onNodeWithTag("loader") + .fetchSemanticsNode() + .config[SemanticsProperties.ProgressBarRangeInfo] + +Assert.assertEquals(0.4f, progressBarInfo.current) +``` + +## Customization + +To change track colors use `color` and `backgroundColor` arguments. diff --git a/docs/readme.md b/docs/readme.md index 1d025dae1..5a2210ff0 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -13,6 +13,7 @@ 1. [ButtonPrimitive](03-components/15-primitives/buttonprimitive.mdx) 1. [Button](03-components/01-action/button.mdx) 1. [Card](03-components/02-structure/card.mdx) +1. [Loading / LinearProgressIndicator](03-components/10-progress-indicators/loading.mdx) 1. [Slider](03-components/07-interaction/slider.mdx) 1. [Tabs](03-components/02-structure/tabs.mdx) 1. [Tile](03-components/02-structure/tile.mdx) diff --git a/ui/src/test/kotlin/kiwi/orbit/compose/ui/controls/LinearProgressIndicatorTest.kt b/ui/src/test/kotlin/kiwi/orbit/compose/ui/controls/LinearProgressIndicatorTest.kt new file mode 100644 index 000000000..430b70a01 --- /dev/null +++ b/ui/src/test/kotlin/kiwi/orbit/compose/ui/controls/LinearProgressIndicatorTest.kt @@ -0,0 +1,33 @@ +package kiwi.orbit.compose.ui.controls + +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.semantics.SemanticsProperties +import androidx.compose.ui.test.junit4.createComposeRule +import androidx.compose.ui.test.onNodeWithTag +import org.junit.Assert +import org.junit.Rule +import org.junit.Test +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner + +@RunWith(RobolectricTestRunner::class) +internal class LinearProgressIndicatorTest { + @get:Rule + val composeTestRule = createComposeRule() + + @Test + fun testBasics() { + composeTestRule.setContent { + LinearProgressIndicator( + progress = 0.4f, + modifier = Modifier.testTag("loader"), + ) + } + val progressBarInfo = composeTestRule + .onNodeWithTag("loader") + .fetchSemanticsNode() + .config[SemanticsProperties.ProgressBarRangeInfo] + Assert.assertEquals(0.4f, progressBarInfo.current) + } +}