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

Unpredictable ListBox behavior when used in Dialog #4793

Open
mattrothenberg opened this issue Jul 19, 2023 · 6 comments
Open

Unpredictable ListBox behavior when used in Dialog #4793

mattrothenberg opened this issue Jul 19, 2023 · 6 comments
Labels
bug Something isn't working RAC

Comments

@mattrothenberg
Copy link

πŸ“ Feedback

Original Twitter thread with @devongovett – https://twitter.com/mattrothenberg/status/1681749782740496384?s=20

I'd like to build a custom Select menu that supports multiple selection. To this end, I've sketched out some code that looks like so. https://codesandbox.io/s/rac-multiselect-yptnvy?file=/src/App.js:324-1192

export default function App() {
  let [selectedKeys, setSelectedKeys] = useState(new Set());
  let selectedItems = [...selectedKeys].map((k) =>
    items.find((item) => item.id === k)
  );

  return (
    <div className="App">
      <DialogTrigger>
        <Button>
          {selectedItems.length
            ? selectedItems.map((i) => i.name).join(", ")
            : "No selected items"}
        </Button>
        <Popover>
          <Dialog>
            <ListBox
              aria-label="Favorite animal"
              selectionMode="multiple"
              autoFocus="first"
              items={items}
              selectedKeys={selectedKeys}
              onSelectionChange={setSelectedKeys}
            >
              {(item) => <Item>{item.name}</Item>}
            </ListBox>
          </Dialog>
        </Popover>
      </DialogTrigger>
    </div>
  );
}

This almost works perfectly. There are two UX issues, however, that prevent me from being to able to add this functionality to my component library.

  1. When the dialog is open and the list of options is visible, hitting Esc clears the selected value. While this is expected behavior for a standalone ListBox, this is unexpected behavior in this context. I would expect hitting Esc would close the dialog and maintain my selection, rather than clobber it.
  2. The autofocus prop can be used to ensure that, the first time you open the dialog, a ListBox item is selected. However, if you open the dialog, select an item, click outside of it to close the dialog, and then re-open, you'll note that autofocus is totally ignored. This feels like a bug, but I'm reticent to make that determination myself.

🌍 Your Environment

Software Version(s)
[react-aria-components] 1.0.0-alpha.5
Chrome
@LFDanLu
Copy link
Member

LFDanLu commented Jul 21, 2023

When the dialog is open and the list of options is visible, hitting Esc clears the selected value. While this is expected behavior for a standalone ListBox, this is unexpected behavior in this context. I would expect hitting Esc would close the dialog and maintain my selection, rather than clobber it.

That makes sense, we've had prior discussions about this here and have implemented that behavior for Menu. For your use case, would a Menu make more sense instead of a ListBox? If not, we would need some way to distinguish when to prevent Esc from clearing the ListBox's selection and close the Dialog since I don't believe we'd want that to happen all the time.

The autofocus prop can be used to ensure that, the first time you open the dialog, a ListBox item is selected. However, if you open the dialog, select an item, click outside of it to close the dialog, and then re-open, you'll note that autofocus is totally ignored. This feels like a bug, but I'm reticent to make that determination myself.

Certainly feels like a bug, digging right now. Doesn't seem to happen for a Menu though, so if you can use a Menu instead it should just work.

EDIT: Looks like ListBox could use the same kind of logic as Menu does here. At the moment the ListBox is rendered, its collection hasn't been formed (needs a second render) and thus useSelectableCollection's call here doesn't actually set a focused key since the collection is empty.

@LFDanLu LFDanLu added bug Something isn't working RAC labels Jul 21, 2023
@mattrothenberg
Copy link
Author

@LFDanLu Thanks so much for the quick response! I'll try using a Menu and see what it feels like.

@LFDanLu
Copy link
Member

LFDanLu commented Aug 9, 2023

For whoever picks up this ticket, we'll consider adding a prop to ListBox to control Esc behavior and fix the second point using the code outlined in my previous comment

@DoReVo
Copy link

DoReVo commented Dec 15, 2023

Trying to do the same thing, using Menu works for me.

@lzhou-aops
Copy link

lzhou-aops commented Apr 26, 2024

Same here - was having a bunch of different issues, saw this thread, swapped out ListBox for Menu with no other changes and everything cleared up. πŸ˜… For any future readers, you can probably also get rid of any Dialogs if you do this

@joshuajaco
Copy link
Contributor

joshuajaco commented May 16, 2024

We are experiencing a similar issue. We have a GridList inside a Popover.
We can't use the Menu component as we need a GridList.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working RAC
Projects
Status: πŸ“‹ Waiting for Sprint
Development

No branches or pull requests

5 participants