Skip to content

Commit

Permalink
library: Add MiuixCheckbox
Browse files Browse the repository at this point in the history
  • Loading branch information
YuKongA committed Aug 22, 2024
1 parent be61218 commit a6a933b
Show file tree
Hide file tree
Showing 8 changed files with 237 additions and 40 deletions.
63 changes: 56 additions & 7 deletions composeApp/src/commonMain/kotlin/component/SecondComponent.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package component

import MiuixCheckbox
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
Expand All @@ -13,25 +14,73 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import top.yukonga.miuix.kmp.MiuixSuperCheckbox
import top.yukonga.miuix.kmp.MiuixSuperSwitch
import top.yukonga.miuix.kmp.basic.MiuixButton
import top.yukonga.miuix.kmp.basic.MiuixSwitch

@Composable
fun SecondComponent() {
var checkbox by remember { mutableStateOf(false) }
var checkboxTrue by remember { mutableStateOf(true) }
var switch by remember { mutableStateOf(false) }
var switchTrue by remember { mutableStateOf(true) }
var buttonText by remember { mutableStateOf("Button") }
var submitButtonText by remember { mutableStateOf("Submit") }
var textWithSwitch by remember { mutableStateOf("State: false") }
var textWishSwitchState by remember { mutableStateOf(false) }
var miuixSuperCheckbox by remember { mutableStateOf("State: false") }
var miuixSuperCheckboxState by remember { mutableStateOf(false) }
var miuixSuperSwitch by remember { mutableStateOf("State: false") }
var miuixSuperSwitchState by remember { mutableStateOf(false) }
var clickCount by remember { mutableStateOf(0) }
var submitClickCount by remember { mutableStateOf(0) }

Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 28.dp),
.padding(horizontal = 28.dp, vertical = 20.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
MiuixCheckbox(
modifier = Modifier,
checked = checkbox,
onCheckedChange = { checkbox = it }

)
MiuixCheckbox(
modifier = Modifier.padding(start = 8.dp),
checked = checkboxTrue,
onCheckedChange = { checkboxTrue = it }
)
MiuixCheckbox(
modifier = Modifier.padding(start = 8.dp),
enabled = false,
checked = false,
onCheckedChange = { }

)
MiuixCheckbox(
modifier = Modifier.padding(start = 8.dp),
enabled = false,
checked = true,
onCheckedChange = { }
)
}


MiuixSuperCheckbox(
title = "Checkbox",
summary = miuixSuperCheckbox,
checked = miuixSuperCheckboxState,
onCheckedChange = {
miuixSuperCheckboxState = it
miuixSuperCheckbox = "State: $it"
},
)

Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 28.dp, vertical = 20.dp),
horizontalArrangement = Arrangement.SpaceBetween
) {
MiuixSwitch(
Expand Down Expand Up @@ -59,11 +108,11 @@ fun SecondComponent() {

MiuixSuperSwitch(
title = "Switch",
summary = textWithSwitch,
checked = textWishSwitchState,
summary = miuixSuperSwitch,
checked = miuixSuperSwitchState,
onCheckedChange = {
textWishSwitchState = it
textWithSwitch = "State: $it"
miuixSuperSwitchState = it
miuixSuperSwitch = "State: $it"
},
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
allprojects {
group = "top.yukonga.miuix.kmp"
version = "0.0.2"
version = "0.0.3"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package top.yukonga.miuix.kmp

import MiuixCheckbox
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.RowScope
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import top.yukonga.miuix.kmp.basic.MiuixBasicComponent

@Composable
fun MiuixSuperCheckbox(
title: String,
summary: String? = null,
rightActions: @Composable RowScope.() -> Unit = {},
checked: Boolean,
onCheckedChange: ((Boolean) -> Unit)?,
modifier: Modifier = Modifier,
insideMargin: DpSize = DpSize(28.dp, 14.dp),
enabled: Boolean = true
) {
var isChecked by remember { mutableStateOf(checked) }
val interactionSource = remember { MutableInteractionSource() }

if (isChecked != checked) {
isChecked = checked
}

MiuixBasicComponent(
modifier = modifier,
insideMargin = insideMargin,
title = title,
summary = summary,
leftAction = {
MiuixCheckbox(
checked = checked,
onCheckedChange = onCheckedChange,
enabled = enabled
)
},
rightActions = rightActions,
interactionSource = interactionSource,
onClick = {
if (enabled) {
isChecked = !isChecked
onCheckedChange?.invoke(isChecked)
}
}
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fun MiuixSuperSwitch(
checked: Boolean,
onCheckedChange: ((Boolean) -> Unit)?,
modifier: Modifier = Modifier,
insideMargin: DpSize = DpSize(28.dp, 7.dp),
insideMargin: DpSize = DpSize(28.dp, 14.dp),
enabled: Boolean = true
) {
var isChecked by remember { mutableStateOf(checked) }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import androidx.compose.animation.animateColorAsState
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.selection.toggleable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Matrix
import androidx.compose.ui.graphics.vector.PathParser
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.unit.dp
import top.yukonga.miuix.kmp.basic.MiuixBox
import top.yukonga.miuix.kmp.theme.MiuixTheme
import top.yukonga.miuix.kmp.utils.squircleshape.SquircleShape

@Composable
fun MiuixCheckbox(
checked: Boolean,
onCheckedChange: ((Boolean) -> Unit)?,
modifier: Modifier = Modifier,
enabled: Boolean = true,
interactionSource: MutableInteractionSource? = remember { MutableInteractionSource() }
) {
val isChecked by rememberUpdatedState(checked)
println("isChecked: $isChecked")
var isPressed by remember { mutableStateOf(false) }
val backgroundColor by animateColorAsState(
if (isChecked) MiuixTheme.colorScheme.primary else MiuixTheme.colorScheme.switchThumb,
animationSpec = tween(durationMillis = 200)
)
val disabledBackgroundColor by rememberUpdatedState(
if (isChecked) MiuixTheme.colorScheme.disabledBg else MiuixTheme.colorScheme.primaryContainer
)
val checkboxSize by animateDpAsState(if (isPressed) 20.dp else 22.dp)
val checkmarkColor by animateColorAsState(if (checked) Color.White else Color.Transparent)
val toggleableModifier = remember(onCheckedChange, isChecked, enabled) {
if (onCheckedChange != null) {
Modifier.toggleable(
value = isChecked,
onValueChange = {
onCheckedChange(it)
},
enabled = enabled,
role = Role.Checkbox,
interactionSource = interactionSource,
indication = null
)
} else {
Modifier
}
}

MiuixBox(
modifier = modifier
.then(toggleableModifier)
.wrapContentSize(Alignment.Center)
.size(22.dp)
.requiredSize(checkboxSize)
.clip(SquircleShape(100.dp))
.background(if (enabled) backgroundColor else disabledBackgroundColor)
.pointerInput(Unit) {
detectTapGestures(
onPress = {
isPressed = true
},
onTap = {
isPressed = false
if (enabled) {
onCheckedChange?.invoke(!isChecked)
}
}
)
}
) {
Canvas(
modifier = Modifier.requiredSize(checkboxSize)
) {
val svgPath =
"m400-416 236-236q11-11 28-11t28 11q11 11 11 28t-11 28L428-332q-12 12-28 12t-28-12L268-436q-11-11-11-28t11-28q11-11 28-11t28 11l76 76Z"
val path = PathParser().parsePathString(svgPath).toPath()
val scaleFactor = size.minDimension / 960f
path.transform(Matrix().apply {
scale(scaleFactor, scaleFactor)
translate(0f, 960f)
})
drawPath(path, checkmarkColor)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.requiredSize
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.selection.toggleable
import androidx.compose.material3.minimumInteractiveComponentSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
Expand Down Expand Up @@ -86,18 +85,17 @@ fun MiuixSwitch(
)
val toggleableModifier = remember(onCheckedChange, isChecked, enabled) {
if (onCheckedChange != null) {
Modifier.minimumInteractiveComponentSize()
.toggleable(
value = isChecked,
onValueChange = {
onCheckedChange(it)
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
},
enabled = enabled,
role = Role.Switch,
interactionSource = interactionSource,
indication = null
)
Modifier.toggleable(
value = isChecked,
onValueChange = {
onCheckedChange(it)
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
},
enabled = enabled,
role = Role.Switch,
interactionSource = interactionSource,
indication = null
)
} else {
Modifier
}
Expand All @@ -107,6 +105,7 @@ fun MiuixSwitch(
modifier = modifier
.then(toggleableModifier)
.wrapContentSize(Alignment.Center)
.size(52.dp, 28.5.dp)
.requiredSize(52.dp, 28.5.dp)
.clip(SquircleShape(100.dp))
.background(if (enabled) backgroundColor else disabledBackgroundColor)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.BasicText
import androidx.compose.foundation.text.InlineTextContent
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.isSpecified
Expand Down Expand Up @@ -78,13 +80,7 @@ fun MiuixText(
style: TextStyle = MiuixTheme.textStyles.main
) {

val textColor: Color = if (color.isSpecified) {
color
} else if (style.color.isSpecified) {
style.color
} else {
MiuixTheme.colorScheme.primary
}
val textColor by rememberUpdatedState(if (color.isSpecified) color else if (style.color.isSpecified) style.color else MiuixTheme.colorScheme.primary)

BasicText(
text,
Expand Down Expand Up @@ -167,13 +163,7 @@ fun MiuixText(
onTextLayout: (TextLayoutResult) -> Unit = {},
style: TextStyle = MiuixTheme.textStyles.main
) {
val textColor: Color = if (color.isSpecified) {
color
} else if (style.color.isSpecified) {
style.color
} else {
MiuixTheme.colorScheme.primary
}
val textColor by rememberUpdatedState(if (color.isSpecified) color else if (style.color.isSpecified) style.color else MiuixTheme.colorScheme.primary)

BasicText(
text = text,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.SolidColor
Expand Down Expand Up @@ -76,9 +77,8 @@ fun MiuixTextField(
) {
val isFocused by interactionSource.collectIsFocusedAsState()
val borderWidth by animateDpAsState(if (isFocused) 1.6.dp else 0.dp)
val borderColor by animateColorAsState(
if (isFocused) MiuixTheme.colorScheme.primary else MiuixTheme.colorScheme.primaryContainer
)
val backgroundColor by rememberUpdatedState(if (isSecondary) MiuixTheme.colorScheme.secondaryContainer else MiuixTheme.colorScheme.primaryContainer)
val borderColor by animateColorAsState(if (isFocused) MiuixTheme.colorScheme.primary else backgroundColor)
val labelOffsetY by animateDpAsState(if (value.isNotEmpty()) -(insideMargin.height / 2) else 0.dp)
val innerTextOffsetY by animateDpAsState(if (value.isNotEmpty()) (insideMargin.height / 2) else 0.dp)
val labelFontSize by animateDpAsState(if (value.isNotEmpty()) 10.dp else 16.dp)
Expand All @@ -104,7 +104,7 @@ fun MiuixTextField(
modifier = Modifier
.fillMaxWidth()
.background(
color = if (isSecondary) MiuixTheme.colorScheme.secondaryContainer else MiuixTheme.colorScheme.primaryContainer,
color = backgroundColor,
shape = SquircleShape(cornerRadius)
)
.border(
Expand Down

0 comments on commit a6a933b

Please sign in to comment.