Giter Club home page Giter Club logo

Comments (6)

so99ynoodles avatar so99ynoodles commented on May 20, 2024 2

Tabs and TabList component are under construction :)

from react-spectrum.

devongovett avatar devongovett commented on May 20, 2024 2

Yep though they were made a long time ago as a POC and never finished. I think at this point I would re-start the implementation or at least heavily modify it. If anyone would like to work on that, I’d be happy to provide some guidance! 😊

from react-spectrum.

devongovett avatar devongovett commented on May 20, 2024 2

Ok, here's the API spec we came up with.

import {CollectionBase, SingleSelection} from '@react-types/shared';
import {SingleSelectListState} from '@react-stately/list';

interface TabsProps<T> extends CollectionBase<T>, SingleSelection {
  /**
   * Whether tabs are activated automatically on focus or manually.
   * @default 'automatic'
   */
  keyboardActivation?: 'automatic' | 'manual',
  /**
   * The orientation of the tabs.
   * @default 'horizontal'
   */
  orientation?: 'horizontal' | 'vertical'
}

interface TabsAria {
  /** Props for the tablist container */
  tabListProps: HTMLAttributes<HTMLElement>
}

declare function useTabs<T>(props: TabsProps<T>, state: SingleSelectListState<T>): TabsAria;

interface TabAria {
  /** Props for the tab element */
  tabProps: HTMLAttributes<HTMLElement>,
  /** Props for the associated tabpanel element */
  tabPanelProps: HTMLAttributes<HTMLElement>
}

interface TabAriaProps<T> {
  /** Collection node for the tab. */
  item: Node<T>
}

declare function useTab<T>(props: TabAriaProps, state: SingleSelectListState<T>): TabAria;

There's also some spectrum specific props. I can provide those if you want to implement the Spectrum part and not just the Aria/Stately parts.

Here's an example of what constructing a tab component would look like for an end user:

<Tabs selectedKey="files">
  <Item key="files" title="Your files">
    <Files />
  </Item>
  <Item key="shared" title="Shared with you">
    <Shared />
  </Item>
</Tabs>

The API follows our collection components API, using <Item> to specify each tab item. In addition, it follows the same selection API that we use for other components.

In terms of implementation, there's a few pieces:

  • For state, we can use the useSingleSelectListState hook. That will handle converting the children from JSX to a Collection object, along with setting up selection state and a SelectionManager. I don't think any other state is needed for tabs beyond this, but if so, we can add a useTabState hook later on.
  • The useTabs hook should be created to manage the tab list and the associated tab panels. It should return ARIA props for the tablist element (see below). It should also call the useSelectableCollection hook, which will handle the keyboard navigation and focus management requirements. You'll need to either add a new KeyboardDelegate implementation to handle the left and right arrow keys, or add an orientation option to the existing ListKeyboardDelegate to allow switching from vertical to horizontal orientation.
  • The useTab hook should be created to handle an individual tab and its associated tabpanel element. It should return ARIA props for those elements, including generating ids and aria-labelledby attributes (see below). It should also call the useSelectableItem hook to handle selecting tabs and focusing accordingly. The hook should receive a Node object from the collection, and use the title and rendered properties for the tab and tabpanel contents respectively.

For accessibility, the spec is listed above in my previous comment. In addition, you can see the two examples from the WAI-ARIA Authoring Practices. They cover the two keyboardActivation modes.

I'd start by making a basic example component using the hooks and use that in the storybook/tests for now. I'm happy to also provide guidance on the Spectrum-specific parts, but they're not required if you'd like to focus on React Aria/React Stately.

Another helpful thing is to start by running the yarn plop command, which will help bootstrap the new packages you'll need to create with some templates. We've removed the existing implementation from the repo since it was old and probably harder to modify than to just start from scratch.

That was a lot. Hopefully I covered enough to get you started, but please let me know if you have any questions! πŸ˜„

from react-spectrum.

so99ynoodles avatar so99ynoodles commented on May 20, 2024 1

@devongovett
Hi. I was creating react-spectrum/tabs for testing the behavior of newly created useTabs and useTab, I found something confusing.

// jsx
<Tabs selectedKey="files">
  <Item key="files" title="Your files">
    Files
  </Item>
  <Item key="shared" title="Shared with you">
    Shared
  </Item>
</Tabs>

// HTML created from jsx above
<div role="tabs">
  <div role="tablist">
    // could be a div, button is expected according to ↓. CSS changes are needed?
    // https://www.w3.org/TR/wai-aria-practices-1.2/examples/tabs/tabs-2/tabs.html
    <button role="tab">Your files</button>
    <button role="tab">Shared with you</button>
  </div>
  <div role="tabpanel">
    Files
  </div>
</div>

// Role based architecture
<Tabs>
  <TabList>
    <Tab />
    <Tab />
  </TabList>
  <TabPanel />
</Tabs>

tabPanelProps are returned by useTab, and useTab is called inside of Tab component,
ButTabPanel is rendered outside of TabList, which makes passing tabPanelProps to it difficult.
Since they are Spectrum-specific parts, if this looks fine to you, I'll just focus on aria parts πŸ˜… .

Please checkout the PR, any advice would be appreciated.

from react-spectrum.

so99ynoodles avatar so99ynoodles commented on May 20, 2024

I'm interested in implementing it. :)

from react-spectrum.

devongovett avatar devongovett commented on May 20, 2024

@so99ynoodles awesome! Let me get back to you with some updated API specs and we can go from there. In the meantime, here’s the accessibility spec we’ll need to follow: https://w3c.github.io/aria-practices/#tabpanel

from react-spectrum.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.