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

Create SelectNext component replacing Select #1247

Merged
merged 1 commit into from
Sep 22, 2023
Merged

Create SelectNext component replacing Select #1247

merged 1 commit into from
Sep 22, 2023

Conversation

acelaya
Copy link
Contributor

@acelaya acelaya commented Sep 21, 2023

Create a new SelectNext component, which is meant to replace existing Select one.

The benefits it presents include being able to customize the listbox UI, and supporting complex objects as values.

SelectNext is a controlled component designed to be used like this:

import { SelectNext } from '@hypothesis/frontend-shared';

const items = [
  { id: 1, name: 'All students' },
  { id: 2, name: 'Albert Banana' },
  { id: 3, name: 'Bernard California' },
  { id: 4, name: 'Cecelia Davenport' },
  { id: 5, name: 'Doris Evanescence' },
];

function App() {
  const [value, setValue] = useState<(typeof items)[number]>();

  return (
    <SelectNext
      selected={value}
      onChange={setValue}
      label={
        value ? (
          <>{value.name} ({value.id})</>
        ) : (
          <>Select one...</>
        )
      }
    >
      {items.map(item => (
        <SelectNext.Option value={item} key={item.id}>
          {({ disabled, isSelected }) => <>{item.name} ({item.id})</>}
        </SelectNext.Option>
      ))}
    </SelectNext>
  )
}

Existing Select is now marked as deprecated, and the plan is to remove it on next major release, while we also rename SelectNext to plain Select.

TODO

  • Add test
  • Fix a11y issues highlighted when testing Select

Follow up improvements

There are a couple of things we can improve, but it would be better to tackle separately to avoid a PR bigger than it already is:

  • Handle too long content in options or select (overflow ellipsis?).
  • Prevent looping back to top/bottom in arrow keys navigation when reaching the end of the list. See comment.
  • Exclude the select toggle button from the arrow key navigation sequence. See comment.
  • Close listbox when focus moves to some other component (make sure the toggle button is not focused in this case).

Nice to have:

A big chunk of this PR is the new pattern library documentation page that you can see by checking out this branch and going to http://localhost:4001/input-select-next

Closes #1223

@acelaya acelaya mentioned this pull request Sep 21, 2023
14 tasks
@acelaya acelaya marked this pull request as ready for review September 21, 2023 14:23
@acelaya acelaya marked this pull request as draft September 21, 2023 14:27
@acelaya acelaya force-pushed the select-next branch 2 times, most recently from deb4942 to c51250f Compare September 21, 2023 14:39
@acelaya acelaya marked this pull request as ready for review September 21, 2023 14:40
@codecov
Copy link

codecov bot commented Sep 21, 2023

Codecov Report

Merging #1247 (c0b16c7) into main (b9b950c) will not change coverage.
The diff coverage is 100.00%.

@@            Coverage Diff            @@
##              main     #1247   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           59        61    +2     
  Lines          790       836   +46     
  Branches       318       327    +9     
=========================================
+ Hits           790       836   +46     
Files Changed Coverage Δ
src/components/input/Select.tsx 100.00% <ø> (ø)
src/components/input/SelectContext.ts 100.00% <100.00%> (ø)
src/components/input/SelectNext.tsx 100.00% <100.00%> (ø)

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@robertknight
Copy link
Member

Some accessibility things I noticed in testing with VoiceOver:

  1. The toggle button is not identified as a control that shows a listbox, but just as an ordinary toggle button.
  2. When pressing tab while the listbox is open, focus moves elsewhere in the document, but the popover remains visible

I think the general pattern that we want to follow here is the Select-Only combobox. In addition to the two items mentioned above, there are other details of keyboard handling etc. in that document.

In my testing, setting role=combobox on the toggle button was sufficient to resolve item (1).

This PR is quite large now so I suggest we resolve that, and then create a follow-up issue for the remaining items.

Copy link
Member

@robertknight robertknight left a comment

Choose a reason for hiding this comment

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

This is generally looking in good shape. There are a few more things to address around keyboard input and accessibility. If we're agreed on following the "select-only combobox" pattern for this, then I think setting role="combobox" is enough to get this to a state where we can merge this version, and then a follow-up issue can be opened for the remaining items.

src/components/input/SelectNext.tsx Outdated Show resolved Hide resolved
src/components/input/SelectNext.tsx Show resolved Hide resolved
src/components/input/SelectNext.tsx Show resolved Hide resolved
src/components/input/SelectNext.tsx Show resolved Hide resolved
src/components/input/SelectNext.tsx Outdated Show resolved Hide resolved
src/components/input/test/SelectNext-test.js Outdated Show resolved Hide resolved
Copy link
Member

@robertknight robertknight left a comment

Choose a reason for hiding this comment

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

Listbox popup button is now announced as expected, including collapsed / expanded state.

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.

Build a custom select that allows for UI customization in the dropdown
2 participants