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(Dropdown): UX behavior of selectedItems and scroll for filtered options. #2375

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open

fix(Dropdown): UX behavior of selectedItems and scroll for filtered options. #2375

wants to merge 11 commits into from

Conversation

francoiscote
Copy link

@francoiscote francoiscote commented Dec 12, 2017

Here is an attempt to fix #1485, fix #2336 and fix #2080. Also, this would make the PR #1510 irrelevant now.

  1. fix selectedIndex of filtered options lists
    So, as mentioned in the other bugs, the problem comes from the fact that Dropdown is setting isselectedIndex using an index from a small filtered list of options when using search. I don't think it is a problem because it represents the actual state of the list at that time. Instead, I think the fix should be to set the selectedIndex again when the full list is shown (on open). This is what I did on line 1103

This PR also brings two small related fixes.

  1. removed scrollSelectedItemIntoView() call in open handler: this does not respect the react component lifecycles and could generate bugs. Also, this is already taken care of by a check on the state.open in componentDidMount()

  2. scrollSelectedItemIntoView when searchQuery has changed: This has been added to componentDidUpdate and fixes a bug where the scroll position would not get update when typing into search input.

This is my first PR on this project and I plan to contribute in the next few weeks. Comments and change request are appreciated. Thanks! 🚀

@francoiscote
Copy link
Author

So I see that tests failed. I wanted to get your opinion first before starting to fix them.

  • Dropdown : search : filters the items based on custom search function: I will have a look at this one.
  • Dropdown : search : sets the selected item to the first search result: This behavior is different now. I could update the tests

@levithomason
Copy link
Member

Hi there! Thanks for contributing and sorry for the delay. I had a very long and crazy holiday season but I'm getting back to the grind now :)

The code and explanations look correct. I'll try to review this one soon.

Instead, I think the fix should be to set the selectedIndex again when the full list is shown (on open). This is what I did on line 1103

Yes, thanks!

Dropdown : search : sets the selected item to the first search result: This behavior is different now. I could update the tests

This should be ensuring that changing the search query sets the selected index to 0. We want to retain that behavior.

@mlmassey
Copy link

Hi guys, I created PR #2523 to address the state of the selected item index when doing searches. It does not address the scrolling items into view though.

@levithomason
Copy link
Member

I looked at the proposed fixes here and in other PRs. I've updated this PR to fix tests. I also changed the logic a bit as to when/why we set the selected index and scroll items into view.

I removed all the scattered calls to set selected index. We were trying to identify all cases where we needed to set it, and call it there. However, even a value prop change would cause a state change and therefore require setting the selected index again.

Rather than trace all these down, I've removed all the calls and just set selected index in response to state changes in value. I've done similar with the scrolling into view. There is one additional case for each, resetting the selected index to 0 on query change and scrolling items into view on open. Both of those are also implemented.

This works with all current tests. I've also ported and simplified the test from #1510 that asserts the index is properly set when dealing with clicks after a search query.

Finally, I've added a memoization optimization to getMenuItems to prevent unnecessary duplicate calls to the search function. This was required as setting state reactively in response to other state changes causes 2 calls to that function in one test.

😅 Hope I don't have to go down that hole again in the next year! Thanks for all the help everyone.

@codecov-io
Copy link

codecov-io commented Feb 14, 2018

Codecov Report

Merging #2375 into master will decrease coverage by 0.22%.
The diff coverage is 91.66%.

Impacted file tree graph

@@            Coverage Diff            @@
##           master   #2375      +/-   ##
=========================================
- Coverage   99.92%   99.7%   -0.23%     
=========================================
  Files         163     152      -11     
  Lines        2739    2669      -70     
=========================================
- Hits         2737    2661      -76     
- Misses          2       8       +6
Impacted Files Coverage Δ
src/modules/Dropdown/Dropdown.js 99.74% <91.66%> (-0.01%) ⬇️
src/modules/Sidebar/Sidebar.js 54.54% <0%> (-45.46%) ⬇️
src/elements/Flag/Flag.js 87.5% <0%> (-12.5%) ⬇️
src/modules/Transition/TransitionGroup.js 100% <0%> (ø) ⬆️
src/collections/Form/FormTextArea.js 100% <0%> (ø) ⬆️
src/views/Feed/FeedDate.js 100% <0%> (ø) ⬆️
src/views/Card/CardMeta.js 100% <0%> (ø) ⬆️
src/modules/Modal/ModalContent.js 100% <0%> (ø) ⬆️
src/views/Item/ItemContent.js 100% <0%> (ø) ⬆️
src/modules/Modal/Modal.js 100% <0%> (ø) ⬆️
... and 153 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1ae2781...7c67340. Read the comment docs.

@levithomason
Copy link
Member

Alright, I've added a failing test for the bug in #2080. The changes made thus far do not solve this one.

The issue is, when a search yields no results the selected index should revert to the currently active item if there is one. Instead, it is currently disregarding the active item's index and keeping 0 as the selected index.

The test is it('retains the selected item after searching with no results'). Once someone gets that to pass, we can merge this.

this.getMenuOptions.lastSearch = search

filteredOptions = search(filteredOptions, searchQuery)
}

Choose a reason for hiding this comment

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

This seems unwise to add more state management, especially outside of this.state. I thought my PR addressed this issue quite well by ensuring this.state stayed in sync with prop changes. Did you have a chance to review my PR?

search.simulate('change', { target: { value: '__nonExistingSearchQuery__' } })

// click outside, close the dropdown
domEvent.click(document)

Choose a reason for hiding this comment

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

This line isn't working really. I noted that once you added describe.only, the call domEvent.click(document) isn't really working, and would also cause a failure in the test closes on click outside because it uses the same call. If you use document.body.click() (like the test blurs the Dropdown node on close by clicking outside component) or domEvent.click(document.body) then things start working. What this causes though is a call to closeOnDocumentClick, which causes the dropdown menu to close, but the focus is still on the input and the input search text is never cleared. In this case, this is correct behavior, since the menu has been closed, but focus is still on the input, so the invalid search text should not be removed. What the test should be doing is calling the handleBlur function which is what you're trying to test with this test case. In summary,

  1. Your checks below with the wrapper.find() calls aren't working because the dropdown still has the search text in the input and is showing the No results message.
  2. Need a different way to trigger a blur event instead of document.body.click(). This applies to this test case and to the blurs the Dropdown node on close by clicking outside component case. May need to include another button element to throw the focus to cause a blur to happen.
  3. Actually, I believe the dropdown is working well with your changes, its just the test case isn't correctly testing it

@levithomason
Copy link
Member

As @mlmassey has pointed out, there are some issues with the tests here. I believe I'm on to resolving this in #1542. There seem to be some issues with shared scope between tests.

@pierrebiver
Copy link

Hey guys,
I have the same issue than #2624 ? is there a release to fix it available soon?

Thanks :)

@stale
Copy link

stale bot commented Aug 5, 2018

There has been no activity in this thread for 90 days. While we care about every issue and we’d love to see this fixed, the core team’s time is limited so we have to focus our attention on the issues that are most pressing. Therefore, we will likely not be able to get to this one.

However, PRs for this issue will of course be accepted and welcome!

If there is no more activity in the next 90 days, this issue will be closed automatically for housekeeping. To prevent this, simply leave a reply here. Thanks!

@stale stale bot added the stale label Aug 5, 2018
@stale stale bot removed the stale label Aug 20, 2018
@stale
Copy link

stale bot commented Feb 21, 2019

There has been no activity in this thread for 180 days. While we care about every issue and we’d love to see this fixed, the core team’s time is limited so we have to focus our attention on the issues that are most pressing. Therefore, we will likely not be able to get to this one.

However, PRs for this issue will of course be accepted and welcome!

If there is no more activity in the next 180 days, this issue will be closed automatically for housekeeping. To prevent this, simply leave a reply here. Thanks!

@stale stale bot added the stale label Feb 21, 2019
@MarianSulgan
Copy link

Hello, any updates on this one? Can we expect fix anytime soon?

@stale stale bot removed the stale label Mar 28, 2019
@layershifter
Copy link
Member

@MarianSulgan this is open source project: pull, apply changes, fix, test and create PR 🚀

@stale
Copy link

stale bot commented Nov 25, 2019

There has been no activity in this thread for 180 days. While we care about every issue and we’d love to see this fixed, the core team’s time is limited so we have to focus our attention on the issues that are most pressing. Therefore, we will likely not be able to get to this one.

However, PRs for this issue will of course be accepted and welcome!

If there is no more activity in the next 180 days, this issue will be closed automatically for housekeeping. To prevent this, simply leave a reply here. Thanks!

@stale stale bot added the stale label Nov 25, 2019
…React into fix/dropdown-search-selected-item

� Conflicts:
�	examples/webpack3/config/env.js
�	examples/webpack3/config/paths.js
�	examples/webpack3/config/webpack.config.common.js
�	examples/webpack3/config/webpack.config.prod.js
�	examples/webpack3/config/webpackDevServer.config.js
�	examples/webpack3/scripts/start.js
�	examples/webpack3/src/components/Navbar/Navbar.js
�	examples/webpack3/src/components/Navbar/NavbarChildren.js
�	examples/webpack3/src/components/Navbar/NavbarDesktop.js
�	examples/webpack3/src/index.js
�	src/modules/Dropdown/Dropdown.js
@codecov-commenter
Copy link

codecov-commenter commented Aug 13, 2020

Codecov Report

Merging #2375 into master will decrease coverage by 0.14%.
The diff coverage is 91.66%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #2375      +/-   ##
==========================================
- Coverage   99.84%   99.70%   -0.15%     
==========================================
  Files         183      152      -31     
  Lines        3275     2669     -606     
==========================================
- Hits         3270     2661     -609     
- Misses          5        8       +3     
Impacted Files Coverage Δ
src/modules/Dropdown/Dropdown.js 99.74% <91.66%> (-0.26%) ⬇️
src/modules/Sidebar/Sidebar.js 54.54% <0.00%> (-45.46%) ⬇️
src/elements/Flag/Flag.js 87.50% <0.00%> (-12.50%) ⬇️
src/modules/Search/Search.js 99.46% <0.00%> (-0.10%) ⬇️
src/modules/Tab/Tab.js 100.00% <0.00%> (ø)
src/views/Card/Card.js 100.00% <0.00%> (ø)
src/views/Feed/Feed.js 100.00% <0.00%> (ø)
src/views/Item/Item.js 100.00% <0.00%> (ø)
src/addons/Radio/Radio.js 100.00% <0.00%> (ø)
src/elements/Icon/Icon.js 100.00% <0.00%> (ø)
... and 174 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ebdb893...b39b782. Read the comment docs.

@layershifter
Copy link
Member

I merged master to this branch, merge conflicts are crazy 😨

It's great that we have all issues linked to this PR, I will check what actually exists still in master. @francoiscote if you can help to restore your changes it will be really appreciated 🙏

@layershifter
Copy link
Member

layershifter commented Aug 13, 2020

Issues verification

#1485

Is no longer present in the latest master #1485 (comment). @francoiscote if you still can reproduce it, please let me know.

#2336

Was also fixed, #2336 (comment)

#2080 ⚔️

The issue #2 which was qualified as a bug is still present, #2080 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
8 participants