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: Fix TimePicker filter behavior. Misc ComboBox Fixes #1139

Merged
merged 31 commits into from
May 7, 2021

Conversation

brandonlenz
Copy link
Contributor

@brandonlenz brandonlenz commented Apr 15, 2021

Summary

The MVP TimePicker filtering behavior was identical to our ComboBox implementation, since it was just wrapping the ComboBox.

USWDS made some changes to filtering to the ComboBox (see #1108). This PR also brings those enhancements to our reactified library.

There was also some existing behavior of our combobox that did not match the USWDS combobox (whether that was always the case, or due to the USWDS changes since our original implementation, I don't know, but I fixed as many as I found here along the way).

Previous ComboBox behavior can be tested at our hosted storybook: https://trussworks.github.io/react-uswds/?path=/story/components-form-controls-combo-box--default-combo-box-with-prop-options

Current USWDS ComboBox behavior: https://designsystem.digital.gov/components/combo-box/

Previous TimePicker behavior can be tested at our hosted storybook: https://trussworks.github.io/react-uswds/?path=/story/components-form-controls-time-picker--complete-time-picker

Current USWDS TimePicker behavior: https://designsystem.digital.gov/components/time-picker/

The following issues were found & resolved (and tests added to hopefully cement the fixes since they're not all obvious):

Note: The videos show the following:

USWDS Model Behavior Current Behavior Fixed Behavior (this PR)
  • Pressing enter on the input without an exact match, but with a previously selected option should revert to the selected option.
Enter.without.exact.match.reverts.to.prev.selection.mov
  • Typing into the input to filter options, then Blurring without selecting should reset the filter (previously it would keep the filter until the input value was changed)
Reset.filters.on.blur.mov
  • Selecting an option should give that option the selected style in the dropdown, even if the input filter allows more than one option to be seen.
Selected.option.maintains.selected.styling.if.filtered.mov
  • When no option is selected, but the dropdown is open, the first option should have the focused style applied (but not actually be focused)
First.option.has.focused.style.mov
  • When the ComboBox is opened and scrolled, then closed, and reopened it should either be at the top, OR if an item is selected, that item should be scrolled into view.
Should.auto.scroll.to.top.or.to.selected.item.mov
  • When an option is selected, but the filter is changed such that the selected option is not visible, the first partial match should be highlighted with the focused style (but not actually be focused)
First.option.should.be.focused.if.filtering.if.the.selected.option.is.not.visible.mov
  • TimePicker should not filter via hiding options, but should move the focus styled element to the first match (and scroll to said match)
time.picker.should.not.filter.options.mov
  • TimePicker should pass custom filtering logic into combobox to generate regex to find options. This allows 5:3p when typed to match 5:30pm:
    image
Time.picker.filtering.works.properly.mov

Related Issues or PRs

closes: #1108

How To Test

The unit tests I added help to cover the scenarios I fixed.

To compare to our existing storybook or the USWDS implementation, use the deployed storybook or checkout this branch and run storybook locally.

@christopherhuii I would love your help in testing this in a project since I want to make sure I didn't break the blurring behavior and focus trap fixes you made recently (I did some testing locally, but I'm not sure I covered everything)

- Verify first element has focused class
- Mock scrollIntoView to keep tests from failing
- Use regex pattern and CustomizableFilter structure
- Unfilter items on Blur: Either an item is selected, and all options should be shown when the list is expanded again, or no option is selected, the field is cleared, and all items should be shown.
- Remove almost unused 'filter' prop from state
- Update TimePicker to use the custom filtering logic
- Allow TimePickerTests to run (mock scroll function)
- Track "closest match" for styling first matching item when filtering the list is disabled
- hide clear button when tpying in combobox
- Update old bug test to succesfully check style
@trussworks-infra-zz trussworks-infra-zz temporarily deployed to storybook April 15, 2021 03:09 Inactive
@trussworks-infra-zz trussworks-infra-zz temporarily deployed to storybook April 15, 2021 03:18 Inactive
* @param {string} query The value to use in the regular expression
* @param {object} extras An object of regular expressions to replace and filter the query
*/
export const generateDynamicRegExp = (
Copy link
Contributor Author

@brandonlenz brandonlenz Apr 15, 2021

Choose a reason for hiding this comment

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

FYI for reviewers, this is from USWDS

@brandonlenz brandonlenz marked this pull request as ready for review April 15, 2021 03:48
@brandonlenz
Copy link
Contributor Author

Looks like the Happo Diffs are from
image

@trussworks-infra-zz trussworks-infra-zz temporarily deployed to storybook April 19, 2021 18:53 Inactive
@trussworks-infra-zz trussworks-infra-zz temporarily deployed to storybook April 19, 2021 19:13 Inactive
@brandonlenz
Copy link
Contributor Author

brandonlenz commented Apr 19, 2021

After an embarrassing demo this morning where I had inadvertently broken one of the first things I fixed in this PR, I made some changes.

In addition to fixing the auto-scroll behavior again, I removed the extra state prop I was using to track the "closest match". This was so similar to focusedOption that I realized it was not only confusing to track both, but also necessary.

Then I added in a few more tests and fixed a test that was previously skipped due to a bug that this refactor happened to fix along the way 🥳 🎉

Thanks Demo effect!

@trussworks-infra-zz trussworks-infra-zz temporarily deployed to storybook April 19, 2021 19:30 Inactive
@trussworks-infra-zz trussworks-infra-zz temporarily deployed to storybook April 19, 2021 19:34 Inactive
@trussworks-infra-zz trussworks-infra-zz temporarily deployed to storybook April 20, 2021 20:00 Inactive
@brandonlenz
Copy link
Contributor Author

Added screen recordings to the description to help illustrate the other misc. fixes I made 😅

@trussworks-infra-zz trussworks-infra-zz temporarily deployed to storybook April 21, 2021 14:08 Inactive
@trussworks-infra-zz trussworks-infra-zz temporarily deployed to storybook April 26, 2021 14:58 Inactive
@trussworks-infra-zz trussworks-infra-zz temporarily deployed to storybook May 3, 2021 20:17 Inactive
@trussworks-infra-zz trussworks-infra-zz temporarily deployed to storybook May 6, 2021 17:58 Inactive
haworku
haworku previously approved these changes May 6, 2021
Copy link
Contributor

@haworku haworku left a comment

Choose a reason for hiding this comment

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

Great work. Whew. The videos helped a lot to understand the expected behavior - really good example of how to make code review easier. I'm excited for some of the new behavior added.

Some of the issues with focus I think could be regressions (specifically the ones about closing/blurring and then coming back and reopening and certain items being focused or highlighted). That logic gets very nuanced particularly with filtering that's in progress. Either way, its good to have more tests around this and remove some of our 🐛 fix TODOs 😆.

Agree that we should have easi or @christopherhuii test this in their app before merging anything to main.

'usa-combo-box__list-option--focused usa-combo-box__list-option--selected'
)
expect(scrollFunction).toHaveBeenCalledTimes(1)
})
Copy link
Contributor

Choose a reason for hiding this comment

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

nice test.

@@ -873,6 +1018,9 @@ describe('ComboBox component', () => {

expect(getByTestId('combo-box-clear-button')).not.toBeVisible()
expect(getByTestId('combo-box-option-list').children.length).toEqual(1)

fireEvent.blur(input)
expect
Copy link
Contributor

Choose a reason for hiding this comment

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

why call expect with no value? I've never seen this pattern now I'm curious

Copy link
Contributor Author

Choose a reason for hiding this comment

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

uuuuuuh 😅

This looks like I started writing expects for this tests, then saw a squirrel, then came back and committed. Nice catch! I'm surprised it's valid code tbh 😆

I'll fix this

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah it was valid code and I was like -- hmm does this do something I don't know lol

Copy link
Contributor Author

Choose a reason for hiding this comment

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


const containerRef = useRef<HTMLDivElement>(null)
const itemRef = useRef<HTMLLIElement>(null)
const focusedItemRef = useRef<HTMLLIElement>(null)
Copy link
Contributor

Choose a reason for hiding this comment

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

This renaming is clarifying ⭐

@trussworks-infra-zz trussworks-infra-zz temporarily deployed to storybook May 6, 2021 22:17 Inactive
@brandonlenz brandonlenz merged commit c684844 into main May 7, 2021
@brandonlenz brandonlenz deleted the bl-time-picker-combo-box-filtering-1108 branch May 7, 2021 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[fix] TimePicker/Combobox filtering
3 participants