All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.com.kizitonwose.calendar.compose.CalendarDefaults.kt Maven / Gradle / Ivy

Go to download

A highly customizable calendar library for Compose Multiplatform, backed by LazyRow/LazyColumn.

There is a newer version: 2.6.0-beta01
Show newest version
package com.kizitonwose.calendar.compose

import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.FlingBehavior
import androidx.compose.foundation.gestures.ScrollableDefaults
import androidx.compose.foundation.gestures.snapping.SnapLayoutInfoProvider
import androidx.compose.foundation.gestures.snapping.SnapPositionInLayout
import androidx.compose.foundation.gestures.snapping.rememberSnapFlingBehavior
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember

internal object CalendarDefaults {
    /**
     * The default implementation in [rememberSnapFlingBehavior] snaps to the center of the layout
     * but we want to snap to the start. For example, in a vertical calendar, when the layout size
     * is larger than the item size(e.g two or more visible months), we don't want the item's
     * center to be at the center of the layout when it snaps, instead we want the item's top
     * to be at the top of the layout.
     */
    @OptIn(ExperimentalFoundationApi::class)
    @Composable
    private fun pagedFlingBehavior(state: LazyListState): FlingBehavior {
        val snappingLayout = remember(state) {
            val provider = SnapLayoutInfoProvider(state, CalendarSnapPositionInLayout())
            CalendarSnapLayoutInfoProvider(provider)
        }
        return rememberSnapFlingBehavior(snappingLayout)
    }

    @Composable
    private fun continuousFlingBehavior(): FlingBehavior = ScrollableDefaults.flingBehavior()

    @Composable
    fun flingBehavior(isPaged: Boolean, state: LazyListState): FlingBehavior {
        return if (isPaged) pagedFlingBehavior(state) else continuousFlingBehavior()
    }
}

@ExperimentalFoundationApi
@Suppress("FunctionName")
private fun CalendarSnapLayoutInfoProvider(
    snapLayoutInfoProvider: SnapLayoutInfoProvider,
): SnapLayoutInfoProvider = object : SnapLayoutInfoProvider by snapLayoutInfoProvider {
    /**
     * In compose 1.3, the default was single page snapping (zero), but this changed
     * in compose 1.4 to decayed page snapping which is not great for calendar usage.
     */
    override fun calculateApproachOffset(initialVelocity: Float): Float = 0f
}

@OptIn(ExperimentalFoundationApi::class)
@Suppress("FunctionName")
private fun CalendarSnapPositionInLayout() = SnapPositionInLayout { _, _, _, _, _ -> 0 }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy