Skip to content

An empty Tree that holds focus does not move focus to its rows when they arrive #10660

Description

@alexandru-bereghici-to

Provide a general summary of the issue here

When an empty Tree holds focus and rows then arrive, ArrowDown does not move focus to a row; focus stays on the treegrid. ListBox does the same thing correctly.

🤔 Expected Behavior?

ArrowDown moves focus to the first row, as it does for ListBox.

😯 Current Behavior

tree focused while empty:           DIV#coll[treegrid] "none"
tree after rows arrive + ArrowDown: DIV#coll[treegrid] "Item 1Item 2Item 3"
listbox focused while empty:           DIV#coll[listbox] "none"
listbox after rows arrive + ArrowDown: DIV#coll-option-i1[option] "Item 1"

💁 Possible Solution

When the collection is empty, useGridList swaps the collection's props for a bare tabIndex (react-aria/dist/private/gridlist/useGridList.mjs:69-72). Focusing the empty grid therefore never runs the collection's onFocus, which is where useSelectableCollection calls manager.setFocused(true) (react-aria/dist/private/selection/useSelectableCollection.mjs:272,281). When rows arrive, the manager still thinks the collection is unfocused. Keeping the collection's focus handlers on an empty grid, as useListBox does, should cover it.

Separate from #9803, which is about autoFocus on an empty collection.

🔦 Context

Found while building a design system on React Aria Components. Observed in headless Chromium (Playwright 1.63, real key and mouse events) with react-aria-components 1.21.1 / react-aria 3.52.1 / react-stately 3.50.0 and no other code.

🖥️ Steps to Reproduce

import { useEffect, useState } from "react";
import { Tree, TreeItem, TreeItemContent } from "react-aria-components";

export function Repro() {
  const [items, setItems] = useState([]);
  useEffect(() => {
    const t = setTimeout(() => setItems([1, 2, 3].map((n) => ({ id: "i" + n, name: "Item " + n }))), 3000);
    return () => clearTimeout(t);
  }, []);
  return (
    <>
      <button>before</button>
      <Tree aria-label="t" id="coll" items={items} renderEmptyState={() => "none"}>
        {(i) => <TreeItem id={i.id} textValue={i.name}><TreeItemContent>{i.name}</TreeItemContent></TreeItem>}
      </Tree>
    </>
  );
}

Tab onto the empty tree within 3 s and leave focus there; once the rows appear, press ArrowDown. Compare with a ListBox in the same place.

Version

react-aria-components 1.21.1, react-aria 3.52.1, react-stately 3.50.0, React 19.3.0

What browsers are you seeing the problem on?

Chrome

What operating system are you using?

macOS

🧢 Your Company/Team

No response

🕷 Tracking Issue

No response

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions