Thanks to visit codestin.com
Credit goes to github.com

Skip to content

TypeScript and class Combobox #22

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

Merged
merged 12 commits into from
Apr 28, 2020
Merged

TypeScript and class Combobox #22

merged 12 commits into from
Apr 28, 2020

Conversation

muan
Copy link
Contributor

@muan muan commented Apr 23, 2020

This pull request includes the changes for

  1. TypeScript conversion (to simplified the compilation step this also removes the UMD build)
  2. Class export instead of function decorators

Before:

import {clearSelection, install, navigate, start, stop, uninstall} from '@github/combobox-nav'
const input = document.querySelector('#robot-input')
const list = document.querySelector('#list-id')

// install combobox pattern on a given input and listbox
install(input, list)
// when options appear, start intercepting keyboard events for navigation
start(input)
// when options disappear, stop intercepting keyboard events for navigation
stop(input)

// move selection to the nth+1 item in the list
navigate(input, list, 1)
// reset selection
clearSelection(input, list)
// uninstall combobox pattern from the input
uninstall(input)

After:

import Combobox from '@github/combobox-nav'
const input = document.querySelector('#robot-input')
const list = document.querySelector('#list-id')

// install combobox pattern on a given input and listbox
const combobox = new Combobox(input, list)
// when options appear, start intercepting keyboard events for navigation
combobox.start()
// when options disappear, stop intercepting keyboard events for navigation
combobox.stop()

// move selection to the nth+1 item in the list
combobox.navigate(1)
// reset selection
combobox.clearSelection()
// uninstall combobox pattern from the input
combobox.destroy()

@muan muan requested a review from a team April 23, 2020 20:56
Copy link
Contributor

@keithamus keithamus left a comment

Choose a reason for hiding this comment

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

👍 This will be a breaking change, but so was #21 so we can release as one set of breaking changes.

Copy link
Contributor

@koddsson koddsson left a comment

Choose a reason for hiding this comment

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

This looks great to me ✨

@muan
Copy link
Contributor Author

muan commented Apr 27, 2020

@jscholes Hello! here's a new demo page for this pull. The list should expand if the input isn't empty.

@jscholes
Copy link

jscholes commented Apr 27, 2020

@muan This is looking good! A few things which don't seem to work:

  1. Pressing Down Arrow or Up Arrow to expand the list only works if a value has been entered. This is desired in some cases, for example if a search string is required to actually populate the list. But with this default test page, the options are statically defined within the mark-up, so users must be able to browse what is available without typing something first.
  2. Nothing happens when I press Enter on an option. Again, the most appropriate behaviour may be determined by each individual use case, for example pressing Enter on a GitHub search result may just activate that result directly. But by default, the list should close, the selected value should be reflected in the input, and focus should return there. I'm eager for this pattern to try to do the right thing by default, and then have any necessary behaviour overridden.
  3. With the list expanded and an option focused, attempting to type an addition to the search string seems to do nothing for a screen reader user. The character(s) are reflected in the input's value, but focus doesn't return to it so SR users won't know that this has happened.
  4. The same applies to the following keys as well, which should all cause focus to return to the input so users can observe the impact of pressing them:
    • Backspace;
    • Left Arrow and Right Arrow; and
    • Home and End (although these can also cause focus to move to the first or last item in the list box, respectively).
  5. Alt+Down Arrow, Alt+Up Arrow and Delete aren't implemented, but these will generally only be used by "power users" and are optional.
  6. The list box wraps. That is, pressing Down Arrow from the last option in the list box (or Up Arrow from the first) causes my focus to circle back around, rather than moving into the combo box input. Moving focus back into the input at these points ensures that all users have a guaranteed way to get out of the list, regardless of knowledge or experience level. Alternatively, to match standard <select> behaviour, these can simply do nothing, but I'd recommend the first option because standard selects aren't editable.

@muan
Copy link
Contributor Author

muan commented Apr 27, 2020

  1. Pressing Down Arrow or Up Arrow to expand the list only works if a value has been entered.

I can add this logic to the demo page, but to be clear this won't be an out-of-box function for combobox-nav because it doesn't know when/how the listbox is populated.

  1. ... But by default, the list should close, the selected value should be reflected in the input, and focus should return there. I'm eager for this pattern to try to do the right thing by default, and then have any necessary behaviour overridden.

I'll give this a go.

  1. With the list expanded and an option focused, ... The character(s) are reflected in the input's value, but focus doesn't return to it so SR users won't know that this has happened.
  1. The same applies to the following keys as well, which should all cause focus to return to the input so users can observe the impact of pressing them:

I'll add clearing selection on non-captured keydown events.

  1. Alt+Down Arrow, Alt+Up Arrow and Delete aren't implemented, but these will generally only be used by "power users" and are optional.

I'll consider these when making this change to <auto-complete> as Alt+Down/Up are to control visibility of the list, which combobox-nav does not have enough information to do. Delete should work once the 4. is added, and we don't do inline autocomplete anywhere.

  1. The list box wraps. ...

I'll try doing the first. Though I noticed that the spec matches your suggestion, but oddly all the APG examples wraps.

@muan
Copy link
Contributor Author

muan commented Apr 27, 2020

Thanks for the feedback @jscholes!

  1. Pressing Down Arrow or Up Arrow to expand the list only works if a value has been entered.

I've added this to the demo page. Though when testing in Safari with Voice Over, the options aren't read out if the input is empty.

  1. With the list expanded and an option focused, ... The character(s) are reflected in the input's value, but focus doesn't return to it so SR users won't know that this has happened.
  1. The same applies to the following keys as well, which should all cause focus to return to the input so users can observe the impact of pressing them:

6. Moving focus back into the input at these points ensures that all users have a guaranteed way to get out of the list, regardless of knowledge or experience level.

I've added these, and the demo page is updated.


Finally..

  1. ... But by default, the list should close, the selected value should be reflected in the input, and focus should return there.

I tried out implementing this, but we don't really know how list close should work (ie is it removed? is it clear? is it hidden? how was it hid?). To avoid assuming how, we'd need the components to pass in a function for how they want it handled, but inevitably there will still be behaviors that are handled by the component that require the same logic, which are then evaluated in two places.

I'm eager for this pattern to try to do the right thing by default, and then have any necessary behaviour overridden.

I hear you, but as it stands now, all our components using combobox-nav will be overriding this, so considering the non-trivial and component logic it needs to know, I don't think it's worth it.

For example, <auto-complete> looks for an attribute value when replacing text and dispatches a custom event, <text-expander> looks for an attribute and does partial replacement depending on cursor position, tree finder and jump-to widget both navigates, and the invitation widget creates a pill list.

On the demo page, I've added close on Enter and added aria-live to ensure the commit event logger is announced.

@jscholes
Copy link

@muan Test page is looking good!

Though when testing in Safari with Voice Over, the options aren't read out if the input is empty.

This is odd. Unless I'm mistaken, all of the use cases you've outlined for GitHub require text to be typed before the combo box is useful. Is that correct, including for ones not mentioned as examples? If so, this doesn't matter right now, but this should probably be investigated and reported. I wonder if the value of aria-autocomplete has anything to do with it?

I hear you, but as it stands now, all our components using combobox-nav will be overriding this

Makes sense.

@koddsson koddsson mentioned this pull request Apr 28, 2020
@muan
Copy link
Contributor Author

muan commented Apr 28, 2020

Though when testing in Safari with Voice Over, the options aren't read out if the input is empty.

Is that correct, including for ones not mentioned as examples?

Yes.

If so, this doesn't matter right now, but this should probably be investigated and reported.

I'll create an isolated test page for this and see if I can track this down.

@muan muan merged commit e8832e8 into master Apr 28, 2020
@muan muan deleted the tsclass branch April 28, 2020 19:10
@muan muan mentioned this pull request Sep 17, 2020
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.

4 participants