Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Cannot paste magic code on mWeb iOS #23254

Merged
16 changes: 7 additions & 9 deletions src/components/MagicCodeInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import FormHelpMessage from './FormHelpMessage';
import {withNetwork} from './OnyxProvider';
import networkPropTypes from './networkPropTypes';
import useNetwork from '../hooks/useNetwork';
import * as Browser from '../libs/Browser';

const propTypes = {
/** Information about the network */
Expand Down Expand Up @@ -264,11 +263,6 @@ function MagicCodeInput(props) {
}
};

// We need to check the browser because, in iOS Safari, an input in a container with its opacity set to
// 0 (completely transparent) cannot handle user interaction, hence the Paste option is never shown.
// Alternate styling will be applied based on this condition.
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
const isMobileSafari = Browser.isMobileSafari();

return (
<>
<View style={[styles.magicCodeInputContainer]}>
Expand All @@ -287,7 +281,8 @@ function MagicCodeInput(props) {
>
<Text style={[styles.magicCodeInput, styles.textAlignCenter]}>{decomposeString(props.value, props.maxLength)[index] || ''}</Text>
</View>
<View style={[StyleSheet.absoluteFillObject, styles.w100, isMobileSafari ? styles.bgTransparent : styles.opacity0]}>
{/* Hide the input above the text. Cannot set opacity to 0 as it would break pasting on iOS Safari. */}
<View style={[StyleSheet.absoluteFillObject, styles.w100, styles.bgTransparent]}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we always passing styles.bgTransparent here? Can you add some comment in the code above this to explain what purpose that serves?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a comment here.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tienifr bump!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading the comment made me wonder why would we need this now in the first place, what does it do?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is that we're basically doing a "hidden input" trick here.

Copy link
Collaborator

@Santhosh-Sellavel Santhosh-Sellavel Aug 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just curious. Because now we do the trick with styles and props on the TextInput itself. So I don't understand why would need this, let me know if am missing anything thanks!

<TextInput
ref={(ref) => (inputRefs.current[index] = ref)}
autoFocus={index === 0 && props.autoFocus && !props.shouldDelayFocus}
Expand All @@ -311,8 +306,11 @@ function MagicCodeInput(props) {
}}
onKeyPress={onKeyPress}
onFocus={(event) => onFocus(event, index)}
caretHidden={isMobileSafari}
inputStyle={[isMobileSafari ? styles.magicCodeInputTransparent : undefined]}
// Manually set selectionColor to make caret transparent.
// We cannot use caretHidden as it breaks the pasting function on Android.
selectionColor="transparent"
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
textInputContainerStyles={[styles.borderNone]}
tienifr marked this conversation as resolved.
Show resolved Hide resolved
inputStyle={[styles.inputTransparent]}
accessibilityRole={CONST.ACCESSIBILITY_ROLE.TEXT}
/>
</View>
Expand Down
21 changes: 14 additions & 7 deletions src/styles/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -2538,14 +2538,21 @@ const styles = {
lineHeight: variables.inputHeight,
},

magicCodeInputTransparent: {
// Manually style transparent, in iOS Safari, an input in a container with its opacity set to
// 0 (completely transparent) cannot handle user interaction, hence the Paste option is never shown
inputTransparent: {
color: 'transparent',
caretColor: 'transparent',
WebkitTextFillColor: 'transparent',
// After setting the input text color to transparent, it acquires the background-color.
// However, it is not possible to override the background-color directly as explained in this resource: https://developer.mozilla.org/en-US/docs/Web/CSS/:autofill
// Therefore, the transition effect needs to be delayed.
transitionDelay: '99999s',
// These properties are available in browser only
...(Browser.getBrowser()
? {
caretColor: 'transparent',
WebkitTextFillColor: 'transparent',
// After setting the input text color to transparent, it acquires the background-color.
// However, it is not possible to override the background-color directly as explained in this resource: https://developer.mozilla.org/en-US/docs/Web/CSS/:autofill
// Therefore, the transition effect needs to be delayed.
transitionDelay: '99999s',
}
: {}),
},

iouAmountText: {
Expand Down
Loading