Skip to content

Implement collapsible top bar and improve state persistence#12

Merged
komodgn merged 6 commits into
developfrom
refactor/topbar
May 14, 2026
Merged

Implement collapsible top bar and improve state persistence#12
komodgn merged 6 commits into
developfrom
refactor/topbar

Conversation

@komodgn
Copy link
Copy Markdown
Owner

@komodgn komodgn commented May 14, 2026

Summary by CodeRabbit

  • New Features

    • Interactive filter chips for component selection.
    • Collapsing top bar with smooth scroll-linked animations.
  • Improvements

    • Shared scroll behavior for coordinated header/content scrolling.
    • Persisted language and input state across process restarts.
    • Refined layout inset handling for better content alignment.

Review Change Stack

komodgn added 2 commits May 14, 2026 19:48
- Hoist scroll state to manage dynamic top bar animations.
- Refactor TopBar into modular components (FilterRow, FilterChip).
- Use rememberSaveable for UI state persistence across configuration changes.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 66d41e87-6a53-4c15-8775-c752d2dba03f

📥 Commits

Reviewing files that changed from the base of the PR and between 7061fb4 and 10254b5.

📒 Files selected for processing (1)
  • example/src/commonMain/kotlin/io/github/komodgn/example/component/DemoTopBar.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • example/src/commonMain/kotlin/io/github/komodgn/example/component/DemoTopBar.kt

📝 Walkthrough

Walkthrough

The PR adds reusable filter-chip components, refactors DemoTopBar to animate/collapse based on a hoisted ScrollState, and updates Application.kt to hoist the scroll state, persist selected UI fields with rememberSaveable, and adjust safe-drawing insets.

Changes

Scroll-Collapsing Header Feature

Layer / File(s) Summary
Filter chip components
example/src/commonMain/kotlin/io/github/komodgn/example/component/DemoFilterChip.kt, example/src/commonMain/kotlin/io/github/komodgn/example/component/DemoComponentFilterRow.kt
DemoFilterChip wraps Material FilterChip with theme-based colors and selection border. DemoComponentFilterRow renders a horizontal row of chips, highlights the selected component, maps values to labels, and forwards selection callbacks.
Scroll-driven header
example/src/commonMain/kotlin/io/github/komodgn/example/component/DemoTopBar.kt
DemoTopBar signature now accepts ScrollState; it computes collapseFraction from scroll position, animates title/subtitle via graphics transforms, and conditionally shows the component filter row with animated visibility and transforms.
App-level state hoisting and wiring
example/src/commonMain/kotlin/io/github/komodgn/example/Application.kt
Hoist ScrollState at app level and pass it to DemoTopBar and MainContent. Change currentLang and userInput to rememberSaveable. Adjust insets handling to use horizontal+bottom safe-drawing and refactor MainContent to accept the external ScrollState.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • komodgn/compose-codeview#10: Related changes to demo UI wiring around Application.kt/DemoTopBar, including component selection and scroll-state handling.
  • komodgn/compose-codeview#1: Prior changes to the example app's Application.kt composition and Scaffold/insets configuration related to scroll/insets behavior.

Poem

🐰 I hoisted a scroll and watched the top fold,

chips stand in a row, both brave and bold.
States now remember when screens restart,
titles that glide — oh, Compose is an art! ✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately captures the two main changes: implementing a collapsible top bar (seen in DemoTopBar changes with ScrollState and collapseFraction logic) and improving state persistence (rememberSaveable for currentLang and userInput in Application.kt).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/topbar

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
example/src/commonMain/kotlin/io/github/komodgn/example/component/DemoTopBar.kt (1)

55-56: ⚡ Quick win

Consider using density-aware threshold.

The scrollThreshold = 120f uses raw pixels, which means the collapse behavior will feel different on screens with varying densities. For consistent UX across devices, consider converting dp to pixels using LocalDensity.

📏 Proposed fix for density-aware threshold
+import androidx.compose.ui.platform.LocalDensity
+
 `@Suppress`("FrequentlyChangingValue")
 `@Composable`
 fun DemoTopBar(
     scrollState: ScrollState,
     isDark: Boolean,
     onToggleTheme: () -> Unit,
     selectedComponent: DemoComponent,
     onComponentSelect: (DemoComponent) -> Unit,
 ) {
-    val scrollThreshold = 120f
+    val density = LocalDensity.current
+    val scrollThreshold = with(density) { 120.dp.toPx() }
     val collapseFraction = (scrollState.value / scrollThreshold).coerceIn(0f, 1f)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@example/src/commonMain/kotlin/io/github/komodgn/example/component/DemoTopBar.kt`
around lines 55 - 56, The fixed code should replace the hardcoded pixel
threshold with a density-aware value: convert 120.dp to pixels using
LocalDensity (e.g., within DemoTopBar's composable scope use
LocalDensity.current to compute scrollThresholdPx = with(LocalDensity.current) {
120.dp.toPx() }) and then compute collapseFraction = (scrollState.value /
scrollThresholdPx).coerceIn(0f, 1f); ensure you reference scrollThresholdPx
instead of the old scrollThreshold and import/use LocalDensity and dp in
DemoTopBar.kt.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@example/src/commonMain/kotlin/io/github/komodgn/example/component/DemoTopBar.kt`:
- Line 86: The text for the top-bar label has inconsistent spacing: when
selectedComponent == DemoComponent.CODE_VIEW it uses " CodeView" with a leading
space while the else branch uses "CodeEditor"; update the conditional in
DemoTopBar (the expression that builds text from selectedComponent) to remove
the leading space so both branches use consistently formatted strings (e.g.,
"CodeView" and "CodeEditor") ensuring uniform visual alignment.
- Line 46: The suppression on DemoTopBar hides a real Compose lint about reading
a frequently-changing value (likely scrollState) during composition; remove
`@Suppress`("FrequentlyChangingValue") and instead read the changing value via a
stable derived value or side-effect: e.g., create a
derivedStateOf(filter/threshold) based on scrollState.value and use that in the
composition, or observe scrollState with snapshotFlow inside a LaunchedEffect to
update a mutable state used for non-recomposing effects; locate the code in
DemoTopBar where scrollState (or other frequently-changing property) is read in
the composition lambda and replace the direct read with derivedStateOf or
snapshotFlow+LaunchedEffect so recompositions are limited.

---

Nitpick comments:
In
`@example/src/commonMain/kotlin/io/github/komodgn/example/component/DemoTopBar.kt`:
- Around line 55-56: The fixed code should replace the hardcoded pixel threshold
with a density-aware value: convert 120.dp to pixels using LocalDensity (e.g.,
within DemoTopBar's composable scope use LocalDensity.current to compute
scrollThresholdPx = with(LocalDensity.current) { 120.dp.toPx() }) and then
compute collapseFraction = (scrollState.value / scrollThresholdPx).coerceIn(0f,
1f); ensure you reference scrollThresholdPx instead of the old scrollThreshold
and import/use LocalDensity and dp in DemoTopBar.kt.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0d43c83e-1c1c-48e3-8476-20edc2ec40fa

📥 Commits

Reviewing files that changed from the base of the PR and between c92258e and 7061fb4.

📒 Files selected for processing (5)
  • .github/workflows/docs.yml
  • example/src/commonMain/kotlin/io/github/komodgn/example/Application.kt
  • example/src/commonMain/kotlin/io/github/komodgn/example/component/DemoComponentFilterRow.kt
  • example/src/commonMain/kotlin/io/github/komodgn/example/component/DemoFilterChip.kt
  • example/src/commonMain/kotlin/io/github/komodgn/example/component/DemoTopBar.kt

Comment thread example/src/commonMain/kotlin/io/github/komodgn/example/component/DemoTopBar.kt Outdated
Comment thread example/src/commonMain/kotlin/io/github/komodgn/example/component/DemoTopBar.kt Outdated
komodgn and others added 4 commits May 14, 2026 19:55
…ent/DemoTopBar.kt

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
- Optimize top bar performance using derivedStateOf and deferred reading.
@komodgn komodgn merged commit edab89f into develop May 14, 2026
1 check passed
@komodgn komodgn deleted the refactor/topbar branch May 14, 2026 13:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant