Repository navigation
Replies: 2 comments 1 reply
|
I can reproduce this with your composition on react-aria-components 1.22.1 (jsdom). With the pinned section first, both Payments rows get Whether duplicates are in scope is for the team, but in the meantime, rendering the pinned section as its own <nav aria-label="Main">
<NavigationTree aria-label="Pinned" selectedRoute={route}>
<Item id="pinned-payments" href="#/grants/awards/payments" label="Payments" />
</NavigationTree>
<NavigationTree aria-label="Navigation" selectedRoute={route} defaultExpandedKeys={['grants', 'awards']}>
{/* Grants › Awards › Payments */}
</NavigationTree>
</nav>With that I get +1 on the dev warning if first-match stays the rule. It took me a minute to spot even with your write-up. |
|
Thanks for the issue. I'm not sure how we'd support multiple being selected even if they are the same "page". The docs for
I think I'd recommend moving "pinned" items out of their normal locations and putting them into the pinned section only instead. Native Mac Finder also only highlights one entry, not both if you have something in both Locations and Favourites. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
NavigationTree(react-aria-components 1.22.1, alpha) matchesselectedRouteagainst each item'shref. The per-itemisCurrenthandles duplicates correctly, but the two lookups that derive state from the match stop at the firsthrefmatch in collection order, so a repeated destination (a "pinned" shortcut, a "recent" list, a footer repeat) placed before the real one captures the focus sync and empties the ancestor set.Question: are duplicate hrefs meant to be supported by
NavigationTree? If yes, I'd like to propose making the two lookups duplicate-aware; if no, a documented first-match rule (and maybe a dev warning when a route matches more than one item) would save consumers the debugging.What happens
With a pinned copy of "Payments" in a section above the hierarchy that also contains "Payments" under Grants › Awards, and
selectedRoutepointing at it:aria-current="page"anddata-current(correct);data-current-ancestor(the pinned copy has no ancestors, and the lookup never reaches the nested copy);Remove the pinned section and "Grants" and "Awards" carry
data-current-ancestoras expected. The reverse holds too: with the route on "Applications" (inside the hierarchy) the flag lands on "Grants"; add a pinned copy of "Applications" above and it is gone again.Composition
Steps: render; read
aria-current,data-currentanddata-current-ancestoracross the rows; Tab into the tree; remove the "Pinned" section and readdata-current-ancestoragain.Source (tag
react-aria-components@1.22.1; identical onmaintoday)findKeyForRoutereturns the first match: https://github.com/adobe/react-spectrum/blob/react-aria-components@1.22.1/packages/react-aria-components/src/NavigationTree.tsx#L313-L320useRouteFocusSyncsets the focused key from it: https://github.com/adobe/react-spectrum/blob/react-aria-components@1.22.1/packages/react-aria-components/src/NavigationTree.tsx#L344-L362getSelectedAncestorswalks up from the same single match and caches per collection: https://github.com/adobe/react-spectrum/blob/react-aria-components@1.22.1/packages/react-aria-components/src/NavigationTree.tsx#L371-L386isCurrentis independent of the lookup: https://github.com/adobe/react-spectrum/blob/react-aria-components@1.22.1/packages/react-aria-components/src/NavigationTree.tsx#L215-L216(#10650 moves
closestVisibleKeyintoutilsfor Tree/Table; it does not change which key the route lookup picks, so it is adjacent rather than overlapping.)Proposed direction, if duplicates are in scope
Collect every key whose
hrefmatches.getSelectedAncestorsreturns the union of their ancestor chains.useRouteFocusSyncprefers the deepest match, or the first match inside an expanded branch, over the first in collection order.isCurrentalready needs no change.Context
Bonterra's Stitch design system. Measured while evaluating
NavigationTreefor an app side navigation whose design has a pinned section above the hierarchy. Chromium 147 via Playwright 1.59 (real key presses) for focus entry; jsdom for the attribute assertions. react-aria-components 1.22.1 / react-aria 3.53.1 / react-stately 3.51.0, React 19.2.3.All reactions