Skip to content

WindowSpinner

WindowSpinner is a dropdown selector component in Miuix that provides titles, summaries, and a list of options with icons and text. It renders at the window level without needing a Scaffold host, making it suitable for use cases where Scaffold is not available or desired.

Note

This component does not rely on Scaffold and can be used in any Composable scope.

Import

kotlin
import top.yukonga.miuix.kmp.extra.WindowSpinner
import top.yukonga.miuix.kmp.extra.SpinnerEntry

Basic Usage

The WindowSpinner component provides basic dropdown selector functionality:

kotlin
var selectedIndex by remember { mutableStateOf(0) }
val options = listOf(
    SpinnerEntry(title = "Option 1"),
    SpinnerEntry(title = "Option 2"),
    SpinnerEntry(title = "Option 3"),
)

WindowSpinner(
    title = "Dropdown Selector",
    items = options,
    selectedIndex = selectedIndex,
    onSelectedIndexChange = { selectedIndex = it }
)

Options with Icons and Summaries

kotlin
// Create a rounded rectangle Painter
private class RoundedRectanglePainter(
    private val cornerRadius: Dp = 6.dp
) : Painter() {
    override val intrinsicSize = Size.Unspecified
    override fun DrawScope.onDraw() {
        drawRoundRect(
            color = Color.White,
            size = Size(size.width, size.height),
            cornerRadius = CornerRadius(cornerRadius.toPx(), cornerRadius.toPx())
        )
    }
}

var selectedIndex by remember { mutableStateOf(0) }
val options = listOf(
    SpinnerEntry(
        icon = { Icon(RoundedRectanglePainter(), "Icon", Modifier.padding(end = 12.dp), Color(0xFFFF5B29)) },
        title = "Red Theme",
        summary = "Energetic Red"
    ),
    SpinnerEntry(
        icon = { Icon(RoundedRectanglePainter(), "Icon", Modifier.padding(end = 12.dp), Color(0xFF3482FF)) },
        title = "Blue Theme",
        summary = "Calm Blue"
    ),
)


WindowSpinner(
    title = "Menu",
    items = options,
    selectedIndex = selectedIndex,
    onSelectedIndexChange = { selectedIndex = it }
)

Component State

Disabled State

kotlin
WindowSpinner(
    title = "Disabled Spinner",
    summary = "This spinner is currently unavailable",
    items = listOf(SpinnerEntry(title = "Option 1")),
    selectedIndex = 0,
    onSelectedIndexChange = {},
    enabled = false
)

Dialog Mode

WindowSpinner also supports a dialog mode, which is useful for displaying a larger list of options or when a more prominent selection interface is needed. This mode is activated by providing a dialogButtonString.

kotlin
var selectedIndex by remember { mutableStateOf(0) }
val options = listOf(
    SpinnerEntry(title = "Option A"),
    SpinnerEntry(title = "Option B"),
    SpinnerEntry(title = "Option C")
)

WindowSpinner(
    title = "Dialog Selector",
    dialogButtonString = "Cancel",
    items = options,
    selectedIndex = selectedIndex,
    onSelectedIndexChange = { selectedIndex = it },
)

Properties

WindowSpinner Properties (Popup Mode)

Property NameTypeDescriptionDefault ValueRequired
itemsList<SpinnerEntry>List of spinner entries-Yes
selectedIndexIntIndex of currently selected item-Yes
titleStringTitle of the spinner-Yes
modifierModifierModifier applied to the componentModifierNo
titleColorBasicComponentColorsTitle text color configurationBasicComponentDefaults.titleColor()No
summaryString?Summary descriptionnullNo
summaryColorBasicComponentColorsSummary text color configurationBasicComponentDefaults.summaryColor()No
spinnerColorsSpinnerColorsColor configuration for spinnerSpinnerDefaults.spinnerColors()No
startAction@Composable (() -> Unit)?Custom start side contentnullNo
bottomAction@Composable (() -> Unit)?Custom bottom side contentnullNo
insideMarginPaddingValuesInternal content paddingBasicComponentDefaults.InsideMarginNo
maxHeightDp?Maximum height of popupnullNo
enabledBooleanWhether component is interactivetrueNo
showValueBooleanWhether to show the selected valuetrueNo
onSelectedIndexChange((Int) -> Unit)?Selection change callback-No

WindowSpinner Properties (Dialog Mode)

Property NameTypeDescriptionDefault ValueRequired
itemsList<SpinnerEntry>List of spinner entries-Yes
selectedIndexIntIndex of currently selected item-Yes
titleStringTitle of the spinner-Yes
dialogButtonStringStringText for the dialog button-Yes
modifierModifierModifier applied to the componentModifierNo
popupModifierModifierModifier for the popup dialogModifierNo
titleColorBasicComponentColorsTitle text color configurationBasicComponentDefaults.titleColor()No
summaryString?Summary descriptionnullNo
summaryColorBasicComponentColorsSummary text color configurationBasicComponentDefaults.summaryColor()No
spinnerColorsSpinnerColorsColor configuration for spinnerSpinnerDefaults.dialogSpinnerColors()No
startAction@Composable (() -> Unit)?Custom start side contentnullNo
bottomAction@Composable (() -> Unit)?Custom bottom side contentnullNo
insideMarginPaddingValuesInternal content paddingBasicComponentDefaults.InsideMarginNo
enabledBooleanWhether component is interactivetrueNo
showValueBooleanWhether to show the selected valuetrueNo
onSelectedIndexChange((Int) -> Unit)?Selection change callback-No

SpinnerEntry Properties

Property NameTypeDescription
icon@Composable ((Modifier) -> Unit)?Icon component for the option
titleString?Title of the option
summaryString?Summary description of the option

SpinnerColors Properties

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 selection indicator icon

Changelog

Released under the Apache-2.0 License