Skip to content

Commit 207ca11

Browse files
authored
Added maxChars and fixed input (#185)
1 parent e70f671 commit 207ca11

File tree

6 files changed

+99
-26
lines changed

6 files changed

+99
-26
lines changed

components-compose/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ Allowed headings:
2020

2121
* `SelectRowView` aligned to top of radio button rather than centered
2222
* Dependency updates
23+
* The `initialInputValue` parameter of `TextInputView` and `CurrencyInputView` has been renamed to `value`
24+
25+
### Added
26+
27+
* `TextInputView` and `CurrencyInputView` now support `maxChars`
28+
29+
### Fixed
30+
31+
* `TextInputView` and `CurrencyInputView` input can now be cleared by setting the `value` parameter
2332

2433
## [0.1.1] - 2024-08-08Z
2534

components-compose/src/main/java/uk/gov/hmrc/components/compose/molecule/input/CurrencyInputView.kt

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import uk.gov.hmrc.components.compose.ui.theme.HmrcTheme
2828
@Composable
2929
fun CurrencyInputView(
3030
modifier: Modifier = Modifier,
31-
initialInputValue: String = "",
31+
value: String? = null,
3232
onInputValueChange: ((String) -> Unit)? = null,
3333
labelText: String? = null,
3434
labelContentDescription: String? = null,
@@ -39,6 +39,7 @@ fun CurrencyInputView(
3939
errorContentDescription: String? = null,
4040
singleLine: Boolean = true,
4141
enableDecimal: Boolean = true,
42+
maxChars: Int? = null,
4243
) {
4344

4445
// pattern matches a decimal number
@@ -54,7 +55,7 @@ fun CurrencyInputView(
5455

5556
TextInputView(
5657
modifier = modifier,
57-
initialInputValue = initialInputValue,
58+
value = value,
5859
onInputValueChange = onInputValueChange,
5960
inputFilter = { it: String, localValue: String -> decimalPatternChecker(it, localValue) },
6061
labelText = labelText,
@@ -73,7 +74,8 @@ fun CurrencyInputView(
7374
singleLine = singleLine,
7475
keyboardOptions = KeyboardOptions(
7576
keyboardType = if (enableDecimal) KeyboardType.Decimal else KeyboardType.Number
76-
)
77+
),
78+
maxChars = maxChars
7779
)
7880
}
7981

components-compose/src/main/java/uk/gov/hmrc/components/compose/molecule/input/TextInputView.kt

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ object TextInputView {
5656
@Composable
5757
operator fun invoke(
5858
modifier: Modifier = Modifier,
59-
initialInputValue: String = "",
59+
value: String? = null,
6060
onInputValueChange: ((String) -> Unit)? = null,
6161
inputFilter: ((String, String) -> String)? = null,
6262
labelText: String? = null,
@@ -68,10 +68,13 @@ object TextInputView {
6868
errorText: String? = null,
6969
errorContentDescription: String? = null,
7070
characterCount: Int? = null,
71+
maxChars: Int? = null,
7172
singleLine: Boolean = false,
7273
keyboardOptions: KeyboardOptions = KeyboardOptions.Default
7374
) {
74-
var localValue: String by rememberSaveable { mutableStateOf(initialInputValue) }
75+
var localValue: String by rememberSaveable { mutableStateOf(value.orEmpty()) }
76+
localValue = value.orEmpty()
77+
7578
var localError: String? by rememberSaveable { mutableStateOf(null) }
7679
localError = errorText
7780

@@ -142,10 +145,13 @@ object TextInputView {
142145
isError = !localError.isNullOrEmpty() || (localValue.length > (characterCount ?: Int.MAX_VALUE)),
143146
value = localValue,
144147
onInputValueChange = { newValue ->
145-
if (onInputValueChange != null) { onInputValueChange(newValue) }
146-
localValue = if (inputFilter != null && newValue.isNotEmpty()) {
147-
inputFilter(newValue, localValue)
148-
} else newValue
148+
if (maxChars?.let { newValue.length <= it } != false) {
149+
localValue = if (inputFilter != null && newValue.isNotEmpty()) {
150+
val filteredValue = inputFilter(newValue, localValue)
151+
if (onInputValueChange != null) { onInputValueChange(filteredValue) }
152+
filteredValue
153+
} else newValue
154+
}
149155
},
150156
prefix = prefix,
151157
placeholderText = { placeholderText?.let { Text(text = it) } },

sample-compose-fragments/src/main/java/uk/gov/hmrc/sample_compose_fragments/presentation/screens/molecules/CurrencyInputViewScreen.kt

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,15 @@ package uk.gov.hmrc.sample_compose_fragments.presentation.screens.molecules
1717

1818
import androidx.compose.foundation.layout.padding
1919
import androidx.compose.runtime.Composable
20+
import androidx.compose.runtime.getValue
21+
import androidx.compose.runtime.mutableStateOf
22+
import androidx.compose.runtime.saveable.rememberSaveable
23+
import androidx.compose.runtime.setValue
2024
import androidx.compose.ui.Modifier
2125
import androidx.compose.ui.res.stringResource
2226
import androidx.lifecycle.compose.collectAsStateWithLifecycle
2327
import androidx.lifecycle.viewmodel.compose.viewModel
28+
import uk.gov.hmrc.components.compose.atom.text.BodyText
2429
import uk.gov.hmrc.components.compose.molecule.input.CurrencyInputView
2530
import uk.gov.hmrc.components.compose.organism.HmrcCardView
2631
import uk.gov.hmrc.components.compose.ui.theme.HmrcTheme
@@ -37,9 +42,17 @@ fun CurrencyInputViewScreen() {
3742

3843
val errorText = stringResource(id = R.string.currency_input_example_error)
3944

45+
var placeholderValue: String by rememberSaveable { mutableStateOf("") }
46+
var example1Value: String by rememberSaveable { mutableStateOf("") }
47+
var example2Value: String by rememberSaveable { mutableStateOf("") }
48+
var example3Value: String by rememberSaveable { mutableStateOf("123.45") }
49+
var example4Value: String by rememberSaveable { mutableStateOf("123.45") }
50+
4051
ScreenScrollViewColumn {
4152
PlaceholderSlot {
4253
CurrencyInputView(
54+
value = placeholderValue,
55+
onInputValueChange = { placeholderValue = it },
4356
labelText = stringResource(id = R.string.currency_input_placeholder_label),
4457
hintText = stringResource(id = R.string.currency_input_placeholder_hint),
4558
placeholderText = stringResource(id = R.string.currency_input_placeholder_placeholder),
@@ -50,36 +63,50 @@ fun CurrencyInputViewScreen() {
5063
ExamplesSlot {
5164
HmrcCardView {
5265
CurrencyInputView(
66+
value = example1Value,
5367
modifier = Modifier.padding(
5468
horizontal = HmrcTheme.dimensions.hmrcSpacing16,
5569
vertical = HmrcTheme.dimensions.hmrcSpacing24,
5670
),
57-
onInputValueChange = { viewModel.isEmptyValidation(it, errorText, 0) },
71+
onInputValueChange = {
72+
viewModel.isEmptyValidation(it, errorText, 0)
73+
example1Value = it
74+
},
5875
errorText = viewModel.textInputErrorEmptyValidation.collectAsStateWithLifecycle().value,
5976
labelText = stringResource(id = R.string.currency_input_example_1_label),
6077
hintText = stringResource(id = R.string.currency_input_example_1_hint),
61-
enableDecimal = true
78+
enableDecimal = true,
79+
maxChars = 4
6280
)
81+
BodyText(text = example1Value)
6382

6483
CurrencyInputView(
84+
value = example2Value,
6585
modifier = Modifier.padding(
6686
horizontal = HmrcTheme.dimensions.hmrcSpacing16,
6787
vertical = HmrcTheme.dimensions.hmrcSpacing24,
6888
),
69-
onInputValueChange = { viewModel.isEmptyValidation(it, errorText, 1) },
89+
onInputValueChange = {
90+
viewModel.isEmptyValidation(it, errorText, 1)
91+
example2Value = it
92+
},
7093
errorText = viewModel.textInputErrorEmptyValidation1.collectAsStateWithLifecycle().value,
7194
labelText = stringResource(id = R.string.currency_input_example_2_label),
7295
hintText = stringResource(id = R.string.currency_input_example_2_hint),
7396
enableDecimal = false
7497
)
98+
BodyText(text = example2Value)
7599

76100
CurrencyInputView(
77101
modifier = Modifier.padding(
78102
horizontal = HmrcTheme.dimensions.hmrcSpacing16,
79103
vertical = HmrcTheme.dimensions.hmrcSpacing24,
80104
),
81-
initialInputValue = stringResource(id = R.string.currency_input_example_3_text),
82-
onInputValueChange = { viewModel.isEmptyValidation(it, errorText, 2) },
105+
value = example3Value,
106+
onInputValueChange = {
107+
viewModel.isEmptyValidation(it, errorText, 2)
108+
example3Value = it
109+
},
83110
errorText = viewModel.textInputErrorEmptyValidation2.collectAsStateWithLifecycle().value,
84111
labelText = stringResource(id = R.string.currency_input_example_3_label),
85112
hintText = stringResource(id = R.string.currency_input_example_3_hint),
@@ -91,8 +118,11 @@ fun CurrencyInputViewScreen() {
91118
horizontal = HmrcTheme.dimensions.hmrcSpacing16,
92119
vertical = HmrcTheme.dimensions.hmrcSpacing24,
93120
),
94-
initialInputValue = stringResource(id = R.string.currency_input_example_3_text),
95-
onInputValueChange = { viewModel.isEmptyValidation(it, errorText, 3) },
121+
value = example4Value,
122+
onInputValueChange = {
123+
viewModel.isEmptyValidation(it, errorText, 3)
124+
example4Value = it
125+
},
96126
errorText = viewModel.textInputErrorEmptyValidation3.collectAsStateWithLifecycle().value,
97127
labelText = stringResource(id = R.string.currency_input_example_4_label),
98128
hintText = stringResource(id = R.string.currency_input_example_4_hint),

sample-compose-fragments/src/main/java/uk/gov/hmrc/sample_compose_fragments/presentation/screens/molecules/TextInputViewScreen.kt

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ package uk.gov.hmrc.sample_compose_fragments.presentation.screens.molecules
1717

1818
import androidx.compose.foundation.layout.padding
1919
import androidx.compose.runtime.Composable
20+
import androidx.compose.runtime.getValue
21+
import androidx.compose.runtime.mutableStateOf
22+
import androidx.compose.runtime.saveable.rememberSaveable
23+
import androidx.compose.runtime.setValue
2024
import androidx.compose.ui.Modifier
2125
import androidx.compose.ui.res.stringResource
2226
import androidx.lifecycle.compose.collectAsStateWithLifecycle
@@ -39,17 +43,26 @@ fun TextInputViewScreen() {
3943
val errorTextEx2 = stringResource(id = R.string.text_input_example_2_error)
4044
val errorTextEx3 = stringResource(id = R.string.text_input_example_3_error)
4145

46+
var placeholderValue: String by rememberSaveable { mutableStateOf("") }
47+
var example1Value: String by rememberSaveable { mutableStateOf("") }
48+
var example2Value: String by rememberSaveable { mutableStateOf("") }
49+
var example3Value: String by rememberSaveable { mutableStateOf("") }
50+
4251

4352
ScreenScrollViewColumn {
4453
val characterCount = 50
4554
PlaceholderSlot {
4655
TextInputView(
47-
onInputValueChange = { viewModel.validateCharCount(
48-
characterCount = characterCount,
49-
input = it,
50-
errorText = null,
51-
id = 0
52-
) },
56+
value = placeholderValue,
57+
onInputValueChange = {
58+
viewModel.validateCharCount(
59+
characterCount = characterCount,
60+
input = it,
61+
errorText = null,
62+
id = 0
63+
)
64+
placeholderValue = it
65+
},
5366
errorText = viewModel.textInputErrorCharCount.collectAsStateWithLifecycle().value,
5467
labelText = stringResource(id = R.string.text_input_placeholder_label),
5568
hintText = stringResource(id = R.string.text_input_placeholder_hint),
@@ -61,33 +74,46 @@ fun TextInputViewScreen() {
6174
ExamplesSlot {
6275
HmrcCardView {
6376
TextInputView(
77+
value = example1Value,
6478
modifier = Modifier.padding(
6579
horizontal = HmrcTheme.dimensions.hmrcSpacing16,
6680
vertical = HmrcTheme.dimensions.hmrcSpacing24,
6781
),
68-
onInputValueChange = { viewModel.validateCharCount(5, it, errorTextEx1, 1) },
82+
onInputValueChange = {
83+
viewModel.validateCharCount(5, it, errorTextEx1, 1)
84+
example1Value = it
85+
},
6986
errorText = viewModel.textInputErrorCharCount1.collectAsStateWithLifecycle().value,
7087
labelText = stringResource(R.string.text_input_example_1_hint),
7188
labelContentDescription = stringResource(R.string.text_input_example_1_content_description),
7289
characterCount = 5,
90+
maxChars = 5
7391
)
7492

7593
TextInputView(
94+
value = example2Value,
7695
modifier = Modifier.padding(
7796
horizontal = HmrcTheme.dimensions.hmrcSpacing16,
7897
vertical = HmrcTheme.dimensions.hmrcSpacing24,
7998
),
80-
onInputValueChange = { viewModel.isEmptyValidation(it, errorTextEx2, 0) },
99+
onInputValueChange = {
100+
viewModel.isEmptyValidation(it, errorTextEx2, 0)
101+
example2Value = it
102+
},
81103
errorText = viewModel.textInputError.collectAsStateWithLifecycle().value,
82104
hintText = stringResource(id = R.string.text_input_example_2_hint)
83105
)
84106

85107
TextInputView(
108+
value = example3Value,
86109
modifier = Modifier.padding(
87110
horizontal = HmrcTheme.dimensions.hmrcSpacing16,
88111
vertical = HmrcTheme.dimensions.hmrcSpacing24,
89112
),
90-
onInputValueChange = { viewModel.isEmptyValidation(it, errorTextEx3, 1) },
113+
onInputValueChange = {
114+
viewModel.isEmptyValidation(it, errorTextEx3, 1)
115+
example3Value = it
116+
},
91117
errorText = viewModel.textInputErrorEmptyValidation.collectAsStateWithLifecycle().value,
92118
labelText = stringResource(R.string.text_input_example_3_hint),
93119
singleLine = true

sample-compose-fragments/src/main/res/values/strings.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@
281281
<string name="currency_input_placeholder_hint">Hint</string>
282282
<string name="currency_input_placeholder_placeholder">Placeholder</string>
283283
<string name="currency_input_example_1_label">Pay amount</string>
284-
<string name="currency_input_example_1_hint">The value can be a decimal</string>
284+
<string name="currency_input_example_1_hint">The value can be a decimal but only 4 chars long</string>
285285
<string name="currency_input_example_2_label">Pay amount (pounds)</string>
286286
<string name="currency_input_example_2_hint">The value must not be a decimal</string>
287287
<string name="currency_input_example_3_label">Pay amount (pounds)</string>

0 commit comments

Comments
 (0)