Skip to content

Conversation

@skydoves
Copy link
Owner

@skydoves skydoves commented Dec 21, 2025

Introduce Modifier.balloon() and BalloonState, deprecate Balloon() composable.

Summary by CodeRabbit

  • New Features

    • Introduced BalloonState API and Modifier.balloon() for modern Compose state management and flexible balloon attachments.
    • Added rememberBalloonState() for managing balloon lifecycle within Compose.
  • Deprecations

    • Deprecated Balloon() composable; use Modifier.balloon() with rememberBalloonState() instead.
    • Deprecated BalloonWindow interface and AwaitBalloonWindowsDsl; migrate to BalloonState.
  • Breaking Changes

    • Removed left/right alignment methods (showAlignLeft, showAlignRight, etc.); use showAlignStart and showAlignEnd for better directional support.

✏️ Tip: You can customize this high-level summary in your review settings.

@skydoves skydoves self-assigned this Dec 21, 2025
@coderabbitai
Copy link

coderabbitai bot commented Dec 21, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Introduces a new Compose-friendly balloon state management API via BalloonState and Modifier.balloon(), deprecates the legacy Balloon composable and AwaitBalloonWindowsDsl, removes left/right alignment methods in favor of directional end/start equivalents, and migrates the demo app to the new state-based pattern. Gradle DSL scope violation suppressions are removed across build files.

Changes

Cohort / File(s) Change Summary
Build Configuration
build.gradle.kts, app/build.gradle.kts, balloon-compose/build.gradle.kts, balloon/build.gradle.kts, benchmark-app/build.gradle.kts
Removed @Suppress("DSL_SCOPE_VIOLATION") annotations, eliminating Kotlin DSL scope violation suppressions.
New Compose State & Modifier API
balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonState.kt, balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonModifier.kt
Added BalloonState class implementing BalloonWindow for Compose state management, with comprehensive public methods for show/dismiss/update operations. Introduced rememberBalloonState() composable function and Modifier.balloon() to attach balloons to composables via anchor views and lifecycle binding.
Deprecations & API Guidance
balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/Balloon.kt, balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/AwaitBalloonWindows.kt, balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/RememberBalloonBuilder.kt, balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonWindow.kt
Marked Balloon, AwaitBalloonWindowsDsl, rememberBalloonWindow, and BalloonWindow as deprecated, directing users to use BalloonState with Modifier.balloon() instead. Added @Suppress("DEPRECATION") and ReplaceWith hints with migration examples.
Alignment API Consolidation
balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonComposeView.kt, balloon/src/main/kotlin/com/skydoves/balloon/Balloon.kt, balloon/src/main/kotlin/com/skydoves/balloon/BalloonExtension.kt
Removed showAlignLeft, showAlignRight, relayShowAlignLeft, relayShowAlignRight methods across Balloon and extension APIs. Added showAlignEnd and awaitAlignEnd extension methods, consolidating directional alignment to start/end terminology.
Layout & Modifier Updates
balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonLayoutInfo.kt
Added height: Int property to BalloonLayoutInfo data class.
API Surface Definitions
balloon-compose/api/balloon-compose.api, balloon/api/balloon.api
Updated public API signatures reflecting new BalloonState and BalloonModifier additions, removal of left/right alignment methods, and corresponding synthetic/default method removals.
Demo App Migration
app/src/main/kotlin/com/skydoves/balloondemo/ComposeActivity.kt
Refactored to use rememberBalloonState() and Modifier.balloon() across composables (TopAppBar, ProfileSection, AnimationDemo, PositionDemos, etc.), replacing nested Balloon wrapper calls with state-based modifier attachments. Added new ModifierDemo composable showcasing the new API.

Sequence Diagram

sequenceDiagram
    actor User
    participant Composable
    participant BalloonState
    participant Modifier.balloon
    participant AnchorView
    participant BalloonComposeView
    participant HostActivity
    
    User->>Composable: Interact with element
    Composable->>BalloonState: rememberBalloonState(builder)
    BalloonState->>BalloonState: Create from Balloon.Builder<br/>(context, lifecycleOwner)
    
    Composable->>Modifier.balloon: Apply balloon(state, content)
    Modifier.balloon->>HostActivity: Create invisible anchor view
    Modifier.balloon->>BalloonComposeView: Wire BalloonComposeView<br/>to BalloonState
    
    Modifier.balloon->>Modifier.balloon: onGloballyPositioned callback
    Modifier.balloon->>Modifier.balloon: Measure balloon content
    Modifier.balloon->>AnchorView: Update position & size
    
    User->>BalloonState: Call showAlignTop()<br/>showAlignBottom(), etc.
    BalloonState->>BalloonComposeView: Delegate show operation
    BalloonComposeView->>BalloonComposeView: Display balloon<br/>from anchor position
    
    User->>BalloonState: Call dismiss()
    BalloonState->>BalloonComposeView: Dismiss balloon
    Modifier.balloon->>AnchorView: Remove from activity
    BalloonState->>BalloonState: Clean up references
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas requiring extra attention:

  • BalloonModifier.kt: High-density composable logic involving anchor view lifecycle, measurement callbacks, layout pass orchestration, and content constraint computation; requires careful verification of anchor creation/disposal and position synchronization.
  • BalloonState.kt: Comprehensive state delegation layer wrapping Balloon.Builder and internal _balloonWindow; verify error handling for unattached access and proper disposal cleanup.
  • API Surface Changes: Multiple method removals across Balloon, BalloonWindow, and extension classes (left/right alignment); ensure no breaking changes for downstream consumers and validate migration path via deprecation messages.
  • Deprecation Paths: Review deprecation annotations across Balloon, AwaitBalloonWindowsDsl, and rememberBalloonWindow to confirm ReplaceWith expressions are accurate and imports are correct.
  • Demo App Refactoring: Verify that ComposeActivity.kt correctly demonstrates new state-based patterns across multiple composables (TopAppBar, ProfileSection, LazyColumn items) and that ModifierDemo adequately showcases the new API usage.

Possibly related PRs

  • Bump Kotlin to 2.2.20 #865: Modifies Compose balloon API surface including AwaitBalloonWindowsDsl and BalloonWindow generated/default method signatures, directly connected to this PR's public API changes.

Poem

🎈 A state-blessed balloon floats free,
No wrapper webs, just Modifier harmony!
BalloonState remembers the dance,
Left and right fade—start, end advance,
The anchor holds true, onward we prance! 🐰

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/modifier-node

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8a1742c and b8e3bda.

📒 Files selected for processing (18)
  • app/build.gradle.kts (1 hunks)
  • app/src/main/kotlin/com/skydoves/balloondemo/ComposeActivity.kt (12 hunks)
  • balloon-compose/api/balloon-compose.api (1 hunks)
  • balloon-compose/build.gradle.kts (1 hunks)
  • balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/AwaitBalloonWindows.kt (2 hunks)
  • balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/Balloon.kt (1 hunks)
  • balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonComposeView.kt (0 hunks)
  • balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonLayoutInfo.kt (1 hunks)
  • balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonModifier.kt (1 hunks)
  • balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonState.kt (1 hunks)
  • balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/BalloonWindow.kt (1 hunks)
  • balloon-compose/src/main/kotlin/com/skydoves/balloon/compose/RememberBalloonBuilder.kt (1 hunks)
  • balloon/api/balloon.api (0 hunks)
  • balloon/build.gradle.kts (0 hunks)
  • balloon/src/main/kotlin/com/skydoves/balloon/Balloon.kt (1 hunks)
  • balloon/src/main/kotlin/com/skydoves/balloon/BalloonExtension.kt (1 hunks)
  • benchmark-app/build.gradle.kts (1 hunks)
  • build.gradle.kts (1 hunks)

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.

@skydoves skydoves merged commit 546cd5b into main Dec 21, 2025
3 of 4 checks passed
@skydoves skydoves deleted the feature/modifier-node branch December 21, 2025 05:59
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.

2 participants