From 6492ee06b5260a7c57984f4ad3313052726f6f98 Mon Sep 17 00:00:00 2001 From: Illia Achour Date: Tue, 15 Sep 2026 19:20:27 -0400 Subject: [PATCH 1/4] Make the ready-made pickers configurable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The six full pickers took state, modifier, showAlpha, coloringMode, colors and shapes, and nothing else. The English labels and screen-reader strings could not be changed without rebuilding a picker out of its sliders; the dialog forwarded its own title and buttons but nothing to the picker inside it; the string "enabled" appeared nowhere in the public API, so nothing could be greyed out; trackHeight existed only on the low-level ColorSlider; and the custom thumb the README demonstrates could not be handed to a picker at all, though the prose beside it says every slider takes one. The androidx component guidelines rule out the obvious fix. A String parameter "restricts styling choice" — no AnnotatedString, no icon, no choice of component — and Material 3 takes DatePicker's title and headline as slots for the same reason. So each slider is a slot, defaulted to the channel slider it names, and localizing is replacing one. That leaves what a replacement would otherwise have to re-declare. Rather than a receiver scope, which the same guidelines reserve for layout APIs, colors and shapes move into CompositionLocals read in parameter defaults — the one use those guidelines sanction, on the condition that the read happens in the default so an explicit argument still wins. A picker provides them, so a replaced slot inherits without the call site forwarding anything. ColorPickerDimensions joins them, bundling the loose constants. That is what fixes trackHeight, and it fixes it for all twenty-one channel sliders without adding a parameter to any of them: a slider reads the track height from the theme, so setting it once reaches every one. enabled stays an explicit parameter, because it is state rather than theme and the same guidelines warn against implicit inputs. A picker refuses pointer input at its own level as well as passing enabled down, so a slot replaced to change a label cannot be left live inside a disabled picker by a call site that forgot to forward it. Such a slider is inert but undimmed, which is the one seam in this; the alternative is the implicit input the guidelines warn about. Disabled drawing is a single disabledAlpha on ColorPickerColors rather than a parallel palette, since a picker's track is a gradient of the colours being chosen and there is no fixed colour to swap in. PickerConfigurationTest covers a replaced slot being drawn, inheriting the picker's colours unforwarded, a themed track height reaching a slider, and a disabled picker refusing a drag on a slot that never saw enabled. The last one needs the drag to land on the track to mean anything, so the enabled case is asserted beside it: without that control the disabled assertions pass whether or not the gesture ever reached a slider. The fourteen screenshot references are unchanged. --- README.md | 37 +++- colorpicker/api/colorpicker.klib.api | 113 +++++++---- colorpicker/api/jvm/colorpicker.api | 146 +++++++++------ .../colorpicker/theme/ColorPickerColors.kt | 4 + .../colorpicker/theme/ColorPickerDefaults.kt | 41 ++++ .../theme/ColorPickerDimensions.kt | 28 +++ .../colorpicker/theme/ColorPickerTheme.kt | 47 +++++ .../codes/side/colorpicker/ui/AlphaSlider.kt | 10 +- .../side/colorpicker/ui/CmykColorPicker.kt | 49 +++-- .../codes/side/colorpicker/ui/CmykSliders.kt | 40 ++-- .../side/colorpicker/ui/ColorPickerDialog.kt | 29 ++- .../codes/side/colorpicker/ui/ColorPlane.kt | 28 ++- .../codes/side/colorpicker/ui/ColorSlider.kt | 25 ++- .../codes/side/colorpicker/ui/ColorSwatch.kt | 4 +- .../side/colorpicker/ui/DisabledInput.kt | 33 ++++ .../side/colorpicker/ui/GradientTrack.kt | 4 +- .../side/colorpicker/ui/HslColorPicker.kt | 57 +++--- .../codes/side/colorpicker/ui/HslPlane.kt | 4 +- .../codes/side/colorpicker/ui/HslSliders.kt | 30 +-- .../side/colorpicker/ui/LabColorPicker.kt | 50 +++-- .../codes/side/colorpicker/ui/LabSliders.kt | 30 +-- .../side/colorpicker/ui/OkhslColorPicker.kt | 55 +++--- .../codes/side/colorpicker/ui/OkhslPlane.kt | 4 +- .../codes/side/colorpicker/ui/OkhslSliders.kt | 30 +-- .../side/colorpicker/ui/OkhsvColorPicker.kt | 55 +++--- .../codes/side/colorpicker/ui/OkhsvPlane.kt | 4 +- .../codes/side/colorpicker/ui/OkhsvSliders.kt | 30 +-- .../side/colorpicker/ui/RgbColorPicker.kt | 45 +++-- .../codes/side/colorpicker/ui/RgbSliders.kt | 30 +-- .../ui/TransparencyCheckerboard.kt | 2 +- .../colorpicker/ui/PickerConfigurationTest.kt | 175 ++++++++++++++++++ docs/index.md | 37 +++- 32 files changed, 974 insertions(+), 302 deletions(-) create mode 100644 colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerDimensions.kt create mode 100644 colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerTheme.kt create mode 100644 colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/DisabledInput.kt create mode 100644 colorpicker/src/jvmTest/kotlin/codes/side/colorpicker/ui/PickerConfigurationTest.kt diff --git a/README.md b/README.md index 56a854aa..a6e86e40 100644 --- a/README.md +++ b/README.md @@ -295,6 +295,27 @@ OkhsvColorPicker(state = state, showAlpha = true) `ColoringMode` controls the slider gradients: `Independent` shows each channel's full range regardless of the other channels, `Contextual` previews the actual resulting color at each position. +Every slider in a picker is a slot, defaulted to the channel slider it names. Replace one to +relabel it — which is how a picker is localized, since the library ships no strings of its own: + +```kotlin +HslColorPicker( + state = state, + hueSlider = { HueSlider(state, label = { Text(stringResource(Res.string.hue)) }) }, +) +``` + +A replacement inherits the picker's colors, shapes and dimensions through the theme, so only +what you actually want to change has to be named. `enabled` is the exception — forward it if +you want your slider dimmed, though the picker refuses input to a disabled slot either way: + +```kotlin +HslColorPicker(state = state, enabled = false) // dimmed, inert, and disabled to a screen reader +``` + +`thumb` reaches every slider in the picker, so [the custom thumb below](#custom-thumb) works +here too rather than only on a slider built by hand. + ### Color Planes `HslPlane` picks both channels at once for the hue currently in `state`, @@ -485,7 +506,7 @@ In-progress edits inside the dialog survive configuration changes; passing a new ### Theming -All pickers and sliders accept `colors` and `shapes` built with `ColorPickerDefaults`, which derive from `MaterialTheme` by default: +All pickers and sliders accept `colors`, `shapes` and dimensions built with `ColorPickerDefaults`, which derive from `MaterialTheme` by default: ```kotlin HslColorPicker( @@ -501,6 +522,20 @@ HslColorPicker( ) ``` +`ColorPickerTheme` sets them for everything inside it instead, which is how a track height +reaches all twenty-one channel sliders without being a parameter on any of them: + +```kotlin +ColorPickerTheme( + dimensions = ColorPickerDefaults.dimensions(trackHeight = 24.dp), +) { + HslColorPicker(state = state) + OkhslPlane(state = state) +} +``` + +A component reads the theme in its parameter defaults, so an explicit argument still wins over +whatever an enclosing `ColorPickerTheme` provided. ## 🔗 State Management `ColorPickerState` is the single source of truth. It reads and writes each color space natively, with no round-trip conversions. diff --git a/colorpicker/api/colorpicker.klib.api b/colorpicker/api/colorpicker.klib.api index 63708dcf..48f38528 100644 --- a/colorpicker/api/colorpicker.klib.api +++ b/colorpicker/api/colorpicker.klib.api @@ -391,21 +391,49 @@ final class codes.side.colorpicker.state/ColorPickerState { // codes.side.colorp } final class codes.side.colorpicker.theme/ColorPickerColors { // codes.side.colorpicker.theme/ColorPickerColors|null[0] - constructor (androidx.compose.ui.graphics/Color, androidx.compose.ui.graphics/Color) // codes.side.colorpicker.theme/ColorPickerColors.|(androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color){}[0] + constructor (androidx.compose.ui.graphics/Color, androidx.compose.ui.graphics/Color, kotlin/Float) // codes.side.colorpicker.theme/ColorPickerColors.|(androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color;kotlin.Float){}[0] final val checkerboardDark // codes.side.colorpicker.theme/ColorPickerColors.checkerboardDark|{}checkerboardDark[0] final fun (): androidx.compose.ui.graphics/Color // codes.side.colorpicker.theme/ColorPickerColors.checkerboardDark.|(){}[0] final val checkerboardLight // codes.side.colorpicker.theme/ColorPickerColors.checkerboardLight|{}checkerboardLight[0] final fun (): androidx.compose.ui.graphics/Color // codes.side.colorpicker.theme/ColorPickerColors.checkerboardLight.|(){}[0] + final val disabledAlpha // codes.side.colorpicker.theme/ColorPickerColors.disabledAlpha|{}disabledAlpha[0] + final fun (): kotlin/Float // codes.side.colorpicker.theme/ColorPickerColors.disabledAlpha.|(){}[0] final fun component1(): androidx.compose.ui.graphics/Color // codes.side.colorpicker.theme/ColorPickerColors.component1|component1(){}[0] final fun component2(): androidx.compose.ui.graphics/Color // codes.side.colorpicker.theme/ColorPickerColors.component2|component2(){}[0] - final fun copy(androidx.compose.ui.graphics/Color = ..., androidx.compose.ui.graphics/Color = ...): codes.side.colorpicker.theme/ColorPickerColors // codes.side.colorpicker.theme/ColorPickerColors.copy|copy(androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color){}[0] + final fun component3(): kotlin/Float // codes.side.colorpicker.theme/ColorPickerColors.component3|component3(){}[0] + final fun copy(androidx.compose.ui.graphics/Color = ..., androidx.compose.ui.graphics/Color = ..., kotlin/Float = ...): codes.side.colorpicker.theme/ColorPickerColors // codes.side.colorpicker.theme/ColorPickerColors.copy|copy(androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color;kotlin.Float){}[0] final fun equals(kotlin/Any?): kotlin/Boolean // codes.side.colorpicker.theme/ColorPickerColors.equals|equals(kotlin.Any?){}[0] final fun hashCode(): kotlin/Int // codes.side.colorpicker.theme/ColorPickerColors.hashCode|hashCode(){}[0] final fun toString(): kotlin/String // codes.side.colorpicker.theme/ColorPickerColors.toString|toString(){}[0] } +final class codes.side.colorpicker.theme/ColorPickerDimensions { // codes.side.colorpicker.theme/ColorPickerDimensions|null[0] + constructor (androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp) // codes.side.colorpicker.theme/ColorPickerDimensions.|(androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp){}[0] + + final val planeMinSize // codes.side.colorpicker.theme/ColorPickerDimensions.planeMinSize|{}planeMinSize[0] + final fun (): androidx.compose.ui.unit/Dp // codes.side.colorpicker.theme/ColorPickerDimensions.planeMinSize.|(){}[0] + final val planeThumbSize // codes.side.colorpicker.theme/ColorPickerDimensions.planeThumbSize|{}planeThumbSize[0] + final fun (): androidx.compose.ui.unit/Dp // codes.side.colorpicker.theme/ColorPickerDimensions.planeThumbSize.|(){}[0] + final val thumbTrackGap // codes.side.colorpicker.theme/ColorPickerDimensions.thumbTrackGap|{}thumbTrackGap[0] + final fun (): androidx.compose.ui.unit/Dp // codes.side.colorpicker.theme/ColorPickerDimensions.thumbTrackGap.|(){}[0] + final val thumbWidth // codes.side.colorpicker.theme/ColorPickerDimensions.thumbWidth|{}thumbWidth[0] + final fun (): androidx.compose.ui.unit/Dp // codes.side.colorpicker.theme/ColorPickerDimensions.thumbWidth.|(){}[0] + final val trackHeight // codes.side.colorpicker.theme/ColorPickerDimensions.trackHeight|{}trackHeight[0] + final fun (): androidx.compose.ui.unit/Dp // codes.side.colorpicker.theme/ColorPickerDimensions.trackHeight.|(){}[0] + + final fun component1(): androidx.compose.ui.unit/Dp // codes.side.colorpicker.theme/ColorPickerDimensions.component1|component1(){}[0] + final fun component2(): androidx.compose.ui.unit/Dp // codes.side.colorpicker.theme/ColorPickerDimensions.component2|component2(){}[0] + final fun component3(): androidx.compose.ui.unit/Dp // codes.side.colorpicker.theme/ColorPickerDimensions.component3|component3(){}[0] + final fun component4(): androidx.compose.ui.unit/Dp // codes.side.colorpicker.theme/ColorPickerDimensions.component4|component4(){}[0] + final fun component5(): androidx.compose.ui.unit/Dp // codes.side.colorpicker.theme/ColorPickerDimensions.component5|component5(){}[0] + final fun copy(androidx.compose.ui.unit/Dp = ..., androidx.compose.ui.unit/Dp = ..., androidx.compose.ui.unit/Dp = ..., androidx.compose.ui.unit/Dp = ..., androidx.compose.ui.unit/Dp = ...): codes.side.colorpicker.theme/ColorPickerDimensions // codes.side.colorpicker.theme/ColorPickerDimensions.copy|copy(androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp){}[0] + final fun equals(kotlin/Any?): kotlin/Boolean // codes.side.colorpicker.theme/ColorPickerDimensions.equals|equals(kotlin.Any?){}[0] + final fun hashCode(): kotlin/Int // codes.side.colorpicker.theme/ColorPickerDimensions.hashCode|hashCode(){}[0] + final fun toString(): kotlin/String // codes.side.colorpicker.theme/ColorPickerDimensions.toString|toString(){}[0] +} + final class codes.side.colorpicker.theme/ColorPickerShapes { // codes.side.colorpicker.theme/ColorPickerShapes|null[0] constructor (androidx.compose.ui.graphics/Shape, androidx.compose.ui.graphics/Shape, androidx.compose.ui.graphics/Shape) // codes.side.colorpicker.theme/ColorPickerShapes.|(androidx.compose.ui.graphics.Shape;androidx.compose.ui.graphics.Shape;androidx.compose.ui.graphics.Shape){}[0] @@ -426,6 +454,8 @@ final class codes.side.colorpicker.theme/ColorPickerShapes { // codes.side.color } final object codes.side.colorpicker.theme/ColorPickerDefaults { // codes.side.colorpicker.theme/ColorPickerDefaults|null[0] + final val DisabledAlpha // codes.side.colorpicker.theme/ColorPickerDefaults.DisabledAlpha|{}DisabledAlpha[0] + final fun (): kotlin/Float // codes.side.colorpicker.theme/ColorPickerDefaults.DisabledAlpha.|(){}[0] final val PlaneMinSize // codes.side.colorpicker.theme/ColorPickerDefaults.PlaneMinSize|{}PlaneMinSize[0] final fun (): androidx.compose.ui.unit/Dp // codes.side.colorpicker.theme/ColorPickerDefaults.PlaneMinSize.|(){}[0] final val PlaneThumbSize // codes.side.colorpicker.theme/ColorPickerDefaults.PlaneThumbSize|{}PlaneThumbSize[0] @@ -439,7 +469,11 @@ final object codes.side.colorpicker.theme/ColorPickerDefaults { // codes.side.co final val TrackHeight // codes.side.colorpicker.theme/ColorPickerDefaults.TrackHeight|{}TrackHeight[0] final fun (): androidx.compose.ui.unit/Dp // codes.side.colorpicker.theme/ColorPickerDefaults.TrackHeight.|(){}[0] - final fun colors(androidx.compose.ui.graphics/Color, androidx.compose.ui.graphics/Color, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): codes.side.colorpicker.theme/ColorPickerColors // codes.side.colorpicker.theme/ColorPickerDefaults.colors|colors(androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] + final fun colors(androidx.compose.ui.graphics/Color, androidx.compose.ui.graphics/Color, kotlin/Float, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): codes.side.colorpicker.theme/ColorPickerColors // codes.side.colorpicker.theme/ColorPickerDefaults.colors|colors(androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color;kotlin.Float;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] + final fun currentColors(androidx.compose.runtime/Composer?, kotlin/Int): codes.side.colorpicker.theme/ColorPickerColors // codes.side.colorpicker.theme/ColorPickerDefaults.currentColors|currentColors(androidx.compose.runtime.Composer?;kotlin.Int){}[0] + final fun currentDimensions(androidx.compose.runtime/Composer?, kotlin/Int): codes.side.colorpicker.theme/ColorPickerDimensions // codes.side.colorpicker.theme/ColorPickerDefaults.currentDimensions|currentDimensions(androidx.compose.runtime.Composer?;kotlin.Int){}[0] + final fun currentShapes(androidx.compose.runtime/Composer?, kotlin/Int): codes.side.colorpicker.theme/ColorPickerShapes // codes.side.colorpicker.theme/ColorPickerDefaults.currentShapes|currentShapes(androidx.compose.runtime.Composer?;kotlin.Int){}[0] + final fun dimensions(androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): codes.side.colorpicker.theme/ColorPickerDimensions // codes.side.colorpicker.theme/ColorPickerDefaults.dimensions|dimensions(androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun shapes(androidx.compose.ui.graphics/Shape?, androidx.compose.ui.graphics/Shape?, androidx.compose.ui.graphics/Shape?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): codes.side.colorpicker.theme/ColorPickerShapes // codes.side.colorpicker.theme/ColorPickerDefaults.shapes|shapes(androidx.compose.ui.graphics.Shape?;androidx.compose.ui.graphics.Shape?;androidx.compose.ui.graphics.Shape?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] } @@ -452,8 +486,15 @@ final val codes.side.colorpicker.model/codes_side_colorpicker_model_OklabColor$s final val codes.side.colorpicker.model/codes_side_colorpicker_model_OklchColor$stableprop // codes.side.colorpicker.model/codes_side_colorpicker_model_OklchColor$stableprop|#static{}codes_side_colorpicker_model_OklchColor$stableprop[0] final val codes.side.colorpicker.model/codes_side_colorpicker_model_RgbColor$stableprop // codes.side.colorpicker.model/codes_side_colorpicker_model_RgbColor$stableprop|#static{}codes_side_colorpicker_model_RgbColor$stableprop[0] final val codes.side.colorpicker.state/codes_side_colorpicker_state_ColorPickerState$stableprop // codes.side.colorpicker.state/codes_side_colorpicker_state_ColorPickerState$stableprop|#static{}codes_side_colorpicker_state_ColorPickerState$stableprop[0] +final val codes.side.colorpicker.theme/LocalColorPickerColors // codes.side.colorpicker.theme/LocalColorPickerColors|{}LocalColorPickerColors[0] + final fun (): androidx.compose.runtime/ProvidableCompositionLocal // codes.side.colorpicker.theme/LocalColorPickerColors.|(){}[0] +final val codes.side.colorpicker.theme/LocalColorPickerDimensions // codes.side.colorpicker.theme/LocalColorPickerDimensions|{}LocalColorPickerDimensions[0] + final fun (): androidx.compose.runtime/ProvidableCompositionLocal // codes.side.colorpicker.theme/LocalColorPickerDimensions.|(){}[0] +final val codes.side.colorpicker.theme/LocalColorPickerShapes // codes.side.colorpicker.theme/LocalColorPickerShapes|{}LocalColorPickerShapes[0] + final fun (): androidx.compose.runtime/ProvidableCompositionLocal // codes.side.colorpicker.theme/LocalColorPickerShapes.|(){}[0] final val codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerColors$stableprop // codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerColors$stableprop|#static{}codes_side_colorpicker_theme_ColorPickerColors$stableprop[0] final val codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerDefaults$stableprop // codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerDefaults$stableprop|#static{}codes_side_colorpicker_theme_ColorPickerDefaults$stableprop[0] +final val codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerDimensions$stableprop // codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerDimensions$stableprop|#static{}codes_side_colorpicker_theme_ColorPickerDimensions$stableprop[0] final val codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerShapes$stableprop // codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerShapes$stableprop|#static{}codes_side_colorpicker_theme_ColorPickerShapes$stableprop[0] final fun (androidx.compose.ui.graphics/Color).codes.side.colorpicker.conversion/toCmykColor(): codes.side.colorpicker.model/CmykColor // codes.side.colorpicker.conversion/toCmykColor|toCmykColor@androidx.compose.ui.graphics.Color(){}[0] @@ -531,42 +572,44 @@ final fun codes.side.colorpicker.model/codes_side_colorpicker_model_RgbColor$sta final fun codes.side.colorpicker.state/codes_side_colorpicker_state_ColorPickerState$stableprop_getter(): kotlin/Int // codes.side.colorpicker.state/codes_side_colorpicker_state_ColorPickerState$stableprop_getter|codes_side_colorpicker_state_ColorPickerState$stableprop_getter(){}[0] final fun codes.side.colorpicker.state/rememberColorPickerState(codes.side.colorpicker.model/PickerColor?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): codes.side.colorpicker.state/ColorPickerState // codes.side.colorpicker.state/rememberColorPickerState|rememberColorPickerState(codes.side.colorpicker.model.PickerColor?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun codes.side.colorpicker.state/rememberSaveableColorPickerState(codes.side.colorpicker.model/PickerColor?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): codes.side.colorpicker.state/ColorPickerState // codes.side.colorpicker.state/rememberSaveableColorPickerState|rememberSaveableColorPickerState(codes.side.colorpicker.model.PickerColor?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.theme/ColorPickerTheme(codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, codes.side.colorpicker.theme/ColorPickerDimensions?, kotlin/Function2, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.theme/ColorPickerTheme|ColorPickerTheme(codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;codes.side.colorpicker.theme.ColorPickerDimensions?;kotlin.Function2;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerColors$stableprop_getter(): kotlin/Int // codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerColors$stableprop_getter|codes_side_colorpicker_theme_ColorPickerColors$stableprop_getter(){}[0] final fun codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerDefaults$stableprop_getter(): kotlin/Int // codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerDefaults$stableprop_getter|codes_side_colorpicker_theme_ColorPickerDefaults$stableprop_getter(){}[0] +final fun codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerDimensions$stableprop_getter(): kotlin/Int // codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerDimensions$stableprop_getter|codes_side_colorpicker_theme_ColorPickerDimensions$stableprop_getter(){}[0] final fun codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerShapes$stableprop_getter(): kotlin/Int // codes.side.colorpicker.theme/codes_side_colorpicker_theme_ColorPickerShapes$stableprop_getter|codes_side_colorpicker_theme_ColorPickerShapes$stableprop_getter(){}[0] -final fun codes.side.colorpicker.ui/AlphaSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/AlphaSlider|AlphaSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/BlueSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/BlueSlider|BlueSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/CmykColorPicker(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/CmykColorPicker|CmykColorPicker(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/ColorPickerDialog(kotlin/Function1, kotlin/Function0, androidx.compose.ui/Modifier?, codes.side.colorpicker.model/HslColor?, kotlin/String?, kotlin/String?, kotlin/String?, kotlin/Boolean, codes.side.colorpicker.theme/ColorPickerColors?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/ColorPickerDialog|ColorPickerDialog(kotlin.Function1;kotlin.Function0;androidx.compose.ui.Modifier?;codes.side.colorpicker.model.HslColor?;kotlin.String?;kotlin.String?;kotlin.String?;kotlin.Boolean;codes.side.colorpicker.theme.ColorPickerColors?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/ColorPlane(kotlin/Float, kotlin/Float, kotlin/Function2, kotlin/Function1, androidx.compose.ui/Modifier?, kotlin/Function0?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/ColorPlane|ColorPlane(kotlin.Float;kotlin.Float;kotlin.Function2;kotlin.Function1;androidx.compose.ui.Modifier?;kotlin.Function0?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/ColorSlider(kotlin/Float, kotlin/Function1, kotlinx.collections.immutable/ImmutableList, androidx.compose.ui.graphics/Color, androidx.compose.ui/Modifier?, kotlin/Function2?, kotlin/Function2?, kotlin/Function0?, androidx.compose.ui.unit/Dp, kotlin/Boolean, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/ColorSlider|ColorSlider(kotlin.Float;kotlin.Function1;kotlinx.collections.immutable.ImmutableList;androidx.compose.ui.graphics.Color;androidx.compose.ui.Modifier?;kotlin.Function2?;kotlin.Function2?;kotlin.Function0?;androidx.compose.ui.unit.Dp;kotlin.Boolean;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/AlphaSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/AlphaSlider|AlphaSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/BlueSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/BlueSlider|BlueSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/CmykColorPicker(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/CmykColorPicker|CmykColorPicker(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/ColorPickerDialog(kotlin/Function1, kotlin/Function0, androidx.compose.ui/Modifier?, codes.side.colorpicker.model/HslColor?, kotlin/String?, kotlin/String?, kotlin/String?, kotlin/Boolean, kotlin/Boolean, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/ColorPickerDialog|ColorPickerDialog(kotlin.Function1;kotlin.Function0;androidx.compose.ui.Modifier?;codes.side.colorpicker.model.HslColor?;kotlin.String?;kotlin.String?;kotlin.String?;kotlin.Boolean;kotlin.Boolean;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/ColorPlane(kotlin/Float, kotlin/Float, kotlin/Function2, kotlin/Function1, androidx.compose.ui/Modifier?, kotlin/Function0?, kotlin/Boolean, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/ColorPlane|ColorPlane(kotlin.Float;kotlin.Float;kotlin.Function2;kotlin.Function1;androidx.compose.ui.Modifier?;kotlin.Function0?;kotlin.Boolean;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/ColorSlider(kotlin/Float, kotlin/Function1, kotlinx.collections.immutable/ImmutableList, androidx.compose.ui.graphics/Color, androidx.compose.ui/Modifier?, kotlin/Function2?, kotlin/Function2?, kotlin/Function0?, kotlin/Boolean, androidx.compose.ui.unit/Dp, kotlin/Boolean, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/ColorSlider|ColorSlider(kotlin.Float;kotlin.Function1;kotlinx.collections.immutable.ImmutableList;androidx.compose.ui.graphics.Color;androidx.compose.ui.Modifier?;kotlin.Function2?;kotlin.Function2?;kotlin.Function0?;kotlin.Boolean;androidx.compose.ui.unit.Dp;kotlin.Boolean;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] final fun codes.side.colorpicker.ui/ColorSwatch(androidx.compose.ui.graphics/Color, androidx.compose.ui/Modifier?, androidx.compose.ui.graphics/Shape?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/ColorSwatch|ColorSwatch(androidx.compose.ui.graphics.Color;androidx.compose.ui.Modifier?;androidx.compose.ui.graphics.Shape?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/CyanSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/CyanSlider|CyanSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/GreenSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/GreenSlider|GreenSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/HslColorPicker(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/HslColorPicker|HslColorPicker(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/HslPlane(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/HslPlane|HslPlane(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/HueSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/HueSlider|HueSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/KeySlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/KeySlider|KeySlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/LabASlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/LabASlider|LabASlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/LabBSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/LabBSlider|LabBSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/LabColorPicker(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/LabColorPicker|LabColorPicker(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/LightnessLabSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/LightnessLabSlider|LightnessLabSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/LightnessSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/LightnessSlider|LightnessSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/MagentaSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/MagentaSlider|MagentaSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/OkhslColorPicker(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhslColorPicker|OkhslColorPicker(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/OkhslHueSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhslHueSlider|OkhslHueSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/OkhslLightnessSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhslLightnessSlider|OkhslLightnessSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/OkhslPlane(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhslPlane|OkhslPlane(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/OkhslSaturationSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhslSaturationSlider|OkhslSaturationSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/OkhsvColorPicker(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhsvColorPicker|OkhsvColorPicker(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/OkhsvHueSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhsvHueSlider|OkhsvHueSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/OkhsvPlane(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhsvPlane|OkhsvPlane(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/OkhsvSaturationSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhsvSaturationSlider|OkhsvSaturationSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/OkhsvValueSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhsvValueSlider|OkhsvValueSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/RedSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/RedSlider|RedSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/RgbColorPicker(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/RgbColorPicker|RgbColorPicker(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/SaturationSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/SaturationSlider|SaturationSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/CyanSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/CyanSlider|CyanSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/GreenSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/GreenSlider|GreenSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/HslColorPicker(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/HslColorPicker|HslColorPicker(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/HslPlane(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/HslPlane|HslPlane(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/HueSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/HueSlider|HueSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/KeySlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/KeySlider|KeySlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/LabASlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/LabASlider|LabASlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/LabBSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/LabBSlider|LabBSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/LabColorPicker(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/LabColorPicker|LabColorPicker(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/LightnessLabSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/LightnessLabSlider|LightnessLabSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/LightnessSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/LightnessSlider|LightnessSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/MagentaSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/MagentaSlider|MagentaSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/OkhslColorPicker(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhslColorPicker|OkhslColorPicker(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/OkhslHueSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhslHueSlider|OkhslHueSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/OkhslLightnessSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhslLightnessSlider|OkhslLightnessSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/OkhslPlane(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhslPlane|OkhslPlane(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/OkhslSaturationSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhslSaturationSlider|OkhslSaturationSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/OkhsvColorPicker(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhsvColorPicker|OkhsvColorPicker(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/OkhsvHueSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhsvHueSlider|OkhsvHueSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/OkhsvPlane(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhsvPlane|OkhsvPlane(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/OkhsvSaturationSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhsvSaturationSlider|OkhsvSaturationSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/OkhsvValueSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/OkhsvValueSlider|OkhsvValueSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/RedSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/RedSlider|RedSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/RgbColorPicker(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, kotlin/Function2?, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/RgbColorPicker|RgbColorPicker(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;kotlin.Function2?;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/SaturationSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/SaturationSlider|SaturationSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] final fun codes.side.colorpicker.ui/SliderLabel(kotlin/String, androidx.compose.runtime/Composer?, kotlin/Int) // codes.side.colorpicker.ui/SliderLabel|SliderLabel(kotlin.String;androidx.compose.runtime.Composer?;kotlin.Int){}[0] final fun codes.side.colorpicker.ui/SliderValueLabel(kotlin/String, androidx.compose.runtime/Composer?, kotlin/Int) // codes.side.colorpicker.ui/SliderValueLabel|SliderValueLabel(kotlin.String;androidx.compose.runtime.Composer?;kotlin.Int){}[0] -final fun codes.side.colorpicker.ui/YellowSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/YellowSlider|YellowSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] +final fun codes.side.colorpicker.ui/YellowSlider(codes.side.colorpicker.state/ColorPickerState, androidx.compose.ui/Modifier?, kotlin/Boolean, codes.side.colorpicker.state/ColoringMode?, kotlin/Function2?, kotlin/Function2?, kotlin/String?, kotlin/String?, codes.side.colorpicker.theme/ColorPickerColors?, codes.side.colorpicker.theme/ColorPickerShapes?, kotlin/Function3?, androidx.compose.ui.unit/Dp, androidx.compose.ui.unit/Dp, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int, kotlin/Int) // codes.side.colorpicker.ui/YellowSlider|YellowSlider(codes.side.colorpicker.state.ColorPickerState;androidx.compose.ui.Modifier?;kotlin.Boolean;codes.side.colorpicker.state.ColoringMode?;kotlin.Function2?;kotlin.Function2?;kotlin.String?;kotlin.String?;codes.side.colorpicker.theme.ColorPickerColors?;codes.side.colorpicker.theme.ColorPickerShapes?;kotlin.Function3?;androidx.compose.ui.unit.Dp;androidx.compose.ui.unit.Dp;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int;kotlin.Int){}[0] final fun codes.side.colorpicker.util/randomHslColor(kotlin/Boolean = ...): codes.side.colorpicker.model/HslColor // codes.side.colorpicker.util/randomHslColor|randomHslColor(kotlin.Boolean){}[0] diff --git a/colorpicker/api/jvm/colorpicker.api b/colorpicker/api/jvm/colorpicker.api index 3b41b3b4..e9a745ea 100644 --- a/colorpicker/api/jvm/colorpicker.api +++ b/colorpicker/api/jvm/colorpicker.api @@ -407,14 +407,16 @@ public final class codes/side/colorpicker/state/SaveableColorPickerStateKt { public final class codes/side/colorpicker/theme/ColorPickerColors { public static final field $stable I - public synthetic fun (JJLkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (JJFLkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1-0d7_KjU ()J public final fun component2-0d7_KjU ()J - public final fun copy--OWjLjI (JJ)Lcodes/side/colorpicker/theme/ColorPickerColors; - public static synthetic fun copy--OWjLjI$default (Lcodes/side/colorpicker/theme/ColorPickerColors;JJILjava/lang/Object;)Lcodes/side/colorpicker/theme/ColorPickerColors; + public final fun component3 ()F + public final fun copy-jxsXWHM (JJF)Lcodes/side/colorpicker/theme/ColorPickerColors; + public static synthetic fun copy-jxsXWHM$default (Lcodes/side/colorpicker/theme/ColorPickerColors;JJFILjava/lang/Object;)Lcodes/side/colorpicker/theme/ColorPickerColors; public fun equals (Ljava/lang/Object;)Z public final fun getCheckerboardDark-0d7_KjU ()J public final fun getCheckerboardLight-0d7_KjU ()J + public final fun getDisabledAlpha ()F public fun hashCode ()I public fun toString ()Ljava/lang/String; } @@ -422,7 +424,12 @@ public final class codes/side/colorpicker/theme/ColorPickerColors { public final class codes/side/colorpicker/theme/ColorPickerDefaults { public static final field $stable I public static final field INSTANCE Lcodes/side/colorpicker/theme/ColorPickerDefaults; - public final fun colors-dgg9oW8 (JJLandroidx/compose/runtime/Composer;II)Lcodes/side/colorpicker/theme/ColorPickerColors; + public final fun colors-Klgx-Pg (JJFLandroidx/compose/runtime/Composer;II)Lcodes/side/colorpicker/theme/ColorPickerColors; + public final fun currentColors (Landroidx/compose/runtime/Composer;I)Lcodes/side/colorpicker/theme/ColorPickerColors; + public final fun currentDimensions (Landroidx/compose/runtime/Composer;I)Lcodes/side/colorpicker/theme/ColorPickerDimensions; + public final fun currentShapes (Landroidx/compose/runtime/Composer;I)Lcodes/side/colorpicker/theme/ColorPickerShapes; + public final fun dimensions-R_JCAzs (FFFFFLandroidx/compose/runtime/Composer;II)Lcodes/side/colorpicker/theme/ColorPickerDimensions; + public final fun getDisabledAlpha ()F public final fun getPlaneMinSize-D9Ej5fM ()F public final fun getPlaneThumbSize-D9Ej5fM ()F public final fun getSwatchSize-D9Ej5fM ()F @@ -432,6 +439,26 @@ public final class codes/side/colorpicker/theme/ColorPickerDefaults { public final fun shapes (Landroidx/compose/ui/graphics/Shape;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/runtime/Composer;II)Lcodes/side/colorpicker/theme/ColorPickerShapes; } +public final class codes/side/colorpicker/theme/ColorPickerDimensions { + public static final field $stable I + public synthetic fun (FFFFFLkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1-D9Ej5fM ()F + public final fun component2-D9Ej5fM ()F + public final fun component3-D9Ej5fM ()F + public final fun component4-D9Ej5fM ()F + public final fun component5-D9Ej5fM ()F + public final fun copy-RyVG9vg (FFFFF)Lcodes/side/colorpicker/theme/ColorPickerDimensions; + public static synthetic fun copy-RyVG9vg$default (Lcodes/side/colorpicker/theme/ColorPickerDimensions;FFFFFILjava/lang/Object;)Lcodes/side/colorpicker/theme/ColorPickerDimensions; + public fun equals (Ljava/lang/Object;)Z + public final fun getPlaneMinSize-D9Ej5fM ()F + public final fun getPlaneThumbSize-D9Ej5fM ()F + public final fun getThumbTrackGap-D9Ej5fM ()F + public final fun getThumbWidth-D9Ej5fM ()F + public final fun getTrackHeight-D9Ej5fM ()F + public fun hashCode ()I + public fun toString ()Ljava/lang/String; +} + public final class codes/side/colorpicker/theme/ColorPickerShapes { public static final field $stable I public fun (Landroidx/compose/ui/graphics/Shape;Landroidx/compose/ui/graphics/Shape;Landroidx/compose/ui/graphics/Shape;)V @@ -448,31 +475,38 @@ public final class codes/side/colorpicker/theme/ColorPickerShapes { public fun toString ()Ljava/lang/String; } +public final class codes/side/colorpicker/theme/ColorPickerThemeKt { + public static final fun ColorPickerTheme (Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lcodes/side/colorpicker/theme/ColorPickerDimensions;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;II)V + public static final fun getLocalColorPickerColors ()Landroidx/compose/runtime/ProvidableCompositionLocal; + public static final fun getLocalColorPickerDimensions ()Landroidx/compose/runtime/ProvidableCompositionLocal; + public static final fun getLocalColorPickerShapes ()Landroidx/compose/runtime/ProvidableCompositionLocal; +} + public final class codes/side/colorpicker/ui/AlphaSliderKt { - public static final fun AlphaSlider-yndP2WQ (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun AlphaSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/CmykColorPickerKt { - public static final fun CmykColorPicker (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Landroidx/compose/runtime/Composer;II)V + public static final fun CmykColorPicker (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZZLcodes/side/colorpicker/state/ColoringMode;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/CmykSlidersKt { - public static final fun CyanSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V - public static final fun KeySlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V - public static final fun MagentaSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V - public static final fun YellowSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun CyanSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun KeySlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun MagentaSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun YellowSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/ColorPickerDialogKt { - public static final fun ColorPickerDialog (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/model/HslColor;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLcodes/side/colorpicker/theme/ColorPickerColors;Landroidx/compose/runtime/Composer;II)V + public static final fun ColorPickerDialog (Lkotlin/jvm/functions/Function1;Lkotlin/jvm/functions/Function0;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/model/HslColor;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZZLcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/ColorPlaneKt { - public static final fun ColorPlane (FFLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function0;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V + public static final fun ColorPlane (FFLkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;Landroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function0;ZLjava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/ColorSliderKt { - public static final fun ColorSlider-pxA9Vh4 (FLkotlin/jvm/functions/Function1;Lkotlinx/collections/immutable/ImmutableList;JLandroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function0;FZLjava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun ColorSlider-3Z_sle4 (FLkotlin/jvm/functions/Function1;Lkotlinx/collections/immutable/ImmutableList;JLandroidx/compose/ui/Modifier;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function0;ZFZLjava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/ColorSwatchKt { @@ -482,118 +516,118 @@ public final class codes/side/colorpicker/ui/ColorSwatchKt { public final class codes/side/colorpicker/ui/ComposableSingletons$AlphaSliderKt { public static final field INSTANCE Lcodes/side/colorpicker/ui/ComposableSingletons$AlphaSliderKt; public fun ()V - public final fun getLambda$1115417337$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$-487996643$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; } public final class codes/side/colorpicker/ui/ComposableSingletons$CmykSlidersKt { public static final field INSTANCE Lcodes/side/colorpicker/ui/ComposableSingletons$CmykSlidersKt; public fun ()V - public final fun getLambda$-136327513$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; - public final fun getLambda$-1437143203$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; - public final fun getLambda$1297774829$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; - public final fun getLambda$1753703870$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$-1441470950$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$1488280137$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$1657561273$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$550393347$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; } public final class codes/side/colorpicker/ui/ComposableSingletons$HslSlidersKt { public static final field INSTANCE Lcodes/side/colorpicker/ui/ComposableSingletons$HslSlidersKt; public fun ()V - public final fun getLambda$1131188849$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; - public final fun getLambda$1297615580$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; - public final fun getLambda$157526155$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$-1665446251$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$-1740035072$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$1815063215$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; } public final class codes/side/colorpicker/ui/ComposableSingletons$LabSlidersKt { public static final field INSTANCE Lcodes/side/colorpicker/ui/ComposableSingletons$LabSlidersKt; public fun ()V - public final fun getLambda$-138566891$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; - public final fun getLambda$1830062601$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; - public final fun getLambda$1980484084$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$-1117603283$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$-780345576$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$823658297$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; } public final class codes/side/colorpicker/ui/ComposableSingletons$OkhslSlidersKt { public static final field INSTANCE Lcodes/side/colorpicker/ui/ComposableSingletons$OkhslSlidersKt; public fun ()V - public final fun getLambda$1151294969$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; - public final fun getLambda$501007118$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; - public final fun getLambda$879958294$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$-642466531$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$1331313970$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$257821498$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; } public final class codes/side/colorpicker/ui/ComposableSingletons$OkhsvSlidersKt { public static final field INSTANCE Lcodes/side/colorpicker/ui/ComposableSingletons$OkhsvSlidersKt; public fun ()V - public final fun getLambda$-2089135351$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; - public final fun getLambda$-378521514$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; - public final fun getLambda$-702366814$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$-1107326010$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$-1708190598$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$693685293$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; } public final class codes/side/colorpicker/ui/ComposableSingletons$RgbSlidersKt { public static final field INSTANCE Lcodes/side/colorpicker/ui/ComposableSingletons$RgbSlidersKt; public fun ()V - public final fun getLambda$-1231945838$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; - public final fun getLambda$-1823617084$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; - public final fun getLambda$-927009905$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$-2008973901$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$-451553610$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; + public final fun getLambda$1717523688$codes_side_colorpicker ()Lkotlin/jvm/functions/Function2; } public final class codes/side/colorpicker/ui/HslColorPickerKt { - public static final fun HslColorPicker (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Landroidx/compose/runtime/Composer;II)V + public static final fun HslColorPicker (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZZLcodes/side/colorpicker/state/ColoringMode;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/HslPlaneKt { - public static final fun HslPlane (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V + public static final fun HslPlane (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLjava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V } public final class codes/side/colorpicker/ui/HslSlidersKt { - public static final fun HueSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V - public static final fun LightnessSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V - public static final fun SaturationSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun HueSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun LightnessSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun SaturationSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/LabColorPickerKt { - public static final fun LabColorPicker (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Landroidx/compose/runtime/Composer;II)V + public static final fun LabColorPicker (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZZLcodes/side/colorpicker/state/ColoringMode;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/LabSlidersKt { - public static final fun LabASlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V - public static final fun LabBSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V - public static final fun LightnessLabSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun LabASlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun LabBSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun LightnessLabSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/OkhslColorPickerKt { - public static final fun OkhslColorPicker (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Landroidx/compose/runtime/Composer;II)V + public static final fun OkhslColorPicker (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZZLcodes/side/colorpicker/state/ColoringMode;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/OkhslPlaneKt { - public static final fun OkhslPlane (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V + public static final fun OkhslPlane (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLjava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V } public final class codes/side/colorpicker/ui/OkhslSlidersKt { - public static final fun OkhslHueSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V - public static final fun OkhslLightnessSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V - public static final fun OkhslSaturationSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun OkhslHueSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun OkhslLightnessSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun OkhslSaturationSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/OkhsvColorPickerKt { - public static final fun OkhsvColorPicker (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Landroidx/compose/runtime/Composer;II)V + public static final fun OkhsvColorPicker (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZZLcodes/side/colorpicker/state/ColoringMode;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/OkhsvPlaneKt { - public static final fun OkhsvPlane (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V + public static final fun OkhsvPlane (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLjava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Landroidx/compose/runtime/Composer;II)V } public final class codes/side/colorpicker/ui/OkhsvSlidersKt { - public static final fun OkhsvHueSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V - public static final fun OkhsvSaturationSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V - public static final fun OkhsvValueSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun OkhsvHueSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun OkhsvSaturationSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun OkhsvValueSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/RgbColorPickerKt { - public static final fun RgbColorPicker (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Landroidx/compose/runtime/Composer;II)V + public static final fun RgbColorPicker (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZZLcodes/side/colorpicker/state/ColoringMode;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Landroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/RgbSlidersKt { - public static final fun BlueSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V - public static final fun GreenSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V - public static final fun RedSlider-7LhMbNw (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;Lcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun BlueSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun GreenSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V + public static final fun RedSlider-q3QzNKE (Lcodes/side/colorpicker/state/ColorPickerState;Landroidx/compose/ui/Modifier;ZLcodes/side/colorpicker/state/ColoringMode;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function2;Ljava/lang/String;Ljava/lang/String;Lcodes/side/colorpicker/theme/ColorPickerColors;Lcodes/side/colorpicker/theme/ColorPickerShapes;Lkotlin/jvm/functions/Function3;FFLandroidx/compose/runtime/Composer;III)V } public final class codes/side/colorpicker/ui/SliderLabelDefaultsKt { diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerColors.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerColors.kt index 68f12509..eaa44c3b 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerColors.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerColors.kt @@ -9,9 +9,13 @@ import androidx.compose.ui.graphics.Color * * @property checkerboardLight color of the light cells of the transparency checkerboard. * @property checkerboardDark color of the dark cells of the transparency checkerboard. + * @property disabledAlpha opacity a disabled track and thumb draw at. One value rather than a + * parallel set of disabled colors: a picker's track is a gradient of the colors being chosen, + * so there is no fixed color to swap it for. */ @Immutable public data class ColorPickerColors( public val checkerboardLight: Color, public val checkerboardDark: Color, + public val disabledAlpha: Float, ) diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerDefaults.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerDefaults.kt index c89f8c37..cdd00da6 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerDefaults.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerDefaults.kt @@ -38,6 +38,9 @@ public object ColorPickerDefaults { /** Diameter of a [codes.side.colorpicker.ui.ColorPlane]'s position indicator. */ public val PlaneThumbSize: Dp = 24.dp + /** Opacity a disabled component draws at, the Material 3 disabled content value. */ + public val DisabledAlpha: Float = 0.38f + // surfaceBright/surfaceDim keep visible checkerboard contrast in both // light and dark color schemes. /** @@ -49,9 +52,47 @@ public object ColorPickerDefaults { public fun colors( checkerboardLight: Color = MaterialTheme.colorScheme.surfaceBright, checkerboardDark: Color = MaterialTheme.colorScheme.surfaceDim, + disabledAlpha: Float = DisabledAlpha, ): ColorPickerColors = ColorPickerColors( checkerboardLight = checkerboardLight, checkerboardDark = checkerboardDark, + disabledAlpha = disabledAlpha, + ) + + /** + * The colors in force here: whatever an enclosing [ColorPickerTheme] provided, or [colors] + * when nothing did. + * + * Every component reads this in a parameter default rather than in its body, so an explicit + * argument still wins and a component composed inside a picker inherits the picker's theme + * without the call site forwarding it. + */ + @Composable + public fun currentColors(): ColorPickerColors = LocalColorPickerColors.current ?: colors() + + /** The shapes in force here; see [currentColors]. */ + @Composable + public fun currentShapes(): ColorPickerShapes = LocalColorPickerShapes.current ?: shapes() + + /** The dimensions in force here; see [currentColors]. */ + @Composable + public fun currentDimensions(): ColorPickerDimensions = + LocalColorPickerDimensions.current ?: dimensions() + + /** Creates a [ColorPickerDimensions] from the constants above. */ + @Composable + public fun dimensions( + trackHeight: Dp = TrackHeight, + thumbWidth: Dp = ThumbWidth, + thumbTrackGap: Dp = ThumbTrackGap, + planeMinSize: Dp = PlaneMinSize, + planeThumbSize: Dp = PlaneThumbSize, + ): ColorPickerDimensions = ColorPickerDimensions( + trackHeight = trackHeight, + thumbWidth = thumbWidth, + thumbTrackGap = thumbTrackGap, + planeMinSize = planeMinSize, + planeThumbSize = planeThumbSize, ) /** diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerDimensions.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerDimensions.kt new file mode 100644 index 00000000..cc7698c4 --- /dev/null +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerDimensions.kt @@ -0,0 +1,28 @@ +package codes.side.colorpicker.theme + +import androidx.compose.runtime.Immutable +import androidx.compose.ui.unit.Dp + +/** + * Dimensions used by color picker components. Obtain instances via + * [ColorPickerDefaults.dimensions] so defaults come from a single source. + * + * These travel with the theme rather than as parameters because they apply to every slider a + * picker draws. A caller wanting a taller track sets it once here instead of on each of the + * twenty-one channel sliders. + * + * @property trackHeight height of a slider's gradient track. + * @property thumbWidth width the track reserves for the thumb. A custom thumb wider than this + * must say so, or the track's gap closes underneath it. + * @property thumbTrackGap clearance left between the thumb and each end of the track. + * @property planeMinSize size a [codes.side.colorpicker.ui.ColorPlane] falls back to. + * @property planeThumbSize diameter of a [codes.side.colorpicker.ui.ColorPlane]'s indicator. + */ +@Immutable +public data class ColorPickerDimensions( + public val trackHeight: Dp, + public val thumbWidth: Dp, + public val thumbTrackGap: Dp, + public val planeMinSize: Dp, + public val planeThumbSize: Dp, +) diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerTheme.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerTheme.kt new file mode 100644 index 00000000..3cfb8a4a --- /dev/null +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerTheme.kt @@ -0,0 +1,47 @@ +package codes.side.colorpicker.theme + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.ProvidableCompositionLocal +import androidx.compose.runtime.compositionLocalOf + +/** + * Colors every picker component below this point uses unless given some of its own. + * + * `null` means nothing has been provided and the component falls back to + * [ColorPickerDefaults.colors], which reads `MaterialTheme` at the point of use. Every + * component reads this in a parameter default rather than in its body, so an explicit + * argument always wins over what an ancestor provided. + */ +public val LocalColorPickerColors: ProvidableCompositionLocal = + compositionLocalOf { null } + +/** Shapes every picker component below this point uses; see [LocalColorPickerColors]. */ +public val LocalColorPickerShapes: ProvidableCompositionLocal = + compositionLocalOf { null } + +/** Dimensions every picker component below this point uses; see [LocalColorPickerColors]. */ +public val LocalColorPickerDimensions: ProvidableCompositionLocal = + compositionLocalOf { null } + +/** + * Provides [colors], [shapes] and [dimensions] to everything in [content]. + * + * Wrap a screen in this to style every picker on it at once. A ready-made picker does the same + * for its own sliders, which is what lets a replaced slider slot inherit them without the call + * site forwarding anything. + */ +@Composable +public fun ColorPickerTheme( + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), + dimensions: ColorPickerDimensions = ColorPickerDefaults.currentDimensions(), + content: @Composable () -> Unit, +) { + CompositionLocalProvider( + LocalColorPickerColors provides colors, + LocalColorPickerShapes provides shapes, + LocalColorPickerDimensions provides dimensions, + content = content, + ) +} diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/AlphaSlider.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/AlphaSlider.kt index 91f1d635..fd5d4d54 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/AlphaSlider.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/AlphaSlider.kt @@ -24,15 +24,16 @@ import kotlinx.collections.immutable.persistentListOf public fun AlphaSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, label: (@Composable () -> Unit)? = { SliderLabel("Alpha") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.hslColor.intAlpha}") }, semanticLabel: String? = "Alpha", semanticValueText: String? = "${state.hslColor.intAlpha}", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val hsl = state.hslColor val opaqueColor = remember(hsl.hue, hsl.saturation, hsl.lightness) { @@ -62,6 +63,7 @@ public fun AlphaSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/CmykColorPicker.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/CmykColorPicker.kt index 5aca6553..4ad23f2a 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/CmykColorPicker.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/CmykColorPicker.kt @@ -1,5 +1,6 @@ package codes.side.colorpicker.ui +import androidx.compose.foundation.interaction.InteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.runtime.Composable @@ -10,36 +11,60 @@ import codes.side.colorpicker.state.ColoringMode import codes.side.colorpicker.theme.ColorPickerColors import codes.side.colorpicker.theme.ColorPickerDefaults import codes.side.colorpicker.theme.ColorPickerShapes +import codes.side.colorpicker.theme.ColorPickerTheme /** * Complete CMYK picker: cyan, magenta, yellow, and key sliders, plus an optional * alpha slider. * + * Each slider is a slot, defaulted to the channel slider it names. Replace one to relabel or + * restyle that channel: whatever is passed inherits this picker's colors, shapes and + * dimensions through the theme, and is dimmed only if [enabled] is forwarded to it — though + * it is refused input either way. + * * @param showAlpha whether to include the [AlphaSlider]. * @param coloringMode defaults to [ColoringMode.Contextual] so each track previews * the resulting color at the current values of the other channels. * @param colors checkerboard colors; see [ColorPickerDefaults.colors]. * @param shapes track shape; see [ColorPickerDefaults.shapes]. + * @param enabled when `false` the picker is dimmed, refuses input, and reports itself + * disabled to accessibility. Input is refused by the picker as well as by each slider, so a + * replaced slider slot cannot stay live even if the call site did not forward this to it. + * @param thumb optional replacement for every slider's thumb; see [ColorSlider]. + * @param cyanSlider slot for the cyan channel; defaults to [CyanSlider]. + * @param magentaSlider slot for the magenta channel; defaults to [MagentaSlider]. + * @param yellowSlider slot for the yellow channel; defaults to [YellowSlider]. + * @param keySlider slot for the key channel; defaults to [KeySlider]. + * @param alphaSlider the [AlphaSlider], shown only when [showAlpha] is `true`. */ @Composable public fun CmykColorPicker( state: ColorPickerState, modifier: Modifier = Modifier, showAlpha: Boolean = true, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Contextual, - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), + thumb: (@Composable (InteractionSource) -> Unit)? = null, + cyanSlider: @Composable () -> Unit = { CyanSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + magentaSlider: @Composable () -> Unit = { MagentaSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + yellowSlider: @Composable () -> Unit = { YellowSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + keySlider: @Composable () -> Unit = { KeySlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + alphaSlider: @Composable () -> Unit = { AlphaSlider(state, enabled = enabled, thumb = thumb) }, ) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { - CyanSlider(state = state, coloringMode = coloringMode, colors = colors, shapes = shapes) - MagentaSlider(state = state, coloringMode = coloringMode, colors = colors, shapes = shapes) - YellowSlider(state = state, coloringMode = coloringMode, colors = colors, shapes = shapes) - KeySlider(state = state, coloringMode = coloringMode, colors = colors, shapes = shapes) - if (showAlpha) { - AlphaSlider(state = state, colors = colors, shapes = shapes) + // Provided rather than passed down, so a replaced slider slot inherits the picker's + // theme without the call site forwarding it. + ColorPickerTheme(colors = colors, shapes = shapes) { + Column( + modifier = modifier.disabledInput(enabled), + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + cyanSlider() + magentaSlider() + yellowSlider() + keySlider() + if (showAlpha) alphaSlider() } } } diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/CmykSliders.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/CmykSliders.kt index 6b86ece7..c8853675 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/CmykSliders.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/CmykSliders.kt @@ -33,16 +33,17 @@ private val PureYellow = CmykColor(cyan = 0f, magenta = 0f, yellow = 1f, key = 0 public fun CyanSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Contextual, label: (@Composable () -> Unit)? = { SliderLabel("Cyan") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.cmykColor.intCyan}%") }, semanticLabel: String? = "Cyan", semanticValueText: String? = "${state.cmykColor.intCyan}%", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val cmyk = state.cmykColor val gradientColors = remember(cmyk.magenta, cmyk.yellow, cmyk.key, coloringMode) { @@ -93,6 +94,7 @@ public fun CyanSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, @@ -114,16 +116,17 @@ public fun CyanSlider( public fun MagentaSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Contextual, label: (@Composable () -> Unit)? = { SliderLabel("Magenta") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.cmykColor.intMagenta}%") }, semanticLabel: String? = "Magenta", semanticValueText: String? = "${state.cmykColor.intMagenta}%", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val cmyk = state.cmykColor val gradientColors = remember(cmyk.cyan, cmyk.yellow, cmyk.key, coloringMode) { @@ -174,6 +177,7 @@ public fun MagentaSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, @@ -195,16 +199,17 @@ public fun MagentaSlider( public fun YellowSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Contextual, label: (@Composable () -> Unit)? = { SliderLabel("Yellow") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.cmykColor.intYellow}%") }, semanticLabel: String? = "Yellow", semanticValueText: String? = "${state.cmykColor.intYellow}%", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val cmyk = state.cmykColor val gradientColors = remember(cmyk.cyan, cmyk.magenta, cmyk.key, coloringMode) { @@ -255,6 +260,7 @@ public fun YellowSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, @@ -276,16 +282,17 @@ public fun YellowSlider( public fun KeySlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Contextual, label: (@Composable () -> Unit)? = { SliderLabel("Key") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.cmykColor.intKey}%") }, semanticLabel: String? = "Key", semanticValueText: String? = "${state.cmykColor.intKey}%", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val cmyk = state.cmykColor val gradientColors = remember(cmyk.cyan, cmyk.magenta, cmyk.yellow, coloringMode) { @@ -336,6 +343,7 @@ public fun KeySlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorPickerDialog.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorPickerDialog.kt index aa007981..a4069e8c 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorPickerDialog.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorPickerDialog.kt @@ -1,5 +1,6 @@ package codes.side.colorpicker.ui +import androidx.compose.foundation.interaction.InteractionSource import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth @@ -19,6 +20,7 @@ import codes.side.colorpicker.state.ColorPickerState import codes.side.colorpicker.state.ColorPickerStateSaver import codes.side.colorpicker.theme.ColorPickerColors import codes.side.colorpicker.theme.ColorPickerDefaults +import codes.side.colorpicker.theme.ColorPickerShapes /** * [AlertDialog] hosting an [HslColorPicker] with a preview swatch and @@ -34,8 +36,16 @@ import codes.side.colorpicker.theme.ColorPickerDefaults * @param title dialog title text; [confirmText] and [dismissText] label the buttons — * pass localized strings to replace the English defaults. * @param showAlpha whether to include the alpha slider. + * @param enabled when `false` the picker inside the dialog is dimmed and refuses input. The + * buttons stay live, so the dialog can still be dismissed. * @param colors checkerboard colors used by both the swatch and the picker's alpha * slider; see [ColorPickerDefaults.colors]. + * @param shapes track and swatch shapes; see [ColorPickerDefaults.shapes]. + * @param thumb optional replacement for every slider's thumb; see [ColorSlider]. + * @param hueSlider slot for the hue channel; `null` keeps [HueSlider]. + * @param saturationSlider slot for the saturation channel; `null` keeps [SaturationSlider]. + * @param lightnessSlider slot for the lightness channel; `null` keeps [LightnessSlider]. + * @param alphaSlider slot for the alpha channel; `null` keeps [AlphaSlider]. */ @Composable public fun ColorPickerDialog( @@ -47,7 +57,14 @@ public fun ColorPickerDialog( confirmText: String = "Select", dismissText: String = "Cancel", showAlpha: Boolean = true, - colors: ColorPickerColors = ColorPickerDefaults.colors(), + enabled: Boolean = true, + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), + thumb: (@Composable (InteractionSource) -> Unit)? = null, + hueSlider: (@Composable () -> Unit)? = null, + saturationSlider: (@Composable () -> Unit)? = null, + lightnessSlider: (@Composable () -> Unit)? = null, + alphaSlider: (@Composable () -> Unit)? = null, ) { // initialColor is a reset key: a new initial color re-creates the state, // while configuration changes restore in-progress edits via the saver. @@ -69,10 +86,20 @@ public fun ColorPickerDialog( colors = colors, ) Spacer(Modifier.height(16.dp)) + // The slots are nullable here rather than defaulted to the sliders: the + // dialog owns the state, so a default would have to name a state the caller + // never sees. Null means whatever the picker would have drawn. HslColorPicker( state = state, showAlpha = showAlpha, + enabled = enabled, colors = colors, + shapes = shapes, + thumb = thumb, + hueSlider = hueSlider ?: { HueSlider(state, enabled = enabled, thumb = thumb) }, + saturationSlider = saturationSlider ?: { SaturationSlider(state, enabled = enabled, thumb = thumb) }, + lightnessSlider = lightnessSlider ?: { LightnessSlider(state, enabled = enabled, thumb = thumb) }, + alphaSlider = alphaSlider ?: { AlphaSlider(state, enabled = enabled, thumb = thumb) }, ) } }, diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorPlane.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorPlane.kt index 2aba33eb..985664ab 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorPlane.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorPlane.kt @@ -16,6 +16,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.graphics.Color @@ -24,14 +25,17 @@ import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.layout.Layout import androidx.compose.ui.semantics.contentDescription +import androidx.compose.ui.semantics.disabled import androidx.compose.ui.semantics.semantics import androidx.compose.ui.semantics.stateDescription import androidx.compose.ui.unit.Constraints +import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp +import codes.side.colorpicker.theme.ColorPickerColors import codes.side.colorpicker.theme.ColorPickerDefaults import codes.side.colorpicker.theme.ColorPickerShapes -import kotlinx.coroutines.launch import kotlin.math.roundToInt +import kotlinx.coroutines.launch /** The fraction across a plane [width] pixels wide that a pointer at [x] sits at. */ internal fun planeXFraction(x: Float, width: Int): Float = @@ -71,13 +75,16 @@ public fun ColorPlane( surface: DrawScope.() -> Unit, modifier: Modifier = Modifier, onValueChangeFinished: (() -> Unit)? = null, + enabled: Boolean = true, semanticLabel: String? = null, semanticValueText: String? = null, - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, ) { val interactionSource = remember { MutableInteractionSource() } val scope = rememberCoroutineScope() + val dimensions = ColorPickerDefaults.currentDimensions() // The gesture handler outlives any one composition, so it reads the callbacks and the // painter through these rather than capturing the values it was built with. val currentOnValueChange by rememberUpdatedState(onValueChange) @@ -97,15 +104,20 @@ public fun ColorPlane( // A bare Box, so the indicator measures to its own size. Giving the wrapper a // size instead squeezes a larger custom thumb into the default diameter and // strands a smaller one in the corner of it, off the value it marks. - Box { if (thumb != null) thumb(interactionSource) else PlaneThumb() } + Box { if (thumb != null) thumb(interactionSource) else PlaneThumb(dimensions.planeThumbSize) } }, modifier = modifier - .defaultMinSize(ColorPickerDefaults.PlaneMinSize, ColorPickerDefaults.PlaneMinSize) + .defaultMinSize(dimensions.planeMinSize, dimensions.planeMinSize) + .alpha(if (enabled) 1f else colors.disabledAlpha) .semantics { semanticLabel?.let { contentDescription = it } semanticValueText?.let { stateDescription = it } + if (!enabled) disabled() } - .pointerInput(Unit) { + // Keyed on enabled so the handler is torn down rather than left running with a + // flag it checks: a gesture in flight when the plane is disabled ends there. + .pointerInput(enabled) { + if (!enabled) return@pointerInput awaitEachGesture { val down = awaitFirstDown(requireUnconsumed = false) val press = DragInteraction.Start() @@ -154,10 +166,10 @@ public fun ColorPlane( } } -/** Default position indicator, sized [ColorPickerDefaults.PlaneThumbSize]. */ +/** Default position indicator, sized from [ColorPickerDefaults.currentDimensions]. */ @Composable -private fun PlaneThumb() { - Canvas(Modifier.size(ColorPickerDefaults.PlaneThumbSize)) { +private fun PlaneThumb(diameter: Dp) { + Canvas(Modifier.size(diameter)) { val radius = size.minDimension / 2f - 2.dp.toPx() // A dark halo under a white ring keeps the indicator readable at both // ends of the surface, where a single-colour ring vanishes. diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorSlider.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorSlider.kt index afdcb797..8f22d334 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorSlider.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorSlider.kt @@ -14,6 +14,7 @@ import androidx.compose.material3.SliderDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha import androidx.compose.ui.graphics.Color import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics @@ -65,17 +66,21 @@ public fun ColorSlider( label: (@Composable () -> Unit)? = null, valueLabel: (@Composable () -> Unit)? = null, onValueChangeFinished: (() -> Unit)? = null, - trackHeight: Dp = ColorPickerDefaults.TrackHeight, + enabled: Boolean = true, + trackHeight: Dp = ColorPickerDefaults.currentDimensions().trackHeight, showCheckerboard: Boolean = false, semanticLabel: String? = null, semanticValueText: String? = null, - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val interactionSource = remember { MutableInteractionSource() } + // The track is a gradient of the colors being picked, so there is no disabled palette to + // swap to — it dims instead, and the thumb with it. + val contentAlpha = if (enabled) 1f else colors.disabledAlpha val sliderColors = SliderDefaults.colors( thumbColor = thumbColor.asOpaqueThumb(), activeTrackColor = Color.Transparent, @@ -99,6 +104,7 @@ public fun ColorSlider( value = value, onValueChange = onValueChange, onValueChangeFinished = onValueChangeFinished, + enabled = enabled, modifier = Modifier .fillMaxWidth() // Merged semantics only — M3 Slider's own progress semantics @@ -121,7 +127,8 @@ public fun ColorSlider( thumbTrackGap = thumbTrackGap, modifier = Modifier .fillMaxWidth() - .height(trackHeight), + .height(trackHeight) + .alpha(contentAlpha), ) }, // The slot takes the InteractionSource rather than M3's SliderState. Two @@ -131,8 +138,10 @@ public fun ColorSlider( // by the lambda; press and drag state is the only thing a caller cannot // reach, because this source is created here. thumb = { - if (thumb != null) thumb(interactionSource) - else SliderDefaults.Thumb(interactionSource, colors = sliderColors) + Box(Modifier.alpha(contentAlpha)) { + if (thumb != null) thumb(interactionSource) + else SliderDefaults.Thumb(interactionSource, colors = sliderColors) + } }, colors = sliderColors, ) diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorSwatch.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorSwatch.kt index f2d95691..774c54ec 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorSwatch.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorSwatch.kt @@ -30,9 +30,9 @@ import codes.side.colorpicker.theme.ColorPickerDefaults public fun ColorSwatch( color: Color, modifier: Modifier = Modifier, - shape: Shape = ColorPickerDefaults.shapes().swatchShape, + shape: Shape = ColorPickerDefaults.currentShapes().swatchShape, contentDescription: String? = null, - colors: ColorPickerColors = ColorPickerDefaults.colors(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), ) { Box( modifier = modifier diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/DisabledInput.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/DisabledInput.kt new file mode 100644 index 00000000..2db129d9 --- /dev/null +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/DisabledInput.kt @@ -0,0 +1,33 @@ +package codes.side.colorpicker.ui + +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.pointer.PointerEventPass +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.semantics.disabled +import androidx.compose.ui.semantics.semantics + +/** + * Refuses pointer input for everything below this point, and says so to accessibility. + * + * A ready-made picker applies this as well as passing `enabled` to each slider it composes. + * The slider parameter is what dims one; this is what makes a *replaced* one inert, since a + * caller who swaps a slider slot in to change its label can forget to forward `enabled` and + * would otherwise be left with one live control inside a disabled picker. + * + * Events are consumed on [PointerEventPass.Initial], which is the pass that reaches an + * ancestor before its children. + */ +internal fun Modifier.disabledInput(enabled: Boolean): Modifier = + if (enabled) { + this + } else { + this + .semantics { disabled() } + .pointerInput(Unit) { + awaitPointerEventScope { + while (true) { + awaitPointerEvent(PointerEventPass.Initial).changes.forEach { it.consume() } + } + } + } + } diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/GradientTrack.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/GradientTrack.kt index 7e878b61..9c358095 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/GradientTrack.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/GradientTrack.kt @@ -56,8 +56,8 @@ internal fun GradientTrack( trackShape: Shape, modifier: Modifier = Modifier, showCheckerboard: Boolean = false, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val interactions = remember { mutableStateListOf() } LaunchedEffect(interactionSource) { diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/HslColorPicker.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/HslColorPicker.kt index 9a0e2831..61b742f9 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/HslColorPicker.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/HslColorPicker.kt @@ -1,5 +1,6 @@ package codes.side.colorpicker.ui +import androidx.compose.foundation.interaction.InteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.runtime.Composable @@ -10,11 +11,17 @@ import codes.side.colorpicker.state.ColoringMode import codes.side.colorpicker.theme.ColorPickerColors import codes.side.colorpicker.theme.ColorPickerDefaults import codes.side.colorpicker.theme.ColorPickerShapes +import codes.side.colorpicker.theme.ColorPickerTheme /** * Complete HSL picker: hue, saturation, and lightness sliders, plus an optional * alpha slider. * + * Each slider is a slot, defaulted to the channel slider it names. Replace one to relabel or + * restyle that channel: whatever is passed inherits this picker's colors, shapes and + * dimensions through the theme, and is dimmed only if [enabled] is forwarded to it — though + * it is refused input either way. + * * @param showAlpha whether to include the [AlphaSlider]. * @param coloringMode defaults to [ColoringMode.Independent], unlike the * RGB/CMYK/LAB pickers, because the hue slider must always show the full spectrum @@ -22,37 +29,41 @@ import codes.side.colorpicker.theme.ColorPickerShapes * track collapses into a near-uniform strip. * @param colors checkerboard colors; see [ColorPickerDefaults.colors]. * @param shapes track shape; see [ColorPickerDefaults.shapes]. + * @param enabled when `false` the picker is dimmed, refuses input, and reports itself + * disabled to accessibility. Input is refused by the picker as well as by each slider, so a + * replaced slider slot cannot stay live even if the call site did not forward this to it. + * @param thumb optional replacement for every slider's thumb; see [ColorSlider]. + * @param hueSlider slot for the hue channel; defaults to [HueSlider]. + * @param saturationSlider slot for the saturation channel; defaults to [SaturationSlider]. + * @param lightnessSlider slot for the lightness channel; defaults to [LightnessSlider]. + * @param alphaSlider the [AlphaSlider], shown only when [showAlpha] is `true`. */ @Composable public fun HslColorPicker( state: ColorPickerState, modifier: Modifier = Modifier, showAlpha: Boolean = true, - // Independent by default (unlike the RGB/CMYK/LAB pickers): the hue slider - // must always show the full spectrum to stay navigable. + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Independent, - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), + thumb: (@Composable (InteractionSource) -> Unit)? = null, + hueSlider: @Composable () -> Unit = { HueSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + saturationSlider: @Composable () -> Unit = { SaturationSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + lightnessSlider: @Composable () -> Unit = { LightnessSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + alphaSlider: @Composable () -> Unit = { AlphaSlider(state, enabled = enabled, thumb = thumb) }, ) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { - HueSlider(state = state, coloringMode = coloringMode, colors = colors, shapes = shapes) - SaturationSlider( - state = state, - coloringMode = coloringMode, - colors = colors, - shapes = shapes, - ) - LightnessSlider( - state = state, - coloringMode = coloringMode, - colors = colors, - shapes = shapes, - ) - if (showAlpha) { - AlphaSlider(state = state, colors = colors, shapes = shapes) + // Provided rather than passed down, so a replaced slider slot inherits the picker's + // theme without the call site forwarding it. + ColorPickerTheme(colors = colors, shapes = shapes) { + Column( + modifier = modifier.disabledInput(enabled), + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + hueSlider() + saturationSlider() + lightnessSlider() + if (showAlpha) alphaSlider() } } } diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/HslPlane.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/HslPlane.kt index f53a6613..62436ad3 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/HslPlane.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/HslPlane.kt @@ -29,10 +29,11 @@ import codes.side.colorpicker.theme.ColorPickerShapes public fun HslPlane( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, semanticLabel: String? = "Saturation and lightness", semanticValueText: String? = "${state.hslColor.intSaturation}% saturation, ${state.hslColor.intLightness}% lightness", - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, ) { val hsl = state.hslColor @@ -67,6 +68,7 @@ public fun HslPlane( drawRect(shading) }, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, semanticLabel = semanticLabel, semanticValueText = semanticValueText, diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/HslSliders.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/HslSliders.kt index 4ac51168..41723d95 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/HslSliders.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/HslSliders.kt @@ -53,16 +53,17 @@ private val HUE_RAINBOW = persistentListOf( public fun HueSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Independent, label: (@Composable () -> Unit)? = { SliderLabel("Hue") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.hslColor.intHue}°") }, semanticLabel: String? = "Hue", semanticValueText: String? = "${state.hslColor.intHue}°", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val hsl = state.hslColor val gradientColors = remember(hsl.saturation, hsl.lightness, coloringMode) { @@ -99,6 +100,7 @@ public fun HueSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, @@ -120,16 +122,17 @@ public fun HueSlider( public fun SaturationSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Independent, label: (@Composable () -> Unit)? = { SliderLabel("Saturation") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.hslColor.intSaturation}%") }, semanticLabel: String? = "Saturation", semanticValueText: String? = "${state.hslColor.intSaturation}%", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val hsl = state.hslColor val gradientColors = remember(hsl.hue, hsl.lightness, coloringMode) { @@ -181,6 +184,7 @@ public fun SaturationSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, @@ -202,16 +206,17 @@ public fun SaturationSlider( public fun LightnessSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Independent, label: (@Composable () -> Unit)? = { SliderLabel("Lightness") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.hslColor.intLightness}%") }, semanticLabel: String? = "Lightness", semanticValueText: String? = "${state.hslColor.intLightness}%", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val hsl = state.hslColor val gradientColors = remember(hsl.hue, hsl.saturation, coloringMode) { @@ -261,6 +266,7 @@ public fun LightnessSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/LabColorPicker.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/LabColorPicker.kt index 81611a84..35b990af 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/LabColorPicker.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/LabColorPicker.kt @@ -1,5 +1,6 @@ package codes.side.colorpicker.ui +import androidx.compose.foundation.interaction.InteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.runtime.Composable @@ -10,39 +11,56 @@ import codes.side.colorpicker.state.ColoringMode import codes.side.colorpicker.theme.ColorPickerColors import codes.side.colorpicker.theme.ColorPickerDefaults import codes.side.colorpicker.theme.ColorPickerShapes +import codes.side.colorpicker.theme.ColorPickerTheme /** * Complete CIELAB picker: L*, a*, and b* sliders, plus an optional alpha slider. * + * Each slider is a slot, defaulted to the channel slider it names. Replace one to relabel or + * restyle that channel: whatever is passed inherits this picker's colors, shapes and + * dimensions through the theme, and is dimmed only if [enabled] is forwarded to it — though + * it is refused input either way. + * * @param showAlpha whether to include the [AlphaSlider]. * @param coloringMode defaults to [ColoringMode.Contextual] so each track previews * the resulting color at the current values of the other channels. * @param colors checkerboard colors; see [ColorPickerDefaults.colors]. * @param shapes track shape; see [ColorPickerDefaults.shapes]. + * @param enabled when `false` the picker is dimmed, refuses input, and reports itself + * disabled to accessibility. Input is refused by the picker as well as by each slider, so a + * replaced slider slot cannot stay live even if the call site did not forward this to it. + * @param thumb optional replacement for every slider's thumb; see [ColorSlider]. + * @param lightnessSlider slot for the lightness channel; defaults to [LightnessLabSlider]. + * @param aSlider slot for the a channel; defaults to [LabASlider]. + * @param bSlider slot for the b channel; defaults to [LabBSlider]. + * @param alphaSlider the [AlphaSlider], shown only when [showAlpha] is `true`. */ @Composable public fun LabColorPicker( state: ColorPickerState, modifier: Modifier = Modifier, showAlpha: Boolean = true, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Contextual, - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), + thumb: (@Composable (InteractionSource) -> Unit)? = null, + lightnessSlider: @Composable () -> Unit = { LightnessLabSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + aSlider: @Composable () -> Unit = { LabASlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + bSlider: @Composable () -> Unit = { LabBSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + alphaSlider: @Composable () -> Unit = { AlphaSlider(state, enabled = enabled, thumb = thumb) }, ) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { - LightnessLabSlider( - state = state, - coloringMode = coloringMode, - colors = colors, - shapes = shapes, - ) - LabASlider(state = state, coloringMode = coloringMode, colors = colors, shapes = shapes) - LabBSlider(state = state, coloringMode = coloringMode, colors = colors, shapes = shapes) - if (showAlpha) { - AlphaSlider(state = state, colors = colors, shapes = shapes) + // Provided rather than passed down, so a replaced slider slot inherits the picker's + // theme without the call site forwarding it. + ColorPickerTheme(colors = colors, shapes = shapes) { + Column( + modifier = modifier.disabledInput(enabled), + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + lightnessSlider() + aSlider() + bSlider() + if (showAlpha) alphaSlider() } } } diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/LabSliders.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/LabSliders.kt index da2d8469..b140cfcb 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/LabSliders.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/LabSliders.kt @@ -69,16 +69,17 @@ private val BAxisIndependentGradient = buildLabBGradient(l = 50f, a = 0f) public fun LightnessLabSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Contextual, label: (@Composable () -> Unit)? = { SliderLabel("L") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.labColor.intL}") }, semanticLabel: String? = "L*", semanticValueText: String? = "${state.labColor.intL}", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val lab = state.labColor val gradientColors = remember(lab.a, lab.b, coloringMode) { @@ -110,6 +111,7 @@ public fun LightnessLabSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, @@ -131,16 +133,17 @@ public fun LightnessLabSlider( public fun LabASlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Contextual, label: (@Composable () -> Unit)? = { SliderLabel("a") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.labColor.intA}") }, semanticLabel: String? = "a*", semanticValueText: String? = "${state.labColor.intA}", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val lab = state.labColor val gradientColors = remember(lab.l, lab.b, coloringMode) { @@ -172,6 +175,7 @@ public fun LabASlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, @@ -193,16 +197,17 @@ public fun LabASlider( public fun LabBSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Contextual, label: (@Composable () -> Unit)? = { SliderLabel("b") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.labColor.intB}") }, semanticLabel: String? = "b*", semanticValueText: String? = "${state.labColor.intB}", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val lab = state.labColor val gradientColors = remember(lab.l, lab.a, coloringMode) { @@ -234,6 +239,7 @@ public fun LabBSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhslColorPicker.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhslColorPicker.kt index c9196751..276a81bc 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhslColorPicker.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhslColorPicker.kt @@ -1,5 +1,6 @@ package codes.side.colorpicker.ui +import androidx.compose.foundation.interaction.InteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.runtime.Composable @@ -10,6 +11,7 @@ import codes.side.colorpicker.state.ColoringMode import codes.side.colorpicker.theme.ColorPickerColors import codes.side.colorpicker.theme.ColorPickerDefaults import codes.side.colorpicker.theme.ColorPickerShapes +import codes.side.colorpicker.theme.ColorPickerTheme /** * Complete Okhsl picker: hue, saturation, and lightness sliders, plus an optional alpha @@ -20,41 +22,52 @@ import codes.side.colorpicker.theme.ColorPickerShapes * is measured against the display gamut, so `100%` is reachable at every hue and * lightness rather than running off the end of what the screen can show. * + * Each slider is a slot, defaulted to the channel slider it names. Replace one to relabel or + * restyle that channel: whatever is passed inherits this picker's colors, shapes and + * dimensions through the theme, and is dimmed only if [enabled] is forwarded to it — though + * it is refused input either way. + * * @param showAlpha whether to include the [AlphaSlider]. * @param coloringMode defaults to [ColoringMode.Independent], for the same reason as * [HslColorPicker]: a contextual hue track collapses into a near-uniform strip at low * saturation or extreme lightness, and stops being navigable. * @param colors checkerboard colors; see [ColorPickerDefaults.colors]. * @param shapes track shape; see [ColorPickerDefaults.shapes]. + * @param enabled when `false` the picker is dimmed, refuses input, and reports itself + * disabled to accessibility. Input is refused by the picker as well as by each slider, so a + * replaced slider slot cannot stay live even if the call site did not forward this to it. + * @param thumb optional replacement for every slider's thumb; see [ColorSlider]. + * @param hueSlider slot for the hue channel; defaults to [OkhslHueSlider]. + * @param saturationSlider slot for the saturation channel; defaults to [OkhslSaturationSlider]. + * @param lightnessSlider slot for the lightness channel; defaults to [OkhslLightnessSlider]. + * @param alphaSlider the [AlphaSlider], shown only when [showAlpha] is `true`. */ @Composable public fun OkhslColorPicker( state: ColorPickerState, modifier: Modifier = Modifier, showAlpha: Boolean = true, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Independent, - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), + thumb: (@Composable (InteractionSource) -> Unit)? = null, + hueSlider: @Composable () -> Unit = { OkhslHueSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + saturationSlider: @Composable () -> Unit = { OkhslSaturationSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + lightnessSlider: @Composable () -> Unit = { OkhslLightnessSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + alphaSlider: @Composable () -> Unit = { AlphaSlider(state, enabled = enabled, thumb = thumb) }, ) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { - OkhslHueSlider(state = state, coloringMode = coloringMode, colors = colors, shapes = shapes) - OkhslSaturationSlider( - state = state, - coloringMode = coloringMode, - colors = colors, - shapes = shapes, - ) - OkhslLightnessSlider( - state = state, - coloringMode = coloringMode, - colors = colors, - shapes = shapes, - ) - if (showAlpha) { - AlphaSlider(state = state, colors = colors, shapes = shapes) + // Provided rather than passed down, so a replaced slider slot inherits the picker's + // theme without the call site forwarding it. + ColorPickerTheme(colors = colors, shapes = shapes) { + Column( + modifier = modifier.disabledInput(enabled), + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + hueSlider() + saturationSlider() + lightnessSlider() + if (showAlpha) alphaSlider() } } } diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhslPlane.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhslPlane.kt index 3e9ac4ab..25951fd6 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhslPlane.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhslPlane.kt @@ -38,10 +38,11 @@ import codes.side.colorpicker.theme.ColorPickerShapes public fun OkhslPlane( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, semanticLabel: String? = "Saturation and lightness", semanticValueText: String? = "${state.okhslColor.intSaturation}% saturation, ${state.okhslColor.intLightness}% lightness", - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, ) { val okhsl = state.okhslColor @@ -63,6 +64,7 @@ public fun OkhslPlane( }, surface = { drawPlaneBitmap(bitmap) }, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, semanticLabel = semanticLabel, semanticValueText = semanticValueText, diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhslSliders.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhslSliders.kt index 856a5764..26b741a5 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhslSliders.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhslSliders.kt @@ -57,16 +57,17 @@ internal inline fun buildOkGradient(stops: Int, color: (Float) -> Color): Immuta public fun OkhslHueSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Independent, label: (@Composable () -> Unit)? = { SliderLabel("Hue") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.okhslColor.intHue}°") }, semanticLabel: String? = "Hue", semanticValueText: String? = "${state.okhslColor.intHue}°", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val okhsl = state.okhslColor // The two coloring modes differ only in which saturation and lightness the strip is @@ -113,6 +114,7 @@ public fun OkhslHueSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, @@ -134,16 +136,17 @@ public fun OkhslHueSlider( public fun OkhslSaturationSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Independent, label: (@Composable () -> Unit)? = { SliderLabel("Saturation") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.okhslColor.intSaturation}%") }, semanticLabel: String? = "Saturation", semanticValueText: String? = "${state.okhslColor.intSaturation}%", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val okhsl = state.okhslColor val trackLightness = when (coloringMode) { @@ -183,6 +186,7 @@ public fun OkhslSaturationSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, @@ -209,16 +213,17 @@ public fun OkhslSaturationSlider( public fun OkhslLightnessSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Independent, label: (@Composable () -> Unit)? = { SliderLabel("Lightness") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.okhslColor.intLightness}%") }, semanticLabel: String? = "Lightness", semanticValueText: String? = "${state.okhslColor.intLightness}%", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val okhsl = state.okhslColor val trackSaturation = when (coloringMode) { @@ -258,6 +263,7 @@ public fun OkhslLightnessSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhsvColorPicker.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhsvColorPicker.kt index ee07213e..cad3a545 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhsvColorPicker.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhsvColorPicker.kt @@ -1,5 +1,6 @@ package codes.side.colorpicker.ui +import androidx.compose.foundation.interaction.InteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.runtime.Composable @@ -10,6 +11,7 @@ import codes.side.colorpicker.state.ColoringMode import codes.side.colorpicker.theme.ColorPickerColors import codes.side.colorpicker.theme.ColorPickerDefaults import codes.side.colorpicker.theme.ColorPickerShapes +import codes.side.colorpicker.theme.ColorPickerTheme /** * Complete Okhsv picker: hue, saturation, and value sliders, plus an optional alpha @@ -21,41 +23,52 @@ import codes.side.colorpicker.theme.ColorPickerShapes * the shape of a paint-program picker; pick Okhsl when the midpoint of the lightness * track should be a mid tone. * + * Each slider is a slot, defaulted to the channel slider it names. Replace one to relabel or + * restyle that channel: whatever is passed inherits this picker's colors, shapes and + * dimensions through the theme, and is dimmed only if [enabled] is forwarded to it — though + * it is refused input either way. + * * @param showAlpha whether to include the [AlphaSlider]. * @param coloringMode defaults to [ColoringMode.Independent], for the same reason as * [HslColorPicker]: a contextual hue track collapses into a near-uniform strip at low * saturation or value, and stops being navigable. * @param colors checkerboard colors; see [ColorPickerDefaults.colors]. * @param shapes track shape; see [ColorPickerDefaults.shapes]. + * @param enabled when `false` the picker is dimmed, refuses input, and reports itself + * disabled to accessibility. Input is refused by the picker as well as by each slider, so a + * replaced slider slot cannot stay live even if the call site did not forward this to it. + * @param thumb optional replacement for every slider's thumb; see [ColorSlider]. + * @param hueSlider slot for the hue channel; defaults to [OkhsvHueSlider]. + * @param saturationSlider slot for the saturation channel; defaults to [OkhsvSaturationSlider]. + * @param valueSlider slot for the value channel; defaults to [OkhsvValueSlider]. + * @param alphaSlider the [AlphaSlider], shown only when [showAlpha] is `true`. */ @Composable public fun OkhsvColorPicker( state: ColorPickerState, modifier: Modifier = Modifier, showAlpha: Boolean = true, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Independent, - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), + thumb: (@Composable (InteractionSource) -> Unit)? = null, + hueSlider: @Composable () -> Unit = { OkhsvHueSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + saturationSlider: @Composable () -> Unit = { OkhsvSaturationSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + valueSlider: @Composable () -> Unit = { OkhsvValueSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + alphaSlider: @Composable () -> Unit = { AlphaSlider(state, enabled = enabled, thumb = thumb) }, ) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { - OkhsvHueSlider(state = state, coloringMode = coloringMode, colors = colors, shapes = shapes) - OkhsvSaturationSlider( - state = state, - coloringMode = coloringMode, - colors = colors, - shapes = shapes, - ) - OkhsvValueSlider( - state = state, - coloringMode = coloringMode, - colors = colors, - shapes = shapes, - ) - if (showAlpha) { - AlphaSlider(state = state, colors = colors, shapes = shapes) + // Provided rather than passed down, so a replaced slider slot inherits the picker's + // theme without the call site forwarding it. + ColorPickerTheme(colors = colors, shapes = shapes) { + Column( + modifier = modifier.disabledInput(enabled), + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + hueSlider() + saturationSlider() + valueSlider() + if (showAlpha) alphaSlider() } } } diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhsvPlane.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhsvPlane.kt index a979263b..0d9c7b1b 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhsvPlane.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhsvPlane.kt @@ -36,10 +36,11 @@ import codes.side.colorpicker.theme.ColorPickerShapes public fun OkhsvPlane( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, semanticLabel: String? = "Saturation and value", semanticValueText: String? = "${state.okhsvColor.intSaturation}% saturation, ${state.okhsvColor.intValue}% value", - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, ) { val okhsv = state.okhsvColor @@ -61,6 +62,7 @@ public fun OkhsvPlane( }, surface = { drawPlaneBitmap(bitmap) }, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, semanticLabel = semanticLabel, semanticValueText = semanticValueText, diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhsvSliders.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhsvSliders.kt index 6bf9e052..fcebac5b 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhsvSliders.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/OkhsvSliders.kt @@ -27,16 +27,17 @@ import codes.side.colorpicker.theme.ColorPickerShapes public fun OkhsvHueSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Independent, label: (@Composable () -> Unit)? = { SliderLabel("Hue") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.okhsvColor.intHue}°") }, semanticLabel: String? = "Hue", semanticValueText: String? = "${state.okhsvColor.intHue}°", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val okhsv = state.okhsvColor // The two coloring modes differ only in which saturation and value the strip is drawn @@ -83,6 +84,7 @@ public fun OkhsvHueSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, @@ -104,16 +106,17 @@ public fun OkhsvHueSlider( public fun OkhsvSaturationSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Independent, label: (@Composable () -> Unit)? = { SliderLabel("Saturation") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.okhsvColor.intSaturation}%") }, semanticLabel: String? = "Saturation", semanticValueText: String? = "${state.okhsvColor.intSaturation}%", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val okhsv = state.okhsvColor val trackValue = when (coloringMode) { @@ -149,6 +152,7 @@ public fun OkhsvSaturationSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, @@ -171,16 +175,17 @@ public fun OkhsvSaturationSlider( public fun OkhsvValueSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Independent, label: (@Composable () -> Unit)? = { SliderLabel("Value") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.okhsvColor.intValue}%") }, semanticLabel: String? = "Value", semanticValueText: String? = "${state.okhsvColor.intValue}%", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val okhsv = state.okhsvColor val trackSaturation = when (coloringMode) { @@ -220,6 +225,7 @@ public fun OkhsvValueSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/RgbColorPicker.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/RgbColorPicker.kt index 25336864..2a929401 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/RgbColorPicker.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/RgbColorPicker.kt @@ -1,5 +1,6 @@ package codes.side.colorpicker.ui +import androidx.compose.foundation.interaction.InteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.runtime.Composable @@ -10,34 +11,56 @@ import codes.side.colorpicker.state.ColoringMode import codes.side.colorpicker.theme.ColorPickerColors import codes.side.colorpicker.theme.ColorPickerDefaults import codes.side.colorpicker.theme.ColorPickerShapes +import codes.side.colorpicker.theme.ColorPickerTheme /** * Complete RGB picker: red, green, and blue sliders, plus an optional alpha slider. * + * Each slider is a slot, defaulted to the channel slider it names. Replace one to relabel or + * restyle that channel: whatever is passed inherits this picker's colors, shapes and + * dimensions through the theme, and is dimmed only if [enabled] is forwarded to it — though + * it is refused input either way. + * * @param showAlpha whether to include the [AlphaSlider]. * @param coloringMode defaults to [ColoringMode.Contextual] so each track previews * the resulting color at the current values of the other channels. * @param colors checkerboard colors; see [ColorPickerDefaults.colors]. * @param shapes track shape; see [ColorPickerDefaults.shapes]. + * @param enabled when `false` the picker is dimmed, refuses input, and reports itself + * disabled to accessibility. Input is refused by the picker as well as by each slider, so a + * replaced slider slot cannot stay live even if the call site did not forward this to it. + * @param thumb optional replacement for every slider's thumb; see [ColorSlider]. + * @param redSlider slot for the red channel; defaults to [RedSlider]. + * @param greenSlider slot for the green channel; defaults to [GreenSlider]. + * @param blueSlider slot for the blue channel; defaults to [BlueSlider]. + * @param alphaSlider the [AlphaSlider], shown only when [showAlpha] is `true`. */ @Composable public fun RgbColorPicker( state: ColorPickerState, modifier: Modifier = Modifier, showAlpha: Boolean = true, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Contextual, - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), + thumb: (@Composable (InteractionSource) -> Unit)? = null, + redSlider: @Composable () -> Unit = { RedSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + greenSlider: @Composable () -> Unit = { GreenSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + blueSlider: @Composable () -> Unit = { BlueSlider(state, enabled = enabled, coloringMode = coloringMode, thumb = thumb) }, + alphaSlider: @Composable () -> Unit = { AlphaSlider(state, enabled = enabled, thumb = thumb) }, ) { - Column( - modifier = modifier, - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { - RedSlider(state = state, coloringMode = coloringMode, colors = colors, shapes = shapes) - GreenSlider(state = state, coloringMode = coloringMode, colors = colors, shapes = shapes) - BlueSlider(state = state, coloringMode = coloringMode, colors = colors, shapes = shapes) - if (showAlpha) { - AlphaSlider(state = state, colors = colors, shapes = shapes) + // Provided rather than passed down, so a replaced slider slot inherits the picker's + // theme without the call site forwarding it. + ColorPickerTheme(colors = colors, shapes = shapes) { + Column( + modifier = modifier.disabledInput(enabled), + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + redSlider() + greenSlider() + blueSlider() + if (showAlpha) alphaSlider() } } } diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/RgbSliders.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/RgbSliders.kt index 6e77ea60..606823b1 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/RgbSliders.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/RgbSliders.kt @@ -29,16 +29,17 @@ import kotlinx.collections.immutable.persistentListOf public fun RedSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Contextual, label: (@Composable () -> Unit)? = { SliderLabel("Red") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.rgbColor.intRed}") }, semanticLabel: String? = "Red", semanticValueText: String? = "${state.rgbColor.intRed}", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val rgb = state.rgbColor val gradientColors = remember(rgb.green, rgb.blue, coloringMode) { @@ -78,6 +79,7 @@ public fun RedSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, @@ -99,16 +101,17 @@ public fun RedSlider( public fun GreenSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Contextual, label: (@Composable () -> Unit)? = { SliderLabel("Green") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.rgbColor.intGreen}") }, semanticLabel: String? = "Green", semanticValueText: String? = "${state.rgbColor.intGreen}", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val rgb = state.rgbColor val gradientColors = remember(rgb.red, rgb.blue, coloringMode) { @@ -148,6 +151,7 @@ public fun GreenSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, @@ -169,16 +173,17 @@ public fun GreenSlider( public fun BlueSlider( state: ColorPickerState, modifier: Modifier = Modifier, + enabled: Boolean = true, coloringMode: ColoringMode = ColoringMode.Contextual, label: (@Composable () -> Unit)? = { SliderLabel("Blue") }, valueLabel: (@Composable () -> Unit)? = { SliderValueLabel("${state.rgbColor.intBlue}") }, semanticLabel: String? = "Blue", semanticValueText: String? = "${state.rgbColor.intBlue}", - colors: ColorPickerColors = ColorPickerDefaults.colors(), - shapes: ColorPickerShapes = ColorPickerDefaults.shapes(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), + shapes: ColorPickerShapes = ColorPickerDefaults.currentShapes(), thumb: (@Composable (InteractionSource) -> Unit)? = null, - thumbWidth: Dp = ColorPickerDefaults.ThumbWidth, - thumbTrackGap: Dp = ColorPickerDefaults.ThumbTrackGap, + thumbWidth: Dp = ColorPickerDefaults.currentDimensions().thumbWidth, + thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val rgb = state.rgbColor val gradientColors = remember(rgb.red, rgb.green, coloringMode) { @@ -218,6 +223,7 @@ public fun BlueSlider( colors = colors, shapes = shapes, modifier = modifier, + enabled = enabled, onValueChangeFinished = { interaction.end() }, thumb = thumb, thumbWidth = thumbWidth, diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/TransparencyCheckerboard.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/TransparencyCheckerboard.kt index 3236f08d..7ba5bfa9 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/TransparencyCheckerboard.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/TransparencyCheckerboard.kt @@ -12,7 +12,7 @@ import codes.side.colorpicker.theme.ColorPickerDefaults internal fun TransparencyCheckerboard( modifier: Modifier = Modifier, cellSize: Dp = CheckerboardCellSize, - colors: ColorPickerColors = ColorPickerDefaults.colors(), + colors: ColorPickerColors = ColorPickerDefaults.currentColors(), ) { val brush = rememberCheckerboardBrush( cellSize = cellSize, diff --git a/colorpicker/src/jvmTest/kotlin/codes/side/colorpicker/ui/PickerConfigurationTest.kt b/colorpicker/src/jvmTest/kotlin/codes/side/colorpicker/ui/PickerConfigurationTest.kt new file mode 100644 index 00000000..54a70767 --- /dev/null +++ b/colorpicker/src/jvmTest/kotlin/codes/side/colorpicker/ui/PickerConfigurationTest.kt @@ -0,0 +1,175 @@ +package codes.side.colorpicker.ui + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.testTag +import androidx.compose.ui.test.ExperimentalTestApi +import androidx.compose.ui.test.assertIsNotEnabled +import androidx.compose.ui.test.getUnclippedBoundsInRoot +import androidx.compose.ui.test.onNodeWithTag +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performTouchInput +import androidx.compose.ui.test.swipeRight +import androidx.compose.ui.test.v2.runComposeUiTest +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.height +import codes.side.colorpicker.model.HslColor +import codes.side.colorpicker.state.ColorPickerState +import codes.side.colorpicker.theme.ColorPickerColors +import codes.side.colorpicker.theme.ColorPickerDefaults +import codes.side.colorpicker.theme.ColorPickerTheme +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +/** + * What the picker parameters are for: replacing one slider, theming every slider at once, and + * turning the whole thing off. None of it means anything outside a real composition. + */ +@OptIn(ExperimentalTestApi::class) +class PickerConfigurationTest { + + private fun state() = ColorPickerState(HslColor(hue = 200f, saturation = 0.8f, lightness = 0.5f)) + + @Test + fun aReplacedSlotIsDrawnInsteadOfTheDefault() = runComposeUiTest { + setContent { + HslColorPicker(state = state(), hueSlider = { Text("Farbton") }) + } + onNodeWithText("Farbton").assertExists() + // The slider it stood in for is gone, and the ones beside it are not. + onNodeWithText("Hue").assertDoesNotExist() + onNodeWithText("Saturation").assertExists() + } + + @Test + fun aReplacedSlotInheritsThePickersColorsWithoutForwardingThem() = runComposeUiTest { + val custom = ColorPickerColors( + checkerboardLight = Color.Red, + checkerboardDark = Color.Green, + disabledAlpha = 0.5f, + ) + var seen: ColorPickerColors? = null + setContent { + HslColorPicker( + state = state(), + colors = custom, + // Nothing is passed to this slot, so anything it reads came through the theme + // the picker provides. + hueSlider = { seen = ColorPickerDefaults.currentColors() }, + ) + } + assertEquals(custom, seen) + } + + /** + * The track is one part of a slider's height, and a Material slider will not measure below + * its own minimum, so the size here has to clear that before the change shows at all. + */ + @Test + fun aThemedTrackHeightReachesAChannelSlider() = runComposeUiTest { + setContent { + Box(Modifier.testTag("default")) { HueSlider(state = state()) } + } + val default = onNodeWithTag("default").getUnclippedBoundsInRoot().height + + setContent { + ColorPickerTheme(dimensions = ColorPickerDefaults.dimensions(trackHeight = 80.dp)) { + Box(Modifier.testTag("raised")) { HueSlider(state = state()) } + } + } + val raised = onNodeWithTag("raised").getUnclippedBoundsInRoot().height + + assertTrue( + raised > default, + "an 80dp track should make the slider taller than the 16dp default, $raised vs $default", + ) + } + + @Test + fun aDisabledPickerRefusesADragOnASlotThatNeverSawEnabled() = runComposeUiTest { + val state = state() + val before = state.hslColor.hue + setContent { + HslColorPicker( + state = state, + enabled = false, + // The trap this guards: replacing a slider to relabel it, and not forwarding + // enabled. The picker has to refuse the drag on the slot's behalf. + hueSlider = { + Box(Modifier.testTag("replaced").width(200.dp)) { + HueSlider(state = state, label = null, valueLabel = null) + } + }, + ) + } + onNodeWithTag("replaced").performTouchInput { swipeRight() } + assertEquals(before, state.hslColor.hue) + } + + @Test + fun aDisabledPickerReportsItselfDisabled() = runComposeUiTest { + setContent { + HslColorPicker( + state = state(), + modifier = Modifier.testTag("picker"), + enabled = false, + ) + } + onNodeWithTag("picker").assertIsNotEnabled() + } + + @Test + fun aDisabledSliderRefusesADrag() = runComposeUiTest { + val state = state() + val before = state.hslColor.hue + setContent { + HueSlider( + state = state, + modifier = Modifier.testTag("slider").width(200.dp), + enabled = false, + label = null, + valueLabel = null, + ) + } + onNodeWithTag("slider").performTouchInput { swipeRight() } + assertEquals(before, state.hslColor.hue) + } + + @Test + fun anEnabledSliderAcceptsADrag() = runComposeUiTest { + val state = state() + val before = state.hslColor.hue + setContent { + HueSlider( + state = state, + modifier = Modifier.testTag("slider").width(200.dp), + label = null, + valueLabel = null, + ) + } + onNodeWithTag("slider").performTouchInput { swipeRight() } + assertTrue(state.hslColor.hue != before, "an enabled slider should have moved") + } + + @Test + fun everyPickerTakesTheSameConfiguration() = runComposeUiTest { + // That this compiles is most of the assertion: the six have to agree on the set. + val pickers: List<@Composable (ColorPickerState) -> Unit> = listOf( + { HslColorPicker(it, enabled = false, thumb = {}) }, + { RgbColorPicker(it, enabled = false, thumb = {}) }, + { CmykColorPicker(it, enabled = false, thumb = {}) }, + { LabColorPicker(it, enabled = false, thumb = {}) }, + { OkhslColorPicker(it, enabled = false, thumb = {}) }, + { OkhsvColorPicker(it, enabled = false, thumb = {}) }, + ) + setContent { + val shared = state() + pickers.forEach { picker -> Box { picker(shared) } } + } + } +} diff --git a/docs/index.md b/docs/index.md index 857b76f7..4c825315 100644 --- a/docs/index.md +++ b/docs/index.md @@ -295,6 +295,27 @@ OkhsvColorPicker(state = state, showAlpha = true) `ColoringMode` controls the slider gradients: `Independent` shows each channel's full range regardless of the other channels, `Contextual` previews the actual resulting color at each position. +Every slider in a picker is a slot, defaulted to the channel slider it names. Replace one to +relabel it — which is how a picker is localized, since the library ships no strings of its own: + +```kotlin +HslColorPicker( + state = state, + hueSlider = { HueSlider(state, label = { Text(stringResource(Res.string.hue)) }) }, +) +``` + +A replacement inherits the picker's colors, shapes and dimensions through the theme, so only +what you actually want to change has to be named. `enabled` is the exception — forward it if +you want your slider dimmed, though the picker refuses input to a disabled slot either way: + +```kotlin +HslColorPicker(state = state, enabled = false) // dimmed, inert, and disabled to a screen reader +``` + +`thumb` reaches every slider in the picker, so [the custom thumb below](#custom-thumb) works +here too rather than only on a slider built by hand. + ### Color Planes `HslPlane` picks both channels at once for the hue currently in `state`, @@ -485,7 +506,7 @@ In-progress edits inside the dialog survive configuration changes; passing a new ### Theming -All pickers and sliders accept `colors` and `shapes` built with `ColorPickerDefaults`, which derive from `MaterialTheme` by default: +All pickers and sliders accept `colors`, `shapes` and dimensions built with `ColorPickerDefaults`, which derive from `MaterialTheme` by default: ```kotlin HslColorPicker( @@ -501,6 +522,20 @@ HslColorPicker( ) ``` +`ColorPickerTheme` sets them for everything inside it instead, which is how a track height +reaches all twenty-one channel sliders without being a parameter on any of them: + +```kotlin +ColorPickerTheme( + dimensions = ColorPickerDefaults.dimensions(trackHeight = 24.dp), +) { + HslColorPicker(state = state) + OkhslPlane(state = state) +} +``` + +A component reads the theme in its parameter defaults, so an explicit argument still wins over +whatever an enclosing `ColorPickerTheme` provided. ## 🔗 State Management `ColorPickerState` is the single source of truth. It reads and writes each color space natively, with no round-trip conversions. From 3ba862053915ea7c49a4b8bfb667db67392b9e72 Mon Sep 17 00:00:00 2001 From: Illia Achour Date: Tue, 15 Sep 2026 20:28:14 -0400 Subject: [PATCH 2/4] Put an enabled switch in the sample MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The pickers gained an enabled parameter with nothing demonstrating it. The sample now carries a switch beside the coloring mode buttons that every slider and plane below reads, so the whole screen greys out together and the difference is something you can look at rather than infer from a parameter list. Two tests come with it, because refusing a gesture and looking refused are separate things and only the first was covered. Both measure how much colour is left in the track and the plane surface — how far apart the channels stay across a row — since dimming over the background flattens that rather than moving it in any one direction. The slider and the plane dim through different code, so they are checked separately. Verified on a Pixel 6 Pro as well: at one colour, with the switch thrown, the plane's saturated corner goes pale while the swatch above it, which belongs to no picker, stays as it was. --- .../colorpicker/ui/PickerConfigurationTest.kt | 80 +++++++++++++++++++ .../side/colorpicker/sample/SampleApp.kt | 58 +++++++++----- 2 files changed, 118 insertions(+), 20 deletions(-) diff --git a/colorpicker/src/jvmTest/kotlin/codes/side/colorpicker/ui/PickerConfigurationTest.kt b/colorpicker/src/jvmTest/kotlin/codes/side/colorpicker/ui/PickerConfigurationTest.kt index 54a70767..f621b690 100644 --- a/colorpicker/src/jvmTest/kotlin/codes/side/colorpicker/ui/PickerConfigurationTest.kt +++ b/colorpicker/src/jvmTest/kotlin/codes/side/colorpicker/ui/PickerConfigurationTest.kt @@ -1,14 +1,18 @@ package codes.side.colorpicker.ui +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toPixelMap import androidx.compose.ui.platform.testTag import androidx.compose.ui.test.ExperimentalTestApi import androidx.compose.ui.test.assertIsNotEnabled +import androidx.compose.ui.test.captureToImage import androidx.compose.ui.test.getUnclippedBoundsInRoot import androidx.compose.ui.test.onNodeWithTag import androidx.compose.ui.test.onNodeWithText @@ -172,4 +176,80 @@ class PickerConfigurationTest { pickers.forEach { picker -> Box { picker(shared) } } } } + + /** + * Refusing the gesture is half of disabled; the other half is looking it. Measured as how + * colourful the track still is, since a dimmed gradient over the background loses spread + * between its channels rather than moving in any one direction. + */ + @Test + fun aDisabledSliderIsDrawnDimmer() = runComposeUiTest { + fun colourfulness(): Float { + val pixels = onNodeWithTag("slider").captureToImage().toPixelMap() + var total = 0f + val y = pixels.height / 2 + for (x in 0 until pixels.width) { + val c = pixels[x, y] + total += maxOf(c.red, c.green, c.blue) - minOf(c.red, c.green, c.blue) + } + return total / pixels.width + } + + setContent { + Box(Modifier.testTag("slider").width(200.dp).background(Color.White)) { + HueSlider(state = state(), label = null, valueLabel = null) + } + } + val lit = colourfulness() + + setContent { + Box(Modifier.testTag("slider").width(200.dp).background(Color.White)) { + HueSlider(state = state(), enabled = false, label = null, valueLabel = null) + } + } + val dimmed = colourfulness() + + assertTrue( + dimmed < lit * 0.75f, + "a disabled track should be visibly washed out: $dimmed against $lit", + ) + } + + /** The planes dim through their own path, not the slider's, so they get their own check. */ + @Test + fun aDisabledPlaneIsDrawnDimmer() = runComposeUiTest { + fun colourfulness(): Float { + val pixels = onNodeWithTag("plane").captureToImage().toPixelMap() + var total = 0f + val y = pixels.height / 2 + for (x in 0 until pixels.width) { + val c = pixels[x, y] + total += maxOf(c.red, c.green, c.blue) - minOf(c.red, c.green, c.blue) + } + return total / pixels.width + } + + setContent { + Box(Modifier.background(Color.White)) { + HslPlane(state = state(), modifier = Modifier.testTag("plane").size(160.dp)) + } + } + val lit = colourfulness() + + setContent { + Box(Modifier.background(Color.White)) { + HslPlane( + state = state(), + enabled = false, + modifier = Modifier.testTag("plane").size(160.dp), + ) + } + } + val dimmed = colourfulness() + + assertTrue( + dimmed < lit * 0.75f, + "a disabled plane should be visibly washed out: $dimmed against $lit", + ) + } } diff --git a/sample/shared/src/commonMain/kotlin/codes/side/colorpicker/sample/SampleApp.kt b/sample/shared/src/commonMain/kotlin/codes/side/colorpicker/sample/SampleApp.kt index d74e8b9c..c7327767 100644 --- a/sample/shared/src/commonMain/kotlin/codes/side/colorpicker/sample/SampleApp.kt +++ b/sample/shared/src/commonMain/kotlin/codes/side/colorpicker/sample/SampleApp.kt @@ -26,6 +26,7 @@ import androidx.compose.material3.Scaffold import androidx.compose.material3.SegmentedButton import androidx.compose.material3.SegmentedButtonDefaults import androidx.compose.material3.SingleChoiceSegmentedButtonRow +import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults @@ -84,6 +85,7 @@ fun SampleApp() { ) var showDialog by rememberSaveable { mutableStateOf(false) } var coloringMode by rememberSaveable { mutableStateOf(ColoringMode.Contextual) } + var enabled by rememberSaveable { mutableStateOf(true) } Scaffold( topBar = { @@ -128,6 +130,18 @@ fun SampleApp() { } } + // Everything below reads this, so the whole sample greys out together. + item { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Text("Enabled") + Switch(checked = enabled, onCheckedChange = { enabled = it }) + } + } + // Color values readout item { val hsl = state.hslColor @@ -198,6 +212,7 @@ fun SampleApp() { item { HslPlane( state = state, + enabled = enabled, modifier = Modifier.fillMaxWidth().height(220.dp), ) } @@ -208,6 +223,7 @@ fun SampleApp() { item { OkhslPlane( state = state, + enabled = enabled, modifier = Modifier.fillMaxWidth().height(220.dp), ) } @@ -218,6 +234,7 @@ fun SampleApp() { item { OkhsvPlane( state = state, + enabled = enabled, modifier = Modifier.fillMaxWidth().height(220.dp), ) } @@ -226,57 +243,57 @@ fun SampleApp() { // HSL section item { SectionHeader("HSL") } - item { HueSlider(state = state, coloringMode = coloringMode) } - item { SaturationSlider(state = state, coloringMode = coloringMode) } - item { LightnessSlider(state = state, coloringMode = coloringMode) } + item { HueSlider(state = state, enabled = enabled, coloringMode = coloringMode) } + item { SaturationSlider(state = state, enabled = enabled, coloringMode = coloringMode) } + item { LightnessSlider(state = state, enabled = enabled, coloringMode = coloringMode) } item { HorizontalDivider() } // RGB section item { SectionHeader("RGB") } - item { RedSlider(state = state, coloringMode = coloringMode) } - item { GreenSlider(state = state, coloringMode = coloringMode) } - item { BlueSlider(state = state, coloringMode = coloringMode) } + item { RedSlider(state = state, enabled = enabled, coloringMode = coloringMode) } + item { GreenSlider(state = state, enabled = enabled, coloringMode = coloringMode) } + item { BlueSlider(state = state, enabled = enabled, coloringMode = coloringMode) } item { HorizontalDivider() } // CMYK section item { SectionHeader("CMYK") } - item { CyanSlider(state = state, coloringMode = coloringMode) } - item { MagentaSlider(state = state, coloringMode = coloringMode) } - item { YellowSlider(state = state, coloringMode = coloringMode) } - item { KeySlider(state = state, coloringMode = coloringMode) } + item { CyanSlider(state = state, enabled = enabled, coloringMode = coloringMode) } + item { MagentaSlider(state = state, enabled = enabled, coloringMode = coloringMode) } + item { YellowSlider(state = state, enabled = enabled, coloringMode = coloringMode) } + item { KeySlider(state = state, enabled = enabled, coloringMode = coloringMode) } item { HorizontalDivider() } // LAB section item { SectionHeader("LAB") } - item { LightnessLabSlider(state = state, coloringMode = coloringMode) } - item { LabASlider(state = state, coloringMode = coloringMode) } - item { LabBSlider(state = state, coloringMode = coloringMode) } + item { LightnessLabSlider(state = state, enabled = enabled, coloringMode = coloringMode) } + item { LabASlider(state = state, enabled = enabled, coloringMode = coloringMode) } + item { LabBSlider(state = state, enabled = enabled, coloringMode = coloringMode) } item { HorizontalDivider() } // Okhsl section. Drag the lightness slider here and then the HSL one // above at the same hue: only this one holds its apparent brightness. item { SectionHeader("Okhsl") } - item { OkhslHueSlider(state = state, coloringMode = coloringMode) } - item { OkhslSaturationSlider(state = state, coloringMode = coloringMode) } - item { OkhslLightnessSlider(state = state, coloringMode = coloringMode) } + item { OkhslHueSlider(state = state, enabled = enabled, coloringMode = coloringMode) } + item { OkhslSaturationSlider(state = state, enabled = enabled, coloringMode = coloringMode) } + item { OkhslLightnessSlider(state = state, enabled = enabled, coloringMode = coloringMode) } item { HorizontalDivider() } // Okhsv section item { SectionHeader("Okhsv") } - item { OkhsvHueSlider(state = state, coloringMode = coloringMode) } - item { OkhsvSaturationSlider(state = state, coloringMode = coloringMode) } - item { OkhsvValueSlider(state = state, coloringMode = coloringMode) } + item { OkhsvHueSlider(state = state, enabled = enabled, coloringMode = coloringMode) } + item { OkhsvSaturationSlider(state = state, enabled = enabled, coloringMode = coloringMode) } + item { OkhsvValueSlider(state = state, enabled = enabled, coloringMode = coloringMode) } item { HorizontalDivider() } // Alpha section item { SectionHeader("Alpha") } - item { AlphaSlider(state = state) } + item { AlphaSlider(state = state, enabled = enabled) } item { HorizontalDivider() } @@ -286,6 +303,7 @@ fun SampleApp() { item { HueSlider( state = state, + enabled = enabled, coloringMode = coloringMode, thumb = { source -> SquareThumb(state.hslColor.toComposeColor(), source) }, thumbWidth = SquareThumbSize, From bef83f8bafc30982faefedfbe8e352f5497bbd84 Mon Sep 17 00:00:00 2001 From: Illia Achour Date: Tue, 15 Sep 2026 20:48:32 -0400 Subject: [PATCH 3/4] Rename DisabledInput to DisabledState The file is about to carry how a disabled control looks as well as whether it takes input, and the old name only covers the second. --- .../side/colorpicker/ui/{DisabledInput.kt => DisabledState.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/{DisabledInput.kt => DisabledState.kt} (100%) diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/DisabledInput.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/DisabledState.kt similarity index 100% rename from colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/DisabledInput.kt rename to colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/DisabledState.kt From fb980a638bc9ee77be0af81c43d14b9b303e3789 Mon Sep 17 00:00:00 2001 From: Illia Achour Date: Tue, 15 Sep 2026 20:48:46 -0400 Subject: [PATCH 4/4] Let a caller choose what disabled looks like MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dimming to 38% is the Material convention and it is what a disabled picker did. It is a poor fit for this one control. A picker's track is made of the colours being chosen, so dimming shows paler versions of real colours — a wrong answer rather than an absent one — and alpha composites against a background the library does not own, so the same value pales the track on white and darkens it on black. Draining the colour has neither problem: it is background independent, and grey claims nothing. It is not strictly better either, since a fully grey saturation track can read as a legitimate low-saturation choice rather than as switched off. So both are knobs. disabledAlpha keeps the Material default of 0.38 and disabledSaturation arrives at 1, which leaves colour alone, so nothing changes until a caller asks. Either at its neutral value switches it off, giving dimming, draining, both or neither, and both are applied in one layer so asking for both costs no more than one. disabledAppearance replaces the two alpha layers ColorSlider used, so the labels dim with the track they belong to rather than staying lit above a greyed-out control. --- colorpicker/api/colorpicker.klib.api | 14 +++-- colorpicker/api/jvm/colorpicker.api | 13 +++-- .../colorpicker/theme/ColorPickerColors.kt | 11 ++-- .../colorpicker/theme/ColorPickerDefaults.kt | 10 +++- .../codes/side/colorpicker/ui/ColorPlane.kt | 3 +- .../codes/side/colorpicker/ui/ColorSlider.kt | 15 ++---- .../side/colorpicker/ui/DisabledState.kt | 43 +++++++++++++++ .../colorpicker/ui/PickerConfigurationTest.kt | 53 +++++++++++++++++++ 8 files changed, 136 insertions(+), 26 deletions(-) diff --git a/colorpicker/api/colorpicker.klib.api b/colorpicker/api/colorpicker.klib.api index 48f38528..de714f28 100644 --- a/colorpicker/api/colorpicker.klib.api +++ b/colorpicker/api/colorpicker.klib.api @@ -391,7 +391,7 @@ final class codes.side.colorpicker.state/ColorPickerState { // codes.side.colorp } final class codes.side.colorpicker.theme/ColorPickerColors { // codes.side.colorpicker.theme/ColorPickerColors|null[0] - constructor (androidx.compose.ui.graphics/Color, androidx.compose.ui.graphics/Color, kotlin/Float) // codes.side.colorpicker.theme/ColorPickerColors.|(androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color;kotlin.Float){}[0] + constructor (androidx.compose.ui.graphics/Color, androidx.compose.ui.graphics/Color, kotlin/Float, kotlin/Float) // codes.side.colorpicker.theme/ColorPickerColors.|(androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color;kotlin.Float;kotlin.Float){}[0] final val checkerboardDark // codes.side.colorpicker.theme/ColorPickerColors.checkerboardDark|{}checkerboardDark[0] final fun (): androidx.compose.ui.graphics/Color // codes.side.colorpicker.theme/ColorPickerColors.checkerboardDark.|(){}[0] @@ -399,11 +399,14 @@ final class codes.side.colorpicker.theme/ColorPickerColors { // codes.side.color final fun (): androidx.compose.ui.graphics/Color // codes.side.colorpicker.theme/ColorPickerColors.checkerboardLight.|(){}[0] final val disabledAlpha // codes.side.colorpicker.theme/ColorPickerColors.disabledAlpha|{}disabledAlpha[0] final fun (): kotlin/Float // codes.side.colorpicker.theme/ColorPickerColors.disabledAlpha.|(){}[0] + final val disabledSaturation // codes.side.colorpicker.theme/ColorPickerColors.disabledSaturation|{}disabledSaturation[0] + final fun (): kotlin/Float // codes.side.colorpicker.theme/ColorPickerColors.disabledSaturation.|(){}[0] final fun component1(): androidx.compose.ui.graphics/Color // codes.side.colorpicker.theme/ColorPickerColors.component1|component1(){}[0] final fun component2(): androidx.compose.ui.graphics/Color // codes.side.colorpicker.theme/ColorPickerColors.component2|component2(){}[0] final fun component3(): kotlin/Float // codes.side.colorpicker.theme/ColorPickerColors.component3|component3(){}[0] - final fun copy(androidx.compose.ui.graphics/Color = ..., androidx.compose.ui.graphics/Color = ..., kotlin/Float = ...): codes.side.colorpicker.theme/ColorPickerColors // codes.side.colorpicker.theme/ColorPickerColors.copy|copy(androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color;kotlin.Float){}[0] + final fun component4(): kotlin/Float // codes.side.colorpicker.theme/ColorPickerColors.component4|component4(){}[0] + final fun copy(androidx.compose.ui.graphics/Color = ..., androidx.compose.ui.graphics/Color = ..., kotlin/Float = ..., kotlin/Float = ...): codes.side.colorpicker.theme/ColorPickerColors // codes.side.colorpicker.theme/ColorPickerColors.copy|copy(androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color;kotlin.Float;kotlin.Float){}[0] final fun equals(kotlin/Any?): kotlin/Boolean // codes.side.colorpicker.theme/ColorPickerColors.equals|equals(kotlin.Any?){}[0] final fun hashCode(): kotlin/Int // codes.side.colorpicker.theme/ColorPickerColors.hashCode|hashCode(){}[0] final fun toString(): kotlin/String // codes.side.colorpicker.theme/ColorPickerColors.toString|toString(){}[0] @@ -454,8 +457,11 @@ final class codes.side.colorpicker.theme/ColorPickerShapes { // codes.side.color } final object codes.side.colorpicker.theme/ColorPickerDefaults { // codes.side.colorpicker.theme/ColorPickerDefaults|null[0] - final val DisabledAlpha // codes.side.colorpicker.theme/ColorPickerDefaults.DisabledAlpha|{}DisabledAlpha[0] + final const val DisabledAlpha // codes.side.colorpicker.theme/ColorPickerDefaults.DisabledAlpha|{}DisabledAlpha[0] final fun (): kotlin/Float // codes.side.colorpicker.theme/ColorPickerDefaults.DisabledAlpha.|(){}[0] + final const val DisabledSaturation // codes.side.colorpicker.theme/ColorPickerDefaults.DisabledSaturation|{}DisabledSaturation[0] + final fun (): kotlin/Float // codes.side.colorpicker.theme/ColorPickerDefaults.DisabledSaturation.|(){}[0] + final val PlaneMinSize // codes.side.colorpicker.theme/ColorPickerDefaults.PlaneMinSize|{}PlaneMinSize[0] final fun (): androidx.compose.ui.unit/Dp // codes.side.colorpicker.theme/ColorPickerDefaults.PlaneMinSize.|(){}[0] final val PlaneThumbSize // codes.side.colorpicker.theme/ColorPickerDefaults.PlaneThumbSize|{}PlaneThumbSize[0] @@ -469,7 +475,7 @@ final object codes.side.colorpicker.theme/ColorPickerDefaults { // codes.side.co final val TrackHeight // codes.side.colorpicker.theme/ColorPickerDefaults.TrackHeight|{}TrackHeight[0] final fun (): androidx.compose.ui.unit/Dp // codes.side.colorpicker.theme/ColorPickerDefaults.TrackHeight.|(){}[0] - final fun colors(androidx.compose.ui.graphics/Color, androidx.compose.ui.graphics/Color, kotlin/Float, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): codes.side.colorpicker.theme/ColorPickerColors // codes.side.colorpicker.theme/ColorPickerDefaults.colors|colors(androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color;kotlin.Float;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] + final fun colors(androidx.compose.ui.graphics/Color, androidx.compose.ui.graphics/Color, kotlin/Float, kotlin/Float, androidx.compose.runtime/Composer?, kotlin/Int, kotlin/Int): codes.side.colorpicker.theme/ColorPickerColors // codes.side.colorpicker.theme/ColorPickerDefaults.colors|colors(androidx.compose.ui.graphics.Color;androidx.compose.ui.graphics.Color;kotlin.Float;kotlin.Float;androidx.compose.runtime.Composer?;kotlin.Int;kotlin.Int){}[0] final fun currentColors(androidx.compose.runtime/Composer?, kotlin/Int): codes.side.colorpicker.theme/ColorPickerColors // codes.side.colorpicker.theme/ColorPickerDefaults.currentColors|currentColors(androidx.compose.runtime.Composer?;kotlin.Int){}[0] final fun currentDimensions(androidx.compose.runtime/Composer?, kotlin/Int): codes.side.colorpicker.theme/ColorPickerDimensions // codes.side.colorpicker.theme/ColorPickerDefaults.currentDimensions|currentDimensions(androidx.compose.runtime.Composer?;kotlin.Int){}[0] final fun currentShapes(androidx.compose.runtime/Composer?, kotlin/Int): codes.side.colorpicker.theme/ColorPickerShapes // codes.side.colorpicker.theme/ColorPickerDefaults.currentShapes|currentShapes(androidx.compose.runtime.Composer?;kotlin.Int){}[0] diff --git a/colorpicker/api/jvm/colorpicker.api b/colorpicker/api/jvm/colorpicker.api index e9a745ea..51e53157 100644 --- a/colorpicker/api/jvm/colorpicker.api +++ b/colorpicker/api/jvm/colorpicker.api @@ -407,29 +407,32 @@ public final class codes/side/colorpicker/state/SaveableColorPickerStateKt { public final class codes/side/colorpicker/theme/ColorPickerColors { public static final field $stable I - public synthetic fun (JJFLkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun (JJFFLkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun component1-0d7_KjU ()J public final fun component2-0d7_KjU ()J public final fun component3 ()F - public final fun copy-jxsXWHM (JJF)Lcodes/side/colorpicker/theme/ColorPickerColors; - public static synthetic fun copy-jxsXWHM$default (Lcodes/side/colorpicker/theme/ColorPickerColors;JJFILjava/lang/Object;)Lcodes/side/colorpicker/theme/ColorPickerColors; + public final fun component4 ()F + public final fun copy-RFnl5yQ (JJFF)Lcodes/side/colorpicker/theme/ColorPickerColors; + public static synthetic fun copy-RFnl5yQ$default (Lcodes/side/colorpicker/theme/ColorPickerColors;JJFFILjava/lang/Object;)Lcodes/side/colorpicker/theme/ColorPickerColors; public fun equals (Ljava/lang/Object;)Z public final fun getCheckerboardDark-0d7_KjU ()J public final fun getCheckerboardLight-0d7_KjU ()J public final fun getDisabledAlpha ()F + public final fun getDisabledSaturation ()F public fun hashCode ()I public fun toString ()Ljava/lang/String; } public final class codes/side/colorpicker/theme/ColorPickerDefaults { public static final field $stable I + public static final field DisabledAlpha F + public static final field DisabledSaturation F public static final field INSTANCE Lcodes/side/colorpicker/theme/ColorPickerDefaults; - public final fun colors-Klgx-Pg (JJFLandroidx/compose/runtime/Composer;II)Lcodes/side/colorpicker/theme/ColorPickerColors; + public final fun colors-6xbWgXg (JJFFLandroidx/compose/runtime/Composer;II)Lcodes/side/colorpicker/theme/ColorPickerColors; public final fun currentColors (Landroidx/compose/runtime/Composer;I)Lcodes/side/colorpicker/theme/ColorPickerColors; public final fun currentDimensions (Landroidx/compose/runtime/Composer;I)Lcodes/side/colorpicker/theme/ColorPickerDimensions; public final fun currentShapes (Landroidx/compose/runtime/Composer;I)Lcodes/side/colorpicker/theme/ColorPickerShapes; public final fun dimensions-R_JCAzs (FFFFFLandroidx/compose/runtime/Composer;II)Lcodes/side/colorpicker/theme/ColorPickerDimensions; - public final fun getDisabledAlpha ()F public final fun getPlaneMinSize-D9Ej5fM ()F public final fun getPlaneThumbSize-D9Ej5fM ()F public final fun getSwatchSize-D9Ej5fM ()F diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerColors.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerColors.kt index eaa44c3b..72905cb7 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerColors.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerColors.kt @@ -9,13 +9,18 @@ import androidx.compose.ui.graphics.Color * * @property checkerboardLight color of the light cells of the transparency checkerboard. * @property checkerboardDark color of the dark cells of the transparency checkerboard. - * @property disabledAlpha opacity a disabled track and thumb draw at. One value rather than a - * parallel set of disabled colors: a picker's track is a gradient of the colors being chosen, - * so there is no fixed color to swap it for. + * @property disabledAlpha opacity a disabled control draws at, `1f` to leave it alone. One value + * rather than a parallel set of disabled colors: a picker's track is a gradient of the colors + * being chosen, so there is no fixed color to swap it for. + * @property disabledSaturation how much colour a disabled control keeps, `0f` for grey and `1f` + * to leave it alone. Dimming shows paler versions of real colours and composites against a + * background the library does not own; draining the colour does neither. Set both, either, or + * neither. */ @Immutable public data class ColorPickerColors( public val checkerboardLight: Color, public val checkerboardDark: Color, public val disabledAlpha: Float, + public val disabledSaturation: Float, ) diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerDefaults.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerDefaults.kt index cdd00da6..5e85d573 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerDefaults.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/theme/ColorPickerDefaults.kt @@ -39,7 +39,13 @@ public object ColorPickerDefaults { public val PlaneThumbSize: Dp = 24.dp /** Opacity a disabled component draws at, the Material 3 disabled content value. */ - public val DisabledAlpha: Float = 0.38f + public const val DisabledAlpha: Float = 0.38f + + /** + * Colour a disabled component keeps. Full, by default: dimming alone is the Material + * convention, and draining the colour as well is a choice a caller makes. + */ + public const val DisabledSaturation: Float = 1f // surfaceBright/surfaceDim keep visible checkerboard contrast in both // light and dark color schemes. @@ -53,10 +59,12 @@ public object ColorPickerDefaults { checkerboardLight: Color = MaterialTheme.colorScheme.surfaceBright, checkerboardDark: Color = MaterialTheme.colorScheme.surfaceDim, disabledAlpha: Float = DisabledAlpha, + disabledSaturation: Float = DisabledSaturation, ): ColorPickerColors = ColorPickerColors( checkerboardLight = checkerboardLight, checkerboardDark = checkerboardDark, disabledAlpha = disabledAlpha, + disabledSaturation = disabledSaturation, ) /** diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorPlane.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorPlane.kt index 985664ab..3acbd0c3 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorPlane.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorPlane.kt @@ -16,7 +16,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.graphics.Color @@ -108,7 +107,7 @@ public fun ColorPlane( }, modifier = modifier .defaultMinSize(dimensions.planeMinSize, dimensions.planeMinSize) - .alpha(if (enabled) 1f else colors.disabledAlpha) + .disabledAppearance(enabled, colors) .semantics { semanticLabel?.let { contentDescription = it } semanticValueText?.let { stateDescription = it } diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorSlider.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorSlider.kt index 8f22d334..575d6042 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorSlider.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/ColorSlider.kt @@ -14,7 +14,6 @@ import androidx.compose.material3.SliderDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.alpha import androidx.compose.ui.graphics.Color import androidx.compose.ui.semantics.contentDescription import androidx.compose.ui.semantics.semantics @@ -78,16 +77,13 @@ public fun ColorSlider( thumbTrackGap: Dp = ColorPickerDefaults.currentDimensions().thumbTrackGap, ) { val interactionSource = remember { MutableInteractionSource() } - // The track is a gradient of the colors being picked, so there is no disabled palette to - // swap to — it dims instead, and the thumb with it. - val contentAlpha = if (enabled) 1f else colors.disabledAlpha val sliderColors = SliderDefaults.colors( thumbColor = thumbColor.asOpaqueThumb(), activeTrackColor = Color.Transparent, inactiveTrackColor = Color.Transparent, ) - Column(modifier = modifier.fillMaxWidth()) { + Column(modifier = modifier.fillMaxWidth().disabledAppearance(enabled, colors)) { if (label != null || valueLabel != null) { Row( modifier = Modifier @@ -127,8 +123,7 @@ public fun ColorSlider( thumbTrackGap = thumbTrackGap, modifier = Modifier .fillMaxWidth() - .height(trackHeight) - .alpha(contentAlpha), + .height(trackHeight), ) }, // The slot takes the InteractionSource rather than M3's SliderState. Two @@ -138,10 +133,8 @@ public fun ColorSlider( // by the lambda; press and drag state is the only thing a caller cannot // reach, because this source is created here. thumb = { - Box(Modifier.alpha(contentAlpha)) { - if (thumb != null) thumb(interactionSource) - else SliderDefaults.Thumb(interactionSource, colors = sliderColors) - } + if (thumb != null) thumb(interactionSource) + else SliderDefaults.Thumb(interactionSource, colors = sliderColors) }, colors = sliderColors, ) diff --git a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/DisabledState.kt b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/DisabledState.kt index 2db129d9..9e126ffc 100644 --- a/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/DisabledState.kt +++ b/colorpicker/src/commonMain/kotlin/codes/side/colorpicker/ui/DisabledState.kt @@ -1,10 +1,17 @@ package codes.side.colorpicker.ui import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawWithContent +import androidx.compose.ui.geometry.toRect +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.ColorMatrix +import androidx.compose.ui.graphics.Paint +import androidx.compose.ui.graphics.drawscope.drawIntoCanvas import androidx.compose.ui.input.pointer.PointerEventPass import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.semantics.disabled import androidx.compose.ui.semantics.semantics +import codes.side.colorpicker.theme.ColorPickerColors /** * Refuses pointer input for everything below this point, and says so to accessibility. @@ -31,3 +38,39 @@ internal fun Modifier.disabledInput(enabled: Boolean): Modifier = } } } + +/** + * Draws [this] the way [colors] says a disabled control should look. + * + * Two knobs rather than one, because the Material convention and this control disagree. Material + * dims a disabled component to 38% and that is what [ColorPickerColors.disabledAlpha] does, but a + * colour picker's track is made of the colours being chosen: dimming it shows paler versions of + * real colours, which is a wrong answer rather than an absent one, and it composites against a + * background the library does not own, so the same value pales on white and darkens on black. + * [ColorPickerColors.disabledSaturation] drains the colour instead, which is background + * independent and claims nothing. + * + * Leave either at its neutral value to switch it off: `1f` alpha keeps full opacity and `1f` + * saturation keeps full colour, so a caller can have dimming, draining, both, or neither. Both + * are applied in one layer, so asking for both costs no more than asking for one. + */ +internal fun Modifier.disabledAppearance(enabled: Boolean, colors: ColorPickerColors): Modifier { + val alpha = colors.disabledAlpha + val saturation = colors.disabledSaturation + if (enabled || (alpha == 1f && saturation == 1f)) return this + return drawWithContent { + val paint = Paint().also { paint -> + paint.alpha = alpha + if (saturation != 1f) { + paint.colorFilter = ColorFilter.colorMatrix( + ColorMatrix().also { it.setToSaturation(saturation) }, + ) + } + } + drawIntoCanvas { canvas -> + canvas.saveLayer(size.toRect(), paint) + drawContent() + canvas.restore() + } + } +} diff --git a/colorpicker/src/jvmTest/kotlin/codes/side/colorpicker/ui/PickerConfigurationTest.kt b/colorpicker/src/jvmTest/kotlin/codes/side/colorpicker/ui/PickerConfigurationTest.kt index f621b690..201addb1 100644 --- a/colorpicker/src/jvmTest/kotlin/codes/side/colorpicker/ui/PickerConfigurationTest.kt +++ b/colorpicker/src/jvmTest/kotlin/codes/side/colorpicker/ui/PickerConfigurationTest.kt @@ -56,6 +56,7 @@ class PickerConfigurationTest { checkerboardLight = Color.Red, checkerboardDark = Color.Green, disabledAlpha = 0.5f, + disabledSaturation = 1f, ) var seen: ColorPickerColors? = null setContent { @@ -252,4 +253,56 @@ class PickerConfigurationTest { "a disabled plane should be visibly washed out: $dimmed against $lit", ) } + + /** + * The two knobs are independent, so all four settings have to behave: dim only, drain only, + * both, and neither. Colourfulness catches draining; lightness toward the white background + * catches dimming. + */ + @Test + fun theDisabledLookIsWhateverTheColorsAskFor() = runComposeUiTest { + fun measure(disabledAlpha: Float, disabledSaturation: Float): Pair { + setContent { + ColorPickerTheme( + colors = ColorPickerDefaults.colors( + disabledAlpha = disabledAlpha, + disabledSaturation = disabledSaturation, + ), + ) { + Box(Modifier.background(Color.White)) { + HslPlane( + state = state(), + enabled = false, + modifier = Modifier.testTag("plane").size(160.dp), + ) + } + } + } + val pixels = onNodeWithTag("plane").captureToImage().toPixelMap() + var colour = 0f + var light = 0f + val y = pixels.height / 2 + for (x in 0 until pixels.width) { + val c = pixels[x, y] + colour += maxOf(c.red, c.green, c.blue) - minOf(c.red, c.green, c.blue) + light += (c.red + c.green + c.blue) / 3f + } + return colour / pixels.width to light / pixels.width + } + + val (untouchedColour, untouchedLight) = measure(1f, 1f) + val (dimmedColour, dimmedLight) = measure(0.38f, 1f) + val (drainedColour, drainedLight) = measure(1f, 0f) + val (bothColour, bothLight) = measure(0.38f, 0f) + + // Neither knob set leaves it looking enabled. + assertTrue(untouchedColour > 0.05f, "untouched should still be colourful: $untouchedColour") + // Dimming lightens it toward the background without draining much colour outright. + assertTrue(dimmedLight > untouchedLight, "dimming should lighten: $dimmedLight vs $untouchedLight") + // Draining removes the colour while leaving the weight alone. + assertTrue(drainedColour < untouchedColour * 0.1f, "draining should remove colour: $drainedColour") + // Both does both. + assertTrue(bothColour < untouchedColour * 0.1f, "both should remove colour: $bothColour") + assertTrue(bothLight > untouchedLight, "both should lighten: $bothLight vs $untouchedLight") + } }