Skip to content

Commit eabca80

Browse files
authored
feat(text-inputs): allow value of type TextFieldValue (#181)
1 parent fcb1a1e commit eabca80

File tree

16 files changed

+215
-1
lines changed

16 files changed

+215
-1
lines changed

sample/src/main/java/com/decathlon/compose/sample/screens/TextInputs.kt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import androidx.compose.runtime.mutableStateOf
1010
import androidx.compose.runtime.remember
1111
import androidx.compose.ui.Modifier
1212
import androidx.compose.ui.graphics.vector.rememberVectorPainter
13+
import androidx.compose.ui.text.TextRange
14+
import androidx.compose.ui.text.input.TextFieldValue
1315
import androidx.compose.ui.tooling.preview.Preview
1416
import androidx.compose.ui.unit.dp
1517
import androidx.navigation.NavController
@@ -116,6 +118,20 @@ object TextInputs : Screen {
116118
},
117119
)
118120
}
121+
item {
122+
VitaminTextInputs.Outlined(
123+
value = TextFieldValue(text = "Input", selection = TextRange(0, Integer.MAX_VALUE)),
124+
label = "Label",
125+
onValueChange = {},
126+
)
127+
}
128+
item {
129+
VitaminTextInputs.Outlined(
130+
value = TextFieldValue(text = "Input", selection = TextRange(2, 2)),
131+
label = "Label",
132+
onValueChange = {},
133+
)
134+
}
119135
item {
120136
VitaminTextInputs.Outlined(
121137
value = "",

text-inputs/text-inputs/src/main/java/com/decathlon/vitamin/compose/textinputs/VitaminTextInputs.kt

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import androidx.compose.ui.res.stringResource
3232
import androidx.compose.ui.semantics.disabled
3333
import androidx.compose.ui.semantics.semantics
3434
import androidx.compose.ui.text.TextStyle
35+
import androidx.compose.ui.text.input.TextFieldValue
3536
import androidx.compose.ui.text.input.VisualTransformation
3637
import androidx.compose.ui.text.style.TextAlign
3738
import androidx.compose.ui.text.style.TextOverflow
@@ -127,6 +128,88 @@ object VitaminTextInputs {
127128
)
128129
}
129130

131+
/**
132+
* Outlined text input to get an input value from the user.
133+
* @param value The value of your text input
134+
* @param label The label to be displayed inside the text input container and pushed at the top
135+
* of text input when the component takes the focus
136+
* @param onValueChange The callback to be called when the user type a new character
137+
* @param modifier The `Modifier` to be applied to the component
138+
* @param helperText The optional helper text to be displayed at the start bottom outside the text input container
139+
* @param counter The optional counter to be displayed the the end bottom outside the text input container
140+
* @param singleLine True if the text input doesn't extend their height, otherwise, false
141+
* @param maxLines The number of maximum lines the text input can have if the `singleLine` is set to `true`
142+
* @param readOnly True if you don't want open the keyboard when the user click on the text field
143+
* @param enabled True if you can type in the text input, otherwise false
144+
* @param transformation Transforms the visual representation of the input value
145+
* @param keyboardOptions When the text input emit an IME action, the corresponding callback is called
146+
* @param keyboardActions Software keyboard options that contains such as KeyboardType and ImeAction
147+
* @param interactionSource Representing the stream of interaction for the text input
148+
* @param colors The color to notify your user if they are in normal, error or success state
149+
* @param textStyle The typography of the text inside the text input
150+
* @param icon The optional trailing icon to be displayed at the end of the text input container
151+
*/
152+
@Composable
153+
fun Outlined(
154+
value: TextFieldValue,
155+
label: String,
156+
onValueChange: (TextFieldValue) -> Unit,
157+
modifier: Modifier = Modifier,
158+
helperText: String? = null,
159+
counter: Pair<Int, Int>? = null,
160+
singleLine: Boolean = false,
161+
maxLines: Int = Int.MAX_VALUE,
162+
readOnly: Boolean = false,
163+
enabled: Boolean = true,
164+
transformation: VisualTransformation = TextInputsTransformations.none,
165+
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
166+
keyboardActions: KeyboardActions = KeyboardActions.Default,
167+
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
168+
colors: TextInputStateColors = TextInputsState.normal(),
169+
textStyle: TextStyle = VitaminTheme.typography.text2,
170+
icon: @Composable (() -> Unit)? = null,
171+
) {
172+
VitaminTextInputLayoutImpl(
173+
helperText = helperText,
174+
counter = counter,
175+
colors = colors,
176+
enabled = enabled,
177+
textInput = {
178+
OutlinedTextField(
179+
value = value,
180+
onValueChange = onValueChange,
181+
label = { Text(text = label) },
182+
colors = colors.outlinedTextFieldColors(),
183+
textStyle = textStyle,
184+
visualTransformation = transformation,
185+
interactionSource = interactionSource,
186+
keyboardOptions = keyboardOptions,
187+
keyboardActions = keyboardActions,
188+
singleLine = singleLine,
189+
maxLines = maxLines,
190+
modifier = Modifier.fillMaxWidth().vtmnSemantics(helperText, counter),
191+
enabled = enabled,
192+
readOnly = readOnly,
193+
isError = colors.state == State.ERROR,
194+
trailingIcon = {
195+
if (icon != null && colors.state != State.SUCCESS) {
196+
icon()
197+
} else if (
198+
colors.imageVector != null &&
199+
(colors.state == State.SUCCESS || colors.state == State.ERROR)
200+
) {
201+
Icon(
202+
imageVector = colors.imageVector,
203+
contentDescription = null,
204+
)
205+
}
206+
},
207+
)
208+
},
209+
modifier = modifier,
210+
)
211+
}
212+
130213
/**
131214
* Outlined dropdown to get the input from a dropdown menu.
132215
* @param value The value of your text input
@@ -268,6 +351,88 @@ object VitaminTextInputs {
268351
)
269352
}
270353

354+
/**
355+
* Filled text input to get an input value from the user.
356+
* @param value The value of your text input
357+
* @param label The label to be displayed inside the text input container and pushed at the top
358+
* of text input when the component takes the focus
359+
* @param onValueChange The callback to be called when the user type a new character
360+
* @param modifier The `Modifier` to be applied to the component
361+
* @param helperText The optional helper text to be displayed at the start bottom outside the text input container
362+
* @param counter The optional counter to be displayed the the end bottom outside the text input container
363+
* @param maxLines The number of maximum lines the text input can have if the `singleLine` is set to `true`
364+
* @param singleLine True if the text input doesn't extend their height, otherwise, false
365+
* @param readOnly True if you don't want open the keyboard when the user click on the text field
366+
* @param enabled True if you can type in the text input, otherwise false
367+
* @param transformation Transforms the visual representation of the input value
368+
* @param keyboardOptions When the text input emit an IME action, the corresponding callback is called
369+
* @param keyboardActions Software keyboard options that contains such as KeyboardType and ImeAction
370+
* @param interactionSource Representing the stream of interaction for the text input
371+
* @param colors The color to notify your user if they are in normal, error or success state
372+
* @param textStyle The typography of the text inside the text input
373+
* @param icon The optional trailing icon to be displayed at the end of the text input container
374+
*/
375+
@Composable
376+
fun Filled(
377+
value: TextFieldValue,
378+
label: String,
379+
onValueChange: (TextFieldValue) -> Unit,
380+
modifier: Modifier = Modifier,
381+
helperText: String? = null,
382+
counter: Pair<Int, Int>? = null,
383+
maxLines: Int = Int.MAX_VALUE,
384+
singleLine: Boolean = false,
385+
readOnly: Boolean = false,
386+
enabled: Boolean = true,
387+
transformation: VisualTransformation = TextInputsTransformations.none,
388+
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
389+
keyboardActions: KeyboardActions = KeyboardActions.Default,
390+
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
391+
colors: TextInputStateColors = TextInputsState.normal(),
392+
textStyle: TextStyle = VitaminTheme.typography.text2,
393+
icon: @Composable (() -> Unit)? = null,
394+
) {
395+
VitaminTextInputLayoutImpl(
396+
helperText = helperText,
397+
counter = counter,
398+
colors = colors,
399+
enabled = enabled,
400+
textInput = {
401+
TextField(
402+
value = value,
403+
onValueChange = onValueChange,
404+
label = { Text(text = label) },
405+
colors = colors.textFieldColors(),
406+
textStyle = textStyle,
407+
visualTransformation = transformation,
408+
interactionSource = interactionSource,
409+
keyboardOptions = keyboardOptions,
410+
keyboardActions = keyboardActions,
411+
singleLine = singleLine,
412+
maxLines = maxLines,
413+
modifier = Modifier.fillMaxWidth().vtmnSemantics(helperText, counter),
414+
enabled = enabled,
415+
isError = colors.state == State.ERROR,
416+
readOnly = readOnly,
417+
trailingIcon = {
418+
if (icon != null && colors.state != State.SUCCESS) {
419+
icon()
420+
} else if (
421+
colors.imageVector != null &&
422+
(colors.state == State.SUCCESS || colors.state == State.ERROR)
423+
) {
424+
Icon(
425+
imageVector = colors.imageVector,
426+
contentDescription = null,
427+
)
428+
}
429+
},
430+
)
431+
},
432+
modifier = modifier,
433+
)
434+
}
435+
271436
/**
272437
* Filled dropdown to get the input from a dropdown menu.
273438
* @param value The value of your text input

text-inputs/text-inputs/src/test/kotlin/com/decathlon/vitamin/compose/textinputs/utils/TextInputVariantsFactory.kt

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package com.decathlon.vitamin.compose.textinputs.utils
22

33
import androidx.compose.runtime.Composable
44
import androidx.compose.ui.Modifier
5+
import androidx.compose.ui.text.TextRange
6+
import androidx.compose.ui.text.input.TextFieldValue
57
import com.decathlon.vitamin.compose.textinputs.TextInputStateColors
68
import com.decathlon.vitamin.compose.textinputs.VitaminTextInputs
79

@@ -17,6 +19,7 @@ object TextInputVariantsFactory {
1719
icon: @Composable (() -> Unit)? = null,
1820
label: String = "Input",
1921
value: String = "",
22+
valueTextFieldValue: TextFieldValue = TextFieldValue("", TextRange.Zero),
2023
counter: Pair<Int, Int>? = Pair(9999, 9999),
2124
helperText: String? = "Helper text",
2225
) {
@@ -34,6 +37,21 @@ object TextInputVariantsFactory {
3437
value = value,
3538
helperText = helperText
3639
)
40+
41+
Variant.OutlinedTextFieldValue -> VitaminTextInputs.Outlined(
42+
modifier = modifier,
43+
label = label,
44+
enabled = enabled,
45+
onValueChange = {
46+
// Nothing to do here
47+
},
48+
colors = colors,
49+
icon = icon,
50+
counter = counter,
51+
value = valueTextFieldValue,
52+
helperText = helperText
53+
)
54+
3755
Variant.OutlinedDropdown -> VitaminTextInputs.OutlinedDropdown(
3856
label = label,
3957
enabled = enabled,
@@ -55,6 +73,21 @@ object TextInputVariantsFactory {
5573
value = value,
5674
helperText = helperText
5775
)
76+
77+
Variant.FilledTextFieldValue -> VitaminTextInputs.Filled(
78+
modifier = modifier,
79+
label = label,
80+
enabled = enabled,
81+
onValueChange = {
82+
// Nothing to do here
83+
},
84+
colors = colors,
85+
icon = icon,
86+
counter = counter,
87+
value = valueTextFieldValue,
88+
helperText = helperText
89+
)
90+
5891
Variant.FilledDropdown -> VitaminTextInputs.FilledDropdown(
5992
label = label,
6093
enabled = enabled,
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
package com.decathlon.vitamin.compose.textinputs.utils
22

33
enum class Variant {
4-
Outlined, OutlinedDropdown, Filled, FilledDropdown
4+
Outlined, OutlinedTextFieldValue, OutlinedDropdown, Filled, FilledTextFieldValue, FilledDropdown
55
}

0 commit comments

Comments
 (0)