Skip to content

Commit

Permalink
[fix] TextInput cursor position with secureTextEntry
Browse files Browse the repository at this point in the history
On web, the cursor jumps to the start of the input when secureTextEntry is toggled.
Preserve and restore previous selection after secureTextEntry is toggled.

Close #2576
  • Loading branch information
Pedro Guerreiro authored and necolas committed Sep 19, 2023
1 parent 67a0bde commit 5e41208
Showing 1 changed file with 22 additions and 10 deletions.
32 changes: 22 additions & 10 deletions packages/react-native-web/src/exports/TextInput/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,15 @@ const TextInput: React.AbstractComponent<

const dimensions = React.useRef({ height: null, width: null });
const hostRef = React.useRef(null);
const prevSelection = React.useRef(null);
const prevSecureTextEntry = React.useRef(false);

React.useEffect(() => {
if (hostRef.current && prevSelection.current) {
setSelection(hostRef.current, prevSelection.current);
}
prevSecureTextEntry.current = secureTextEntry;
}, [secureTextEntry]);

const handleContentSizeChange = React.useCallback(
(hostNode) => {
Expand Down Expand Up @@ -324,18 +333,21 @@ const TextInput: React.AbstractComponent<
}

function handleSelectionChange(e) {
if (onSelectionChange) {
try {
const node = e.target;
const { selectionStart, selectionEnd } = node;
e.nativeEvent.selection = {
start: selectionStart,
end: selectionEnd
};
try {
const { selectionStart, selectionEnd } = e.target;
const selection = {
start: selectionStart,
end: selectionEnd
};
if (onSelectionChange) {
e.nativeEvent.selection = selection;
e.nativeEvent.text = e.target.value;
onSelectionChange(e);
} catch (e) {}
}
}
if (prevSecureTextEntry.current === secureTextEntry) {
prevSelection.current = selection;
}
} catch (e) {}
}

useLayoutEffect(() => {
Expand Down

0 comments on commit 5e41208

Please sign in to comment.