{"id":49122805,"url":"https://github.com/flaringapp/ComposeCollapsingTopBar","last_synced_at":"2026-05-24T09:01:05.490Z","repository":{"id":247452844,"uuid":"825947316","full_name":"flaringapp/ComposeCollapsingTopBar","owner":"flaringapp","description":"The ultimate Compose Multiplatform collapsing toolbar library with dynamic sizing, different scroll modes, and extensive customization options","archived":false,"fork":false,"pushed_at":"2026-04-03T21:25:23.000Z","size":27727,"stargazers_count":62,"open_issues_count":7,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-03T21:43:13.377Z","etag":null,"topics":["android","compose","compose-multiplatform","ios","kotlin","kotlin-multiplaform"],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/flaringapp.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2024-07-08T20:14:23.000Z","updated_at":"2026-04-03T20:05:29.000Z","dependencies_parsed_at":"2025-08-15T20:19:35.158Z","dependency_job_id":"caf3d84d-a01b-4bb7-832e-775c0e7e2e17","html_url":"https://github.com/flaringapp/ComposeCollapsingTopBar","commit_stats":null,"previous_names":["flaringapp/composecollapsingtopbar"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/flaringapp/ComposeCollapsingTopBar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flaringapp%2FComposeCollapsingTopBar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flaringapp%2FComposeCollapsingTopBar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flaringapp%2FComposeCollapsingTopBar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flaringapp%2FComposeCollapsingTopBar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/flaringapp","download_url":"https://codeload.github.com/flaringapp/ComposeCollapsingTopBar/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/flaringapp%2FComposeCollapsingTopBar/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33427584,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-23T22:14:44.296Z","status":"online","status_checked_at":"2026-05-24T02:00:06.296Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["android","compose","compose-multiplatform","ios","kotlin","kotlin-multiplaform"],"created_at":"2026-04-21T13:00:29.138Z","updated_at":"2026-05-24T09:01:05.473Z","avatar_url":"https://github.com/flaringapp.png","language":"Kotlin","funding_links":[],"categories":["Libraries"],"sub_categories":["🍎 Compose UI"],"readme":"# ComposeCollapsingTopBar\n\n[![Maven Central](https://img.shields.io/maven-central/v/io.github.flaringapp/ComposeCollapsingTopBar)](https://central.sonatype.com/artifact/io.github.flaringapp/ComposeCollapsingTopBar)\n[![Build Status](https://img.shields.io/github/actions/workflow/status/patrykandpatrick/vico/build.yml?branch=master)](https://github.com/flaringapp/ComposeCollapsingTopBar/actions)\n[![Kotlin](https://img.shields.io/badge/Kotlin-2.3.10-slateblue.svg?logo=kotlin)](http://kotlinlang.org)\n[![Compose](https://img.shields.io/badge/Compose-1.10.1-dodgerblue.svg?logo=jetpackcompose)](https://www.jetbrains.com/lp/compose-multiplatform)\n![API](https://img.shields.io/badge/API-23%2B-forestgreen.svg)\n[![ktlint](https://img.shields.io/badge/ktlint%20code--style-%E2%9D%A4-FF4081)](https://pinterest.github.io/ktlint/)\n[![Licence](https://img.shields.io/github/license/flaringapp/ComposeCollapsingTopBar)](https://github.com/flaringapp/ComposeCollapsingTopBar/blob/main/LICENSE)\n\n![badge-Android](https://img.shields.io/badge/Platform-Android-forestgreen)\n![badge-iOS](https://img.shields.io/badge/Platform-iOS-silver)\n\nIf you like this project, :star: star and :loudspeaker: share it!\n\n**ComposeCollapsingTopBar** is the ultimate **Compose Multiplatform** library for creating versatile\ncollapsing header UIs. It provides the capability to build custom top bars with automatic height\nadjustment, featuring common scroll modes, snapping, and offering plenty of customization options.\nIt's designed with ease of use and optimization in mind while providing features similar to\nAndroid `CoordinatorLayout`.\n\n![](/docs/assets/cover_collapsing_stack.gif)\n\u0026nbsp;\u0026nbsp;\n![](/docs/assets/cover_collapsing_column.gif)\n\n## Download\n\nAdd the dependency to your target module's `build.gradle.kts` file:\n\n```kotlin\ndependencies {\n    implementation(\"io.github.flaringapp:ComposeCollapsingTopBar:2.1.0\")\n}\n```\n\nEnsure you've configured repositories in `settings.gradle.kts`:\n\n```kotlin\ndependencyResolutionManagement {\n    repositories {\n        mavenCentral()\n    }\n}\n```\n\n## Usage\n\nYou need scrollable content for the collapsing header to work. For the sake of optimization, this\nlibrary does something similar to `CoordinatorLayout`: by default, body content is measured as if\nthe top bar were already collapsed, and then simply offset as the top bar expands and\ncollapses. That's why you need a `Scaffold`-like wrapper.\n\n```kotlin\nCollapsingTopBarScaffold(\n    scrollMode = CollapsingTopBarScaffoldScrollMode.enterAlwaysCollapsed(),\n    snapBehavior = rememberCollapsingTopBarSnapBehavior(),\n    topBar = {\n        TopBarImage()\n        TopAppBar()\n    },\n    body = {\n        ContentUnderTopBar()\n    },\n)\n```\n\nIn some cases you may want a direct body child to resize together with collapse instead of using\nthe default fixed measurement strategy. For those cases, `CollapsingTopBarScaffold()` exposes\n`CollapsingTopBarScaffoldBodyScope.resizeWithCollapse()`:\n\n```kotlin\nCollapsingTopBarScaffold(\n    scrollMode = CollapsingTopBarScaffoldScrollMode.collapse(expandAlways = false),\n    topBar = {\n        TopBarImage()\n        TopAppBar()\n    },\n    body = {\n        ScrollableContent()\n        Overlay(\n            modifier = Modifier.resizeWithCollapse(),\n        )\n    },\n)\n```\n\nUse `resizeWithCollapse()` as a targeted override, typically for lightweight direct children such\nas overlays or panels that must track the currently visible body height. It may increase\nremeasurement cost during collapse, so the default scaffold behavior remains the preferred choice\nfor scrollable content.\n\n`CollapsingTopBarScaffold()` is flexible enough to cover a variety of use cases. However, there's\nsome extra room for customization: you can use `CollapsingTopBar()` as the actual collapsing header,\nand implement your own mechanism to control header and content positioning. Feel free to take a\nlook at the `CollapsingTopBarScaffold()` source code if you decide to do so.\n\n### Scroll modes\n\n|                   Collapse                    |             Collapse and exit              |                    Enter always collapsed                    |\n|:---------------------------------------------:|:------------------------------------------:|:------------------------------------------------------------:|\n| ![](/docs/assets/collapsing_mode_regular.gif) | ![](/docs/assets/collapsing_mode_exit.gif) | ![](/docs/assets/collapsing_mode_enter_always_collapsed.gif) |\n\n\u003e [!TIP]\n\u003e For most scroll modes you can also specify whether or not to expand anywhere in the list.\n\nUse a required parameter `scrollMode` of `CollapsingTopBarScaffold()`:\n\n```kotlin\nCollapsingTopBarScaffold(\n    // ...\n    scrollMode = CollapsingTopBarScaffoldScrollMode.enterAlwaysCollapsed(),\n    // ...\n)\n```\n\n\u003cdetails\u003e\n\u003csummary\u003eRegular collapse\u003c/summary\u003e\n\n#### Regular collapse\n\n```kotlin\nCollapsingTopBarScaffoldScrollMode.collapse(expandAlways = false)\n```\n\nThe top bar will collapse to the height of the smallest child. It has an option `expandAlways` to\ncontrol whether or not to expand anywhere in the list.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCollapse and exit\u003c/summary\u003e\n\n#### Collapse and exit\n\n```kotlin\nCollapsingTopBarScaffoldScrollMode.collapseAndExit(expandAlways = false)\n```\n\nThe top bar will collapse to the height of the smallest child and then completely exit outside its\nbounds. It has an option `expandAlways` to control whether or not to expand anywhere in the list.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eEnter always collapsed\u003c/summary\u003e\n\n#### Enter always collapsed\n\n```kotlin\nCollapsingTopBarScaffoldScrollMode.enterAlwaysCollapsed()\n```\n\nThe top bar will collapse to the height of the smallest child and then completely exit outside its\nbounds. Then it'll enter collapsed anywhere in the list and fully expand only at the top.\n\u003c/details\u003e\n\n### Snapping\n\n![](/docs/assets/snapping.gif)\n\nUse a `snapBehavior` parameter of `CollapsingTopBarScaffold()`:\n\n```kotlin\nCollapsingTopBarScaffold(\n    // ...\n    snapBehavior = rememberCollapsingTopBarSnapBehavior(),\n    // ...\n)\n```\n\nYou can optionally specify a `threshold` fraction of collapse progress to control the bound of\nsnapping direction:\n\n```kotlin\nrememberCollapsingTopBarSnapBehavior(threshold = 0.75f)\n```\n\n### Customization\n\nWhen using `CollapsingTopBarScaffold`, you get access to a `CollapsingTopBarScope` in the `topBar`\nblock. It offers a few predefined Modifiers to customize element placement and more.\n\n|            Parallax            |            Floating            |          Progress           |\n|:------------------------------:|:------------------------------:|:---------------------------:|\n| ![](/docs/assets/parallax.gif) | ![](/docs/assets/floating.gif) | ![](/docs/assets/scrim.gif) |\n\nSee all supported placement customization Modifiers:\n\n\u003cdetails\u003e\n\u003csummary\u003eAlign\u003c/summary\u003e\n\n#### Align\n\n```kotlin\nModifier.align(Alignment)\n```\n\nAligns an element within the bounds of `CollapsingTopBar`.\n\nAligned elements still contribute to minimum height resolution. If you want an aligned element to\nbehave like an overlay and not affect the collapsed height, combine `align(...)` with\n`floating()`.\n\n```kotlin\nCollapsingTopBarScaffold(\n    scrollMode = CollapsingTopBarScaffoldScrollMode.collapse(expandAlways = false),\n    topBar = {\n        SampleTopBarImage()\n        AlignmentElement(\n            modifier = Modifier\n                .align(Alignment.BottomEnd)\n                .floating(),\n            text = \"Nebula\",\n        )\n    },\n    body = {\n        SampleContent()\n    },\n)\n```\n\n\u003e In this example the \"Nebula\" element is aligned to the bottom end of the top bar and kept out of\n\u003e minimum height resolution, so it behaves like an overlay.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eParallax\u003c/summary\u003e\n\n#### Parallax\n\n```kotlin\nModifier.parallax()\n```\n\nCreates a parallax effect by offsetting an element upward by `ratio` as a fraction of the\ncollapsible height while the top bar collapses.\n\n```kotlin\nCollapsingTopBarScaffold(\n    scrollMode = CollapsingTopBarScaffoldScrollMode.collapse(expandAlways = false),\n    topBar = {\n        SampleTopBarImage(\n            modifier = Modifier.parallax(0.25f),\n        )\n        SampleTopAppBar(\n            containerColor = Color.Transparent,\n        )\n    },\n    body = {\n        SampleContent()\n    },\n)\n```\n\n\u003e In this example the top bar image is collapsing with a 25% parallax effect.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003ePin\u003c/summary\u003e\n\n#### Pin\n\n```kotlin\nModifier.pin(stopAtTop = false)\n```\n\nKeeps an element at its regular position until its bottom edge reaches the visible bottom of\n`CollapsingTopBar`, then makes it ride upward with the collapsing top bar.\n\nBy default, a pinned element continues riding past the top edge. Set `stopAtTop = true` to stop\nit at `y = 0`.\n\n`pin(...)` affects placement only and does not change minimum height resolution. Combine it with\n`floating()` when the pinned element should behave like an overlay and stay out of collapsed height\ncalculation.\n\n```kotlin\nCollapsingTopBarScaffold(\n    scrollMode = CollapsingTopBarScaffoldScrollMode.collapse(expandAlways = false),\n    topBar = {\n        SampleTopBarImage()\n        PinnedElement(\n            modifier = Modifier\n                .floating()\n                .align(Alignment.BottomEnd)\n                .pin(),\n        )\n        SampleTopAppBar(\n            containerColor = Color.Transparent,\n        )\n    },\n    body = {\n        SampleContent()\n    },\n)\n```\n\n\u003e In this example the bottom-end element is pinned and keeps riding with the top bar, excluded from\n\u003e collapsed height calculation.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eFloating\u003c/summary\u003e\n\n#### Floating\n\n```kotlin\nModifier.floating()\n```\n\nExcludes an element from the collapsed height calculation, allowing it to float and position itself\nin any way you want (floating button, indicator, etc). Should be used only in the presence of\nother non-floating elements in the top bar.\n\n```kotlin\nCollapsingTopBarScaffold(\n    scrollMode = CollapsingTopBarScaffoldScrollMode.collapseAndExit(expandAlways = false),\n    topBar = { topBarState -\u003e\n        SampleTopBarImage()\n        SampleTopAppBar(\n            containerColor = Color.Transparent,\n        )\n        FloatingButton(\n            modifier = Modifier.floating(),\n            state = topBarState,\n        )\n    },\n    body = {\n        SampleContent()\n    },\n)\n```\n\n\u003e In this example there's a floating button with the `floating` modifier implementing its own\n\u003e placement logic using `topBarState`.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eProgress\u003c/summary\u003e\n\n#### Progress\n\n```kotlin\nModifier.progress { totalProgress, itemProgress -\u003e }\n```\n\nAllows you to track the current progress of both the top bar and an element to which this modifier\nis applied. As a result, you can create your own transformations of any kind.\n\n```kotlin\nCollapsingTopBarScaffold(\n    scrollMode = CollapsingTopBarScaffoldScrollMode.collapse(expandAlways = false),\n    topBar = {\n        var topBarColorProgress by remember { mutableFloatStateOf(1f) }\n        SampleTopBarImage(\n            modifier = Modifier.progress { _, itemProgress -\u003e\n                topBarColorProgress =\n                    itemProgress.coerceAtMost(SCRIM_START_FRACTION) / SCRIM_START_FRACTION\n            },\n        )\n        SampleTopAppBar(\n            containerColor = MaterialTheme.colorScheme.surface.copy(\n                alpha = lerp(1f, 0f, topBarColorProgress),\n            ),\n        )\n    },\n    body = {\n        SampleContent()\n    },\n)\n```\n\n\u003e In this example the top app bar dynamically changes its color as the top bar image collapses.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eNested collapse\u003c/summary\u003e\n\n#### Nested collapse\n\n```kotlin\nModifier.nestedCollapse()\n```\n\nDefines a connection between an element with a custom nested collapsing mechanism and the top bar.\nShould be used when creating custom complex collapsing elements, e.g.,\n[CollapsingTopBarColumn](#CollapsingTopBarColumn).\n\n\u003c/details\u003e\n\n### CollapsingTopBarColumn\n\nA `Column`-like layout that creates an amazing stacking collapse effect with predefined placement\ncustomization options and the possibility to build custom transformations based on collapse\nprogress.\n\n|              Fully collapsible               |               Partially collapsible               |                 Custom transformations                 |\n|:--------------------------------------------:|:-------------------------------------------------:|:------------------------------------------------------:|\n| ![](/docs/assets/collapsing_column_full.gif) | ![](/docs/assets/collapsing_column_partially.gif) | ![](/docs/assets/collapsing_column_moving_element.gif) |\n\n#### Collapse direction\n\n`CollapsingTopBarColumn` supports two collapse directions:\n\n- `CollapsingTopBarColumnDirection.BottomUp` (default) - starts collapsing with the\n  bottommost element sliding under the second last and so on;\n- `CollapsingTopBarColumnDirection.TopToBottom` - starts collapsing with the\n  topmost element sliding up and so on.\n\n|                     BottomUp                      |                   TopToBottom                   |\n|:-------------------------------------------------:|:-----------------------------------------------:|\n| ![](/docs/assets/collapsing_column_partially.gif) | ![](/docs/assets/collapsing_column_reverse.gif) |\n\nUse a parameter `collapseDirection` of `CollapsingTopBarColumn()`:\n\n```kotlin\nCollapsingTopBarColumn(\n    state = topBarState,\n    collapseDirection = CollapsingTopBarColumnDirection.TopToBottom,\n) { /* ... */ }\n```\n\n#### Customization\n\nSee all supported placement customization Modifiers:\n\n\u003cdetails\u003e\n\u003csummary\u003eAlign\u003c/summary\u003e\n\n#### Align\n\n```kotlin\nModifier.align(Alignment.Horizontal)\n```\n\nAligns an element horizontally within the width of `CollapsingTopBarColumn`.\n\n```kotlin\nCollapsingTopBarScaffold(\n    scrollMode = CollapsingTopBarScaffoldScrollMode.collapse(expandAlways = false),\n    topBar = { topBarState -\u003e\n        CollapsingTopBarColumn(topBarState) {\n            SampleTopAppBar(\n                modifier = Modifier.notCollapsible(),\n            )\n            AlignmentElement(\n                modifier = Modifier.align(Alignment.CenterHorizontally),\n            )\n        }\n    },\n    body = {\n        SampleContent()\n    },\n)\n```\n\n\u003e In this example the element is aligned to the center of the column.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eNot collapsible\u003c/summary\u003e\n\n#### Not collapsible\n\n```kotlin\nModifier.notCollapsible()\n```\n\nExcludes an element from the collapsing process, so that it remains always visible and just slides\nup and down with the collapsing movement.\n\n```kotlin\nCollapsingTopBarScaffold(\n    scrollMode = CollapsingTopBarScaffoldScrollMode.collapse(expandAlways = false),\n    topBar = { topBarState -\u003e\n        CollapsingTopBarColumn(topBarState) {\n            SampleTopBarBanner()\n            SampleTopAppBar(\n                modifier = Modifier.notCollapsible(),\n            )\n            CollapsingTopBarVerticalFadingEdge()\n            SampleFilterChips()\n        }\n    },\n    body = {\n        SampleContent()\n    },\n)\n```\n\n\u003e In this example the top app bar is not collapsible, but every other element is.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003ePin when collapsed\u003c/summary\u003e\n\n#### Pin when collapsed\n\n```kotlin\nModifier.pinWhenCollapsed()\n```\n\nUnlike the default placement behavior that stops sliding an element when it is fully collapsed,\nthis modifier makes the element continue its movement (pin). Useful if you want an element to\nslide all the way up under other transparent elements.\n\n```kotlin\nCollapsingTopBarScaffold(\n    modifier = modifier,\n    scrollMode = CollapsingTopBarScaffoldScrollMode.collapse(expandAlways = false),\n    topBar = { topBarState -\u003e\n        CollapsingTopBarColumn(\n            state = topBarState,\n            collapseDirection = CollapsingTopBarColumnDirection.TopToBottom,\n        ) {\n            SampleTopAppBar(\n                modifier = Modifier.notCollapsible(),\n            )\n            InfoBlock(\n                modifier = Modifier.pinWhenCollapsed(),\n            )\n            SearchBar(\n                modifier = Modifier.zIndex(1f),\n            )\n        }\n    },\n    body = {\n        SampleContent()\n    },\n)\n```\n\n\u003e In this example the `InfoBlock` is pinned when collapsed, and it'll slide under the top app bar\n\u003e out of the screen bounds.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eClip to collapse\u003c/summary\u003e\n\n#### Clip to collapse\n\n```kotlin\nModifier.clipToCollapse()\n```\n\nClips an element to its bounds as it collapses, so that it's not visible under the following\ntransparent element.\n\n```kotlin\nCollapsingTopBarScaffold(\n    scrollMode = CollapsingTopBarScaffoldScrollMode.collapse(expandAlways = true),\n    topBar = { topBarState -\u003e\n        CollapsingTopBarColumn(\n            state = topBarState,\n        ) {\n            SampleFilterChips(\n                modifier = Modifier.clipToCollapse(),\n            )\n            SampleTopAppBar(\n                modifier = Modifier.notCollapsible(),\n                containerColor = Color.Transparent,\n            )\n            SampleFilterChips(\n                modifier = Modifier.clipToCollapse(),\n            )\n        }\n    },\n    body = {\n        SampleContent()\n    },\n)\n```\n\n\u003e In this example all elements but the top app bar clip themselves to collapse bounds.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eColumn Progress\u003c/summary\u003e\n\n#### Column Progress\n\n```kotlin\nModifier.columnProgress()\n```\n\nAllows you to track the current progress of both the top bar column and an element to which this\nmodifier is applied. As a result, you can create your own transformations of any kind.\n\n```kotlin\nCollapsingTopBarScaffold(\n    scrollMode = CollapsingTopBarScaffoldScrollMode.collapse(expandAlways = false),\n    topBar = { topBarState -\u003e\n        CollapsingTopBarColumn(topBarState) {\n            SampleTopAppBar(\n                modifier = Modifier.notCollapsible(),\n                title = \"Column Moving Element\",\n                onBack = onBack,\n            )\n\n            var textCollapseProgress by remember {\n                mutableFloatStateOf(1f)\n            }\n            Text(\n                modifier = Modifier\n                    .columnProgress { _, itemProgress -\u003e textCollapseProgress = itemProgress }\n                    .graphicsLayer {\n                        alpha = textCollapseProgress\n                    },\n                text = \"Collapsible element\",\n            )\n        }\n    },\n    body = {\n        SampleContent()\n    },\n)\n```\n\n\u003e In this example the `Text` element keeps track of its collapse progress and fades out on collapse.\n\n\u003c/details\u003e\n\n### Decorations\n\n`ComposeCollapsingTopBar` also provides small decoration composables to improve collapsing visuals\nin certain scenarios.\n\n#### Vertical fading edge\n\n```kotlin\nCollapsingTopBarVerticalFadingEdge(\n    color = MaterialTheme.colorScheme.surface,\n)\n```\n\n`CollapsingTopBarVerticalFadingEdge()` draws a vertical fading overlay with zero layout height.\nIt's useful for smoothing visible overlap between stacked top bar elements in\n`CollapsingTopBarColumn` and regular top bar layouts.\n\n### React to state changes\n\nYou can easily access `CollapsingTopBarScaffoldState` and its nested states to observe state\nchanges. For convenience, you can also access `CollapsingTopBarState` from within the `topBar`\nblock of `CollapsingTopBarScaffold()`. Now just use your imagination to figure out what beautiful\neffects to create. :wink:\n\n\u003cdetails\u003e\n\u003csummary\u003eExample\u003c/summary\u003e\n\n```kotlin\nval state = rememberCollapsingTopBarScaffoldState()\nval topBarShadowElevation by animateDpAsState(\n    label = \"ShadowAnimation\",\n    targetValue = if (state.topBarState.isCollapsed) 12.dp else 0.dp,\n)\nCollapsingTopBarScaffold(\n    state = state,\n    scrollMode = CollapsingTopBarScaffoldScrollMode.collapse(expandAlways = false),\n    topBarModifier = Modifier.graphicsLayer {\n        shadowElevation = topBarShadowElevation.toPx()\n    },\n    topBar = {\n        SampleTopBarImage()\n        SampleTopAppBar()\n    },\n    body = {\n        SampleContent()\n    },\n)\n```\n\n\u003e In this example the top bar drops a shadow that appears with animation as soon as the top bar is\n\u003e collapsed.\n\n\u003c/details\u003e\n\n#### Working with states\n\n\u003cdetails\u003e\n\u003csummary\u003eCollapsingTopBarScaffoldState\u003c/summary\u003e\n\n#### CollapsingTopBarScaffoldState\n\nThis is a state holder for top bar layout data that also allows some manual control.\n\nYou can easily access the current top bar state with `state.isExpanded` and `state.isCollapsed`.\nOr you can programmatically toggle one with `state.expand()` and `state.collapse()` inside\n`LaunchedEffect` or a custom coroutine.\n\nIf you need more detailed layout data, refer to:\n\n- `topBarState` for collapsing progress;\n- `exitState` for exiting progress;\n    - note that it's empty unless you use a *scroll mode that supports exiting*.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCollapsingTopBarState\u003c/summary\u003e\n\n#### CollapsingTopBarState\n\nContains information about the collapsing state up until top bar starts exiting (if chosen scroll\nmode supports that). Offers state data similar to scaffold: `state.isExpanded` and\n`state.isCollapsed`, as well as manual controls: `state.expand()` and `state.collapse()`.\n\nThis state also exposes `hasMeasured` to indicate whether the top bar has already received\nactual layout measurements.\n\nComprehensive measurement data is available via `layoutInfo`, such as collapse progress\n`layoutInfo.collapseProgress`, collapsed height `layoutInfo.collapsedHeight` etc. Before\n`hasMeasured` becomes true, `layoutInfo` contains safe placeholder values rather than actual\nmeasured bounds.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eCollapsingTopBarExitState\u003c/summary\u003e\n\n#### CollapsingTopBarExitState\n\n\u003e This state only makes sense if you use a scroll mode that supports exiting: `collapseAndExit()`,\n\u003e `enterAlwaysCollapsed()`.\n\nContains information about the top bar exiting state up from when top bar is collapsed. Offers state\ndata: `state.isFullyEntered` and `state.isFullyExited`, as well as manual controls:\n`state.expand()` and `state.collapse()`.\n\nThis state exposes current exit offset via `exitHeight`.\n\n\u003c/details\u003e\n\n## More examples\n\nFeel free to install a demo [Android](/sample/android) or [iOS](/sample/ios) app and try yourself\neven more samples!\n\n## Contributing\n\nPlease contribute! I will gladly review any pull requests.\n\n## License\n\nComposeCollapsingTopBar is distributed under the terms of the Apache License (Version 2.0).\nSee the [license](LICENSE) for more information.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflaringapp%2FComposeCollapsingTopBar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflaringapp%2FComposeCollapsingTopBar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflaringapp%2FComposeCollapsingTopBar/lists"}