Skip to content

WindowCascadingListPopup

WindowCascadingListPopup is a popup list with two-level cascading menu support, rendered at the window level via Dialog. Unlike OverlayCascadingListPopup, it does not require a Scaffold or COUIPopupHost. Items whose DropdownItem.children is non-empty become submenu triggers; cascading depth is limited to 2.

TIP

This component does not depend on Scaffold and can be used in any composable scope.

Import

kotlin
import io.github.suqi8.coui.kmp.window.WindowCascadingListPopup
import io.github.suqi8.coui.kmp.basic.DropdownEntry
import io.github.suqi8.coui.kmp.basic.DropdownItem

Basic Usage

WindowCascadingListPopup is used the same way as OverlayCascadingListPopup but does not need a Scaffold host. The example below shows two top-level items: a flat sort group, and a "View mode" trigger that expands a secondary list.

kotlin
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 },
                    )
                },
            ),
        ),
    ),
)

Box {
    TextButton(
        text = "Click to show menu",
        onClick = { showPopup = true },
    )
    WindowCascadingListPopup(
        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.

Properties

WindowCascadingListPopup

Property NameTypeDescriptionDefault Value
showBooleanWhether to show the popup.-
entriesList<DropdownEntry>Grouped dropdown entries; top-level items with non-empty children become submenu triggers.-
onDismissRequest() -> UnitCalled when the user requests dismissal (e.g., clicking outside, tapping the back button).-
popupModifierModifierModifier applied to the popup body.Modifier
onDismissFinished(() -> Unit)?Called after the exit animation finishes.null
popupPositionProviderPopupPositionProviderPosition strategy for the primary popup relative to its anchor.ListPopupDefaults.DropdownPositionProvider
alignmentPopupPositionProvider.AlignAlignment of the primary popup.PopupPositionProvider.Align.End
enableWindowDimBooleanWhether to dim the rest of the window while the popup is shown.true
maxHeightDp?Maximum height of either side. Null bounds it by the safe area.null
minWidthDpMinimum width of the popup.200.dp
dropdownColorsDropdownColorsColors used by every row.DropdownDefaults.dropdownColors()
collapseOnSelectionBooleanWhen true, selecting any leaf dismisses the popup.true
Property NameTypeDescriptionDefault ValueRequired
itemsList<DropdownItem>Items shown in this dropdown group-Yes
enabledBooleanWhether this group is enabled. False disables all items; true still respects each item's enabled statetrueNo
titleString?Optional non-clickable group header rendered above the items (12sp medium, secondary label, max 2 lines)nullNo
Property NameTypeDescriptionDefault ValueRequired
textStringText shown for the item-Yes
enabledBooleanWhether the item can be clicked. Disabled items are graytrueNo
selectedBooleanWhether the item is selectedfalseNo
onClick(() -> Unit)?Callback invoked when the item is clicked. Ignored when children is non-empty (the click expands the submenu instead)nullNo
icon@Composable ((Modifier) -> Unit)?Icon shown before the item textnullNo
summaryString?Summary text shown below the item textnullNo
childrenList<DropdownItem>?Optional submenu items; only the cascading variants render these as a submenu (depth limited to 2)nullNo
hint@Composable (() -> Unit)?Optional trailing hint slot (badge, red dot, short count) shown before the selection indicator, width-capped at 40dp. Hidden entirely while the row is disablednullNo
alertBooleanWhether this is an alert (destructive) item; its title uses the error colorfalseNo
Property NameTypeDescription
contentColorColorColor of the option title
summaryColorColorColor of the option summary
containerColorColorBackground color of the option
selectedContentColorColorTitle color of the selected option
selectedSummaryColorColorSummary color of the selected option
selectedContainerColorColorBackground color of the selected option
selectedIndicatorColorColorColor of the selected indicator icon
disabledContentColorColorTitle color of a disabled option
alertContentColorColorTitle color of an alert option
headerColorColorTitle color of a group header row

PopupPositionProvider.Align

ValueDescription
StartAligns the popup to the start of the anchor.
EndAligns the popup to the end of the anchor.
TopStartAligns the popup to the top-start of the anchor.
TopEndAligns the popup to the top-end of the anchor.
BottomStartAligns the popup to the bottom-start of the anchor.
BottomEndAligns the popup to the bottom-end of the anchor.

Changelog

Released under the Apache-2.0 License