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

Standardize arrow navigation in OptionsLists #7702

Merged
merged 132 commits into from
Jun 27, 2022

Conversation

roryabraham
Copy link
Contributor

@roryabraham roryabraham commented Feb 11, 2022

Details

  • Creates the ArrowKeyFocusManager component, which takes a few generic props and uses the arrow keys to manage a focusedIndex state.
  • Removes the keyboard event handling from the OptionsSelector component in preference of the ArrowKeyFocusManager
  • Implements ArrowKeyFocusManager in the IOUConfirmationList component
  • Implements scrollToIndex correctly for sections lists
  • Includes several performance improvements

Notable changes

The IOU currency page used to have an inconsistent UX compared to our other list pages. This PR DRYs that, gives it support for arrow navigation, and makes the UX consistent with other list pages. The behavior before was:

  1. When you open the IOU currency page, the full list appears, and the current currency is selected in the list (appears with a checkbox next to it).
  2. Selecting another currency deselects the current currency and selects another
  3. There is a "confirm" button that changes the currency to whatever is selected.

The new behavior is:

  1. When you open the IOU currency page, the full list appears
  2. Selecting another currency changes the currency to whatever is selected

Furthermore, it now supports mouseless use via arrow navigation / enter to submit.

Known Limitations

  • When a single item is selected, arrow navigation does not always scroll to the right position (the selected item is sometimes partially or fully covered)
  • On Android, selecting the first item from recents section, scrolls the list and hide the selected item

Fixed Issues

$ #7648

PR Reviewer Checklist

  • I verified the Author pulled main before submitting the PR
  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the testing environment is mentioned in the test steps
  • I verified testing steps cover success & fail scenarios (if applicable)
  • I verified tests pass on all platforms & I tested again on all platforms
  • I checked that screenshots or videos are included for tests on all platforms
  • I verified there are no console errors related to changes in this PR
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified comments were added when the code was not self explanatory
    • I verified any copy / text shown in the product was added in all src/languages/* files (if applicable)
    • I verified proper naming convention for platform-specific files was followed (if applicable)
    • I verified style guidelines were followed
  • I verified that this PR follows the guidelines as stated in the Review Guidelines

Tests / QA Steps

Log in to New Expensify.

Search Page

All Platforms
  1. Click/tap on the magnifying glass icon to open the search page.
  2. Click/tap on the x icon to close the search page.
  3. Click/tap on the magnifying glass to open the search page.
  4. Ensure you can scroll up and down in the results.
  5. Enter a search query – the list should update accordingly.
  6. Click/tap on a result: the search page should close and that chat should open.
Web/Desktop
  1. Press CMD+K to open the search page.
  2. Press Esc to close the search page.
  3. Press CMD+K to reopen the search page.
  4. Type in a search query.
  5. Use the arrow keys to go through the search results. Make sure that the list "wraps", so:
    1. If you are focused on the last result and press ArrowDown you are taken to the first result
    2. If you are focused on the first result and press ArrowUp you are taken to the last result
  6. With the focus somewhere in the middle of the list, update the search input such that there are no results.
  7. Press the arrow keys a few times – nothing should happen.
  8. Undo the change from the previous step – the focus should be where you left it and you should be able to use the arrows to navigate focus (as before)
  9. With a specific item focused, update the search term such that the position of that item moves up or down in the list.
  10. Verify that that same item remains focused (even though its position in the list changed).
  11. With a chat focused on the search page, press Enter. The search page should close and that chat should open.
  12. Use the mouse to click on the magnifying glass icon and reopen the search page.
  13. Press Esc to close the search page.
  14. Click on the magnifying glass to reopen the search page.
  15. Use the arrow keys and the enter key to select and open a different chat.

New Chat Page

All Platforms
  1. Click/tap on the green + icon on the home screen
  2. Click/tap on New Chat.
  3. Ensure that you can scroll the list of results.
  4. Enter a search query and the results should update accordingly.
  5. click/tap on a search result
  6. The New Chat Page should close and a chat with your selected result should open.
Web/Desktop
  1. Click on the green + icon on the home screen
  2. Click on New Chat
  3. Press ESC – the New Chat Page should close.
  4. Click on the green + icon on the home screen.
  5. Click on New Chat
  6. Use the arrow keys to traverse the list of results. Make sure that the list "wraps", so:
    1. If you are focused on the last result and press ArrowDown you are taken to the first result
    2. If you are focused on the first result and press ArrowUp you are taken to the last result
  7. With the focus somewhere in the middle of the list, update the search input such that there are no results.
  8. Press the arrow keys a few times – nothing should happen.
  9. Undo the change from the previous step – the focus should be where you left it and you should be able to use the arrows to navigate focus (as before)
  10. With a result highlighted, press Enter and that chat should open.
  11. Reopen the New Chat page and use the arrow keys to highlight a different chat than the one you have open.
  12. Press CMD+Enter and that chat should open.

New Group Page

All Platforms
  1. Click/tap on the green + icon on the home screen
  2. Click/tap on New Group.
  3. Ensure that you can scroll the list of results.
  4. Enter a search query and the results should update accordingly.
  5. Click/tap on a result. That result should become checked and move to the top of the results.
  6. Click/tap on another result. That result should become checked and move to the top of the results.
  7. Click/tap on Create Group. The New Group page should close and a chat with all the selected users should open.
Web/Desktop
  1. Click on the green + icon on the home screen.
  2. Click New Group. The New Group Page should open.
  3. Press ESC. The New Group page should close.
  4. Press CMD+SHIFT+K. The New Group Page should open.
  5. Press ESC. The New Group page should close.
  6. Reopen the New Group Page.
  7. If necessary, repeat the following until there are enough elements in the New Group page that the results are scrollable:
    1. Close the New Group page.
    2. Open the New Chat page.
    3. Create a chat with a user that you've not interacted with before.
    4. Reopen the New Group page and check if it's scrollable. If not, go back to the first step.
  8. Use the arrow keys to traverse the list of results. Make sure that the list "wraps". There is a notable difference in expected behavior between this page and the New Chat Page in that the search bar is one of the focusable elements.
    1. If you are focused on the last result and press ArrowDown you are taken to the search bar. None of the elements should be highlighted.
    2. If you are focused on the first result and press ArrowUp you are taken to the search bar. None of the elements should be highlighted.
    3. If you are focused on the search bar and press ArrowUp, you are taken to the last result.
    4. If you are focused on the search bar and press ArrowDown, you are taken to the first result.
  9. With one of the search results highlighted, press Enter. That result should get checked and move to the top of the list.
  10. Use the ArrowDown key to highlight the first unselected result. It should be completely visible.
  11. Use the arrow keys and Enter to select multiple results.
  12. Use the arrow keys to highlight a selected result.
  13. Press Enter to de-select that result.
  14. With a result highlighted, press CMD+Enter, and a group should be opened with your selected results.
  15. Reopen the New Group Page and select several results.
  16. Use the arrow keys to go to the search bar (no results highlighted).
  17. Press CMD+Enter, and a group should be opened with your selected results.
  18. Reopen the New Group Page and select several results.
  19. Use the arrow keys to go to the search bar (no results highlighted).
  20. Press Enter (not CMD+Enter), and a group should be opened with your selected results.

IOU Participants (split bill)

All Platforms
  1. Click/tap on the green + icon on the home screen.
  2. Click/tap on Split Bill
  3. Enter an amount.
  4. Ensure that you can scroll the list of results.
  5. Enter a search query and the results should update accordingly.
  6. Make sure you can toggle / untoggle list items.
  7. With some items selected and others not, press Next.
  8. Verify that you the selected items are shown on the next page.
Web/Desktop
  1. Click/tap on the green + icon on the home screen.
  2. Click/tap on Split Bill
  3. Enter an amount and press Next.
  4. Enter a search query to get a reasonable-length list of options.
  5. Use the arrow keys to traverse the list of results. Make sure that the list "wraps":
    1. If you are focused on the last result and press ArrowDown you are taken to the search bar. None of the elements should be highlighted.
    2. If you are focused on the first result and press ArrowUp you are taken to the search bar. None of the elements should be highlighted.
    3. If you are focused on the search bar and press ArrowUp, you are taken to the last result.
    4. If you are focused on the search bar and press ArrowDown, you are taken to the first result.
  6. With one of the search results highlighted, press Enter. That result should get checked and move to the top of the list.
  7. Use the arrow keys and Enter to select multiple results.
  8. Use the arrow keys to highlight a selected result.
  9. Press Enter to de-select that result.
  10. With a result highlighted, press CMD+Enter, and you should move to the next page with your selected results.
  11. Press the back arrow to go to the previous page.
  12. With the search bar focused (no results highlighted), press CMD+Enter, and you should move to the next page with your selected results.
  13. Press the back arrow to go to the previous page.
  14. With the search bar focused (no results highlighted), press Enter (not CMD+Enter), and you should move to the next page with your selected results.

IOU Participants (1:1 request)

All Platforms
  1. Click/tap on the green + icon on the home screen.
  2. Click/tap on Request Money
  3. Enter an amount and press Next
  4. Ensure that you can scroll the list of results.
  5. Enter a search query and the results should update accordingly.
  6. Click/tap on a result, and there should be a new IOU request between you and your selected user.
Web/Desktop
  1. Click/tap on the green + icon on the home screen.
  2. Click/tap on Request Money
  3. Enter an amount and press Next
  4. Enter a search query to get a reasonable-length list of results.
  5. Use the arrow keys to traverse the list of results. Make sure that the list "wraps":
    1. If you are focused on the last result and press ArrowDown you are taken to the first result
    2. If you are focused on the first result and press ArrowUp you are taken to the last result
  6. With a result highlighted, press Enter. That should take you to the next page with your selected user.
  7. Click on the back button.
  8. Use the arrow keys to highlight different result.
  9. Press CMD+Enter. That should take you to the next page with your new selected user.

IOU Confirmation List

All Platforms
  1. Click/tap on the green + icon on the home screen.
  2. Click/tap on Split Bill.
  3. Enter an amount and press Next.
  4. Select some participants and press Next.
  5. Make sure that you can not select or deselect participants.
  6. Hover the mouse over your participants – it should not change into a pointer cursor.
  7. Press Split YOUR_AMOUNT
  8. A new request should be created between you and each of your selected bill split participants.
  9. Open a group chat.
  10. Press the + in the composer and select Split Bill.
  11. Make sure you can select and deselect participants, and that their proportional amount adjusts accordingly.
  12. Hover your mouse over the participants – it should change into a pointer cursor and clicking on participants should select/deselect them.
  13. With some participants selected and others not, press Split YOUR_AMOUNT.
  14. A new request should be created between you and each of your selected bill split participants.
Web/Desktop
  1. Open a group chat.
  2. Click/tap on the + in the composer.
  3. Click/tap on Split Bill.
  4. Enter an amount and press Next.
  5. Use the arrow keys to highlight participants. Make sure that the list "wraps":
    1. If you are focused on the last result and press ArrowDown you are taken to the text input. None of the elements should be highlighted.
    2. If you are focused on the first result and press ArrowUp you are taken to the text input. None of the elements should be highlighted.
    3. If you are focused on the text input and press ArrowUp, you are taken to the last result.
    4. If you are focused on the text input and press ArrowDown, you are taken to the first result.
  6. With a result highlighted, pressing Enter should select and deselect participants, and their proportional amount should adjust accordingly.
  7. Deselect all participants.
  8. Press CMD + Enter. Verify that nothing happens (no IOU should be created with just yourself)
  9. Reselect one or more participants.
  10. With no result highlighted, press Enter. A new request should be created between you and each of your selected participants.
  11. Open a group chat.
  12. Click/tap on the + in the composer.
  13. Click/tap on Split Bill.
  14. Enter an amount and press Next.
  15. With a result highlighted, press CMD+Enter. A new request should be created between you and each of your selected participants.
  16. Open a 1:1 DM with another user (not Chronos or Concierge).
  17. Press the + button in the compose bar and click Request Money
  18. Enter an amount and press Next
  19. Press Enter. The IOU should be created.

Workspace invite page

All Platforms
  1. Create a workspace if you do not already have one.
  2. Navigate to Settings -> Your Workspace -> Manage Members -> Invite.
  3. Verify that you can scroll + search the results on the invite page.
  4. Select several users from the list.
  5. Press Invite, and verify that you are taken to the previous page and the new invitees are shown as members.
Web/Desktop
  1. Create a workspace if you do not already have one.
  2. Navigate to Settings -> Your Workspace -> Manage Members -> Invite.
  3. Use the arrow keys to traverse the list. Verify that the list "wraps":
    1. If you are focused on the last result and press ArrowDown you are taken to the search bar. None of the elements should be highlighted.
    2. If you are focused on the first result and press ArrowUp you are taken to the search bar. None of the elements should be highlighted.
    3. If you are focused on the search bar and press ArrowUp, you are taken to the last result.
    4. If you are focused on the search bar and press ArrowDown, you are taken to the first result.
  4. With an option highlighted, press Enter. That option should be selected and moved to the top of the list.
  5. Select a few more options.
  6. Highlight a selected option and press Enter. That should deselect the option.
  7. With a few options selected, move focus to the search bar (no items highlighted), and press Enter. That should take you to the previous page with the new invitees shown as members.
  8. Press Invite again.
  9. Use the arrow keys to select a few options.
  10. With a search result highlighted, press CMD+Enter. That should take you to the previous page with the new invitees shown as members.

IOU currency selection

All Platforms
  1. Press the big green + to open the global create menu.
  2. Select "request money"
  3. Tap on the currency symbol ($ in US)
  4. Search for another currency, verify the results list updates.
  5. Select another currency, verify that the currency selection modal closes and the IOU amount page shows the new symbol for the currency you selected.
Web/Desktop
  1. Press the big green + to open the global create menu.
  2. Select "request money"
  3. Click on the currency symbol ($ in US)
  4. Search for another currency, verify the results lists updates.
  5. Use the arrow key to scroll through the list. Verify that it "wraps" such that if you are at the bottom and press ArrowDown, you are taken to the top, and vice-versa.
  6. With an item highlighted, change the search term.
  7. Verify that the list scrolls back to the top and that the first item is highlighted
  8. With an item highlighted, press the enter key.
  9. Verify that the currency selection modal close and the IOU amount page shows the new symbol for the currency you selected.

Applause (important): Ensure that all of the above steps are covered in our regression test suite in TestFlight

In particular, we may need to add regression tests to cover using arrows to traverse lists. That is the main focus of this PR. Feel free to create an issue if necessary to give yourself more time and make it easier to track. Let me know if you have any questions.

  • Verify that no errors appear in the JS console

Tested On

  • Web
  • Mobile Web
  • Desktop
  • iOS
  • Android

Screenshots

Web

Web_Arrow_Navigation.mov

Mobile Web

Desktop

Desktop_Arrow_Nav.mov

iOS

Android

@roryabraham

This comment was marked as off-topic.

@roryabraham roryabraham changed the title Implement arrow navigation in more OptionsLists Standardize arrow navigation in OptionsLists Feb 15, 2022
@roryabraham roryabraham self-assigned this Feb 15, 2022
@roryabraham
Copy link
Contributor Author

@kavimuru We created a separate issue for this: #9594. No need to block deploy on it

@Julesssss
Copy link
Contributor

@roryabraham would you mind attempting to resolve the regression again today? Thanks

@marcaaron
Copy link
Contributor

Found a potential bug with this one related to the loading spinner. To reproduce:

  1. Be on mobile web
  2. Open a new tab and navigate to /search
  3. Note that the loading spinner never goes away.

2022-07-05_11-42-12

@marcaaron marcaaron mentioned this pull request Jul 5, 2022
89 tasks
@rushatgabhane
Copy link
Member

rushatgabhane commented Jul 5, 2022

@marcaaron interesting.. can you also repro the bug on staging?

Because I can't

@marcaaron
Copy link
Contributor

nope just tried and it only happens on main

@roryabraham
Copy link
Contributor Author

@marcaaron I'm not able to reproduce that on main, which makes me think it's probably related to some API or Auth change that I don't have locally.

@marcaaron
Copy link
Contributor

Cool. I will update and try to see if that resolves the issue. Mainly mentioned it here because it broke on a line of code this PR introduced so it seemed like a possible regression.

@OSBotify
Copy link
Contributor

OSBotify commented Jul 8, 2022

🚀 Deployed to production by @roryabraham in version: 1.1.79-17 🚀

platform result
🤖 android 🤖 failure ❌
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

@luacmartins
Copy link
Contributor

luacmartins commented Feb 13, 2023

I believe that this PR introduced this really edge-case bug. We should have either disabled the focus on disabled options or updated the logic in ComponentDidUpdate to match the one used in state, like this.

@rushatgabhane
Copy link
Member

@luacmartins what's the bug again, you put the wrong link by mistake i think

@luacmartins
Copy link
Contributor

ah sorry, edited with the correct link

@rushatgabhane
Copy link
Member

woah, that is an edge case that i would have never thought of.

thanks for posting here!

headerMessage={headerMessage}
hideAdditionalOptionStates
forceTextUnreadStyle
shouldFocusOnSelectRow={this.props.isGroupChat}
Copy link
Collaborator

Choose a reason for hiding this comment

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

This causes a minor regression on mobile web, showing the keyboard for every contact selection. Handled it by excluding for mobile browsers

Copy link
Member

Choose a reason for hiding this comment

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

This was intentional behaviour.

ref={el => this.textInput = el}
value={this.props.value}
label={this.props.textInputLabel}
onChangeText={(text) => {
Copy link
Member

Choose a reason for hiding this comment

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

Hi, we should have used the onSubmitEditing prop to enable selection using the software enter key for mobile.

Coming from #21472

// Note: react-native's SectionList automatically strips out any empty sections.
// So we need to reduce the sectionIndex to remove any empty sections in front of the one we're trying to scroll to.
// Otherwise, it will cause an index-out-of-bounds error and crash the app.
let adjustedSectionIndex = sectionIndex;
Copy link
Contributor

@c3024 c3024 Feb 4, 2024

Choose a reason for hiding this comment

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

SectionList does not appear to be removing the empty sections so this adjustment caused this issue #34112. This has been fixed with removing this adjustment of index.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
External Added to denote the issue can be worked on by a contributor
Projects
None yet
Development

Successfully merging this pull request may close these issues.