Open lanitochka17 opened 3 days ago
Triggered auto assignment to @RachCHopkins (Bug
), see https://stackoverflow.com/c/expensify/questions/14418 for more details. Please add this bug to a GH project, as outlined in the SO.
When opening group´s name tab to edit it, the input should be displayed at the end of the group´s name
1) The underlying component for TextInput accepts a prop selection={{start, end}} to control the cursor position, ensuring it is displayed at the end of the text value. This prop needs to be passed from the GroupChatNameEditPage to achieve the desired behaviour https://github.com/Expensify/App/blob/3ebe8520d74c57a2fe9548b7d4307206e2b7c673/src/pages/GroupChatNameEditPage.tsx#L102
2) In addition to this, the selection prop is only supported in the native environment. For the web environment, additional logic is required to achieve the desired behaviour. This can be implemented by setting the selectionRange
and scrollLeft
on the inputRef
explicitly to ensure the cursor is positioned at the end of the text value.
https://github.com/Expensify/App/blob/3ebe8520d74c57a2fe9548b7d4307206e2b7c673/src/components/TextInput/BaseTextInput/index.tsx#L32
1) Add the selection
prop with the value selection={{start: currentChatName?.length ?? 0, end: currentChatName?.length ?? 0}}
to the InputWrapper
in the GroupChatNameEditPage
https://github.com/Expensify/App/blob/3ebe8520d74c57a2fe9548b7d4307206e2b7c673/src/pages/GroupChatNameEditPage.tsx#L102
2) Add a useEffect
in the web implementation of BaseTextInput to handle text selection and scrolling. The effect listens for changes to isFocused
and inputProps.selection
. When triggered, it validates the selection props and sets the cursor or selection range using setSelectionRange. Additionally, it adjusts the scrollLeft property of the input element to ensure the text is scrolled to the end if necessary.
https://github.com/Expensify/App/blob/3ebe8520d74c57a2fe9548b7d4307206e2b7c673/src/components/TextInput/BaseTextInput/index.tsx#L32
useEffect(() => {
const inputElement = input.current;
// Set selection range and handle scrolling
inputElement.setSelectionRange(inputProps.selection.start, inputProps.selection.end);
inputElement.scrollLeft = inputElement.scrollWidth;
}, [isFocused, inputProps.selection]);
Works fine on iOS. I will need Android to test this properly
When trying to edit a group´s long name, the input shows the name in the middle and the user has to scroll to the right to reach the end of the name and the cursor
This issue is caused by the TextInputClearButton component. It works fine when shouldShowClearButton is false.
In Chrome (both macOS and Android), the input cursor automatically scrolls to the end when the input is focused. However, upon focusing on the input, there is logic to display the TextInputClearButton component: https://github.com/Expensify/App/blob/2d5479e4a416da6a4617476dbfba67541adeed68/src/components/TextInput/BaseTextInput/index.tsx#L430 This causes the input's width to reduce because the TextInputClearButton occupies some space, resulting in the input cursor becoming hidden.
We need to have a logic to scroll the input cursor to the end when the shouldShowClearButton is displayed. So we can update:
to:
{isFocused && !isReadOnly && shouldShowClearButton && !!value && (
<View
onLayout={() => {
if (!didScrollToEndRef.current) {
input.current.scrollLeft = input.current?.scrollWidth;
didScrollToEndRef.current = true;
}
}}
>
<TextInputClearButton onPressButton={() => setValue('')} />
</View>
)}
In the example above, I added an onLayout function that scrolls the input cursor to the end only the first time (when the input is auto-focused). For subsequent focuses, scrolling isn't necessary as those are triggered manually.
useEffect(() => {
if (!didScrollToEndRef.current && isFocused && !isReadOnly && shouldShowClearButton && !!value) {
input.current.scrollLeft = input.current?.scrollWidth;
didScrollToEndRef.current = true;
}
}, [isFocused, shouldShowClearButton, value, isReadOnly]);
to this place instead of using onLayout.
setTimeout(()=>{
inputRef.current.scrollLeft = inputRef.current?.scrollWidth;
}, 300)
to this place: https://github.com/Expensify/App/blob/2d5479e4a416da6a4617476dbfba67541adeed68/src/hooks/useAutoFocusInput.ts#L32
It will auto-scroll the input cursor to the end after 300ms
If you haven’t already, check out our contributing guidelines for onboarding and email contributors@expensify.com to request to join our Slack channel!
Version Number: 9.0.66-0 Reproducible in staging?: Y Reproducible in production?: Y If this was caught on HybridApp, is this reproducible on New Expensify Standalone?: N/A If this was caught during regression testing, add the test name, ID and link from TestRail: https://expensify.testrail.io/index.php?/tests/view/5256940&group_by=cases:section_id&group_order=asc&group_id=229067 Email or phone of affected tester (no customers): ibellicotest+36@gmail.com Issue reported by: Applause - Internal Team
Action Performed:
Expected Result:
When opening group´s name tab to edit it, the input should be displayed at the end of the group´s name
Actual Result:
When trying to edit a group´s long name, the input shows the name in the middle and the user has to scroll to the right to reach the end of the name and the cursor
Workaround:
Unknown
Platforms:
Which of our officially supported platforms is this issue occurring on?
Screenshots/Videos
Add any screenshot/video evidence
https://github.com/user-attachments/assets/50f318b3-a69a-477d-a83c-0cc22b01a44b
View all open jobs on GitHub