|
| 1 | +# RangeSliderPreference |
| 2 | + |
| 3 | +`RangeSliderPreference` is a preference component in Miuix that combines a title/summary with a range slider control. The range slider is placed in the bottom action area of the `BasicComponent`, making it ideal for settings screens where users need to select a range of values such as price filters, frequency bands, or dual-threshold controls. |
| 4 | + |
| 5 | +## Import |
| 6 | + |
| 7 | +```kotlin |
| 8 | +import top.yukonga.miuix.kmp.preference.RangeSliderPreference |
| 9 | +``` |
| 10 | + |
| 11 | +## Basic Usage |
| 12 | + |
| 13 | +```kotlin |
| 14 | +var rangeValue by remember { mutableStateOf(0.2f..0.8f) } |
| 15 | + |
| 16 | +RangeSliderPreference( |
| 17 | + value = rangeValue, |
| 18 | + onValueChange = { rangeValue = it }, |
| 19 | + title = "Range Selection" |
| 20 | +) |
| 21 | +``` |
| 22 | + |
| 23 | +## With Summary |
| 24 | + |
| 25 | +```kotlin |
| 26 | +var priceRange by remember { mutableStateOf(100f..500f) } |
| 27 | + |
| 28 | +RangeSliderPreference( |
| 29 | + value = priceRange, |
| 30 | + onValueChange = { priceRange = it }, |
| 31 | + title = "Price Range", |
| 32 | + summary = "$${priceRange.start.roundToInt()} - $${priceRange.endInclusive.roundToInt()}", |
| 33 | + valueRange = 0f..1000f |
| 34 | +) |
| 35 | +``` |
| 36 | + |
| 37 | +## Component States |
| 38 | + |
| 39 | +### Disabled State |
| 40 | + |
| 41 | +```kotlin |
| 42 | +var rangeValue by remember { mutableStateOf(0.3f..0.7f) } |
| 43 | + |
| 44 | +RangeSliderPreference( |
| 45 | + value = rangeValue, |
| 46 | + onValueChange = { rangeValue = it }, |
| 47 | + title = "Disabled Range", |
| 48 | + summary = "This range slider is currently unavailable", |
| 49 | + enabled = false |
| 50 | +) |
| 51 | +``` |
| 52 | + |
| 53 | +## Properties |
| 54 | + |
| 55 | +### RangeSliderPreference Properties |
| 56 | + |
| 57 | +| Property Name | Type | Description | Default Value | Required | |
| 58 | +| --------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------- | -------- | |
| 59 | +| value | ClosedFloatingPointRange\<Float\> | Current values of the range slider. If either value is outside of valueRange, it will be coerced | - | Yes | |
| 60 | +| onValueChange | (ClosedFloatingPointRange\<Float\>) -> Unit | Lambda in which values should be updated | - | Yes | |
| 61 | +| title | String? | Title of the preference | null | No | |
| 62 | +| modifier | Modifier | Modifier applied to the component | Modifier | No | |
| 63 | +| titleColor | BasicComponentColors | Title text color configuration | BasicComponentDefaults.titleColor() | No | |
| 64 | +| summary | String? | Summary description | null | No | |
| 65 | +| summaryColor | BasicComponentColors | Summary text color configuration | BasicComponentDefaults.summaryColor() | No | |
| 66 | +| startAction | @Composable (() -> Unit)? | Custom start side content | null | No | |
| 67 | +| valueText | String? | Current slider value text displayed in the end area with summary-style formatting. Rendered inside the Row layout with center-vertical alignment and weight | null | No | |
| 68 | +| endActions | @Composable (RowScope.() -> Unit)? | Custom end side content, rendered after valueText within the same Row | null | No | |
| 69 | +| bottomAction | @Composable (() -> Unit)? | Custom content at the top of the bottom area, above the range slider | null | No | |
| 70 | +| onClick | (() -> Unit)? | Callback triggered on click. When non-null, an arrow icon is displayed in the end area | null | No | |
| 71 | +| holdDownState | Boolean | Whether the component is in the pressed state | false | No | |
| 72 | +| enabled | Boolean | Whether the preference is enabled | true | No | |
| 73 | +| valueRange | ClosedFloatingPointRange\<Float\> | Range of values that range slider values can take. Passed value will be coerced to this range | 0f..1f | No | |
| 74 | +| steps | Int | Amount of discrete allowable values. If 0, the slider will behave continuously. Must not be negative | 0 | No | |
| 75 | +| onValueChangeFinished | (() -> Unit)? | Called when value change has ended | null | No | |
| 76 | +| sliderHeight | Dp | Height of the range slider | SliderDefaults.MinHeight | No | |
| 77 | +| sliderColors | SliderColors | Color configuration of the range slider | SliderDefaults.sliderColors() | No | |
| 78 | +| hapticEffect | SliderDefaults.SliderHapticEffect | Type of haptic feedback | SliderDefaults.DefaultHapticEffect | No | |
| 79 | +| showKeyPoints | Boolean | Whether to show key point indicators on the slider. Only works when keyPoints is not null | false | No | |
| 80 | +| keyPoints | List\<Float\>? | Custom key point values to display on the slider. If null, uses step positions from steps parameter. Values should be within valueRange | null | No | |
| 81 | +| magnetThreshold | Float | Magnetic snap threshold as a fraction (0.0 to 1.0). When slider value is within this distance from a key point, it will snap to that point. Only applies when keyPoints is set | 0.02f | No | |
| 82 | +| insideMargin | PaddingValues | Internal content padding | BasicComponentDefaults.InsideMargin | No | |
| 83 | + |
| 84 | +## Advanced Usage |
| 85 | + |
| 86 | +### Price Range Filter |
| 87 | + |
| 88 | +```kotlin |
| 89 | +var priceRange by remember { mutableStateOf(100f..500f) } |
| 90 | + |
| 91 | +RangeSliderPreference( |
| 92 | + value = priceRange, |
| 93 | + onValueChange = { priceRange = it }, |
| 94 | + title = "Price Filter", |
| 95 | + summary = "$${priceRange.start.roundToInt()} - $${priceRange.endInclusive.roundToInt()}", |
| 96 | + valueRange = 0f..1000f, |
| 97 | + steps = 99 |
| 98 | +) |
| 99 | +``` |
| 100 | + |
| 101 | +### With Start Icon |
| 102 | + |
| 103 | +```kotlin |
| 104 | +var frequencyRange by remember { mutableStateOf(20f..20000f) } |
| 105 | + |
| 106 | +RangeSliderPreference( |
| 107 | + value = frequencyRange, |
| 108 | + onValueChange = { frequencyRange = it }, |
| 109 | + title = "Frequency Range", |
| 110 | + summary = "${frequencyRange.start.roundToInt()}Hz - ${frequencyRange.endInclusive.roundToInt()}Hz", |
| 111 | + startAction = { |
| 112 | + Icon( |
| 113 | + imageVector = MiuixIcons.Basic.Audio, |
| 114 | + contentDescription = "Frequency Icon", |
| 115 | + tint = MiuixTheme.colorScheme.onBackground, |
| 116 | + modifier = Modifier.padding(end = 16.dp) |
| 117 | + ) |
| 118 | + }, |
| 119 | + valueRange = 20f..20000f, |
| 120 | + showKeyPoints = true, |
| 121 | + keyPoints = listOf(20f, 100f, 1000f, 5000f, 10000f, 20000f) |
| 122 | +) |
| 123 | +``` |
| 124 | + |
| 125 | +### With Custom Key Points |
| 126 | + |
| 127 | +```kotlin |
| 128 | +var range by remember { mutableStateOf(20f..80f) } |
| 129 | + |
| 130 | +RangeSliderPreference( |
| 131 | + value = range, |
| 132 | + onValueChange = { range = it }, |
| 133 | + title = "Custom Range", |
| 134 | + summary = "${range.start.roundToInt()}% - ${range.endInclusive.roundToInt()}%", |
| 135 | + valueRange = 0f..100f, |
| 136 | + showKeyPoints = true, |
| 137 | + keyPoints = listOf(0f, 20f, 40f, 60f, 80f, 100f), |
| 138 | + magnetThreshold = 0.03f |
| 139 | +) |
| 140 | +``` |
0 commit comments