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

commonMain.io.github.lyxnx.compose.pine.Switch.kt Maven / Gradle / Ivy

package io.github.lyxnx.compose.pine

import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.selection.toggleable
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import io.github.lyxnx.compose.ui.animateAlignmentAsState
import io.github.lyxnx.compose.ui.dropShadow
import io.github.lyxnx.compose.ui.ifTrue

/**
 * A switch that has a toggled on/off state
 *
 * @param checked whether the switch is toggled on or off
 * @param onCheckChanged handler to use when the toggle state is changed
 * @param modifier the modifier to apply to the switch
 * @param colors colors to be used for this switch
 * @param enabled whether the switch is enabled and responds to user input
 * @param interactionSource interaction source used to dispatch interaction events to
 * @param thumbContent any custom content to be used within the thumb
 */
@Composable
public fun Switch(
    checked: Boolean,
    onCheckChanged: ((Boolean) -> Unit)?,
    modifier: Modifier = Modifier,
    colors: SwitchColors = SwitchDefaults.switchColors(),
    enabled: Boolean = true,
    interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
    thumbContent: (@Composable BoxScope.() -> Unit)? = null
) {
    val alignment by animateAlignmentAsState(if (checked) Alignment.CenterEnd else Alignment.CenterStart)

    val isFocused by interactionSource.collectIsFocusedAsState()

    val trackBorderColor by colors.trackBorderColor(interactionSource, checked, enabled)
    val trackColor by colors.trackColor(interactionSource, checked, enabled)
    val thumbBorderColor by colors.thumbBorderColor(interactionSource, checked, enabled)
    val thumbColor by colors.thumbColor(interactionSource, checked, enabled)

    val focusShadowColor by colors.focusShadowColor(checked)

    Box(
        modifier = modifier
            .ifTrue(isFocused) {
                dropShadow(
                    color = focusShadowColor,
                    shape = CircleShape,
                    spread = 2.dp
                )
            }
            .clip(CircleShape)
            .ifTrue(onCheckChanged != null) {
                toggleable(
                    value = checked,
                    interactionSource = interactionSource,
                    indication = null,
                    enabled = enabled,
                    role = Role.Switch,
                    onValueChange = onCheckChanged!!
                )
            }
            .border(
                width = 1.dp,
                color = trackBorderColor,
                shape = CircleShape
            )
            .background(trackColor)
            .size(width = 40.dp, height = 24.dp)
            .padding(2.dp)
    ) {
        Box(
            Modifier
                .aspectRatio(1f)
                .fillMaxHeight()
                .dropShadow(PineTheme.shadows.extraSmall.copy(allCornerRadii = 999.dp))
                .clip(CircleShape)
                .background(thumbColor)
                .border(
                    width = 1.dp,
                    color = thumbBorderColor,
                    shape = CircleShape
                )
                .align(alignment)
        ) {
            if (thumbContent != null) {
                thumbContent()
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy