---
title: Toggle Switch
description: A switch component with an animated thumb slot.
---



```kotlin expandable title="ToggleSwitchDemo.kt" githubUrl="https://github.com/composablehorizons/compose-unstyled/blob/main/demo/src/commonMain/kotlin/com/composeunstyled/demo/toggleswitch/ToggleSwitchDemo.kt"
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.composeunstyled.Text
import com.composeunstyled.Thumb
import com.composeunstyled.Track
import com.composeunstyled.UnstyledSwitch
import com.composeunstyled.demo.borderToken
import com.composeunstyled.demo.colors
import com.composeunstyled.demo.contentToken
import com.composeunstyled.demo.inputBackgroundToken
import com.composeunstyled.demo.surfaceToken
import com.composeunstyled.theme.Theme

@Preview
@Composable
fun ToggleSwitchDemo() {
  var toggled by remember { mutableStateOf(true) }
  val backgroundColor by animateColorAsState(
    if (toggled) Theme[colors][contentToken] else Theme[colors][inputBackgroundToken],
  )
  val pillShape = RoundedCornerShape(100)

  Box(
    modifier = Modifier.fillMaxSize(),
    contentAlignment = Alignment.Center,
  ) {
    UnstyledSwitch(
      checked = toggled,
      onCheckedChange = { toggled = it },
      modifier = Modifier
        .width(300.dp)
        .clip(RectangleShape),
      indication = LocalIndication.current,
    ) {
      Row(
        modifier = Modifier
          .fillMaxWidth()
          .padding(8.dp),
        horizontalArrangement = Arrangement.SpaceBetween,
        verticalAlignment = Alignment.CenterVertically,
      ) {
        Text("Airplane Mode", fontSize = 18.sp)
        Track(
          modifier = Modifier
            .width(58.dp)
            .height(32.dp)
            .clip(pillShape)
            .background(backgroundColor, pillShape)
            .border(1.dp, Theme[colors][borderToken], pillShape),
        ) {
          Thumb(
            animationSpec = tween(),
            modifier = Modifier
              .padding(4.dp)
              .clip(CircleShape)
              .background(Theme[colors][surfaceToken])
              .border(1.dp, Theme[colors][borderToken], CircleShape)
              .size(24.dp),
          )
        }
      }
    }
  }
}
```



## Installation

```kotlin
implementation("com.composables:composeunstyled-toggle-switch:2.10.0")
```

## Anatomy

```kotlin
UnstyledSwitch(
  checked = checked,
  onCheckedChange = onCheckedChange,
) {
  SwitchThumb {
  }
}
```

## Concepts

- `UnstyledSwitch` represents the interactive switch.
- `SwitchThumb` places thumb content at the start or end of the switch layout.

## Accessibility

Use the `onCheckedChange` parameter to make the switch interactive. Set it to `null` only when an
accessible parent component owns the toggle interaction.

## Code Examples

### Toggling a switch

Use the `checked` and `onCheckedChange` parameters to control switch state:

```kotlin expandable
var checked by remember { mutableStateOf(false) }

UnstyledSwitch(
  checked = checked,
  onCheckedChange = { checked = it },
) {
  SwitchThumb {
    BasicText(if (checked) "On" else "Off")
  }
}
```

### Animating the switch thumb

Use the `animationSpec` parameter on `SwitchThumb` to change the thumb animation:

```kotlin expandable
UnstyledSwitch(
  checked = checked,
  onCheckedChange = { checked = it },
) {
  SwitchThumb(animationSpec = tween(durationMillis = 200)) {
    BasicText(if (checked) "On" else "Off")
  }
}
```

### Moving toggle behavior to a parent

Use the `onCheckedChange` parameter with `null` when a parent toggleable surface owns the
interaction. This is useful when the switch is only the visual control inside a larger row.

```kotlin expandable
Row(
  modifier = Modifier.toggleable(
    value = checked,
    role = Role.Switch,
    onValueChange = { checked = it },
  ),
) {
  BasicText("Notifications")

  UnstyledSwitch(
    checked = checked,
    onCheckedChange = null,
  ) {
    SwitchThumb {
      BasicText(if (checked) "On" else "Off")
    }
  }
}
```

## API Reference

### UnstyledSwitch

| Parameter | Type | Description |
|-----------|------|-------------|
| `checked` | `Boolean` | Whether the switch is on or off. |
| `onCheckedChange` | `((Boolean) -> Unit)?` | Callback when the switch changes state. Pass `null` when another control owns the interaction. |
| `modifier` | `Modifier` | Modifier to be applied to the switch. |
| `enabled` | `Boolean` | Whether the switch is enabled. |
| `interactionSource` | `MutableInteractionSource?` | Interaction source for press, focus, and drag interactions. |
| `indication` | `Indication?` | Indication used for the switch interaction. |
| `accessibilityLabel` | `String?` |  |
| `content` | `SwitchScope.() -> Unit` | Content drawn inside the switch scope. |
### SwitchScope

| Parameter | Type | Description |
|-----------|------|-------------|
| `checked` | `Boolean` | Whether the switch is on or off. |
| `enabled` | `Boolean` | Whether the switch is enabled. |
| `interactionSource` | `MutableInteractionSource` | Interaction source for press, focus, and drag interactions. |
### SwitchScope.SwitchThumb

| Parameter | Type | Description |
|-----------|------|-------------|
| `modifier` | `Modifier` | Modifier to apply to the thumb container. |
| `animationSpec` | `FiniteAnimationSpec<Dp>` | Animation used when the thumb moves between states. |
| `content` | `() -> Unit` | Thumb content. |
