Skip to content

ColorPicker

ColorPicker is a color selection component in Miuix that allows users to pick colors by adjusting hue, saturation, brightness, and transparency. The component provides an intuitive slider interface with haptic feedback and real-time color preview.

Import

kotlin
import top.yukonga.miuix.kmp.basic.ColorPicker

Basic Usage

The ColorPicker component enables users to select custom colors:

kotlin
var selectedColor by remember { mutableStateOf(Color.Red) }

ColorPicker(
    color = selectedColor,
    onColorChanged = { newColor ->
        selectedColor = newColor
    }
)

Component Variants

Without Color Preview

By default, ColorPicker displays a preview of the currently selected color. If you don't want to show the default color preview, set showPreview to false:

kotlin
ColorPicker(
    color = Color.Blue,
    onColorChanged = { /* Handle color change */ },
    showPreview = false
)

Haptic Feedback

ColorPicker supports haptic feedback, which can be customized using the hapticEffect parameter. See SliderHapticEffect for details.

kotlin
ColorPicker(
    color = Color.Green,
    onColorChanged = { /* Handle color change */ },
    hapticEffect = SliderHapticEffect.Step
)

Properties

ColorPicker Properties

Property NameTypeDescriptionDefault ValueRequired
colorColorCurrent color-Yes
onColorChanged(Color) -> UnitCallback for color changes-Yes
modifierModifierModifier for the componentModifierNo
showPreviewBooleanShow color previewtrueNo
hapticEffectSliderDefaults.SliderHapticEffectSlider haptic feedback effectSliderDefaults.DefaultHapticEffectNo
colorSpaceColorSpaceColor space to useColorSpace.HSVNo

Individual Slider Components

The HSV color space exposes four sliders that can be used independently. Other color spaces have their own slider families — see Other Color Space Sliders.

HsvHueSlider

kotlin
var hue by remember { mutableStateOf(0f) }

HsvHueSlider(
    currentHue = hue,
    onHueChanged = { newHue ->
        hue = newHue * 360f
    }
)

HsvSaturationSlider

kotlin
var saturation by remember { mutableStateOf(0.5f) }

HsvSaturationSlider(
    currentHue = 180f, // Current hue
    currentSaturation = saturation,
    onSaturationChanged = { newSaturation ->
        saturation = newSaturation
    }
)

HsvValueSlider

kotlin
var value by remember { mutableStateOf(0.5f) }

HsvValueSlider(
    currentHue = 180f, // Current hue
    currentSaturation = 0.5f, // Current saturation
    currentValue = value,
    onValueChanged = { newValue ->
        value = newValue
    }
)

HsvAlphaSlider

kotlin
var alpha by remember { mutableStateOf(1f) }

HsvAlphaSlider(
    currentHue = 180f, // Current hue
    currentSaturation = 0.5f, // Current saturation
    currentValue = 0.5f, // Current value
    currentAlpha = alpha,
    onAlphaChanged = { newAlpha ->
        alpha = newAlpha
    }
)

Other Color Space Sliders

In addition to the HSV-family sliders above, each color space ColorPicker supports has its own set of standalone sliders:

Color spaceSliders
OkHSVOkHsvHueSlider, OkHsvSaturationSlider, OkHsvValueSlider, OkHsvAlphaSlider
OkLCHOkLchLightnessSlider, OkLchChromaSlider, OkLchHueSlider, OkLchAlphaSlider
OkLabOkLabLightnessSlider, OkLabAChannelSlider, OkLabBChannelSlider, OkLabAlphaSlider

The parameter shapes mirror their HSV counterparts (current value(s) and an on*Changed callback, plus an optional hapticEffect); refer to the source KDoc for the exact parameter list of each.

Advanced Usage

Color Spaces

ColorPicker supports multiple color spaces via colorSpace:

  • ColorSpace.HSV — classic HSV sliders (Hue, Saturation, Value, Alpha).
  • ColorSpace.OKHSV — perceptual HSV variant based on OkLCH, more uniform hue steps.
  • ColorSpace.OKLAB — OkLab sliders (Lightness, a, b, Alpha) for perceptual editing.
  • ColorSpace.OKLCH — OkLCH sliders (Lightness, Chroma, Hue, Alpha). Chroma is clamped to typical sRGB gamut.

Example: use the OKLCH color space

kotlin
ColorPicker(
    color = Color(0xFF4CAF50),
    onColorChanged = { /* Handle color change */ },
    colorSpace = ColorSpace.OKLCH
)

Using in Forms

Combine with other input controls to create a color selection form:

kotlin
var currentColor by remember { mutableStateOf(Color.Red) }
var hexValue by remember(currentColor) {
    mutableStateOf(
        "#${(currentColor.red * 255).toInt().toString(16).padStart(2, '0').uppercase()}" +
                (currentColor.green * 255).toInt().toString(16).padStart(2, '0').uppercase() +
                (currentColor.blue * 255).toInt().toString(16).padStart(2, '0').uppercase()
    )
}

Surface {
    Column(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp)
    ) {
        Text(
            text = "Select Color",
            style = MiuixTheme.textStyles.title2
        )
        Spacer(modifier = Modifier.height(16.dp))
        ColorPicker(
            color = currentColor,
            onColorChanged = {
                currentColor = it
                hexValue = "#${(it.red * 255).toInt().toString(16).padStart(2, '0').uppercase()}" +
                        (it.green * 255).toInt().toString(16).padStart(2, '0').uppercase() +
                        (it.blue * 255).toInt().toString(16).padStart(2, '0').uppercase()
            }
        )
        Spacer(modifier = Modifier.height(16.dp))
        TextField(
            value = hexValue,
            onValueChange = { /* Add hex value parsing logic */ },
            label = "Hex Value",
            modifier = Modifier.fillMaxWidth()
        )
    }
}

Using with Dialog

Use ColorPicker in a dialog to create a color selector:

kotlin
var showColorDialog by remember { mutableStateOf(false) }
var selectedColor by remember { mutableStateOf(Color.Red) }

Scaffold {
    TextButton(
        text = "Select Color",
        onClick = { showColorDialog = true }
    )
    OverlayDialog(
        title = "Select Color",
        show = showColorDialog,
        onDismissRequest = { showColorDialog = false } // Close dialog
    ) {
        Column {
            ColorPicker(
                color = selectedColor,
                onColorChanged = { selectedColor = it }
            )
            Spacer(modifier = Modifier.height(16.dp))
            Row(
                modifier = Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.spacedBy(8.dp),
            ) {
                TextButton(
                    modifier = Modifier.weight(1f),
                    text = "Cancel",
                    onClick = { showColorDialog = false } // Close dialog
                )
                TextButton(
                    modifier = Modifier.weight(1f),
                    text = "Confirm",
                    colors = ButtonDefaults.textButtonColorsPrimary(), // Use theme color
                    onClick = {
                        showColorDialog = false
                        // Handle confirmation logic
                        // For example: save the selected color
                    })
            }
        }
    }
}

Changelog

Released under the Apache-2.0 License