---
title: Disclosure
description: An expandable content component with a dedicated trigger and content slot.
---



```kotlin expandable title="DisclosureDemo.kt" githubUrl="https://github.com/composablehorizons/compose-unstyled/blob/main/demo/src/commonMain/kotlin/com/composeunstyled/demo/disclosure/DisclosureDemo.kt"
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.VisibilityThreshold
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.spring
import androidx.compose.animation.core.tween
import androidx.compose.animation.expandVertically
import androidx.compose.animation.shrinkVertically
import androidx.compose.foundation.LocalIndication
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.widthIn
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.alpha
import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import com.composables.icons.lucide.ChevronDown
import com.composables.icons.lucide.Lucide
import com.composeunstyled.DisclosedContent
import com.composeunstyled.DisclosureButton
import com.composeunstyled.Text
import com.composeunstyled.UnstyledDisclosure
import com.composeunstyled.UnstyledIcon
import com.composeunstyled.demo.borderToken
import com.composeunstyled.demo.colors
import com.composeunstyled.demo.contentToken
import com.composeunstyled.demo.surfaceToken
import com.composeunstyled.theme.Theme

@Preview
@Composable
fun DisclosureDemo() {
  var expanded by remember { mutableStateOf(false) }
  Box(
    modifier = Modifier.fillMaxSize().padding(top = 24.dp),
    contentAlignment = Alignment.TopCenter,
  ) {
    UnstyledDisclosure(
      expanded = expanded,
      onExpandedChange = { expanded = it },
    ) {
      Column(
        modifier = Modifier
          .widthIn(max = 560.dp)
          .clip(RectangleShape)
          .background(Theme[colors][surfaceToken])
          .border(1.dp, Theme[colors][borderToken], RectangleShape),
      ) {
        DisclosureButton(
          modifier = Modifier.fillMaxWidth(),
          indication = LocalIndication.current,
        ) {
          Row(
            modifier = Modifier.fillMaxWidth().padding(vertical = 12.dp, horizontal = 16.dp),
            verticalAlignment = Alignment.CenterVertically,
          ) {
            Text("What is Compose Unstyled", modifier = Modifier.weight(1f))

            val degrees by animateFloatAsState(if (expanded) -180f else 0f, tween())
            UnstyledIcon(
              imageVector = Lucide.ChevronDown,
              contentDescription = null,
              modifier = Modifier.rotate(degrees),
              tint = Theme[colors][contentToken],
            )
          }
        }
        DisclosedContent(
          enter = expandVertically(
            spring(
              stiffness = Spring.StiffnessMediumLow,
              visibilityThreshold = IntSize.VisibilityThreshold,
            ),
          ),
          exit = shrinkVertically(),
        ) {
          Text(
            "Compose Unstyled is a collection of unstyled, accessible UI components for Compose " +
              "Multiplatform. It provides the building blocks for creating beautiful, consistent " +
              "user interfaces.",
            modifier = Modifier.padding(16.dp).alpha(0.66f),
          )
        }
      }
    }
  }
}
```



## Installation

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

## Anatomy

```kotlin
UnstyledDisclosure(
  expanded = expanded,
  onExpandedChange = onExpandedChange,
) {
  DisclosureButton {
  }

  DisclosedContent {
  }
}
```

## Concepts

- `UnstyledDisclosure` represents an expandable region.
- `DisclosureButton` renders the trigger that toggles the disclosure.
- `DisclosedContent` renders content only while the disclosure is expanded.

## Accessibility

Use `DisclosureButton` for the disclosure trigger so assistive technology receives expand and collapse actions.

## Code Examples

### Showing hidden content

Use the `expanded` parameter to control whether `DisclosedContent` is visible:

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

UnstyledDisclosure(
  expanded = expanded,
  onExpandedChange = { expanded = it },
) {
  DisclosureButton {
    BasicText(if (expanded) "Hide details" else "Show details")
  }

  DisclosedContent {
    BasicText("Details")
  }
}
```

### Animating disclosed content

Use the `enter` and `exit` parameters on `DisclosedContent` to animate the disclosed content:

```kotlin expandable
UnstyledDisclosure(
  expanded = expanded,
  onExpandedChange = { expanded = it },
) {
  DisclosureButton {
    BasicText("Details")
  }

  DisclosedContent(
    enter = expandVertically(),
    exit = shrinkVertically(),
  ) {
    BasicText("Hidden content")
  }
}
```

## API Reference

### UnstyledDisclosure

| Parameter | Type | Description |
|-----------|------|-------------|
| `expanded` | `Boolean` | Controls whether the disclosure is expanded. |
| `onExpandedChange` | `(Boolean) -> Unit` |  |
| `modifier` | `Modifier` | Modifier to be applied to the panel. |
| `content` | `DisclosureScope.() -> Unit` | A composable function that defines the content of the panel. |
### UnstyledDisclosureButton

| Parameter | Type | Description |
|-----------|------|-------------|
| `modifier` | `Modifier` | Modifier to be applied to the panel. |
| `enabled` | `Boolean` | Indicates if the heading is enabled. |
| `contentPadding` | `PaddingValues` | Padding values for the content. |
| `indication` | `Indication?` | The indication to be shown when the heading is interacted with. |
| `interactionSource` | `MutableInteractionSource?` | The interaction source for the heading. |
| `contentAlignment` | `Alignment` |  |
| `content` | `() -> Unit` | A composable function that defines the content of the panel. |
### UnstyledDisclosedContent

| Parameter | Type | Description |
|-----------|------|-------------|
| `modifier` | `Modifier` | Modifier to be applied to the panel. |
| `enter` | `EnterTransition` | The enter transition for the panel. |
| `exit` | `ExitTransition` | The exit transition for the panel. |
| `content` | `() -> Unit` | A composable function that defines the content of the panel. |
### DisclosureScope.DisclosureButton

| Parameter | Type | Description |
|-----------|------|-------------|
| `modifier` | `Modifier` | Modifier to be applied to the panel. |
| `enabled` | `Boolean` | Indicates if the heading is enabled. |
| `contentPadding` | `PaddingValues` | Padding values for the content. |
| `indication` | `Indication?` | The indication to be shown when the heading is interacted with. |
| `interactionSource` | `MutableInteractionSource?` | The interaction source for the heading. |
| `contentAlignment` | `Alignment` |  |
| `content` | `() -> Unit` | A composable function that defines the content of the panel. |
### DisclosureScope.DisclosedContent

| Parameter | Type | Description |
|-----------|------|-------------|
| `modifier` | `Modifier` | Modifier to be applied to the panel. |
| `enter` | `EnterTransition` | The enter transition for the panel. |
| `exit` | `ExitTransition` | The exit transition for the panel. |
| `content` | `() -> Unit` | A composable function that defines the content of the panel. |
