Search code examples
reactjstypescriptvitereact-aria

Cannot find type for useTabListState in react-aria


I'm testing react-aria tabs and I'm trying to add types to their example.

The thing is, I'm not sure which type to use for the props used in the tabs component. useTabListState uses TabListStateOptions but I can't find them in the packages. I checked on the repository, but it seems it's not being exported in the library.

Should I use the types from node_modules? Am I missing some strategy to find the types?

This is the current code on the page (excluding css and usage):

import {useTab, useTabList, useTabPanel} from 'react-aria';
import {Item, useTabListState} from 'react-stately';

function Tabs(props) {
  let state = useTabListState(props);
  let ref = React.useRef(null);
  let { tabListProps } = useTabList(props, state, ref);
  return (
    <div className={`tabs ${props.orientation || ''}`}>
      <div {...tabListProps} ref={ref}>
        {[...state.collection].map((item) => (
          <Tab
            key={item.key}
            item={item}
            state={state}
            orientation={props.orientation}
          />
        ))}
      </div>
      <TabPanel key={state.selectedItem?.key} state={state} />
    </div>
  );
}

function Tab({ item, state, orientation }) {
  let { key, rendered } = item;
  let ref = React.useRef(null);
  let { tabProps } = useTab({ key }, state, ref);
  return (
    <div {...tabProps} ref={ref}>
      {rendered}
    </div>
  );
}

function TabPanel({ state, ...props }) {
  let ref = React.useRef(null);
  let { tabPanelProps } = useTabPanel(props, state, ref);
  return (
    <div {...tabPanelProps} ref={ref}>
      {state.selectedItem?.props.children}
    </div>
  );
}


Solution

  • useTabsListState code can be found here. It takes a TabListStateOptions<T> which is just TabListProps<T> without the children. TabListProps<T> source code can be found here. However, the Tabs component takes a AriaTabListProps<T>, which extends TabListProps<T>. The <T> is just any additional props of each tab. So I think you are looking for something like:

    import { 
      useTab, 
      useTabList, 
      useTabPanel, 
      AriaTabListProps, 
      AriaTabProps 
    } from "react-aria";
    import { Item, useTabListState } from "react-stately";
    
    function Tabs(props: AriaTabListProps<AriaTabProps>) {
      let state = useTabListState(props);
      let ref = useRef(null);
      let { tabListProps } = useTabList(props, state, ref);
      return (
        <div className={`tabs ${props.orientation || ''}`}>
          <div {...tabListProps} ref={ref}>
            {[...state.collection].map((item) => (
              <Tab
                key={item.key}
                item={item}
                state={state}
                orientation={props.orientation}
              />
            ))}
          </div>
          <TabPanel key={state.selectedItem?.key} state={state} />
        </div>
      );
    }
    

    I've created a sandbox with as much typing as I can. I'm not sure all of it has the right types, but hopefully this is useful.