OverlayCascadingListPopup
OverlayCascadingListPopup is a popup list that supports a two-level cascading menu. Items whose DropdownItem.children is non-empty become submenu triggers; tapping such an item morphs the popup into a secondary list anchored at the trigger row, while the primary list scales down behind a translucent mask. Cascading depth is limited to 2.
Prerequisite
This component depends on Scaffold providing MiuixPopupHost to render popup content. It must be used within Scaffold, otherwise popup content will not render correctly.
Import
import top.yukonga.miuix.kmp.overlay.OverlayCascadingListPopup
import top.yukonga.miuix.kmp.basic.DropdownEntry
import top.yukonga.miuix.kmp.basic.DropdownItemBasic Usage
Build entries so that some DropdownItems carry a non-empty children list. The component renders a chevron next to such trigger rows; tapping the trigger expands the second level inline.
var showPopup by remember { mutableStateOf(false) }
var sortIndex by remember { mutableStateOf(0) }
var viewIndex by remember { mutableStateOf(0) }
val sortLabels = listOf("Sort by capture date", "Sort by date added")
val viewLabels = listOf("Group by date", "Compact")
val entries = listOf(
DropdownEntry(
items = sortLabels.mapIndexed { idx, label ->
DropdownItem(
text = label,
selected = sortIndex == idx,
onClick = { sortIndex = idx },
)
},
),
DropdownEntry(
items = listOf(
DropdownItem(
text = "View mode",
children = viewLabels.mapIndexed { idx, label ->
DropdownItem(
text = label,
selected = viewIndex == idx,
onClick = { viewIndex = idx },
)
},
),
),
),
)
Scaffold {
Box {
TextButton(
text = "Click to show menu",
onClick = { showPopup = true },
)
OverlayCascadingListPopup(
show = showPopup,
entries = entries,
onDismissRequest = { showPopup = false },
)
}
}Cascading Depth
Cascading depth is capped at 2. Items at the secondary level cannot have their own children; deeper trees are silently ignored.
Component States
Different Alignments
OverlayCascadingListPopup(
show = showPopup,
entries = entries,
onDismissRequest = { showPopup = false },
alignment = PopupPositionProvider.Align.Start,
)Disable Window Dimming
OverlayCascadingListPopup(
show = showPopup,
entries = entries,
onDismissRequest = { showPopup = false },
enableWindowDim = false,
)Keep Popup Open After Selection
By default the popup closes when the user picks any leaf item. Set collapseOnSelection = false to keep it open (e.g., for multi-select within a submenu).
OverlayCascadingListPopup(
show = showPopup,
entries = entries,
onDismissRequest = { showPopup = false },
collapseOnSelection = false,
)Properties
OverlayCascadingListPopup
| Property Name | Type | Description | Default Value |
|---|---|---|---|
| show | Boolean | Whether to show the popup. | - |
| entries | List<DropdownEntry> | Grouped dropdown entries; top-level items with non-empty children become submenu triggers. | - |
| onDismissRequest | () -> Unit | Called when the user requests dismissal (e.g., clicking outside, tapping the back button). | - |
| popupModifier | Modifier | Modifier applied to the popup body. | Modifier |
| onDismissFinished | (() -> Unit)? | Called after the exit animation finishes. | null |
| popupPositionProvider | PopupPositionProvider | Position strategy for the primary popup relative to its anchor. | ListPopupDefaults.DropdownPositionProvider |
| alignment | PopupPositionProvider.Align | Alignment of the primary popup. | PopupPositionProvider.Align.End |
| enableWindowDim | Boolean | Whether to dim the rest of the window while the popup is shown. | true |
| maxHeight | Dp? | Maximum height of either side. Null bounds it by the safe area. | null |
| minWidth | Dp | Minimum width of the popup. | 200.dp |
| renderInRootScaffold | Boolean | Whether to render the popup in the root (outermost) Scaffold. When true, the popup covers the full screen. When false, it renders within the current Scaffold's bounds with position compensation. | true |
| dropdownColors | DropdownColors | Colors used by every row. | DropdownDefaults.dropdownColors() |
| collapseOnSelection | Boolean | When true, selecting any leaf dismisses the popup. | true |
DropdownEntry
| Property Name | Type | Description | Default Value | Required |
|---|---|---|---|---|
| items | List<DropdownItem> | Items shown in this dropdown group | - | Yes |
| enabled | Boolean | Whether this group is enabled. False disables all items; true still respects each item's enabled state | true | No |
DropdownItem
| Property Name | Type | Description | Default Value | Required |
|---|---|---|---|---|
| text | String | Text shown for the item | - | Yes |
| enabled | Boolean | Whether the item can be clicked. Disabled items are gray | true | No |
| selected | Boolean | Whether the item is selected | false | No |
| onClick | (() -> Unit)? | Callback invoked when the item is clicked. Ignored when children is non-empty (the click expands the submenu instead) | null | No |
| icon | @Composable ((Modifier) -> Unit)? | Icon shown before the item text | null | No |
| summary | String? | Summary text shown below the item text | null | No |
| children | List<DropdownItem>? | Optional submenu items; only the cascading variants render these as a submenu (depth limited to 2) | null | No |
DropdownColors
| Property Name | Type | Description |
|---|---|---|
| contentColor | Color | Color of the option title |
| summaryColor | Color | Color of the option summary |
| containerColor | Color | Background color of the option |
| selectedContentColor | Color | Title color of the selected option |
| selectedSummaryColor | Color | Summary color of the selected option |
| selectedContainerColor | Color | Background color of the selected option |
| selectedIndicatorColor | Color | Color of the selected indicator icon |
PopupPositionProvider.Align
| Value | Description |
|---|---|
| Start | Aligns the popup to the start of the anchor. |
| End | Aligns the popup to the end of the anchor. |
| TopStart | Aligns the popup to the top-start of the anchor. |
| TopEnd | Aligns the popup to the top-end of the anchor. |
| BottomStart | Aligns the popup to the bottom-start of the anchor. |
| BottomEnd | Aligns the popup to the bottom-end of the anchor. |
