|  | @@ -4,15 +4,17 @@ import androidx.compose.foundation.BorderStroke
 | 
	
		
			
				|  |  |  import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
 | 
	
		
			
				|  |  |  import androidx.compose.foundation.layout.Box
 | 
	
		
			
				|  |  |  import androidx.compose.foundation.layout.PaddingValues
 | 
	
		
			
				|  |  | -import androidx.compose.foundation.layout.Row
 | 
	
		
			
				|  |  |  import androidx.compose.foundation.layout.height
 | 
	
		
			
				|  |  |  import androidx.compose.foundation.layout.size
 | 
	
		
			
				|  |  |  import androidx.compose.foundation.layout.width
 | 
	
		
			
				|  |  |  import androidx.compose.foundation.lazy.LazyItemScope
 | 
	
		
			
				|  |  |  import androidx.compose.foundation.lazy.LazyListItemInfo
 | 
	
		
			
				|  |  |  import androidx.compose.foundation.lazy.LazyListState
 | 
	
		
			
				|  |  | +import androidx.compose.foundation.lazy.itemsIndexed
 | 
	
		
			
				|  |  |  import androidx.compose.foundation.lazy.rememberLazyListState
 | 
	
		
			
				|  |  |  import androidx.compose.foundation.shape.RoundedCornerShape
 | 
	
		
			
				|  |  | +import androidx.compose.foundation.text.BasicTextField
 | 
	
		
			
				|  |  | +import androidx.compose.foundation.text.KeyboardOptions
 | 
	
		
			
				|  |  |  import androidx.compose.material3.MaterialTheme
 | 
	
		
			
				|  |  |  import androidx.compose.material3.Text
 | 
	
		
			
				|  |  |  import androidx.compose.runtime.Composable
 | 
	
	
		
			
				|  | @@ -20,81 +22,55 @@ import androidx.compose.runtime.LaunchedEffect
 | 
	
		
			
				|  |  |  import androidx.compose.runtime.getValue
 | 
	
		
			
				|  |  |  import androidx.compose.runtime.mutableStateOf
 | 
	
		
			
				|  |  |  import androidx.compose.runtime.remember
 | 
	
		
			
				|  |  | +import androidx.compose.runtime.rememberCoroutineScope
 | 
	
		
			
				|  |  |  import androidx.compose.runtime.setValue
 | 
	
		
			
				|  |  |  import androidx.compose.runtime.snapshotFlow
 | 
	
		
			
				|  |  |  import androidx.compose.ui.Alignment
 | 
	
		
			
				|  |  |  import androidx.compose.ui.Modifier
 | 
	
		
			
				|  |  |  import androidx.compose.ui.draw.alpha
 | 
	
		
			
				|  |  | +import androidx.compose.ui.graphics.SolidColor
 | 
	
		
			
				|  |  |  import androidx.compose.ui.hapticfeedback.HapticFeedbackType
 | 
	
		
			
				|  |  |  import androidx.compose.ui.platform.LocalHapticFeedback
 | 
	
		
			
				|  |  | +import androidx.compose.ui.text.TextRange
 | 
	
		
			
				|  |  | +import androidx.compose.ui.text.TextStyle
 | 
	
		
			
				|  |  | +import androidx.compose.ui.text.input.ImeAction
 | 
	
		
			
				|  |  | +import androidx.compose.ui.text.input.KeyboardType
 | 
	
		
			
				|  |  | +import androidx.compose.ui.text.input.TextFieldValue
 | 
	
		
			
				|  |  | +import androidx.compose.ui.text.style.TextAlign
 | 
	
		
			
				|  |  |  import androidx.compose.ui.unit.DpSize
 | 
	
		
			
				|  |  |  import androidx.compose.ui.unit.dp
 | 
	
		
			
				|  |  |  import kotlinx.coroutines.flow.collectLatest
 | 
	
		
			
				|  |  |  import kotlinx.coroutines.flow.distinctUntilChanged
 | 
	
		
			
				|  |  |  import kotlinx.coroutines.flow.drop
 | 
	
		
			
				|  |  |  import kotlinx.coroutines.flow.map
 | 
	
		
			
				|  |  | +import kotlinx.coroutines.launch
 | 
	
		
			
				|  |  |  import tachiyomi.presentation.core.components.material.padding
 | 
	
		
			
				|  |  | -import java.text.DateFormatSymbols
 | 
	
		
			
				|  |  | -import java.time.LocalDate
 | 
	
		
			
				|  |  | +import tachiyomi.presentation.core.util.clearFocusOnSoftKeyboardHide
 | 
	
		
			
				|  |  | +import tachiyomi.presentation.core.util.clickableNoIndication
 | 
	
		
			
				|  |  | +import tachiyomi.presentation.core.util.showSoftKeyboard
 | 
	
		
			
				|  |  |  import kotlin.math.absoluteValue
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  @Composable
 | 
	
		
			
				|  |  | -fun WheelPicker(
 | 
	
		
			
				|  |  | +fun WheelNumberPicker(
 | 
	
		
			
				|  |  |      modifier: Modifier = Modifier,
 | 
	
		
			
				|  |  |      startIndex: Int = 0,
 | 
	
		
			
				|  |  | -    count: Int,
 | 
	
		
			
				|  |  | +    items: List<Number>,
 | 
	
		
			
				|  |  |      size: DpSize = DpSize(128.dp, 128.dp),
 | 
	
		
			
				|  |  |      onSelectionChanged: (index: Int) -> Unit = {},
 | 
	
		
			
				|  |  |      backgroundContent: (@Composable (size: DpSize) -> Unit)? = {
 | 
	
		
			
				|  |  |          WheelPickerDefaults.Background(size = it)
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    itemContent: @Composable LazyItemScope.(index: Int) -> Unit,
 | 
	
		
			
				|  |  |  ) {
 | 
	
		
			
				|  |  | -    val lazyListState = rememberLazyListState(startIndex)
 | 
	
		
			
				|  |  | -    val haptic = LocalHapticFeedback.current
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    LaunchedEffect(lazyListState, onSelectionChanged) {
 | 
	
		
			
				|  |  | -        snapshotFlow { lazyListState.firstVisibleItemScrollOffset }
 | 
	
		
			
				|  |  | -            .map { calculateSnappedItemIndex(lazyListState) }
 | 
	
		
			
				|  |  | -            .distinctUntilChanged()
 | 
	
		
			
				|  |  | -            .drop(1)
 | 
	
		
			
				|  |  | -            .collectLatest {
 | 
	
		
			
				|  |  | -                haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove)
 | 
	
		
			
				|  |  | -                onSelectionChanged(it)
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -    Box(
 | 
	
		
			
				|  |  | +    WheelPicker(
 | 
	
		
			
				|  |  |          modifier = modifier,
 | 
	
		
			
				|  |  | -        contentAlignment = Alignment.Center,
 | 
	
		
			
				|  |  | +        startIndex = startIndex,
 | 
	
		
			
				|  |  | +        items = items,
 | 
	
		
			
				|  |  | +        size = size,
 | 
	
		
			
				|  |  | +        onSelectionChanged = onSelectionChanged,
 | 
	
		
			
				|  |  | +        manualInputType = KeyboardType.Number,
 | 
	
		
			
				|  |  | +        backgroundContent = backgroundContent,
 | 
	
		
			
				|  |  |      ) {
 | 
	
		
			
				|  |  | -        backgroundContent?.invoke(size)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        LazyColumn(
 | 
	
		
			
				|  |  | -            modifier = Modifier
 | 
	
		
			
				|  |  | -                .height(size.height)
 | 
	
		
			
				|  |  | -                .width(size.width),
 | 
	
		
			
				|  |  | -            state = lazyListState,
 | 
	
		
			
				|  |  | -            contentPadding = PaddingValues(vertical = size.height / RowCount * ((RowCount - 1) / 2)),
 | 
	
		
			
				|  |  | -            flingBehavior = rememberSnapFlingBehavior(lazyListState = lazyListState),
 | 
	
		
			
				|  |  | -        ) {
 | 
	
		
			
				|  |  | -            items(count) { index ->
 | 
	
		
			
				|  |  | -                Box(
 | 
	
		
			
				|  |  | -                    modifier = Modifier
 | 
	
		
			
				|  |  | -                        .height(size.height / RowCount)
 | 
	
		
			
				|  |  | -                        .width(size.width)
 | 
	
		
			
				|  |  | -                        .alpha(
 | 
	
		
			
				|  |  | -                            calculateAnimatedAlpha(
 | 
	
		
			
				|  |  | -                                lazyListState = lazyListState,
 | 
	
		
			
				|  |  | -                                index = index,
 | 
	
		
			
				|  |  | -                            ),
 | 
	
		
			
				|  |  | -                        ),
 | 
	
		
			
				|  |  | -                    contentAlignment = Alignment.Center,
 | 
	
		
			
				|  |  | -                ) {
 | 
	
		
			
				|  |  | -                    itemContent(index)
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +        WheelPickerDefaults.Item(text = "$it")
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -102,7 +78,7 @@ fun WheelPicker(
 | 
	
		
			
				|  |  |  fun WheelTextPicker(
 | 
	
		
			
				|  |  |      modifier: Modifier = Modifier,
 | 
	
		
			
				|  |  |      startIndex: Int = 0,
 | 
	
		
			
				|  |  | -    texts: List<String>,
 | 
	
		
			
				|  |  | +    items: List<String>,
 | 
	
		
			
				|  |  |      size: DpSize = DpSize(128.dp, 128.dp),
 | 
	
		
			
				|  |  |      onSelectionChanged: (index: Int) -> Unit = {},
 | 
	
		
			
				|  |  |      backgroundContent: (@Composable (size: DpSize) -> Unit)? = {
 | 
	
	
		
			
				|  | @@ -112,122 +88,126 @@ fun WheelTextPicker(
 | 
	
		
			
				|  |  |      WheelPicker(
 | 
	
		
			
				|  |  |          modifier = modifier,
 | 
	
		
			
				|  |  |          startIndex = startIndex,
 | 
	
		
			
				|  |  | -        count = remember(texts) { texts.size },
 | 
	
		
			
				|  |  | +        items = items,
 | 
	
		
			
				|  |  |          size = size,
 | 
	
		
			
				|  |  |          onSelectionChanged = onSelectionChanged,
 | 
	
		
			
				|  |  |          backgroundContent = backgroundContent,
 | 
	
		
			
				|  |  |      ) {
 | 
	
		
			
				|  |  | -        WheelPickerDefaults.Item(text = texts[it])
 | 
	
		
			
				|  |  | +        WheelPickerDefaults.Item(text = it)
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  @Composable
 | 
	
		
			
				|  |  | -fun WheelDatePicker(
 | 
	
		
			
				|  |  | +private fun <T> WheelPicker(
 | 
	
		
			
				|  |  |      modifier: Modifier = Modifier,
 | 
	
		
			
				|  |  | -    startDate: LocalDate = LocalDate.now(),
 | 
	
		
			
				|  |  | -    minDate: LocalDate? = null,
 | 
	
		
			
				|  |  | -    maxDate: LocalDate? = null,
 | 
	
		
			
				|  |  | -    size: DpSize = DpSize(256.dp, 128.dp),
 | 
	
		
			
				|  |  | +    startIndex: Int = 0,
 | 
	
		
			
				|  |  | +    items: List<T>,
 | 
	
		
			
				|  |  | +    size: DpSize = DpSize(128.dp, 128.dp),
 | 
	
		
			
				|  |  | +    onSelectionChanged: (index: Int) -> Unit = {},
 | 
	
		
			
				|  |  | +    manualInputType: KeyboardType? = null,
 | 
	
		
			
				|  |  |      backgroundContent: (@Composable (size: DpSize) -> Unit)? = {
 | 
	
		
			
				|  |  |          WheelPickerDefaults.Background(size = it)
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    onSelectionChanged: (date: LocalDate) -> Unit = {},
 | 
	
		
			
				|  |  | +    itemContent: @Composable LazyItemScope.(item: T) -> Unit,
 | 
	
		
			
				|  |  |  ) {
 | 
	
		
			
				|  |  | -    var internalSelection by remember { mutableStateOf(startDate) }
 | 
	
		
			
				|  |  | -    val internalOnSelectionChange: (LocalDate) -> Unit = {
 | 
	
		
			
				|  |  | -        internalSelection = it
 | 
	
		
			
				|  |  | -        onSelectionChanged(internalSelection)
 | 
	
		
			
				|  |  | +    val haptic = LocalHapticFeedback.current
 | 
	
		
			
				|  |  | +    val lazyListState = rememberLazyListState(startIndex)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    var internalIndex by remember { mutableStateOf(startIndex) }
 | 
	
		
			
				|  |  | +    val internalOnSelectionChanged: (Int) -> Unit = {
 | 
	
		
			
				|  |  | +        internalIndex = it
 | 
	
		
			
				|  |  | +        onSelectionChanged(it)
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    Box(modifier = modifier, contentAlignment = Alignment.Center) {
 | 
	
		
			
				|  |  | +    LaunchedEffect(lazyListState, onSelectionChanged) {
 | 
	
		
			
				|  |  | +        snapshotFlow { lazyListState.firstVisibleItemScrollOffset }
 | 
	
		
			
				|  |  | +            .map { calculateSnappedItemIndex(lazyListState) }
 | 
	
		
			
				|  |  | +            .distinctUntilChanged()
 | 
	
		
			
				|  |  | +            .drop(1)
 | 
	
		
			
				|  |  | +            .collectLatest {
 | 
	
		
			
				|  |  | +                haptic.performHapticFeedback(HapticFeedbackType.TextHandleMove)
 | 
	
		
			
				|  |  | +                internalOnSelectionChanged(it)
 | 
	
		
			
				|  |  | +            }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    Box(
 | 
	
		
			
				|  |  | +        modifier = modifier
 | 
	
		
			
				|  |  | +            .height(size.height)
 | 
	
		
			
				|  |  | +            .width(size.width),
 | 
	
		
			
				|  |  | +        contentAlignment = Alignment.Center,
 | 
	
		
			
				|  |  | +    ) {
 | 
	
		
			
				|  |  |          backgroundContent?.invoke(size)
 | 
	
		
			
				|  |  | -        Row {
 | 
	
		
			
				|  |  | -            val singularPickerSize = DpSize(
 | 
	
		
			
				|  |  | -                width = size.width / 3,
 | 
	
		
			
				|  |  | -                height = size.height,
 | 
	
		
			
				|  |  | -            )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            // Day
 | 
	
		
			
				|  |  | -            val dayOfMonths = remember(internalSelection, minDate, maxDate) {
 | 
	
		
			
				|  |  | -                if (minDate == null && maxDate == null) {
 | 
	
		
			
				|  |  | -                    1..internalSelection.lengthOfMonth()
 | 
	
		
			
				|  |  | -                } else {
 | 
	
		
			
				|  |  | -                    val minDay = if (minDate?.month == internalSelection.month &&
 | 
	
		
			
				|  |  | -                        minDate?.year == internalSelection.year
 | 
	
		
			
				|  |  | -                    ) {
 | 
	
		
			
				|  |  | -                        minDate.dayOfMonth
 | 
	
		
			
				|  |  | -                    } else {
 | 
	
		
			
				|  |  | -                        1
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                    val maxDay = if (maxDate?.month == internalSelection.month &&
 | 
	
		
			
				|  |  | -                        maxDate?.year == internalSelection.year
 | 
	
		
			
				|  |  | -                    ) {
 | 
	
		
			
				|  |  | -                        maxDate.dayOfMonth
 | 
	
		
			
				|  |  | -                    } else {
 | 
	
		
			
				|  |  | -                        31
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                    minDay..maxDay.coerceAtMost(internalSelection.lengthOfMonth())
 | 
	
		
			
				|  |  | -                }.toList()
 | 
	
		
			
				|  |  | +        var showManualInput by remember { mutableStateOf(false) }
 | 
	
		
			
				|  |  | +        if (showManualInput) {
 | 
	
		
			
				|  |  | +            var value by remember {
 | 
	
		
			
				|  |  | +                val currentString = items[internalIndex].toString()
 | 
	
		
			
				|  |  | +                mutableStateOf(TextFieldValue(text = currentString, selection = TextRange(currentString.length)))
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            WheelTextPicker(
 | 
	
		
			
				|  |  | -                size = singularPickerSize,
 | 
	
		
			
				|  |  | -                texts = dayOfMonths.map { it.toString() },
 | 
	
		
			
				|  |  | -                backgroundContent = null,
 | 
	
		
			
				|  |  | -                startIndex = dayOfMonths.indexOfFirst { it == startDate.dayOfMonth }.coerceAtLeast(0),
 | 
	
		
			
				|  |  | -                onSelectionChanged = { index ->
 | 
	
		
			
				|  |  | -                    val newDayOfMonth = dayOfMonths[index]
 | 
	
		
			
				|  |  | -                    internalOnSelectionChange(internalSelection.withDayOfMonth(newDayOfMonth))
 | 
	
		
			
				|  |  | -                },
 | 
	
		
			
				|  |  | -            )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -            // Month
 | 
	
		
			
				|  |  | -            val months = remember(internalSelection, minDate, maxDate) {
 | 
	
		
			
				|  |  | -                val monthRange = if (minDate == null && maxDate == null) {
 | 
	
		
			
				|  |  | -                    1..12
 | 
	
		
			
				|  |  | -                } else {
 | 
	
		
			
				|  |  | -                    val minMonth = if (minDate?.year == internalSelection.year) {
 | 
	
		
			
				|  |  | -                        minDate.monthValue
 | 
	
		
			
				|  |  | -                    } else {
 | 
	
		
			
				|  |  | -                        1
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                    val maxMonth = if (maxDate?.year == internalSelection.year) {
 | 
	
		
			
				|  |  | -                        maxDate.monthValue
 | 
	
		
			
				|  |  | -                    } else {
 | 
	
		
			
				|  |  | -                        12
 | 
	
		
			
				|  |  | +            val scope = rememberCoroutineScope()
 | 
	
		
			
				|  |  | +            BasicTextField(
 | 
	
		
			
				|  |  | +                modifier = Modifier
 | 
	
		
			
				|  |  | +                    .align(Alignment.Center)
 | 
	
		
			
				|  |  | +                    .showSoftKeyboard(true)
 | 
	
		
			
				|  |  | +                    .clearFocusOnSoftKeyboardHide {
 | 
	
		
			
				|  |  | +                        scope.launch {
 | 
	
		
			
				|  |  | +                            items
 | 
	
		
			
				|  |  | +                                .indexOfFirst { it.toString() == value.text }
 | 
	
		
			
				|  |  | +                                .takeIf { it >= 0 }
 | 
	
		
			
				|  |  | +                                ?.apply {
 | 
	
		
			
				|  |  | +                                    internalOnSelectionChanged(this)
 | 
	
		
			
				|  |  | +                                    lazyListState.scrollToItem(this)
 | 
	
		
			
				|  |  | +                                }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +                            showManualInput = false
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    },
 | 
	
		
			
				|  |  | +                value = value,
 | 
	
		
			
				|  |  | +                onValueChange = { value = it },
 | 
	
		
			
				|  |  | +                singleLine = true,
 | 
	
		
			
				|  |  | +                keyboardOptions = KeyboardOptions(
 | 
	
		
			
				|  |  | +                    keyboardType = manualInputType!!,
 | 
	
		
			
				|  |  | +                    imeAction = ImeAction.Done,
 | 
	
		
			
				|  |  | +                ),
 | 
	
		
			
				|  |  | +                textStyle = MaterialTheme.typography.titleMedium +
 | 
	
		
			
				|  |  | +                    TextStyle(
 | 
	
		
			
				|  |  | +                        color = MaterialTheme.colorScheme.onSurface,
 | 
	
		
			
				|  |  | +                        textAlign = TextAlign.Center,
 | 
	
		
			
				|  |  | +                    ),
 | 
	
		
			
				|  |  | +                cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
 | 
	
		
			
				|  |  | +            )
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +            LazyColumn(
 | 
	
		
			
				|  |  | +                modifier = Modifier
 | 
	
		
			
				|  |  | +                    .let {
 | 
	
		
			
				|  |  | +                        if (manualInputType != null) {
 | 
	
		
			
				|  |  | +                            it.clickableNoIndication { showManualInput = true }
 | 
	
		
			
				|  |  | +                        } else {
 | 
	
		
			
				|  |  | +                            it
 | 
	
		
			
				|  |  | +                        }
 | 
	
		
			
				|  |  | +                    },
 | 
	
		
			
				|  |  | +                state = lazyListState,
 | 
	
		
			
				|  |  | +                contentPadding = PaddingValues(vertical = size.height / RowCount * ((RowCount - 1) / 2)),
 | 
	
		
			
				|  |  | +                flingBehavior = rememberSnapFlingBehavior(lazyListState = lazyListState),
 | 
	
		
			
				|  |  | +            ) {
 | 
	
		
			
				|  |  | +                itemsIndexed(items) { index, item ->
 | 
	
		
			
				|  |  | +                    Box(
 | 
	
		
			
				|  |  | +                        modifier = Modifier
 | 
	
		
			
				|  |  | +                            .height(size.height / RowCount)
 | 
	
		
			
				|  |  | +                            .width(size.width)
 | 
	
		
			
				|  |  | +                            .alpha(
 | 
	
		
			
				|  |  | +                                calculateAnimatedAlpha(
 | 
	
		
			
				|  |  | +                                    lazyListState = lazyListState,
 | 
	
		
			
				|  |  | +                                    index = index,
 | 
	
		
			
				|  |  | +                                ),
 | 
	
		
			
				|  |  | +                            ),
 | 
	
		
			
				|  |  | +                        contentAlignment = Alignment.Center,
 | 
	
		
			
				|  |  | +                    ) {
 | 
	
		
			
				|  |  | +                        itemContent(item)
 | 
	
		
			
				|  |  |                      }
 | 
	
		
			
				|  |  | -                    minMonth..maxMonth
 | 
	
		
			
				|  |  |                  }
 | 
	
		
			
				|  |  | -                val dateFormatSymbols = DateFormatSymbols()
 | 
	
		
			
				|  |  | -                monthRange.map { it to dateFormatSymbols.months[it - 1] }
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            WheelTextPicker(
 | 
	
		
			
				|  |  | -                size = singularPickerSize,
 | 
	
		
			
				|  |  | -                texts = months.map { it.second },
 | 
	
		
			
				|  |  | -                backgroundContent = null,
 | 
	
		
			
				|  |  | -                startIndex = months.indexOfFirst { it.first == startDate.monthValue }.coerceAtLeast(0),
 | 
	
		
			
				|  |  | -                onSelectionChanged = { index ->
 | 
	
		
			
				|  |  | -                    val newMonth = months[index].first
 | 
	
		
			
				|  |  | -                    internalOnSelectionChange(internalSelection.withMonth(newMonth))
 | 
	
		
			
				|  |  | -                },
 | 
	
		
			
				|  |  | -            )
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            // Year
 | 
	
		
			
				|  |  | -            val years = remember(minDate, maxDate) {
 | 
	
		
			
				|  |  | -                val minYear = minDate?.year?.coerceAtLeast(1900) ?: 1900
 | 
	
		
			
				|  |  | -                val maxYear = maxDate?.year?.coerceAtMost(2100) ?: 2100
 | 
	
		
			
				|  |  | -                val yearRange = minYear..maxYear
 | 
	
		
			
				|  |  | -                yearRange.toList()
 | 
	
		
			
				|  |  | -            }
 | 
	
		
			
				|  |  | -            WheelTextPicker(
 | 
	
		
			
				|  |  | -                size = singularPickerSize,
 | 
	
		
			
				|  |  | -                texts = years.map { it.toString() },
 | 
	
		
			
				|  |  | -                backgroundContent = null,
 | 
	
		
			
				|  |  | -                startIndex = years.indexOfFirst { it == startDate.year }.coerceAtLeast(0),
 | 
	
		
			
				|  |  | -                onSelectionChanged = { index ->
 | 
	
		
			
				|  |  | -                    val newYear = years[index]
 | 
	
		
			
				|  |  | -                    internalOnSelectionChange(internalSelection.withYear(newYear))
 | 
	
		
			
				|  |  | -                },
 | 
	
		
			
				|  |  | -            )
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |  }
 |