summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaewoong Eum <skydoves2@gmail.com>2026-09-16 13:14:47 +0300
committerGitHub <noreply@github.com>2026-09-16 13:14:47 +0300
commit2818dc8935a83d6ba5e49f0fe3b37c49dc1e71c6 (patch)
tree91db8975442b6aac0e9dd0ed7b34db79cdee1427
parenta756e7c8d213579de61b905d54aa53f1e1c83a2e (diff)
parent6eaa22397405aa79f7912f34d92599c663543bb0 (diff)
downloadcolorpicker-compose-main.tar.xz
Merge pull request #216 from skydoves/release/1.3.0HEAD1.3.0main
Prepare for release 1.3.0
-rw-r--r--README.md10
-rw-r--r--buildSrc/src/main/kotlin/com/github/skydoves/colorpicker/compose/Configuration.kt4
-rw-r--r--docs/src/wasmJsMain/kotlin/docs/DocsApp.kt4
-rw-r--r--docs/src/wasmJsMain/kotlin/docs/navigation/DocsRoute.kt4
-rw-r--r--docs/src/wasmJsMain/kotlin/docs/screen/ApiAlphaSliderScreen.kt66
-rw-r--r--docs/src/wasmJsMain/kotlin/docs/screen/ApiAlphaTileScreen.kt5
-rw-r--r--docs/src/wasmJsMain/kotlin/docs/screen/ApiBrightnessSliderScreen.kt66
-rw-r--r--docs/src/wasmJsMain/kotlin/docs/screen/ApiHsvColorPickerScreen.kt76
-rw-r--r--docs/src/wasmJsMain/kotlin/docs/screen/ApiHueSliderScreen.kt277
-rw-r--r--docs/src/wasmJsMain/kotlin/docs/screen/ApiImageColorPickerScreen.kt40
-rw-r--r--docs/src/wasmJsMain/kotlin/docs/screen/ApiSaturationSliderScreen.kt278
11 files changed, 802 insertions, 28 deletions
diff --git a/README.md b/README.md
index 5b50437..e507957 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@
<p align="center">
🎨 Kotlin Multiplatform color picker library that allows you to get colors from any images like gallery pictures by tapping on the desired color.
-Also, it ships with alpha, brightness, hue, and saturation sliders to adjust ARGB and HSV factors, plus gesture lifecycle callbacks for fine-grained interaction handling.
+Also, it ships with alpha, brightness, hue, and saturation sliders that run horizontally or vertically to adjust ARGB and HSV factors, plus gesture lifecycle callbacks for fine-grained interaction handling.
</p>
## Preview
@@ -33,7 +33,7 @@ If you're using Version Catalog, you can configure the dependency by adding it t
```toml
[versions]
#...
-colorpicker = "1.2.0"
+colorpicker = "1.3.0"
[libraries]
#...
@@ -45,7 +45,7 @@ Add the dependency below to your **module**'s `build.gradle.kts` file:
```gradle
dependencies {
- implementation("com.github.skydoves:colorpicker-compose:1.2.0")
+ implementation("com.github.skydoves:colorpicker-compose:1.3.0")
// if you're using Version Catalog
implementation(libs.compose.colorpicker)
@@ -146,6 +146,10 @@ ImageColorPicker(
)
```
+`FIT` leaves bands beside the palette when the image and the canvas have different shapes, and an
+image can carry transparent pixels. Neither has a color to offer, so a tap there leaves the
+selection where it was instead of reporting the nearest edge pixel.
+
<img src="preview/preview2.gif" width="270" align="right">
### HsvColorPicker
diff --git a/buildSrc/src/main/kotlin/com/github/skydoves/colorpicker/compose/Configuration.kt b/buildSrc/src/main/kotlin/com/github/skydoves/colorpicker/compose/Configuration.kt
index 085e3c6..eb73a9c 100644
--- a/buildSrc/src/main/kotlin/com/github/skydoves/colorpicker/compose/Configuration.kt
+++ b/buildSrc/src/main/kotlin/com/github/skydoves/colorpicker/compose/Configuration.kt
@@ -6,10 +6,10 @@ object Configuration {
const val minSdk = 21
const val demoMinSdk = 24
const val majorVersion = 1
- const val minorVersion = 2
+ const val minorVersion = 3
const val patchVersion = 0
const val versionName = "$majorVersion.$minorVersion.$patchVersion"
- const val versionCode = 16
+ const val versionCode = 17
const val snapshotVersionName = "$majorVersion.$minorVersion.${patchVersion + 1}-SNAPSHOT"
const val artifactGroup = "com.github.skydoves"
}
diff --git a/docs/src/wasmJsMain/kotlin/docs/DocsApp.kt b/docs/src/wasmJsMain/kotlin/docs/DocsApp.kt
index 419b14a..9066866 100644
--- a/docs/src/wasmJsMain/kotlin/docs/DocsApp.kt
+++ b/docs/src/wasmJsMain/kotlin/docs/DocsApp.kt
@@ -33,7 +33,9 @@ import docs.screen.ApiAlphaTileScreen
import docs.screen.ApiBrightnessSliderScreen
import docs.screen.ApiControllerScreen
import docs.screen.ApiHsvColorPickerScreen
+import docs.screen.ApiHueSliderScreen
import docs.screen.ApiImageColorPickerScreen
+import docs.screen.ApiSaturationSliderScreen
import docs.screen.GettingStartedScreen
import docs.screen.HomeScreen
import docs.screen.InstallationScreen
@@ -70,6 +72,8 @@ fun DocsApp() {
DocsRoute.ApiImageColorPicker -> ApiImageColorPickerScreen()
DocsRoute.ApiAlphaSlider -> ApiAlphaSliderScreen()
DocsRoute.ApiBrightnessSlider -> ApiBrightnessSliderScreen()
+ DocsRoute.ApiHueSlider -> ApiHueSliderScreen()
+ DocsRoute.ApiSaturationSlider -> ApiSaturationSliderScreen()
DocsRoute.ApiAlphaTile -> ApiAlphaTileScreen()
DocsRoute.ApiController -> ApiControllerScreen()
DocsRoute.Playground -> PlaygroundScreen()
diff --git a/docs/src/wasmJsMain/kotlin/docs/navigation/DocsRoute.kt b/docs/src/wasmJsMain/kotlin/docs/navigation/DocsRoute.kt
index 3b342d9..dd71af1 100644
--- a/docs/src/wasmJsMain/kotlin/docs/navigation/DocsRoute.kt
+++ b/docs/src/wasmJsMain/kotlin/docs/navigation/DocsRoute.kt
@@ -24,6 +24,8 @@ sealed class DocsRoute(val path: String, val title: String) {
data object ApiImageColorPicker : DocsRoute("/api/image-color-picker", "ImageColorPicker")
data object ApiAlphaSlider : DocsRoute("/api/alpha-slider", "AlphaSlider")
data object ApiBrightnessSlider : DocsRoute("/api/brightness-slider", "BrightnessSlider")
+ data object ApiHueSlider : DocsRoute("/api/hue-slider", "HueSlider")
+ data object ApiSaturationSlider : DocsRoute("/api/saturation-slider", "SaturationSlider")
data object ApiAlphaTile : DocsRoute("/api/alpha-tile", "AlphaTile")
data object ApiController : DocsRoute("/api/controller", "ColorPickerController")
data object Playground : DocsRoute("/playground", "Playground")
@@ -35,6 +37,8 @@ sealed class DocsRoute(val path: String, val title: String) {
ApiImageColorPicker,
ApiAlphaSlider,
ApiBrightnessSlider,
+ ApiHueSlider,
+ ApiSaturationSlider,
ApiAlphaTile,
ApiController,
)
diff --git a/docs/src/wasmJsMain/kotlin/docs/screen/ApiAlphaSliderScreen.kt b/docs/src/wasmJsMain/kotlin/docs/screen/ApiAlphaSliderScreen.kt
index e0df00b..9b5ebf4 100644
--- a/docs/src/wasmJsMain/kotlin/docs/screen/ApiAlphaSliderScreen.kt
+++ b/docs/src/wasmJsMain/kotlin/docs/screen/ApiAlphaSliderScreen.kt
@@ -140,6 +140,72 @@ fun ApiAlphaSliderScreen() {
type = "Dp",
description = "Size of each tile in the transparency pattern",
)
+ ParameterItem(
+ name = "wheelAlpha",
+ type = "Float",
+ description = "Alpha applied to the wheel indicator",
+ )
+ ParameterItem(
+ name = "wheelPaint",
+ type = "Paint",
+ description = "Paint used to draw the wheel indicator",
+ )
+ ParameterItem(
+ name = "initialColor",
+ type = "Color?",
+ description = "Color the slider starts from, or the controller's current color when null",
+ )
+ ParameterItem(
+ name = "orientation",
+ type = "SliderOrientation",
+ description = "Horizontal by default, or Vertical to run bottom to top",
+ )
+ ParameterItem(
+ name = "onColorChanged",
+ type = "(ColorEnvelope) -> Unit",
+ description = "Invoked with the color the controller ends up on, so the slider " +
+ "works without a picker",
+ )
+ ParameterItem(
+ name = "onStart",
+ type = "() -> Unit",
+ description = "Invoked when the user starts interacting with the slider",
+ )
+ ParameterItem(
+ name = "onFinish",
+ type = "() -> Unit",
+ description = "Invoked when the user stops interacting with the slider",
+ )
+
+ Spacer(modifier = Modifier.height(32.dp))
+
+ // Orientation
+ Text(
+ text = "Orientation",
+ style = DocsTheme.typography.h2,
+ color = DocsTheme.colors.onBackground,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ Text(
+ text = "Sliders run left to right by default. Pass orientation to stand one up instead, " +
+ "and it fills the height it is given with the lowest value at the bottom.",
+ style = DocsTheme.typography.body,
+ color = DocsTheme.colors.onSurface,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ CodeBlock(
+ code = """AlphaSlider(
+ modifier = Modifier
+ .width(35.dp)
+ .height(300.dp),
+ controller = controller,
+ orientation = SliderOrientation.Vertical,
+)""",
+ )
Spacer(modifier = Modifier.height(32.dp))
diff --git a/docs/src/wasmJsMain/kotlin/docs/screen/ApiAlphaTileScreen.kt b/docs/src/wasmJsMain/kotlin/docs/screen/ApiAlphaTileScreen.kt
index 0ba4f59..be8edcd 100644
--- a/docs/src/wasmJsMain/kotlin/docs/screen/ApiAlphaTileScreen.kt
+++ b/docs/src/wasmJsMain/kotlin/docs/screen/ApiAlphaTileScreen.kt
@@ -94,6 +94,11 @@ fun ApiAlphaTileScreen() {
description = "Controller that provides the current color",
)
ParameterItem(
+ name = "selectedColor",
+ type = "Color",
+ description = "Color shown over the tiles when no controller is given",
+ )
+ ParameterItem(
name = "tileOddColor",
type = "Color",
description = "Color of odd tiles in the checkered pattern (default: White)",
diff --git a/docs/src/wasmJsMain/kotlin/docs/screen/ApiBrightnessSliderScreen.kt b/docs/src/wasmJsMain/kotlin/docs/screen/ApiBrightnessSliderScreen.kt
index be4a606..198a8d4 100644
--- a/docs/src/wasmJsMain/kotlin/docs/screen/ApiBrightnessSliderScreen.kt
+++ b/docs/src/wasmJsMain/kotlin/docs/screen/ApiBrightnessSliderScreen.kt
@@ -125,6 +125,72 @@ fun ApiBrightnessSliderScreen() {
type = "ImageBitmap?",
description = "Custom image for the wheel indicator",
)
+ ParameterItem(
+ name = "wheelAlpha",
+ type = "Float",
+ description = "Alpha applied to the wheel indicator",
+ )
+ ParameterItem(
+ name = "wheelPaint",
+ type = "Paint",
+ description = "Paint used to draw the wheel indicator",
+ )
+ ParameterItem(
+ name = "initialColor",
+ type = "Color?",
+ description = "Color the slider starts from, or the controller's current color when null",
+ )
+ ParameterItem(
+ name = "orientation",
+ type = "SliderOrientation",
+ description = "Horizontal by default, or Vertical to run bottom to top",
+ )
+ ParameterItem(
+ name = "onColorChanged",
+ type = "(ColorEnvelope) -> Unit",
+ description = "Invoked with the color the controller ends up on, so the slider " +
+ "works without a picker",
+ )
+ ParameterItem(
+ name = "onStart",
+ type = "() -> Unit",
+ description = "Invoked when the user starts interacting with the slider",
+ )
+ ParameterItem(
+ name = "onFinish",
+ type = "() -> Unit",
+ description = "Invoked when the user stops interacting with the slider",
+ )
+
+ Spacer(modifier = Modifier.height(32.dp))
+
+ // Orientation
+ Text(
+ text = "Orientation",
+ style = DocsTheme.typography.h2,
+ color = DocsTheme.colors.onBackground,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ Text(
+ text = "Sliders run left to right by default. Pass orientation to stand one up instead, " +
+ "and it fills the height it is given with the lowest value at the bottom.",
+ style = DocsTheme.typography.body,
+ color = DocsTheme.colors.onSurface,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ CodeBlock(
+ code = """BrightnessSlider(
+ modifier = Modifier
+ .width(35.dp)
+ .height(300.dp),
+ controller = controller,
+ orientation = SliderOrientation.Vertical,
+)""",
+ )
Spacer(modifier = Modifier.height(32.dp))
diff --git a/docs/src/wasmJsMain/kotlin/docs/screen/ApiHsvColorPickerScreen.kt b/docs/src/wasmJsMain/kotlin/docs/screen/ApiHsvColorPickerScreen.kt
index 4782975..007c1f9 100644
--- a/docs/src/wasmJsMain/kotlin/docs/screen/ApiHsvColorPickerScreen.kt
+++ b/docs/src/wasmJsMain/kotlin/docs/screen/ApiHsvColorPickerScreen.kt
@@ -101,33 +101,44 @@ fun ApiHsvColorPickerScreen() {
)
ParameterItem(
name = "initialColor",
- type = "Color",
- description = "Initial color to be selected (default: White)",
+ type = "Color?",
+ description = "Color selected on the first layout pass, or the center of the wheel when null",
)
ParameterItem(
- name = "wheelRadius",
- type = "Dp",
- description = "Radius of the selector wheel indicator",
+ name = "wheelImageBitmap",
+ type = "ImageBitmap?",
+ description = "Custom image drawn in place of the default indicator",
)
ParameterItem(
- name = "wheelColor",
- type = "Color",
- description = "Color of the wheel indicator",
+ name = "drawOnPosSelected",
+ type = "(DrawScope.() -> Unit)?",
+ description = "Draws anything you like at the selected position",
)
ParameterItem(
- name = "wheelAlpha",
- type = "Float",
- description = "Alpha value of the wheel indicator",
+ name = "drawDefaultWheelIndicator",
+ type = "Boolean",
+ description = "Whether to draw the built in indicator, off by default once you " +
+ "pass a wheel image or a draw block",
)
ParameterItem(
- name = "wheelImageBitmap",
- type = "ImageBitmap?",
- description = "Custom image for the wheel indicator",
+ name = "onColorChanged",
+ type = "(ColorEnvelope) -> Unit",
+ description = "Invoked for every step of a gesture",
)
ParameterItem(
- name = "onColorChanged",
+ name = "onColorPickingFinished",
type = "(ColorEnvelope) -> Unit",
- description = "Callback invoked when color changes",
+ description = "Invoked once when a tap lands or a drag ends",
+ )
+ ParameterItem(
+ name = "onStart",
+ type = "() -> Unit",
+ description = "Invoked when the user starts interacting with the picker",
+ )
+ ParameterItem(
+ name = "onFinish",
+ type = "() -> Unit",
+ description = "Invoked when the user stops interacting with the picker",
)
Spacer(modifier = Modifier.height(32.dp))
@@ -160,6 +171,39 @@ fun ApiHsvColorPickerScreen() {
Spacer(modifier = Modifier.height(32.dp))
+ Text(
+ text = "Knowing when a pick is finished",
+ style = DocsTheme.typography.h2,
+ color = DocsTheme.colors.onBackground,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ Text(
+ text = "onColorChanged fires for every step of a drag, which is more often than you want " +
+ "for saving a choice or logging one. onColorPickingFinished fires once, when the " +
+ "gesture is over.",
+ style = DocsTheme.typography.body,
+ color = DocsTheme.colors.onSurface,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ CodeBlock(
+ code = """HsvColorPicker(
+ modifier = Modifier.fillMaxWidth().height(450.dp),
+ controller = controller,
+ onColorChanged = { colorEnvelope: ColorEnvelope ->
+ preview(colorEnvelope.color) // every step of the drag
+ },
+ onColorPickingFinished = { colorEnvelope: ColorEnvelope ->
+ save(colorEnvelope.color) // once, when the finger lifts
+ },
+)""",
+ )
+
+ Spacer(modifier = Modifier.height(32.dp))
+
Callout(
text = "Note: HsvColorPicker draws its own palette, so setPaletteImageBitmap() on the " +
"controller and the paletteContentScale parameter are for ImageColorPicker only.",
diff --git a/docs/src/wasmJsMain/kotlin/docs/screen/ApiHueSliderScreen.kt b/docs/src/wasmJsMain/kotlin/docs/screen/ApiHueSliderScreen.kt
new file mode 100644
index 0000000..8ee52a1
--- /dev/null
+++ b/docs/src/wasmJsMain/kotlin/docs/screen/ApiHueSliderScreen.kt
@@ -0,0 +1,277 @@
+/*
+ * Designed and developed by 2022 skydoves (Jaewoong Eum)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package docs.screen
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import docs.component.CodeBlock
+import docs.theme.DocsTheme
+
+@Composable
+fun ApiHueSliderScreen() {
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .verticalScroll(rememberScrollState())
+ .padding(32.dp),
+ ) {
+ Text(
+ text = "HueSlider",
+ style = DocsTheme.typography.h1,
+ color = DocsTheme.colors.onBackground,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ Text(
+ text = "A slider component that allows users to adjust the hue component of the " +
+ "selected color. The slider displays the full hue wheel as a gradient, running " +
+ "red, yellow, green, cyan, blue, magenta, and back around to red, so every hue " +
+ "is reachable in a single drag.",
+ style = DocsTheme.typography.body,
+ color = DocsTheme.colors.onSurfaceVariant,
+ )
+
+ Spacer(modifier = Modifier.height(32.dp))
+
+ // Basic Usage
+ Text(
+ text = "Basic Usage",
+ style = DocsTheme.typography.h2,
+ color = DocsTheme.colors.onBackground,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ CodeBlock(
+ code = """HueSlider(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(10.dp)
+ .height(35.dp),
+ controller = controller,
+)""",
+ )
+
+ Spacer(modifier = Modifier.height(32.dp))
+
+ // Parameters
+ Text(
+ text = "Parameters",
+ style = DocsTheme.typography.h2,
+ color = DocsTheme.colors.onBackground,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ ParameterItem(
+ name = "modifier",
+ type = "Modifier",
+ description = "Modifier to be applied to the slider (default: Modifier)",
+ )
+ ParameterItem(
+ name = "controller",
+ type = "ColorPickerController",
+ description = "Controller that manages the color picker state (required)",
+ )
+ ParameterItem(
+ name = "borderRadius",
+ type = "Dp",
+ description = "Corner radius of the slider border (default: 6.dp)",
+ )
+ ParameterItem(
+ name = "borderSize",
+ type = "Dp",
+ description = "Thickness of the slider border (default: 5.dp)",
+ )
+ ParameterItem(
+ name = "borderColor",
+ type = "Color",
+ description = "Color of the slider border (default: Color.LightGray)",
+ )
+ ParameterItem(
+ name = "wheelImageBitmap",
+ type = "ImageBitmap?",
+ description = "Custom image drawn instead of the default circular wheel (default: null)",
+ )
+ ParameterItem(
+ name = "wheelRadius",
+ type = "Dp",
+ description = "Radius of the slider wheel indicator (default: 12.dp)",
+ )
+ ParameterItem(
+ name = "wheelColor",
+ type = "Color",
+ description = "Color of the wheel indicator (default: Color.White)",
+ )
+ ParameterItem(
+ name = "wheelAlpha",
+ type = "Float",
+ description = "Alpha value applied to the wheel indicator (default: 1.0f)",
+ )
+ ParameterItem(
+ name = "wheelPaint",
+ type = "Paint",
+ description = "Paint used to draw the wheel indicator " +
+ "(default: a Paint built from wheelColor and wheelAlpha)",
+ )
+ ParameterItem(
+ name = "initialColor",
+ type = "Color?",
+ description = "Color the slider starts on. When null, the slider follows the " +
+ "controller's current color (default: null)",
+ )
+ ParameterItem(
+ name = "orientation",
+ type = "SliderOrientation",
+ description = "Whether the slider runs left to right (Horizontal) or bottom to top " +
+ "(Vertical). A horizontal slider fills the width it is given, a vertical one fills " +
+ "the height (default: SliderOrientation.Horizontal)",
+ )
+ ParameterItem(
+ name = "onColorChanged",
+ type = "(ColorChangeSource, Float) -> Unit",
+ description = "Callback invoked when the hue changes. It receives the " +
+ "ColorChangeSource (Tap, Drag, or Programmatic) and the position along the slider " +
+ "as a Float in 0f..1f. That Float is a normalized position, NOT degrees, so " +
+ "multiply it by 360f when you need the hue angle (default: no-op)",
+ )
+ ParameterItem(
+ name = "onStart",
+ type = "() -> Unit",
+ description = "Callback invoked when user interaction with the slider starts " +
+ "(default: no-op)",
+ )
+ ParameterItem(
+ name = "onFinish",
+ type = "() -> Unit",
+ description = "Callback invoked when user interaction with the slider ends " +
+ "(default: no-op)",
+ )
+
+ Spacer(modifier = Modifier.height(32.dp))
+
+ // Customization
+ Text(
+ text = "Customization",
+ style = DocsTheme.typography.h2,
+ color = DocsTheme.colors.onBackground,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ Text(
+ text = "You can customize the appearance of the slider:",
+ style = DocsTheme.typography.body,
+ color = DocsTheme.colors.onSurface,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ CodeBlock(
+ code = """HueSlider(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(35.dp),
+ controller = controller,
+ borderRadius = 6.dp,
+ borderSize = 5.dp,
+ borderColor = Color.LightGray,
+ wheelRadius = 30.dp,
+ wheelColor = Color.White,
+ wheelAlpha = 1.0f,
+)""",
+ )
+
+ Spacer(modifier = Modifier.height(24.dp))
+
+ Text(
+ text = "Set orientation to SliderOrientation.Vertical to run the slider bottom to " +
+ "top instead. A vertical slider fills the height it is given, so give it a height " +
+ "and a width:",
+ style = DocsTheme.typography.body,
+ color = DocsTheme.colors.onSurface,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ CodeBlock(
+ code = """HueSlider(
+ modifier = Modifier
+ .height(250.dp)
+ .width(35.dp),
+ controller = controller,
+ orientation = SliderOrientation.Vertical,
+)""",
+ )
+
+ Spacer(modifier = Modifier.height(24.dp))
+
+ Text(
+ text = "Observe the hue while the user drags. The Float reports the position along " +
+ "the slider in 0f..1f, so convert it to degrees yourself if that is what you need:",
+ style = DocsTheme.typography.body,
+ color = DocsTheme.colors.onSurface,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ CodeBlock(
+ code = """HueSlider(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(35.dp),
+ controller = controller,
+ onColorChanged = { source: ColorChangeSource, position: Float ->
+ // position is 0f..1f along the slider, not degrees
+ val hueDegrees = position * 360f
+ },
+ onStart = { isDragging = true },
+ onFinish = { isDragging = false },
+)""",
+ )
+
+ Spacer(modifier = Modifier.height(32.dp))
+ }
+}
+
+@Composable
+private fun ParameterItem(name: String, type: String, description: String) {
+ Column(
+ modifier = Modifier.padding(vertical = 8.dp),
+ ) {
+ Text(
+ text = "$name: $type",
+ style = DocsTheme.typography.body,
+ color = DocsTheme.colors.primary,
+ )
+ Spacer(modifier = Modifier.height(4.dp))
+ Text(
+ text = description,
+ style = DocsTheme.typography.bodySmall,
+ color = DocsTheme.colors.onSurfaceVariant,
+ )
+ }
+}
diff --git a/docs/src/wasmJsMain/kotlin/docs/screen/ApiImageColorPickerScreen.kt b/docs/src/wasmJsMain/kotlin/docs/screen/ApiImageColorPickerScreen.kt
index 1b0123c..619c889 100644
--- a/docs/src/wasmJsMain/kotlin/docs/screen/ApiImageColorPickerScreen.kt
+++ b/docs/src/wasmJsMain/kotlin/docs/screen/ApiImageColorPickerScreen.kt
@@ -110,19 +110,45 @@ fun ApiImageColorPickerScreen() {
description = "How to scale the palette image (FIT or CROP)",
)
ParameterItem(
- name = "wheelRadius",
- type = "Dp",
- description = "Radius of the selector wheel indicator",
+ name = "wheelImageBitmap",
+ type = "ImageBitmap?",
+ description = "Custom image drawn in place of the default indicator",
)
ParameterItem(
- name = "wheelColor",
- type = "Color",
- description = "Color of the wheel indicator",
+ name = "drawOnPosSelected",
+ type = "(DrawScope.() -> Unit)?",
+ description = "Draws anything you like at the selected position",
+ )
+ ParameterItem(
+ name = "drawDefaultWheelIndicator",
+ type = "Boolean",
+ description = "Whether to draw the built in indicator, off by default once you " +
+ "pass a wheel image or a draw block",
+ )
+ ParameterItem(
+ name = "previewImagePainter",
+ type = "Painter?",
+ description = "Shown instead of the palette in an Android Studio preview",
)
ParameterItem(
name = "onColorChanged",
type = "(ColorEnvelope) -> Unit",
- description = "Callback invoked when color changes",
+ description = "Invoked for every step of a gesture",
+ )
+ ParameterItem(
+ name = "onColorPickingFinished",
+ type = "(ColorEnvelope) -> Unit",
+ description = "Invoked once when a tap lands or a drag ends",
+ )
+ ParameterItem(
+ name = "onStart",
+ type = "() -> Unit",
+ description = "Invoked when the user starts interacting with the picker",
+ )
+ ParameterItem(
+ name = "onFinish",
+ type = "() -> Unit",
+ description = "Invoked when the user stops interacting with the picker",
)
Spacer(modifier = Modifier.height(32.dp))
diff --git a/docs/src/wasmJsMain/kotlin/docs/screen/ApiSaturationSliderScreen.kt b/docs/src/wasmJsMain/kotlin/docs/screen/ApiSaturationSliderScreen.kt
new file mode 100644
index 0000000..38e7607
--- /dev/null
+++ b/docs/src/wasmJsMain/kotlin/docs/screen/ApiSaturationSliderScreen.kt
@@ -0,0 +1,278 @@
+/*
+ * Designed and developed by 2022 skydoves (Jaewoong Eum)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package docs.screen
+
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.rememberScrollState
+import androidx.compose.foundation.verticalScroll
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.unit.dp
+import docs.component.CodeBlock
+import docs.theme.DocsTheme
+
+@Composable
+fun ApiSaturationSliderScreen() {
+ Column(
+ modifier = Modifier
+ .fillMaxSize()
+ .verticalScroll(rememberScrollState())
+ .padding(32.dp),
+ ) {
+ Text(
+ text = "SaturationSlider",
+ style = DocsTheme.typography.h1,
+ color = DocsTheme.colors.onBackground,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ Text(
+ text = "A slider component that allows users to adjust the saturation component of " +
+ "the selected color. The slider displays a gradient of the currently selected hue, " +
+ "running from fully washed out on one end to fully saturated on the other. When a " +
+ "BrightnessSlider is attached to the same controller, the gradient is drawn at the " +
+ "current brightness as well.",
+ style = DocsTheme.typography.body,
+ color = DocsTheme.colors.onSurfaceVariant,
+ )
+
+ Spacer(modifier = Modifier.height(32.dp))
+
+ // Basic Usage
+ Text(
+ text = "Basic Usage",
+ style = DocsTheme.typography.h2,
+ color = DocsTheme.colors.onBackground,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ CodeBlock(
+ code = """SaturationSlider(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(10.dp)
+ .height(35.dp),
+ controller = controller,
+)""",
+ )
+
+ Spacer(modifier = Modifier.height(32.dp))
+
+ // Parameters
+ Text(
+ text = "Parameters",
+ style = DocsTheme.typography.h2,
+ color = DocsTheme.colors.onBackground,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ ParameterItem(
+ name = "modifier",
+ type = "Modifier",
+ description = "Modifier to be applied to the slider (default: Modifier)",
+ )
+ ParameterItem(
+ name = "controller",
+ type = "ColorPickerController",
+ description = "Controller that manages the color picker state (required)",
+ )
+ ParameterItem(
+ name = "borderRadius",
+ type = "Dp",
+ description = "Corner radius of the slider border (default: 6.dp)",
+ )
+ ParameterItem(
+ name = "borderSize",
+ type = "Dp",
+ description = "Thickness of the slider border (default: 5.dp)",
+ )
+ ParameterItem(
+ name = "borderColor",
+ type = "Color",
+ description = "Color of the slider border (default: Color.LightGray)",
+ )
+ ParameterItem(
+ name = "wheelImageBitmap",
+ type = "ImageBitmap?",
+ description = "Custom image drawn instead of the default circular wheel (default: null)",
+ )
+ ParameterItem(
+ name = "wheelRadius",
+ type = "Dp",
+ description = "Radius of the slider wheel indicator (default: 12.dp)",
+ )
+ ParameterItem(
+ name = "wheelColor",
+ type = "Color",
+ description = "Color of the wheel indicator (default: Color.White)",
+ )
+ ParameterItem(
+ name = "wheelAlpha",
+ type = "Float",
+ description = "Alpha value applied to the wheel indicator (default: 1.0f)",
+ )
+ ParameterItem(
+ name = "wheelPaint",
+ type = "Paint",
+ description = "Paint used to draw the wheel indicator " +
+ "(default: a Paint built from wheelColor and wheelAlpha)",
+ )
+ ParameterItem(
+ name = "initialColor",
+ type = "Color?",
+ description = "Color the slider starts on. When null, the slider follows the " +
+ "controller's current color (default: null)",
+ )
+ ParameterItem(
+ name = "orientation",
+ type = "SliderOrientation",
+ description = "Whether the slider runs left to right (Horizontal) or bottom to top " +
+ "(Vertical). A horizontal slider fills the width it is given, a vertical one fills " +
+ "the height (default: SliderOrientation.Horizontal)",
+ )
+ ParameterItem(
+ name = "onColorChanged",
+ type = "(ColorEnvelope) -> Unit",
+ description = "Callback invoked with the ColorEnvelope the controller ends up on, " +
+ "carrying the color, its hex code, whether the change came from the user, and the " +
+ "ColorChangeSource. This is what makes the slider usable on its own, without a " +
+ "picker beside it (default: no-op)",
+ )
+ ParameterItem(
+ name = "onStart",
+ type = "() -> Unit",
+ description = "Callback invoked when user interaction with the slider starts " +
+ "(default: no-op)",
+ )
+ ParameterItem(
+ name = "onFinish",
+ type = "() -> Unit",
+ description = "Callback invoked when user interaction with the slider ends " +
+ "(default: no-op)",
+ )
+
+ Spacer(modifier = Modifier.height(32.dp))
+
+ // Customization
+ Text(
+ text = "Customization",
+ style = DocsTheme.typography.h2,
+ color = DocsTheme.colors.onBackground,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ Text(
+ text = "You can customize the appearance of the slider:",
+ style = DocsTheme.typography.body,
+ color = DocsTheme.colors.onSurface,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ CodeBlock(
+ code = """SaturationSlider(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(35.dp),
+ controller = controller,
+ borderRadius = 6.dp,
+ borderSize = 5.dp,
+ borderColor = Color.LightGray,
+ wheelRadius = 30.dp,
+ wheelColor = Color.White,
+ wheelAlpha = 1.0f,
+)""",
+ )
+
+ Spacer(modifier = Modifier.height(24.dp))
+
+ Text(
+ text = "Set orientation to SliderOrientation.Vertical to run the slider bottom to " +
+ "top instead. A vertical slider fills the height it is given, so give it a height " +
+ "and a width:",
+ style = DocsTheme.typography.body,
+ color = DocsTheme.colors.onSurface,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ CodeBlock(
+ code = """SaturationSlider(
+ modifier = Modifier
+ .height(250.dp)
+ .width(35.dp),
+ controller = controller,
+ orientation = SliderOrientation.Vertical,
+)""",
+ )
+
+ Spacer(modifier = Modifier.height(24.dp))
+
+ Text(
+ text = "Because onColorChanged hands you a full ColorEnvelope, the slider can stand " +
+ "alone as the only color control on the screen:",
+ style = DocsTheme.typography.body,
+ color = DocsTheme.colors.onSurface,
+ )
+
+ Spacer(modifier = Modifier.height(16.dp))
+
+ CodeBlock(
+ code = """SaturationSlider(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(35.dp),
+ controller = controller,
+ onColorChanged = { colorEnvelope: ColorEnvelope ->
+ selectedColor = colorEnvelope.color
+ hexCode = colorEnvelope.hexCode
+ },
+ onStart = { isDragging = true },
+ onFinish = { isDragging = false },
+)""",
+ )
+
+ Spacer(modifier = Modifier.height(32.dp))
+ }
+}
+
+@Composable
+private fun ParameterItem(name: String, type: String, description: String) {
+ Column(
+ modifier = Modifier.padding(vertical = 8.dp),
+ ) {
+ Text(
+ text = "$name: $type",
+ style = DocsTheme.typography.body,
+ color = DocsTheme.colors.primary,
+ )
+ Spacer(modifier = Modifier.height(4.dp))
+ Text(
+ text = description,
+ style = DocsTheme.typography.bodySmall,
+ color = DocsTheme.colors.onSurfaceVariant,
+ )
+ }
+}