diff --git a/components-compose/CHANGELOG.md b/components-compose/CHANGELOG.md
index 6fc30073..7e0a0839 100644
--- a/components-compose/CHANGELOG.md
+++ b/components-compose/CHANGELOG.md
@@ -20,6 +20,15 @@ Allowed headings:
* `SelectRowView` aligned to top of radio button rather than centered
* Dependency updates
+* The `initialInputValue` parameter of `TextInputView` and `CurrencyInputView` has been renamed to `value`
+
+### Added
+
+* `TextInputView` and `CurrencyInputView` now support `maxChars`
+
+### Fixed
+
+* `TextInputView` and `CurrencyInputView` input can now be cleared by setting the `value` parameter
## [0.1.1] - 2024-08-08Z
diff --git a/components-compose/src/main/java/uk/gov/hmrc/components/compose/molecule/input/CurrencyInputView.kt b/components-compose/src/main/java/uk/gov/hmrc/components/compose/molecule/input/CurrencyInputView.kt
index da8d479c..505d5988 100644
--- a/components-compose/src/main/java/uk/gov/hmrc/components/compose/molecule/input/CurrencyInputView.kt
+++ b/components-compose/src/main/java/uk/gov/hmrc/components/compose/molecule/input/CurrencyInputView.kt
@@ -28,7 +28,7 @@ import uk.gov.hmrc.components.compose.ui.theme.HmrcTheme
@Composable
fun CurrencyInputView(
modifier: Modifier = Modifier,
- initialInputValue: String = "",
+ value: String? = null,
onInputValueChange: ((String) -> Unit)? = null,
labelText: String? = null,
labelContentDescription: String? = null,
@@ -39,6 +39,7 @@ fun CurrencyInputView(
errorContentDescription: String? = null,
singleLine: Boolean = true,
enableDecimal: Boolean = true,
+ maxChars: Int? = null,
) {
// pattern matches a decimal number
@@ -54,7 +55,7 @@ fun CurrencyInputView(
TextInputView(
modifier = modifier,
- initialInputValue = initialInputValue,
+ value = value,
onInputValueChange = onInputValueChange,
inputFilter = { it: String, localValue: String -> decimalPatternChecker(it, localValue) },
labelText = labelText,
@@ -73,7 +74,8 @@ fun CurrencyInputView(
singleLine = singleLine,
keyboardOptions = KeyboardOptions(
keyboardType = if (enableDecimal) KeyboardType.Decimal else KeyboardType.Number
- )
+ ),
+ maxChars = maxChars
)
}
diff --git a/components-compose/src/main/java/uk/gov/hmrc/components/compose/molecule/input/TextInputView.kt b/components-compose/src/main/java/uk/gov/hmrc/components/compose/molecule/input/TextInputView.kt
index 56b9c1ac..8246e1ae 100644
--- a/components-compose/src/main/java/uk/gov/hmrc/components/compose/molecule/input/TextInputView.kt
+++ b/components-compose/src/main/java/uk/gov/hmrc/components/compose/molecule/input/TextInputView.kt
@@ -56,7 +56,7 @@ object TextInputView {
@Composable
operator fun invoke(
modifier: Modifier = Modifier,
- initialInputValue: String = "",
+ value: String? = null,
onInputValueChange: ((String) -> Unit)? = null,
inputFilter: ((String, String) -> String)? = null,
labelText: String? = null,
@@ -68,10 +68,13 @@ object TextInputView {
errorText: String? = null,
errorContentDescription: String? = null,
characterCount: Int? = null,
+ maxChars: Int? = null,
singleLine: Boolean = false,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default
) {
- var localValue: String by rememberSaveable { mutableStateOf(initialInputValue) }
+ var localValue: String by rememberSaveable { mutableStateOf(value.orEmpty()) }
+ localValue = value.orEmpty()
+
var localError: String? by rememberSaveable { mutableStateOf(null) }
localError = errorText
@@ -142,10 +145,13 @@ object TextInputView {
isError = !localError.isNullOrEmpty() || (localValue.length > (characterCount ?: Int.MAX_VALUE)),
value = localValue,
onInputValueChange = { newValue ->
- if (onInputValueChange != null) { onInputValueChange(newValue) }
- localValue = if (inputFilter != null && newValue.isNotEmpty()) {
- inputFilter(newValue, localValue)
- } else newValue
+ if (maxChars?.let { newValue.length <= it } != false) {
+ localValue = if (inputFilter != null && newValue.isNotEmpty()) {
+ val filteredValue = inputFilter(newValue, localValue)
+ if (onInputValueChange != null) { onInputValueChange(filteredValue) }
+ filteredValue
+ } else newValue
+ }
},
prefix = prefix,
placeholderText = { placeholderText?.let { Text(text = it) } },
diff --git a/sample-compose-fragments/src/main/java/uk/gov/hmrc/sample_compose_fragments/presentation/screens/molecules/CurrencyInputViewScreen.kt b/sample-compose-fragments/src/main/java/uk/gov/hmrc/sample_compose_fragments/presentation/screens/molecules/CurrencyInputViewScreen.kt
index 30b26851..914b530d 100644
--- a/sample-compose-fragments/src/main/java/uk/gov/hmrc/sample_compose_fragments/presentation/screens/molecules/CurrencyInputViewScreen.kt
+++ b/sample-compose-fragments/src/main/java/uk/gov/hmrc/sample_compose_fragments/presentation/screens/molecules/CurrencyInputViewScreen.kt
@@ -17,10 +17,15 @@ package uk.gov.hmrc.sample_compose_fragments.presentation.screens.molecules
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel
+import uk.gov.hmrc.components.compose.atom.text.BodyText
import uk.gov.hmrc.components.compose.molecule.input.CurrencyInputView
import uk.gov.hmrc.components.compose.organism.HmrcCardView
import uk.gov.hmrc.components.compose.ui.theme.HmrcTheme
@@ -37,9 +42,17 @@ fun CurrencyInputViewScreen() {
val errorText = stringResource(id = R.string.currency_input_example_error)
+ var placeholderValue: String by rememberSaveable { mutableStateOf("") }
+ var example1Value: String by rememberSaveable { mutableStateOf("") }
+ var example2Value: String by rememberSaveable { mutableStateOf("") }
+ var example3Value: String by rememberSaveable { mutableStateOf("123.45") }
+ var example4Value: String by rememberSaveable { mutableStateOf("123.45") }
+
ScreenScrollViewColumn {
PlaceholderSlot {
CurrencyInputView(
+ value = placeholderValue,
+ onInputValueChange = { placeholderValue = it },
labelText = stringResource(id = R.string.currency_input_placeholder_label),
hintText = stringResource(id = R.string.currency_input_placeholder_hint),
placeholderText = stringResource(id = R.string.currency_input_placeholder_placeholder),
@@ -50,36 +63,50 @@ fun CurrencyInputViewScreen() {
ExamplesSlot {
HmrcCardView {
CurrencyInputView(
+ value = example1Value,
modifier = Modifier.padding(
horizontal = HmrcTheme.dimensions.hmrcSpacing16,
vertical = HmrcTheme.dimensions.hmrcSpacing24,
),
- onInputValueChange = { viewModel.isEmptyValidation(it, errorText, 0) },
+ onInputValueChange = {
+ viewModel.isEmptyValidation(it, errorText, 0)
+ example1Value = it
+ },
errorText = viewModel.textInputErrorEmptyValidation.collectAsStateWithLifecycle().value,
labelText = stringResource(id = R.string.currency_input_example_1_label),
hintText = stringResource(id = R.string.currency_input_example_1_hint),
- enableDecimal = true
+ enableDecimal = true,
+ maxChars = 4
)
+ BodyText(text = example1Value)
CurrencyInputView(
+ value = example2Value,
modifier = Modifier.padding(
horizontal = HmrcTheme.dimensions.hmrcSpacing16,
vertical = HmrcTheme.dimensions.hmrcSpacing24,
),
- onInputValueChange = { viewModel.isEmptyValidation(it, errorText, 1) },
+ onInputValueChange = {
+ viewModel.isEmptyValidation(it, errorText, 1)
+ example2Value = it
+ },
errorText = viewModel.textInputErrorEmptyValidation1.collectAsStateWithLifecycle().value,
labelText = stringResource(id = R.string.currency_input_example_2_label),
hintText = stringResource(id = R.string.currency_input_example_2_hint),
enableDecimal = false
)
+ BodyText(text = example2Value)
CurrencyInputView(
modifier = Modifier.padding(
horizontal = HmrcTheme.dimensions.hmrcSpacing16,
vertical = HmrcTheme.dimensions.hmrcSpacing24,
),
- initialInputValue = stringResource(id = R.string.currency_input_example_3_text),
- onInputValueChange = { viewModel.isEmptyValidation(it, errorText, 2) },
+ value = example3Value,
+ onInputValueChange = {
+ viewModel.isEmptyValidation(it, errorText, 2)
+ example3Value = it
+ },
errorText = viewModel.textInputErrorEmptyValidation2.collectAsStateWithLifecycle().value,
labelText = stringResource(id = R.string.currency_input_example_3_label),
hintText = stringResource(id = R.string.currency_input_example_3_hint),
@@ -91,8 +118,11 @@ fun CurrencyInputViewScreen() {
horizontal = HmrcTheme.dimensions.hmrcSpacing16,
vertical = HmrcTheme.dimensions.hmrcSpacing24,
),
- initialInputValue = stringResource(id = R.string.currency_input_example_3_text),
- onInputValueChange = { viewModel.isEmptyValidation(it, errorText, 3) },
+ value = example4Value,
+ onInputValueChange = {
+ viewModel.isEmptyValidation(it, errorText, 3)
+ example4Value = it
+ },
errorText = viewModel.textInputErrorEmptyValidation3.collectAsStateWithLifecycle().value,
labelText = stringResource(id = R.string.currency_input_example_4_label),
hintText = stringResource(id = R.string.currency_input_example_4_hint),
diff --git a/sample-compose-fragments/src/main/java/uk/gov/hmrc/sample_compose_fragments/presentation/screens/molecules/TextInputViewScreen.kt b/sample-compose-fragments/src/main/java/uk/gov/hmrc/sample_compose_fragments/presentation/screens/molecules/TextInputViewScreen.kt
index 6e0f27cd..9dca4e6e 100644
--- a/sample-compose-fragments/src/main/java/uk/gov/hmrc/sample_compose_fragments/presentation/screens/molecules/TextInputViewScreen.kt
+++ b/sample-compose-fragments/src/main/java/uk/gov/hmrc/sample_compose_fragments/presentation/screens/molecules/TextInputViewScreen.kt
@@ -17,6 +17,10 @@ package uk.gov.hmrc.sample_compose_fragments.presentation.screens.molecules
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -39,17 +43,26 @@ fun TextInputViewScreen() {
val errorTextEx2 = stringResource(id = R.string.text_input_example_2_error)
val errorTextEx3 = stringResource(id = R.string.text_input_example_3_error)
+ var placeholderValue: String by rememberSaveable { mutableStateOf("") }
+ var example1Value: String by rememberSaveable { mutableStateOf("") }
+ var example2Value: String by rememberSaveable { mutableStateOf("") }
+ var example3Value: String by rememberSaveable { mutableStateOf("") }
+
ScreenScrollViewColumn {
val characterCount = 50
PlaceholderSlot {
TextInputView(
- onInputValueChange = { viewModel.validateCharCount(
- characterCount = characterCount,
- input = it,
- errorText = null,
- id = 0
- ) },
+ value = placeholderValue,
+ onInputValueChange = {
+ viewModel.validateCharCount(
+ characterCount = characterCount,
+ input = it,
+ errorText = null,
+ id = 0
+ )
+ placeholderValue = it
+ },
errorText = viewModel.textInputErrorCharCount.collectAsStateWithLifecycle().value,
labelText = stringResource(id = R.string.text_input_placeholder_label),
hintText = stringResource(id = R.string.text_input_placeholder_hint),
@@ -61,33 +74,46 @@ fun TextInputViewScreen() {
ExamplesSlot {
HmrcCardView {
TextInputView(
+ value = example1Value,
modifier = Modifier.padding(
horizontal = HmrcTheme.dimensions.hmrcSpacing16,
vertical = HmrcTheme.dimensions.hmrcSpacing24,
),
- onInputValueChange = { viewModel.validateCharCount(5, it, errorTextEx1, 1) },
+ onInputValueChange = {
+ viewModel.validateCharCount(5, it, errorTextEx1, 1)
+ example1Value = it
+ },
errorText = viewModel.textInputErrorCharCount1.collectAsStateWithLifecycle().value,
labelText = stringResource(R.string.text_input_example_1_hint),
labelContentDescription = stringResource(R.string.text_input_example_1_content_description),
characterCount = 5,
+ maxChars = 5
)
TextInputView(
+ value = example2Value,
modifier = Modifier.padding(
horizontal = HmrcTheme.dimensions.hmrcSpacing16,
vertical = HmrcTheme.dimensions.hmrcSpacing24,
),
- onInputValueChange = { viewModel.isEmptyValidation(it, errorTextEx2, 0) },
+ onInputValueChange = {
+ viewModel.isEmptyValidation(it, errorTextEx2, 0)
+ example2Value = it
+ },
errorText = viewModel.textInputError.collectAsStateWithLifecycle().value,
hintText = stringResource(id = R.string.text_input_example_2_hint)
)
TextInputView(
+ value = example3Value,
modifier = Modifier.padding(
horizontal = HmrcTheme.dimensions.hmrcSpacing16,
vertical = HmrcTheme.dimensions.hmrcSpacing24,
),
- onInputValueChange = { viewModel.isEmptyValidation(it, errorTextEx3, 1) },
+ onInputValueChange = {
+ viewModel.isEmptyValidation(it, errorTextEx3, 1)
+ example3Value = it
+ },
errorText = viewModel.textInputErrorEmptyValidation.collectAsStateWithLifecycle().value,
labelText = stringResource(R.string.text_input_example_3_hint),
singleLine = true
diff --git a/sample-compose-fragments/src/main/res/values/strings.xml b/sample-compose-fragments/src/main/res/values/strings.xml
index c99c8bcd..daad2173 100644
--- a/sample-compose-fragments/src/main/res/values/strings.xml
+++ b/sample-compose-fragments/src/main/res/values/strings.xml
@@ -281,7 +281,7 @@
Hint
Placeholder
Pay amount
- The value can be a decimal
+ The value can be a decimal but only 4 chars long
Pay amount (pounds)
The value must not be a decimal
Pay amount (pounds)