Skip to content
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
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ Use the Gradle wrapper from the repo root:

Minimum expectation for most code changes:
- Run `./gradlew :sample:android:assembleDebug ktlintCheck checkLegacyAbi` when feasible.
- For Compose API or implementation changes, also run the relevant Compose lint task for each changed module, for example `./gradlew :ComposeCollapsingTopBar:compileLint` or the corresponding sample-module lint task when changes are made there.
- For public API changes, pay special attention to `checkLegacyAbi` and the `.klib.api` snapshot.
- For behavior changes, validate through the sample app, especially `sample/shared/` and the Android sample shell.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ final fun (androidx.compose.ui/Modifier).com.flaringapp.compose.topbar.dependent
final fun (androidx.compose.ui/Modifier).com.flaringapp.compose.topbar.dependent/collapsingTopBarExitStateConnection(com.flaringapp.compose.topbar/CollapsingTopBarState, com.flaringapp.compose.topbar.dependent/CollapsingTopBarExitState): androidx.compose.ui/Modifier // com.flaringapp.compose.topbar.dependent/collapsingTopBarExitStateConnection|collapsingTopBarExitStateConnection@androidx.compose.ui.Modifier(com.flaringapp.compose.topbar.CollapsingTopBarState;com.flaringapp.compose.topbar.dependent.CollapsingTopBarExitState){}[0]
final fun (com.flaringapp.compose.topbar/CollapsingTopBarScope).com.flaringapp.compose.topbar.nestedcollapse/CollapsingTopBarColumn(com.flaringapp.compose.topbar/CollapsingTopBarState, androidx.compose.ui/Modifier?, com.flaringapp.compose.topbar.nestedcollapse/CollapsingTopBarColumnDirection?, kotlin/Function3<com.flaringapp.compose.topbar.nestedcollapse/CollapsingTopBarColumnScope, androidx.compose.runtime/Composer, kotlin/Int, kotlin/Unit>, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.flaringapp.compose.topbar.nestedcollapse/CollapsingTopBarColumn|CollapsingTopBarColumn@com.flaringapp.compose.topbar.CollapsingTopBarScope(com.flaringapp.compose.topbar.CollapsingTopBarState;androidx.compose.ui.Modifier?;com.flaringapp.compose.topbar.nestedcollapse.CollapsingTopBarColumnDirection?;kotlin.Function3<com.flaringapp.compose.topbar.nestedcollapse.CollapsingTopBarColumnScope,androidx.compose.runtime.Composer,kotlin.Int,kotlin.Unit>;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun <#A: kotlin/Any?> (com.flaringapp.compose.topbar.nestedscroll/CollapsingTopBarNestedScrollStrategy<#A>).com.flaringapp.compose.topbar.nestedscroll/rememberNestedScrollConnection(#A, androidx.compose.foundation.gestures/FlingBehavior?, com.flaringapp.compose.topbar.snap/CollapsingTopBarSnapBehavior?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): androidx.compose.ui.input.nestedscroll/NestedScrollConnection // com.flaringapp.compose.topbar.nestedscroll/rememberNestedScrollConnection|rememberNestedScrollConnection@com.flaringapp.compose.topbar.nestedscroll.CollapsingTopBarNestedScrollStrategy<0:0>(0:0;androidx.compose.foundation.gestures.FlingBehavior?;com.flaringapp.compose.topbar.snap.CollapsingTopBarSnapBehavior?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){0§<kotlin.Any?>}[0]
final fun com.flaringapp.compose.topbar.decoration/CollapsingTopBarVerticalFadingEdge(androidx.compose.ui.graphics/Color, androidx.compose.ui/Modifier?, androidx.compose.ui.unit/Dp, kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // com.flaringapp.compose.topbar.decoration/CollapsingTopBarVerticalFadingEdge|CollapsingTopBarVerticalFadingEdge(androidx.compose.ui.graphics.Color;androidx.compose.ui.Modifier?;androidx.compose.ui.unit.Dp;kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun com.flaringapp.compose.topbar.dependent/com_flaringapp_compose_topbar_dependent_CollapsingTopBarExitState$stableprop_getter(): kotlin/Int // com.flaringapp.compose.topbar.dependent/com_flaringapp_compose_topbar_dependent_CollapsingTopBarExitState$stableprop_getter|com_flaringapp_compose_topbar_dependent_CollapsingTopBarExitState$stableprop_getter(){}[0]
final fun com.flaringapp.compose.topbar.dependent/rememberCollapsingTopBarExitState(kotlin/Boolean, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): com.flaringapp.compose.topbar.dependent/CollapsingTopBarExitState // com.flaringapp.compose.topbar.dependent/rememberCollapsingTopBarExitState|rememberCollapsingTopBarExitState(kotlin.Boolean;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0]
final fun com.flaringapp.compose.topbar.nestedcollapse/com_flaringapp_compose_topbar_nestedcollapse_CollapsingTopBarColumnDirection$stableprop_getter(): kotlin/Int // com.flaringapp.compose.topbar.nestedcollapse/com_flaringapp_compose_topbar_nestedcollapse_CollapsingTopBarColumnDirection$stableprop_getter|com_flaringapp_compose_topbar_nestedcollapse_CollapsingTopBarColumnDirection$stableprop_getter(){}[0]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,57 +14,58 @@
* limitations under the License.
*/

package com.flaringapp.compose.topbar.sample.shared.ui.samples.common
package com.flaringapp.compose.topbar.decoration

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.material3.MaterialTheme
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.layout
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import com.flaringapp.compose.topbar.sample.shared.ui.theme.ComposeCollapsingTopBarTheme

/**
* Draws a vertical fading edge without affecting layout height.
*
* This can be used as an overlay between stacked top bar elements to soften visible overlap while
* keeping surrounding layout positions unchanged.
*
* @param color the opaque edge color that fades to transparent.
* @param modifier the [Modifier] to be applied to this fading edge.
* @param height the visible height of the fading edge.
* @param reverse when `false`, fades from top to bottom; when `true`, fades from bottom to top.
*/
@Composable
fun SampleVerticalFadingEdge(
public fun CollapsingTopBarVerticalFadingEdge(
color: Color,
modifier: Modifier = Modifier,
height: Dp = 12.dp,
color: Color = MaterialTheme.colorScheme.surface,
reverse: Boolean = false,
) {
val brush = remember(color) {
Brush.verticalGradient(
listOf(color, color.copy(alpha = 0f)),
)
val brush = remember(color, reverse) {
if (reverse) {
Brush.verticalGradient(
listOf(color.copy(alpha = 0f), color),
)
} else {
Brush.verticalGradient(
listOf(color, color.copy(alpha = 0f)),
)
}
}

Box(
modifier = modifier
.layout { measurable, constraints ->
val placeable = measurable.measure(constraints)
layout(placeable.width, 0) {
placeable.place(IntOffset.Zero)
}
}
.fillMaxWidth()
.height(0.dp)
.wrapContentHeight(Alignment.Top, unbounded = true)
.height(height)
.background(brush),
)
}

@Preview
@Composable
private fun Preview() {
ComposeCollapsingTopBarTheme {
Box(modifier = Modifier.height(40.dp)) {
SampleVerticalFadingEdge()
}
}
}
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ CollapsingTopBarScaffold(
SampleTopAppBar(
modifier = Modifier.notCollapsible(),
)
SampleVerticalFadingEdge()
CollapsingTopBarVerticalFadingEdge()
SampleFilterChips()
}
},
Expand Down Expand Up @@ -544,6 +544,23 @@ CollapsingTopBarScaffold(

</details>

### Decorations

`ComposeCollapsingTopBar` also provides small decoration composables to improve collapsing visuals
in certain scenarios.

#### Vertical fading edge

```kotlin
CollapsingTopBarVerticalFadingEdge(
color = MaterialTheme.colorScheme.surface,
)
```

`CollapsingTopBarVerticalFadingEdge()` draws a vertical fading overlay with zero layout height.
It's useful for smoothing visible overlap between stacked top bar elements in
`CollapsingTopBarColumn` and regular top bar layouts.

### React to state changes

You can easily access `CollapsingTopBarScaffoldState` and its nested states to observe state
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex
import com.flaringapp.compose.topbar.decoration.CollapsingTopBarVerticalFadingEdge
import com.flaringapp.compose.topbar.nestedcollapse.CollapsingTopBarColumn
import com.flaringapp.compose.topbar.sample.shared.screen
import com.flaringapp.compose.topbar.sample.shared.ui.samples.CollapsingTopBarSample
import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleContent
import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleFilterChips
import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleTopAppBar
import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleTopBarBanner
import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleVerticalFadingEdge
import com.flaringapp.compose.topbar.sample.shared.ui.theme.ComposeCollapsingTopBarTheme
import com.flaringapp.compose.topbar.scaffold.CollapsingTopBarScaffold
import com.flaringapp.compose.topbar.scaffold.CollapsingTopBarScaffoldScrollMode
Expand Down Expand Up @@ -102,7 +102,9 @@ private fun CollapsingContent(
ignoreWindowInsets = true,
)

SampleVerticalFadingEdge()
CollapsingTopBarVerticalFadingEdge(
color = MaterialTheme.colorScheme.surface,
)
SampleFilterChips()

FixedElement(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,20 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.flaringapp.compose.topbar.decoration.CollapsingTopBarVerticalFadingEdge
import com.flaringapp.compose.topbar.nestedcollapse.CollapsingTopBarColumn
import com.flaringapp.compose.topbar.sample.shared.screen
import com.flaringapp.compose.topbar.sample.shared.ui.samples.CollapsingTopBarSample
import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleContent
import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleFilterChips
import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleTopAppBar
import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleTopBarBanner
import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleVerticalFadingEdge
import com.flaringapp.compose.topbar.sample.shared.ui.theme.ComposeCollapsingTopBarTheme
import com.flaringapp.compose.topbar.scaffold.CollapsingTopBarScaffold
import com.flaringapp.compose.topbar.scaffold.CollapsingTopBarScaffoldScrollMode
Expand Down Expand Up @@ -85,7 +86,9 @@ private fun CollapsingContent(
ignoreWindowInsets = true,
)

SampleVerticalFadingEdge()
CollapsingTopBarVerticalFadingEdge(
color = MaterialTheme.colorScheme.surface,
)
SampleFilterChips()
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.flaringapp.compose.topbar.decoration.CollapsingTopBarVerticalFadingEdge
import com.flaringapp.compose.topbar.nestedcollapse.CollapsingTopBarColumn
import com.flaringapp.compose.topbar.nestedcollapse.CollapsingTopBarColumnDirection
import com.flaringapp.compose.topbar.sample.shared.screen
Expand All @@ -34,7 +36,6 @@ import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleConte
import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleFilterChips
import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleTopAppBar
import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleTopBarBanner
import com.flaringapp.compose.topbar.sample.shared.ui.samples.common.SampleVerticalFadingEdge
import com.flaringapp.compose.topbar.sample.shared.ui.theme.ComposeCollapsingTopBarTheme
import com.flaringapp.compose.topbar.scaffold.CollapsingTopBarScaffold
import com.flaringapp.compose.topbar.scaffold.CollapsingTopBarScaffoldScrollMode
Expand Down Expand Up @@ -112,7 +113,9 @@ private fun CollapsingContent(
onBack = onBack,
)

SampleVerticalFadingEdge()
CollapsingTopBarVerticalFadingEdge(
color = MaterialTheme.colorScheme.surface,
)
SampleFilterChips()
}
},
Expand Down
Loading