@@ -6,6 +6,9 @@ import androidx.compose.foundation.focusGroup
66import androidx.compose.foundation.layout.*
77import androidx.compose.foundation.text.KeyboardActions
88import androidx.compose.foundation.text.KeyboardOptions
9+ import androidx.compose.foundation.text.contextmenu.builder.item
10+ import androidx.compose.foundation.text.contextmenu.modifier.appendTextContextMenuComponents
11+ import androidx.compose.foundation.text.contextmenu.modifier.filterTextContextMenuComponents
912import androidx.compose.runtime.*
1013import androidx.compose.ui.Alignment
1114import androidx.compose.ui.Modifier
@@ -30,15 +33,16 @@ import com.processout.sdk.ui.core.component.PORequestFocus
3033import com.processout.sdk.ui.core.component.POText
3134import com.processout.sdk.ui.core.component.field.POField
3235import com.processout.sdk.ui.core.component.field.POField.stateStyle
36+ import com.processout.sdk.ui.core.component.field.code.POCodeField.ContextMenuPasteKey
3337import com.processout.sdk.ui.core.component.field.code.POCodeField.align
3438import com.processout.sdk.ui.core.component.field.code.POCodeField.rememberTextFieldWidth
3539import com.processout.sdk.ui.core.component.field.code.POCodeField.validLength
3640import com.processout.sdk.ui.core.component.field.text.POTextField
37- import com.processout.sdk.ui.core.component.texttoolbar.ProcessOutTextToolbar
3841import com.processout.sdk.ui.core.state.POInputFilter
3942import com.processout.sdk.ui.core.theme.ProcessOutTheme.colors
4043import com.processout.sdk.ui.core.theme.ProcessOutTheme.spacing
4144import com.processout.sdk.ui.core.theme.ProcessOutTheme.typography
45+ import kotlinx.coroutines.launch
4246
4347/* * @suppress */
4448@ProcessOutInternalApi
@@ -111,31 +115,7 @@ private fun Code(
111115 keyboardActions : KeyboardActions ,
112116 modifier : Modifier = Modifier
113117) {
114- val validLength = remember(length) { validLength(length) }
115- var values by remember(validLength) { mutableStateOf(values(value.text, validLength, inputFilter)) }
116- var focusedIndex by remember(validLength) { mutableIntStateOf(values.focusedIndex()) }
117- val clipboardManager = LocalClipboardManager .current
118- CompositionLocalProvider (
119- LocalLayoutDirection provides LayoutDirection .Ltr ,
120- LocalTextToolbar provides ProcessOutTextToolbar (
121- view = LocalView .current,
122- onPasteRequested = {
123- if (clipboardManager.hasText()) {
124- val pastedValues = values(
125- text = clipboardManager.getText()?.text ? : String (),
126- length = validLength,
127- inputFilter = inputFilter
128- )
129- if (! pastedValues.all { it.text.isEmpty() }) {
130- values = pastedValues
131- focusedIndex = values.focusedIndex()
132- onValueChange(values.codeValue())
133- }
134- }
135- },
136- hideUnspecifiedActions = true
137- )
138- ) {
118+ CompositionLocalProvider (LocalLayoutDirection provides LayoutDirection .Ltr ) {
139119 var rowWidthPx by remember { mutableIntStateOf(0 ) }
140120 val horizontalSpace = spacing.space8
141121 Row (
@@ -146,7 +126,15 @@ private fun Code(
146126 horizontalArrangement = Arrangement .spacedBy(horizontalSpace),
147127 verticalAlignment = Alignment .CenterVertically
148128 ) {
129+ val context = LocalContext .current
130+ val clipboard = LocalClipboard .current
149131 val focusManager = LocalFocusManager .current
132+ val coroutineScope = rememberCoroutineScope()
133+
134+ val validLength = remember(length) { validLength(length) }
135+ var values by remember(validLength) { mutableStateOf(values(value.text, validLength, inputFilter)) }
136+ var focusedIndex by remember(validLength) { mutableIntStateOf(values.focusedIndex()) }
137+
150138 for (textFieldIndex in values.indices) {
151139 val focusRequester = remember { FocusRequester () }
152140 POTextField (
@@ -225,6 +213,31 @@ private fun Code(
225213 }
226214 false
227215 }
216+ .appendTextContextMenuComponents {
217+ item(
218+ key = ContextMenuPasteKey ,
219+ label = context.getString(android.R .string.paste)
220+ ) {
221+ coroutineScope.launch {
222+ val pastedText = clipboard.getClipEntry()?.clipData
223+ ?.getItemAt(0 )?.text?.toString() ? : String ()
224+ val pastedValues = values(
225+ text = pastedText,
226+ length = validLength,
227+ inputFilter = inputFilter
228+ )
229+ if (! pastedValues.all { it.text.isEmpty() }) {
230+ values = pastedValues
231+ focusedIndex = values.focusedIndex()
232+ onValueChange(values.codeValue())
233+ }
234+ close()
235+ }
236+ }
237+ }
238+ .filterTextContextMenuComponents {
239+ it.key == ContextMenuPasteKey
240+ }
228241 .focusRequester(focusRequester)
229242 .onFocusChanged {
230243 if (it.isFocused) {
@@ -289,6 +302,8 @@ private fun List<TextFieldValue>.codeValue() = TextFieldValue(
289302@ProcessOutInternalApi
290303object POCodeField {
291304
305+ data object ContextMenuPasteKey
306+
292307 val default: POField .Style
293308 @Composable get() = POField .default.let {
294309 val text = POText .Style (
0 commit comments