Skip to content

Commit b4cd909

Browse files
committed
Add rich text for text input and its counterparts
1 parent beffa47 commit b4cd909

7 files changed

Lines changed: 1273 additions & 24 deletions

File tree

core/src/main/java/com/orange/ouds/core/component/OudsPasswordInput.kt

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
3838
import androidx.compose.ui.unit.Density
3939
import com.orange.ouds.core.R
4040
import com.orange.ouds.core.component.common.OudsError
41+
import com.orange.ouds.core.component.common.text.OudsAnnotatedHelperText
4142
import com.orange.ouds.core.extensions.collectInteractionStateAsState
4243
import com.orange.ouds.core.theme.OudsTheme
4344
import com.orange.ouds.core.utilities.OudsPreview
@@ -119,6 +120,145 @@ fun OudsPasswordInput(
119120
onKeyboardAction: KeyboardActionHandler? = null,
120121
onTextLayout: (Density.(getResult: () -> TextLayoutResult?) -> Unit)? = null,
121122
interactionSource: MutableInteractionSource? = null
123+
) {
124+
OudsPasswordInput(
125+
state = state,
126+
modifier = modifier,
127+
label = label,
128+
placeholder = placeholder,
129+
lockIcon = lockIcon,
130+
prefix = prefix,
131+
enabled = enabled,
132+
readOnly = readOnly,
133+
loader = loader,
134+
outlined = outlined,
135+
error = error,
136+
helperText = helperText,
137+
annotatedHelperText = null,
138+
constrainedMaxWidth = constrainedMaxWidth,
139+
inputTransformation = inputTransformation,
140+
keyboardOptions = keyboardOptions,
141+
onKeyboardAction = onKeyboardAction,
142+
onTextLayout = onTextLayout,
143+
interactionSource = interactionSource
144+
)
145+
}
146+
147+
/**
148+
* Password input is a UI element that allows to securely and confidentially capture a user's password.
149+
* Password Input enhances privacy by replacing characters with dots, while they are being typed; and also embeds usability features such as the ability
150+
* to show and hide password, and helper text to guide password creation.
151+
*
152+
* Rounded corners can be enabled or disabled using [OudsThemeSettings.roundedCornerTextInputs] property in the settings of the theme provided when calling
153+
* the [com.orange.ouds.core.theme.OudsTheme] method.
154+
*
155+
* > Design guidelines: [unified-design-system.orange.com](https://r.orange.fr/r/S-ouds-doc-password-input)
156+
*
157+
* > Design version: 1.2.0
158+
*
159+
* @param state The editable text state of the password input, including the text itself, position of the cursor or selection and the text obfuscation mode.
160+
* @param modifier [Modifier] applied to the password input.
161+
* @param label Label displayed above the password input. It describes the purpose of the input.
162+
* @param placeholder Text displayed when the password input is empty. It provides a hint or guidance inside the field to suggest expected input.
163+
* @param lockIcon When `true`, a lock icon is displayed at the start of the password input to visually reinforce the security context. Defaults to `false`.
164+
* @param prefix Text placed before the user's input. A prefix is not common and is discouraged in a Password Input component. In very specific cases,
165+
* it can provide context or format requirements (e.g., “DEV-” for test accounts, "admin-" as a pattern to define an admin password)
166+
* @param enabled Controls the enabled state of the password input. When `false`, this password input will not be focusable and will not react to input events.
167+
* True by default.
168+
* @param readOnly Controls the read-only state of the password input. When `true`, the text is visible but not editable.
169+
* False by default.
170+
* @param loader An optional loading progress indicator displayed in the password input to indicate an ongoing operation.
171+
* @param outlined Controls the style of the password input. When `true`, it displays a minimalist password input with a transparent background and a visible
172+
* stroke outlining the field.
173+
* @param error Optional [OudsError] to indicate that the user input does not meet validation rules or expected formatting. Pass `null` if there is no error.
174+
* @param helperText An annotated helper text displayed below the password input. It conveys additional information about the input field, such as how it will be
175+
* used. It should ideally only take up a single line, though it may wrap to multiple lines if required.
176+
* @param constrainedMaxWidth When `true`, the password input width is constrained to a maximum value defined by the design system.
177+
* When `false`, no specific width constraint is applied, allowing the component to size itself or follow external modifiers.
178+
* Defaults to `false`.
179+
* @param inputTransformation An optional [InputTransformation] that will be used to transform changes to the [OudsPasswordInputState] made by the user. The transformation
180+
* will be applied to changes made by hardware and software keyboard events, pasting or dropping text, accessibility services, and tests. The transformation
181+
* will _not_ be applied when changing the [state] programmatically, or when the transformation is changed. If the transformation is changed on an
182+
* existing text field, it will be applied to the next user edit. The transformation will not immediately affect the current [state].
183+
* @param keyboardOptions Software keyboard options that contain configurations such as [KeyboardType] and [ImeAction].
184+
* @param onKeyboardAction Called when the user presses the action button in the input method editor (IME), or by pressing the enter key on a hardware keyboard.
185+
* By default this parameter is null, and would execute the default behavior for a received IME Action e.g., [ImeAction.Done] would close the keyboard,
186+
* [ImeAction.Next] would switch the focus to the next focusable item on the screen.
187+
* @param onTextLayout Callback that is executed when a new text layout is calculated. A [TextLayoutResult] object that callback provides contains paragraph
188+
* information, size of the text, baselines and other details. The callback can be used to add additional decoration or functionality to the text.
189+
* For example, to draw a cursor or selection around the text.
190+
* @param interactionSource An optional hoisted [MutableInteractionSource] for observing and emitting [Interaction]s for this password input. Note that if `null`
191+
* is provided, interactions will still happen internally.
192+
*
193+
* @sample com.orange.ouds.core.component.samples.OudsPasswordInputSample
194+
*
195+
* @sample com.orange.ouds.core.component.samples.OudsPasswordInputErrorSample
196+
*/
197+
@Composable
198+
fun OudsPasswordInput(
199+
state: OudsPasswordInputState,
200+
modifier: Modifier = Modifier,
201+
label: String? = null,
202+
placeholder: String? = null,
203+
lockIcon: Boolean = false,
204+
prefix: String? = null,
205+
enabled: Boolean = true,
206+
readOnly: Boolean = false,
207+
loader: OudsTextInputLoader? = null,
208+
outlined: Boolean = false,
209+
error: OudsError? = null,
210+
helperText: OudsAnnotatedHelperText,
211+
constrainedMaxWidth: Boolean = false,
212+
inputTransformation: InputTransformation? = null,
213+
keyboardOptions: KeyboardOptions = OudsPasswordInputDefaults.KeyboardOptions,
214+
onKeyboardAction: KeyboardActionHandler? = null,
215+
onTextLayout: (Density.(getResult: () -> TextLayoutResult?) -> Unit)? = null,
216+
interactionSource: MutableInteractionSource? = null
217+
) {
218+
OudsPasswordInput(
219+
state = state,
220+
modifier = modifier,
221+
label = label,
222+
placeholder = placeholder,
223+
lockIcon = lockIcon,
224+
prefix = prefix,
225+
enabled = enabled,
226+
readOnly = readOnly,
227+
loader = loader,
228+
outlined = outlined,
229+
error = error,
230+
helperText = null,
231+
annotatedHelperText = helperText,
232+
constrainedMaxWidth = constrainedMaxWidth,
233+
inputTransformation = inputTransformation,
234+
keyboardOptions = keyboardOptions,
235+
onKeyboardAction = onKeyboardAction,
236+
onTextLayout = onTextLayout,
237+
interactionSource = interactionSource
238+
)
239+
}
240+
241+
@Composable
242+
private fun OudsPasswordInput(
243+
state: OudsPasswordInputState,
244+
modifier: Modifier = Modifier,
245+
label: String? = null,
246+
placeholder: String? = null,
247+
lockIcon: Boolean = false,
248+
prefix: String? = null,
249+
enabled: Boolean = true,
250+
readOnly: Boolean = false,
251+
loader: OudsTextInputLoader? = null,
252+
outlined: Boolean = false,
253+
error: OudsError? = null,
254+
helperText: String? = null,
255+
annotatedHelperText: OudsAnnotatedHelperText? = null,
256+
constrainedMaxWidth: Boolean = false,
257+
inputTransformation: InputTransformation? = null,
258+
keyboardOptions: KeyboardOptions = OudsPasswordInputDefaults.KeyboardOptions,
259+
onKeyboardAction: KeyboardActionHandler? = null,
260+
onTextLayout: (Density.(getResult: () -> TextLayoutResult?) -> Unit)? = null,
261+
interactionSource: MutableInteractionSource? = null
122262
) {
123263
@Suppress("NAME_SHADOWING") val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
124264
val interactionState by interactionSource.collectInteractionStateAsState()
@@ -168,6 +308,7 @@ fun OudsPasswordInput(
168308
outlined = outlined,
169309
error = error,
170310
helperText = helperText,
311+
annotatedHelperText = annotatedHelperText,
171312
helperLink = null,
172313
constrainedMaxWidth = constrainedMaxWidth
173314
)

core/src/main/java/com/orange/ouds/core/component/OudsPinCodeInput.kt

Lines changed: 90 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ import androidx.constraintlayout.compose.ConstraintLayout
6666
import androidx.constraintlayout.compose.Dimension
6767
import com.orange.ouds.core.R
6868
import com.orange.ouds.core.component.common.OudsError
69+
import com.orange.ouds.core.component.common.text.OudsAnnotatedHelperText
6970
import com.orange.ouds.core.extensions.InteractionState
7071
import com.orange.ouds.core.extensions.collectInteractionStateAsState
7172
import com.orange.ouds.core.theme.OudsTheme
@@ -112,7 +113,6 @@ import kotlinx.coroutines.launch
112113
*
113114
* @sample com.orange.ouds.core.component.samples.OudsPinCodeInputErrorSample
114115
*/
115-
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
116116
@Composable
117117
fun OudsPinCodeInput(
118118
value: String,
@@ -124,6 +124,91 @@ fun OudsPinCodeInput(
124124
helperText: String? = null,
125125
onKeyboardAction: KeyboardActionHandler? = null,
126126
interactionSource: MutableInteractionSource? = null
127+
) {
128+
OudsPinCodeInput(
129+
value = value,
130+
onValueChange = onValueChange,
131+
modifier = modifier,
132+
length = length,
133+
outlined = outlined,
134+
error = error,
135+
helperText = helperText,
136+
annotatedHelperText = null,
137+
onKeyboardAction = onKeyboardAction,
138+
interactionSource = interactionSource
139+
)
140+
}
141+
142+
/**
143+
* PIN code input is a UI element that allows to capture short, fixed-length numeric codes, typically for authentication or confirmation purposes, such as a
144+
* four, six or eight-digit personal identification number (PIN). PIN code input is presented as a series of individual input fields or boxes, each
145+
* representing a single digit, to enhance readability and encourage accurate input, while supporting smooth keyboard navigation and secured input masking if
146+
* needed.
147+
*
148+
* Rounded corners can be enabled or disabled using [OudsThemeSettings.roundedCornerTextInputs] property in the settings of the theme provided when calling
149+
* the [com.orange.ouds.core.theme.OudsTheme] method.
150+
*
151+
* > Design guidelines: [unified-design-system.orange.com](https://r.orange.fr/r/S-ouds-doc-pin-code-input)
152+
*
153+
* > Design version: 1.2.0
154+
*
155+
* @param value The current PIN code value as a string of digits. The value is automatically truncated to the specified [length].
156+
* @param onValueChange Callback invoked when the PIN code value changes. The updated PIN code value comes as a parameter of the callback.
157+
* @param modifier [Modifier] applied to the PIN code input.
158+
* @param length The number of digits in the PIN code. Defaults to [OudsPinCodeInputDefaults.Length].
159+
* @param outlined Controls the style of the PIN code input. When `true`, it displays a minimalist PIN code input with a transparent background and a visible
160+
* stroke outlining each digit box.
161+
* @param error Optional [OudsError] to indicate that the user input does not meet validation rules or expected formatting. Pass `null` if there is no error.
162+
* @param helperText An annotated helper text displayed below the PIN code input. It conveys additional information about the input field, such as how it will be
163+
* used. It should ideally only take up a single line, though it may wrap to multiple lines if required.
164+
* @param onKeyboardAction Called when the user presses the action button in the input method editor (IME), or by pressing the enter key on a hardware keyboard.
165+
* By default, this parameter is null, and would execute the default behavior for a received IME Action e.g., [androidx.compose.ui.text.input.ImeAction.Done] would close the keyboard,
166+
* [androidx.compose.ui.text.input.ImeAction.Next] would switch the focus to the next focusable item on the screen.
167+
* @param interactionSource An optional hoisted [MutableInteractionSource] for observing and emitting [Interaction]s for this PIN code input. Note that if `null`
168+
* is provided, interactions will still happen internally.
169+
*
170+
* @sample com.orange.ouds.core.component.samples.OudsPinCodeInputSample
171+
*
172+
* @sample com.orange.ouds.core.component.samples.OudsPinCodeInputErrorSample
173+
*/
174+
@Composable
175+
fun OudsPinCodeInput(
176+
value: String,
177+
onValueChange: (String) -> Unit,
178+
modifier: Modifier = Modifier,
179+
length: OudsPinCodeInputLength = OudsPinCodeInputDefaults.Length,
180+
outlined: Boolean = false,
181+
error: OudsError? = null,
182+
helperText: OudsAnnotatedHelperText,
183+
onKeyboardAction: KeyboardActionHandler? = null,
184+
interactionSource: MutableInteractionSource? = null
185+
) {
186+
OudsPinCodeInput(
187+
value = value,
188+
onValueChange = onValueChange,
189+
modifier = modifier,
190+
length = length,
191+
outlined = outlined,
192+
error = error,
193+
helperText = null,
194+
annotatedHelperText = helperText,
195+
onKeyboardAction = onKeyboardAction,
196+
interactionSource = interactionSource
197+
)
198+
}
199+
200+
@Composable
201+
private fun OudsPinCodeInput(
202+
value: String,
203+
onValueChange: (String) -> Unit,
204+
modifier: Modifier = Modifier,
205+
length: OudsPinCodeInputLength = OudsPinCodeInputDefaults.Length,
206+
outlined: Boolean = false,
207+
error: OudsError? = null,
208+
helperText: String? = null,
209+
annotatedHelperText: OudsAnnotatedHelperText? = null,
210+
onKeyboardAction: KeyboardActionHandler? = null,
211+
interactionSource: MutableInteractionSource? = null
127212
) {
128213
@Suppress("NAME_SHADOWING") val interactionSource = interactionSource ?: remember { MutableInteractionSource() }
129214
val paddedValue = value.take(length.value).padEnd(length.value, OudsDigitInputPlaceholder)
@@ -172,6 +257,7 @@ fun OudsPinCodeInput(
172257
outlined = outlined,
173258
error = error,
174259
helperText = helperText,
260+
annotatedHelperText = annotatedHelperText,
175261
onDigitClick = {
176262
focusRequester.requestFocus()
177263
// If keyboard is dismissed using the Android back key, the keyboard won't reappear when digit is clicked
@@ -234,6 +320,7 @@ private fun OudsPinCodeInputDecorator(
234320
outlined: Boolean,
235321
error: OudsError?,
236322
helperText: String?,
323+
annotatedHelperText: OudsAnnotatedHelperText?,
237324
onDigitClick: (Int) -> Unit,
238325
interactionSource: MutableInteractionSource
239326
) {
@@ -290,7 +377,8 @@ private fun OudsPinCodeInputDecorator(
290377
},
291378
enabled = true,
292379
error = error,
293-
helperText = helperText
380+
helperText = helperText,
381+
annotatedHelperText = annotatedHelperText
294382
)
295383
}
296384
}

0 commit comments

Comments
 (0)