# Customization ## Colors ```kotlin setBackgroundColor(Color(0xFF785EF0)) setArrowColor(Color.White) // Color.Unspecified inherits the background setAlpha(0.9f) ``` `setAlpha` applies to the whole balloon in one layer, so overlapping parts do not double blend. ## Border

Stroke

```kotlin setBorder(color = Color.White, thickness = 2.dp) setBalloonStroke(color = Color.White, thickness = 2.dp) // same thing, 1.x name ``` The stroke traces the real silhouette, arrow included, at exactly the thickness you asked for. Leave `borderColor` at `Color.Unspecified` or `borderThickness` at `0.dp` to disable it. ## Content The balloon body is a Compose slot, so there is nothing to configure on the builder. Build it with the same composables you use everywhere else.

Balloon example

```kotlin Balloon( state = balloonState, balloonContent = { Column { Text( text = "Choose a drink", color = Color.White, style = MaterialTheme.typography.titleSmall, ) Spacer(modifier = Modifier.height(8.dp)) drinks.forEach { drink -> Row( modifier = Modifier .fillMaxWidth() .clickable { onDrinkSelected(drink) } .padding(vertical = 6.dp), verticalAlignment = Alignment.CenterVertically, ) { Icon(painter = painterResource(drink.icon), contentDescription = null) Spacer(modifier = Modifier.width(8.dp)) Text(text = drink.name, color = Color.White) } } } }, ) { Button(onClick = { balloonState.showAlignBottom() }) { Text(text = "Drinks") } } ``` Interactive content works normally. A tap that a child consumes never reaches the balloon's own tap handler, so a clickable row inside the body does not accidentally trigger `setDismissWhenClicked`. ## Reusing a style `BalloonStyle` is immutable, and `derive` makes a variant that changes only what you name: ```kotlin val base = rememberBalloonBuilder { setCornerRadius(8.dp) setPadding(12.dp) setBackgroundColor(Color(0xFF785EF0)) } val warning = base.derive { setBackgroundColor(Color(0xFFFF6F00)) } val subtle = base.derive { setAlpha(0.85f) setArrowSize(8.dp) } ``` `derive` takes the same builder block as `rememberBalloonBuilder`, starting from an existing style instead of the defaults. It exists instead of a data class `copy` because a generated `copy` would name all 43 properties in the published binary interface and make adding a 44th option a breaking change. `DefaultBalloonStyle` is the same value the builder produces with no calls, which makes a convenient starting point. ## Restyling a visible balloon `rememberBalloonState` re-applies the style on every recomposition, so an animated style updates a balloon that is already showing without hiding it: ```kotlin val color by animateColorAsState(if (selected) Color(0xFF785EF0) else Color(0xFF444444)) val balloonState = rememberBalloonState(style.derive { setBackgroundColor(color) }) ``` ## Behavior ```kotlin setDismissWhenClicked(true) // tapping the body closes it setDismissWhenTouchOutside(true) // tapping outside closes it setDismissWhenBackPressed(true) // back or Escape closes it setDismissWhenShowAgain(true) // showing a visible balloon closes it instead setDismissWhenTouchMargin(true) // a tap in the margin band closes it too setDismissWhenOverlayClicked(true) // tapping the scrim closes it setAutoDismissDuration(2_000L) // 0L disables setFocusable(true) ``` Two of these carry side effects, kept from 1.x so ported call sites behave the same: - `setDismissWhenTouchOutside(false)` also clears focusability, so a balloon that ignores outside taps does not sit there swallowing them - `setBalloonAnimation(BalloonAnimation.CIRCULAR)` also clears focusability, so the reveal can play without the popup stealing input Call `setFocusable(true)` after either one if you want focus back. ## Accessibility Balloon content is marked with an unmergeable semantics property, so a screen reader treats it as its own subtree instead of folding it into a clickable ancestor. Give the content itself meaningful semantics the way you normally would: ```kotlin balloonContent = { Text( modifier = Modifier.semantics { liveRegion = LiveRegionMode.Polite }, text = "Now you can edit your profile!", ) } ```