diff --git a/CHANGELOG.md b/CHANGELOG.md index 712154e3..de8d75e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Kotlin `1.8.10` - Jetpack Compose Compiler to `1.4.3` - Jetpack Compose Runtime to `1.3.3` -- Jetpack Compose UI to `1.3.1` +- Jetpack Compose UI to `1.4.0-beta02` - Jetpack Compose Material 3 to `1.1.0-alpha07` - Ktlint to `11.2.0` - Androidx Lifecycle to `2.6.0-rc01` diff --git a/buildSrc/src/main/kotlin/Versions.kt b/buildSrc/src/main/kotlin/Versions.kt index a8da5eda..692a348b 100644 --- a/buildSrc/src/main/kotlin/Versions.kt +++ b/buildSrc/src/main/kotlin/Versions.kt @@ -6,7 +6,7 @@ object Versions { const val JETPACK_COMPOSE_RUNTIME = "1.3.3" const val JETPACK_COMPOSE_FOUNDATION = "1.3.1" const val JETPACK_COMPOSE_UI_TOOLING = "1.3.3" - const val JETPACK_COMPOSE_MATERIAL = "1.3.1" + const val JETPACK_COMPOSE_MATERIAL = "1.4.0-beta02" const val JETPACK_COMPOSE_MATERIAL_3 = "1.1.0-alpha07" const val COIL = "2.0.0-rc03" const val KTLINT = "11.2.0" diff --git a/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDBasicTextField.kt b/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDBasicTextField.kt index ec95ecfc..530bd8cf 100644 --- a/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDBasicTextField.kt +++ b/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDBasicTextField.kt @@ -36,6 +36,7 @@ fun VMDBasicTextField( keyboardActions: KeyboardActions = KeyboardActions(), singleLine: Boolean = false, maxLines: Int = Int.MAX_VALUE, + minLines: Int = 1, isError: Boolean = false, onTextLayout: (TextLayoutResult) -> Unit = {}, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, @@ -71,6 +72,7 @@ fun VMDBasicTextField( ), keyboardActions = keyboardActionsDelegate, maxLines = maxLines, + minLines = minLines, singleLine = singleLine, visualTransformation = visualTransformation, onTextLayout = onTextLayout, diff --git a/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDButton.kt b/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDButton.kt index 1ecc90b6..b2186ce8 100644 --- a/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDButton.kt +++ b/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDButton.kt @@ -22,6 +22,7 @@ fun VMDButton( modifier: Modifier = Modifier, viewModel: VMDButtonViewModel, contentAlignment: Alignment = Alignment.Center, + propagateMinConstraints: Boolean = false, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, indication: Indication? = rememberRipple(), content: @Composable (BoxScope.(field: C) -> Unit) @@ -39,6 +40,7 @@ fun VMDButton( indication = indication ), contentAlignment = contentAlignment, + propagateMinConstraints = propagateMinConstraints, content = { content(buttonViewModel.content) } ) } diff --git a/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCheckbox.kt b/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCheckbox.kt index c2e913dd..89b64878 100644 --- a/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCheckbox.kt +++ b/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCheckbox.kt @@ -1,5 +1,6 @@ package com.mirego.trikot.viewmodels.declarative.compose.viewmodel +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.RowScope import androidx.compose.material.Checkbox import androidx.compose.material.CheckboxColors @@ -7,6 +8,7 @@ import androidx.compose.material.CheckboxDefaults import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import com.mirego.trikot.viewmodels.declarative.components.VMDToggleViewModel @@ -23,6 +25,7 @@ fun VMDCheckbox( modifier: Modifier = Modifier, componentModifier: Modifier = Modifier, viewModel: VMDToggleViewModel, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, colors: CheckboxColors = CheckboxDefaults.colors() ) { VMDCheckbox( @@ -30,6 +33,7 @@ fun VMDCheckbox( componentModifier = componentModifier, viewModel = viewModel, label = {}, + interactionSource = interactionSource, colors = colors ) } @@ -40,6 +44,7 @@ fun VMDCheckbox( componentModifier: Modifier = Modifier, viewModel: VMDToggleViewModel, label: @Composable (RowScope.(field: C) -> Unit), + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, colors: CheckboxColors = CheckboxDefaults.colors() ) { val toggleViewModel: VMDToggleViewModel by viewModel.observeAsState(excludedProperties = if (modifier.isOverridingAlpha()) listOf(viewModel::isHidden) else emptyList()) @@ -51,11 +56,12 @@ fun VMDCheckbox( label = { label(toggleViewModel.label) }, content = { Checkbox( + onCheckedChange = { checked -> viewModel.onValueChange(checked) }, modifier = componentModifier, enabled = toggleViewModel.isEnabled, checked = toggleViewModel.isOn, - colors = colors, - onCheckedChange = { checked -> viewModel.onValueChange(checked) }, + interactionSource = interactionSource, + colors = colors ) } ) diff --git a/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCircularProgressIndicator.kt b/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCircularProgressIndicator.kt index f0d3d4e9..9969846d 100644 --- a/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCircularProgressIndicator.kt +++ b/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCircularProgressIndicator.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import com.mirego.trikot.viewmodels.declarative.components.VMDProgressViewModel @@ -22,7 +23,9 @@ fun VMDCircularProgressIndicator( modifier: Modifier = Modifier, viewModel: VMDProgressViewModel, color: Color = MaterialTheme.colors.primary, - strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth + strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth, + backgroundColor: Color = Color.Transparent, + strokeCap: StrokeCap = StrokeCap.Square, ) { val progressViewModel: VMDProgressViewModel by viewModel.observeAsState(excludedProperties = if (modifier.isOverridingAlpha()) listOf(viewModel::isHidden) else emptyList()) val animatedProgress by animateFloatAsState(targetValue = progressViewModel.determination?.progressRatio ?: 0f) @@ -35,14 +38,18 @@ fun VMDCircularProgressIndicator( CircularProgressIndicator( modifier = newModifier, color = color, - strokeWidth = strokeWidth + strokeWidth = strokeWidth, + backgroundColor = backgroundColor, + strokeCap = strokeCap ) } else { CircularProgressIndicator( modifier = newModifier, progress = animatedProgress, color = color, - strokeWidth = strokeWidth + strokeWidth = strokeWidth, + backgroundColor = backgroundColor, + strokeCap = strokeCap ) } } diff --git a/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDSwitch.kt b/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDSwitch.kt index f1f5277e..2ffab8e1 100644 --- a/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDSwitch.kt +++ b/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDSwitch.kt @@ -1,5 +1,6 @@ package com.mirego.trikot.viewmodels.declarative.compose.viewmodel +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.RowScope import androidx.compose.material.Switch import androidx.compose.material.SwitchColors @@ -7,6 +8,7 @@ import androidx.compose.material.SwitchDefaults import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import com.mirego.trikot.viewmodels.declarative.components.VMDToggleViewModel @@ -23,6 +25,7 @@ fun VMDSwitch( modifier: Modifier = Modifier, componentModifier: Modifier = Modifier, viewModel: VMDToggleViewModel, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, colors: SwitchColors = SwitchDefaults.colors() ) { VMDSwitch( @@ -40,6 +43,7 @@ fun VMDSwitch( componentModifier: Modifier = Modifier, viewModel: VMDToggleViewModel, label: @Composable (RowScope.(field: C) -> Unit), + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, colors: SwitchColors = SwitchDefaults.colors() ) { val toggleViewModel: VMDToggleViewModel by viewModel.observeAsState(excludedProperties = if (modifier.isOverridingAlpha()) listOf(viewModel::isHidden) else emptyList()) @@ -55,6 +59,7 @@ fun VMDSwitch( enabled = toggleViewModel.isEnabled, checked = toggleViewModel.isOn, colors = colors, + interactionSource = interactionSource, onCheckedChange = { checked -> viewModel.onValueChange(checked) }, ) } diff --git a/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDText.kt b/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDText.kt index 714661f7..c119dd45 100644 --- a/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDText.kt +++ b/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDText.kt @@ -36,6 +36,7 @@ fun VMDText( overflow: TextOverflow = TextOverflow.Clip, softWrap: Boolean = true, maxLines: Int = Int.MAX_VALUE, + minLines: Int = 1, onTextLayout: (TextLayoutResult) -> Unit = {}, style: TextStyle = LocalTextStyle.current ) { @@ -58,6 +59,7 @@ fun VMDText( overflow = overflow, softWrap = softWrap, maxLines = maxLines, + minLines = minLines, onTextLayout = onTextLayout, style = style ) diff --git a/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDTextField.kt b/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDTextField.kt index 1c43a12c..85dab7a6 100644 --- a/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDTextField.kt +++ b/trikot-viewmodels-declarative-flow/compose-flow/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDTextField.kt @@ -1,15 +1,20 @@ package com.mirego.trikot.viewmodels.declarative.compose.viewmodel +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.shape.ZeroCornerSize import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.LocalTextStyle +import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.material.TextField import androidx.compose.material.TextFieldColors import androidx.compose.material.TextFieldDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Shape import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.input.OffsetMapping @@ -28,11 +33,17 @@ fun VMDTextField( viewModel: VMDTextFieldViewModel, textStyle: TextStyle = LocalTextStyle.current, placeHolderStyle: TextStyle = LocalTextStyle.current, + label: @Composable (() -> Unit)? = null, + placeholder: @Composable (() -> Unit)? = null, leadingIcon: @Composable (() -> Unit)? = null, trailingIcon: @Composable (() -> Unit)? = null, keyboardActions: KeyboardActions = KeyboardActions(), - singleLine: Boolean = true, isError: Boolean = false, + singleLine: Boolean = false, + maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE, + minLines: Int = 1, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + shape: Shape = MaterialTheme.shapes.small.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize), textFieldColors: TextFieldColors = TextFieldDefaults.textFieldColors() ) { val textFieldViewModel: VMDTextFieldViewModel by viewModel.observeAsState(excludedProperties = if (modifier.isOverridingAlpha()) listOf(viewModel::isHidden) else emptyList()) @@ -47,6 +58,7 @@ fun VMDTextField( viewModel.onValueChange(value) }, enabled = textFieldViewModel.isEnabled, + label = label, placeholder = { Text( text = textFieldViewModel.placeholder, @@ -55,8 +67,9 @@ fun VMDTextField( }, leadingIcon = leadingIcon, trailingIcon = trailingIcon, - colors = textFieldColors, textStyle = textStyle, + isError = isError, + visualTransformation = FormattedVisualTransformation(viewModel.formatText), keyboardActions = keyboardActionsDelegate, keyboardOptions = KeyboardOptions( keyboardType = textFieldViewModel.keyboardType.composeValue, @@ -64,8 +77,11 @@ fun VMDTextField( imeAction = textFieldViewModel.keyboardReturnKeyType.composeValue ), singleLine = singleLine, - isError = isError, - visualTransformation = FormattedVisualTransformation(viewModel.formatText) + maxLines = maxLines, + minLines = minLines, + interactionSource = interactionSource, + shape = shape, + colors = textFieldColors ) } diff --git a/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDButton.kt b/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDButton.kt index 1ecc90b6..b2186ce8 100644 --- a/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDButton.kt +++ b/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDButton.kt @@ -22,6 +22,7 @@ fun VMDButton( modifier: Modifier = Modifier, viewModel: VMDButtonViewModel, contentAlignment: Alignment = Alignment.Center, + propagateMinConstraints: Boolean = false, interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, indication: Indication? = rememberRipple(), content: @Composable (BoxScope.(field: C) -> Unit) @@ -39,6 +40,7 @@ fun VMDButton( indication = indication ), contentAlignment = contentAlignment, + propagateMinConstraints = propagateMinConstraints, content = { content(buttonViewModel.content) } ) } diff --git a/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCheckbox.kt b/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCheckbox.kt index 55ce7487..74fde78b 100644 --- a/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCheckbox.kt +++ b/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCheckbox.kt @@ -1,5 +1,6 @@ package com.mirego.trikot.viewmodels.declarative.compose.viewmodel +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.RowScope import androidx.compose.material.Checkbox import androidx.compose.material.CheckboxColors @@ -7,6 +8,7 @@ import androidx.compose.material.CheckboxDefaults import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import com.mirego.trikot.streams.cancellable.CancellableManager @@ -23,6 +25,7 @@ fun VMDCheckbox( modifier: Modifier = Modifier, componentModifier: Modifier = Modifier, viewModel: VMDToggleViewModel, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, colors: CheckboxColors = CheckboxDefaults.colors() ) { VMDCheckbox( @@ -30,6 +33,7 @@ fun VMDCheckbox( componentModifier = componentModifier, viewModel = viewModel, label = {}, + interactionSource = interactionSource, colors = colors ) } @@ -40,6 +44,7 @@ fun VMDCheckbox( componentModifier: Modifier = Modifier, viewModel: VMDToggleViewModel, label: @Composable (RowScope.(field: C) -> Unit), + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, colors: CheckboxColors = CheckboxDefaults.colors() ) { val toggleViewModel: VMDToggleViewModel by viewModel.observeAsState(excludedProperties = if (modifier.isOverridingAlpha()) listOf(viewModel::isHidden) else emptyList()) @@ -51,11 +56,12 @@ fun VMDCheckbox( label = { label(toggleViewModel.label) }, content = { Checkbox( + onCheckedChange = { checked -> viewModel.onValueChange(checked) }, modifier = componentModifier, enabled = toggleViewModel.isEnabled, checked = toggleViewModel.isOn, - colors = colors, - onCheckedChange = { checked -> viewModel.onValueChange(checked) }, + interactionSource = interactionSource, + colors = colors ) } ) diff --git a/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCircularProgressIndicator.kt b/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCircularProgressIndicator.kt index 8300846c..96732474 100644 --- a/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCircularProgressIndicator.kt +++ b/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDCircularProgressIndicator.kt @@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.StrokeCap import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.Dp import com.mirego.trikot.streams.cancellable.CancellableManager @@ -22,7 +23,9 @@ fun VMDCircularProgressIndicator( modifier: Modifier = Modifier, viewModel: VMDProgressViewModel, color: Color = MaterialTheme.colors.primary, - strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth + strokeWidth: Dp = ProgressIndicatorDefaults.StrokeWidth, + backgroundColor: Color = Color.Transparent, + strokeCap: StrokeCap = StrokeCap.Square, ) { val progressViewModel: VMDProgressViewModel by viewModel.observeAsState(excludedProperties = if (modifier.isOverridingAlpha()) listOf(viewModel::isHidden) else emptyList()) val animatedProgress by animateFloatAsState(targetValue = progressViewModel.determination?.progressRatio ?: 0f) @@ -35,14 +38,18 @@ fun VMDCircularProgressIndicator( CircularProgressIndicator( modifier = newModifier, color = color, - strokeWidth = strokeWidth + strokeWidth = strokeWidth, + backgroundColor = backgroundColor, + strokeCap = strokeCap ) } else { CircularProgressIndicator( modifier = newModifier, progress = animatedProgress, color = color, - strokeWidth = strokeWidth + strokeWidth = strokeWidth, + backgroundColor = backgroundColor, + strokeCap = strokeCap ) } } diff --git a/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDSwitch.kt b/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDSwitch.kt index 9287f9e5..ed808ff8 100644 --- a/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDSwitch.kt +++ b/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDSwitch.kt @@ -1,5 +1,6 @@ package com.mirego.trikot.viewmodels.declarative.compose.viewmodel +import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.RowScope import androidx.compose.material.Switch import androidx.compose.material.SwitchColors @@ -7,6 +8,7 @@ import androidx.compose.material.SwitchDefaults import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.tooling.preview.Preview import com.mirego.trikot.streams.cancellable.CancellableManager @@ -17,13 +19,13 @@ import com.mirego.trikot.viewmodels.declarative.compose.extensions.isOverridingA import com.mirego.trikot.viewmodels.declarative.compose.extensions.observeAsState import com.mirego.trikot.viewmodels.declarative.content.VMDContent import com.mirego.trikot.viewmodels.declarative.content.VMDNoContent -import com.mirego.trikot.viewmodels.declarative.content.VMDTextContent @Composable fun VMDSwitch( modifier: Modifier = Modifier, componentModifier: Modifier = Modifier, viewModel: VMDToggleViewModel, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, colors: SwitchColors = SwitchDefaults.colors() ) { VMDSwitch( @@ -41,6 +43,7 @@ fun VMDSwitch( componentModifier: Modifier = Modifier, viewModel: VMDToggleViewModel, label: @Composable (RowScope.(field: C) -> Unit), + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, colors: SwitchColors = SwitchDefaults.colors() ) { val toggleViewModel: VMDToggleViewModel by viewModel.observeAsState(excludedProperties = if (modifier.isOverridingAlpha()) listOf(viewModel::isHidden) else emptyList()) @@ -56,6 +59,7 @@ fun VMDSwitch( enabled = toggleViewModel.isEnabled, checked = toggleViewModel.isOn, colors = colors, + interactionSource = interactionSource, onCheckedChange = { checked -> viewModel.onValueChange(checked) }, ) } diff --git a/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDText.kt b/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDText.kt index 714661f7..c119dd45 100644 --- a/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDText.kt +++ b/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDText.kt @@ -36,6 +36,7 @@ fun VMDText( overflow: TextOverflow = TextOverflow.Clip, softWrap: Boolean = true, maxLines: Int = Int.MAX_VALUE, + minLines: Int = 1, onTextLayout: (TextLayoutResult) -> Unit = {}, style: TextStyle = LocalTextStyle.current ) { @@ -58,6 +59,7 @@ fun VMDText( overflow = overflow, softWrap = softWrap, maxLines = maxLines, + minLines = minLines, onTextLayout = onTextLayout, style = style ) diff --git a/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDTextField.kt b/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDTextField.kt index e2e56446..2ac54724 100644 --- a/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDTextField.kt +++ b/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/VMDTextField.kt @@ -1,25 +1,27 @@ package com.mirego.trikot.viewmodels.declarative.compose.viewmodel +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.shape.ZeroCornerSize import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material.LocalTextStyle +import androidx.compose.material.MaterialTheme import androidx.compose.material.Text import androidx.compose.material.TextField import androidx.compose.material.TextFieldColors import androidx.compose.material.TextFieldDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier -import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.graphics.Shape import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.input.OffsetMapping -import androidx.compose.ui.text.input.TransformedText -import androidx.compose.ui.text.input.VisualTransformation import com.mirego.trikot.viewmodels.declarative.components.VMDTextFieldViewModel import com.mirego.trikot.viewmodels.declarative.compose.extensions.composeValue import com.mirego.trikot.viewmodels.declarative.compose.extensions.hidden import com.mirego.trikot.viewmodels.declarative.compose.extensions.isOverridingAlpha import com.mirego.trikot.viewmodels.declarative.compose.extensions.observeAsState +import com.mirego.trikot.viewmodels.declarative.compose.viewmodel.internal.FormattedVisualTransformation @Composable fun VMDTextField( @@ -27,11 +29,17 @@ fun VMDTextField( viewModel: VMDTextFieldViewModel, textStyle: TextStyle = LocalTextStyle.current, placeHolderStyle: TextStyle = LocalTextStyle.current, + label: @Composable (() -> Unit)? = null, + placeholder: @Composable (() -> Unit)? = null, leadingIcon: @Composable (() -> Unit)? = null, trailingIcon: @Composable (() -> Unit)? = null, keyboardActions: KeyboardActions = KeyboardActions(), - singleLine: Boolean = true, isError: Boolean = false, + singleLine: Boolean = false, + maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE, + minLines: Int = 1, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, + shape: Shape = MaterialTheme.shapes.small.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize), textFieldColors: TextFieldColors = TextFieldDefaults.textFieldColors() ) { val textFieldViewModel: VMDTextFieldViewModel by viewModel.observeAsState(excludedProperties = if (modifier.isOverridingAlpha()) listOf(viewModel::isHidden) else emptyList()) @@ -46,6 +54,7 @@ fun VMDTextField( viewModel.onValueChange(value) }, enabled = textFieldViewModel.isEnabled, + label = label, placeholder = { Text( text = textFieldViewModel.placeholder, @@ -54,8 +63,9 @@ fun VMDTextField( }, leadingIcon = leadingIcon, trailingIcon = trailingIcon, - colors = textFieldColors, textStyle = textStyle, + isError = isError, + visualTransformation = FormattedVisualTransformation(viewModel.formatText), keyboardActions = keyboardActionsDelegate, keyboardOptions = KeyboardOptions( keyboardType = textFieldViewModel.keyboardType.composeValue, @@ -63,8 +73,11 @@ fun VMDTextField( imeAction = textFieldViewModel.keyboardReturnKeyType.composeValue ), singleLine = singleLine, - isError = isError, - visualTransformation = FormattedVisualTransformation(viewModel.formatText) + maxLines = maxLines, + minLines = minLines, + interactionSource = interactionSource, + shape = shape, + colors = textFieldColors ) } @@ -95,24 +108,3 @@ fun buildKeyboardActions(viewModel: VMDTextFieldViewModel, keyboardActions: Keyb keyboardActions.onSend?.invoke(this) }, ) - -private class FormattedVisualTransformation(private val formatter: (text: String) -> String) : - VisualTransformation { - - override fun filter(text: AnnotatedString): TransformedText { - val formattedString = formatter(text.text) - val offsetDelta = formattedString.length - text.length - return TransformedText( - text = AnnotatedString(formattedString), - offsetMapping = object : OffsetMapping { - override fun originalToTransformed(offset: Int): Int { - return offset + offsetDelta - } - - override fun transformedToOriginal(offset: Int): Int { - return offset - offsetDelta - } - } - ) - } -} diff --git a/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/internal/FormattedVisualTransformation.kt b/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/internal/FormattedVisualTransformation.kt new file mode 100644 index 00000000..2340a229 --- /dev/null +++ b/trikot-viewmodels-declarative/compose/src/main/kotlin/com/mirego/trikot/viewmodels/declarative/compose/viewmodel/internal/FormattedVisualTransformation.kt @@ -0,0 +1,27 @@ +package com.mirego.trikot.viewmodels.declarative.compose.viewmodel.internal + +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.input.OffsetMapping +import androidx.compose.ui.text.input.TransformedText +import androidx.compose.ui.text.input.VisualTransformation + +internal class FormattedVisualTransformation(private val formatter: (text: String) -> String) : + VisualTransformation { + + override fun filter(text: AnnotatedString): TransformedText { + val formattedString = formatter(text.text) + val offsetDelta = formattedString.length - text.length + return TransformedText( + text = AnnotatedString(formattedString), + offsetMapping = object : OffsetMapping { + override fun originalToTransformed(offset: Int): Int { + return offset + offsetDelta + } + + override fun transformedToOriginal(offset: Int): Int { + return offset - offsetDelta + } + } + ) + } +}