Skip to content

MarkPreference

MarkPreference is a single-select row with a selection mark, mirroring ColorOS's COUIMarkPreference. The mark renders the COUI 16 coui_btn_check_mark selector — which resolves to the radio drawables (coui_btn_radio_on / coui_btn_radio_off, 24dp): a primary disc with a solid center dot when checked, and an outline ring otherwise. The mark sits at the end of the row by default (COUI TAIL_MARK) and the whole row is the click target.

Use a group of MarkPreference rows as a single-select list: clicking a row invokes onClick and the caller moves the checked state to that row.

Import

kotlin
import io.github.suqi8.coui.kmp.preference.MarkPreference
import io.github.suqi8.coui.kmp.preference.MarkLocation

Basic Usage

kotlin
var selected by remember { mutableIntStateOf(0) }
val options = listOf("Every day", "Workdays only", "Never")

Column {
    options.forEachIndexed { index, option ->
        MarkPreference(
            title = option,
            checked = selected == index,
            onClick = { selected = index }
        )
    }
}

Mark at the Start (HEAD_MARK)

kotlin
MarkPreference(
    title = "Head Mark",
    checked = true,
    onClick = {},
    markLocation = MarkLocation.Start
)

Component States

Disabled State

kotlin
MarkPreference(
    title = "Disabled Option",
    checked = true,
    onClick = {},
    enabled = false
)

Properties

MarkPreference Properties

Property NameTypeDescriptionDefault ValueRequired
titleStringPreference title-Yes
checkedBooleanWhether this row currently carries the mark-Yes
onClick(() -> Unit)?Callback when the row is clicked-Yes
modifierModifierComponent modifierModifierNo
titleColorBasicComponentColorsTitle text color configurationBasicComponentDefaults.titleColor()No
summaryString?Preference summarynullNo
summaryColorBasicComponentColorsSummary text color configurationBasicComponentDefaults.summaryColor()No
markColorsRadioButtonColorsMark color configuration (shares the COUI radio drawables)RadioButtonDefaults.radioButtonColors()No
startAction@Composable (() -> Unit)?Custom start side contentnullNo
endActions@Composable (RowScope.() -> Unit)?Custom end side content (before an end mark)nullNo
markLocationMarkLocationMark location: End (COUI TAIL_MARK) or Start (COUI HEAD_MARK)MarkLocation.EndNo
bottomAction@Composable (() -> Unit)?Custom bottom side contentnullNo
insideMarginPaddingValuesComponent internal content paddingBasicComponentDefaults.InsideMarginNo
cardListPositionCardListPositionRow position inside its card group; rounded outer edges gain extra paddingCardListPosition.NoneNo
holdDownStateBooleanWhether the component is held downfalseNo
enabledBooleanComponent interactive statetrueNo

MarkLocation Options

ValueDescriptionCOUI Equivalent
MarkLocation.EndThe mark is placed at the end of the rowTAIL_MARK
MarkLocation.StartThe mark is placed at the start of the rowHEAD_MARK

Advanced Usage

With Summary and Custom Mark Colors

kotlin
MarkPreference(
    title = "High Quality",
    summary = "Uses more data",
    checked = selected == 0,
    onClick = { selected = 0 },
    markColors = RadioButtonDefaults.radioButtonColors(
        selectedColor = COUITheme.colorScheme.primary
    )
)

Single-Select Group inside a Card

kotlin
var selected by remember { mutableIntStateOf(0) }
val options = listOf("Option A", "Option B", "Option C")

Card {
    options.forEachIndexed { index, option ->
        if (index > 0) HorizontalDivider(Modifier.padding(horizontal = 16.dp))
        MarkPreference(
            title = option,
            checked = selected == index,
            onClick = { selected = index }
        )
    }
}

Changelog

Released under the Apache-2.0 License