Skip to content

[react-aria-components] Tabs' onSelectionChange prop doesn't fire correctly when using tabs as links #5252

Open
@neefrehman

Description

@neefrehman

Provide a general summary of the issue here

After doing a Tabs implementation where we are using each Tab as a link, per the docs, I've noticed that onSelectionChange doesn't fire correctly.

🤔 Expected Behavior?

  • onSelectionChange should fire with the current key
  • onSelectionChange should fire on keyboard navigation between tabs

😯 Current Behavior

  • onSelectionChange is firing with the previous key
  • onSelectionChange is not firing on keyboard navigation

💁 Possible Solution

No response

🔦 Context

I've been adding analytics functionality to our implementation of Tabs, that should track each tab change a user makes. To make it easier for our product/analytics people to use the results in their dashboards and reports, the tracking should include the tab's text value, as opposed to it's key. To do this without using useTabList—because we would like to keep the rest of what Tabs offers for 'free'—I am having to use a sub-component that can access TabListState, which we can then use to create the tracking function and pass it back to Tabs via state.

const UpdateTabTrackingFunction = ({ setTrackTabChange }) => {
  const tabListState = useContext(TabListStateContext);
  useEffect(() => {
    setTrackTabChange(() => (key) => {
      track('TabChange', tabListState?.collection?.getItem(key)?.textValue);
    });
  }, [tabListState?.collection]); // eslint-disable-line react-hooks/exhaustive-deps
  return null;
};

const CustomTabs = (props: ComponentPropsWithoutRef<typeof Tabs>) => {
  const [trackTabChange, setTrackTabChange] = useState(null);

  const onSelectionChange = (key) => {
    props.onSelectionChange?.(key);
    trackTabChange?.(key);
  };

  return (
    <Tabs {...props} onSelectionChange={onSelectionChange}>
      <>
        <UpdateTabTrackingFunction setTrackTabChange={setTrackTabChange} />
        {props.children}
      </>
    </Tabs>
  );
};

It's a little ugly, but does the job! I should also note that it would be really nice to have access to the full tab item in onSelectionChange, which would help us avoid this situation.

When testing this with our tabs that use links, I noticed the reported behaviour.

🖥️ Steps to Reproduce

Minimal reproduction: https://codesandbox.io/p/sandbox/react-aria-components-tabs-onselectionchange-bug-cv6wh2?file=%2Fapp%2Fpage.js%3A7%2C21

Version

1.0.0-beta-1

What browsers are you seeing the problem on?

Firefox, Chrome, Safari

If other, please specify.

No response

What operating system are you using?

MacOS

🧢 Your Company/Team

No response

🕷 Tracking Issue

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    RACbugSomething isn't workingdocumentationImprovements or additions to documentation

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions