# TabList

- Page: https://jiguang132.com/resources/astryx/docs/tab-list
- Resource: Astryx (https://jiguang132.com/resources/astryx.md)
- All guides: https://jiguang132.com/resources/astryx/docs.md

TabList provides tab-style navigation for organizing content into categorized sections. Use it to let users switch between related views without leaving the page, with overflow items handled by a built-in "more" menu.

## Installation

```bash
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0
```

Requires React 19+, base CSS and a Theme provider. See [Setup](/resources/astryx/docs/getting-started).

## Tab

Individual tab item that renders as a button or an anchor link, with selected-state styling and optional icons.

| Prop | Type | Default | Description |
|---|---|---|---|
| value * | string |  | Unique value for this tab, matched against TabListContext.value. |
| label * | string |  | Accessible label for this tab. Used as visible text by default, or as aria-label when isLabelHidden is true. |
| isLabelHidden | boolean | false | Whether the label is visually hidden. When true, only the icon and endContent are displayed, and label is used as aria-label for accessibility. |
| href | string |  | URL to navigate to; when provided, the tab renders as an anchor element. Ignored in a TabList given an explicit role="tablist". |
| panelId | string |  | Id of the panel this tab controls, wired up as aria-controls where the TabList speaks the tabs pattern. Put the same id on the panel element. No effect under the navigation pattern, and a development warning says so. |
| as | LinkComponentType |  | Custom component to render instead of <a> for link tabs. Overrides the LinkProvider default. Only applies when href is provided. |
| icon | ReactNode |  | Icon element shown when the tab is not selected. |
| selectedIcon | ReactNode |  | Icon element shown when the tab is selected; falls back to icon if not provided. |
| endContent | ReactNode |  | Content rendered after the label, such as a badge count or status dot. |
| xstyle | StyleXStyles |  | StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value: not an inline style object like style={{}}. |

## Tab List

TabList provides tab-style navigation for organizing content into categorized sections. Use it to let users switch between related views without leaving the page, with overflow items handled by a built-in "more" menu.

| Prop | Type | Default | Description |
|---|---|---|---|
| value * | string |  | The currently selected tab value. |
| onChange * | (value: string) => void |  | Callback fired when a tab is selected. |
| size | 'sm' \| 'md' \| 'lg' | 'md' | Size variant applied to all child tabs. |
| layout | 'hug' \| 'fill' | 'hug' | Layout mode for tab sizing. 'hug': each tab hugs its content width. 'fill': tabs stretch equally to fill the container width. |
| hasDivider | boolean | false | Whether to show a bottom border divider under the tab list. |
| isFullBleed | boolean | false | Makes the tab strip escape its parent's container padding, extending to the container's content edges (cancels the nearest padded Layout container's --container-padding-* custom properties with negative margins). The inner strip pads back by the portion of the container inset that is not already supplied by the first or last tab stop, keeping edge labels aligned while a hasDivider underline spans the full content width. Matches Divider's isFullBleed: inline (start/end) edges only; block-edge docking stays with the surrounding layout. |
| role | AriaRole |  | ARIA role for the strip. 'tablist' asks for the WAI-ARIA tabs pattern: role="tablist" / role="tab" and aria-selected, with each tab pointing at the panel it controls via its panelId; only tabs may live in a tablist strip, and an href on a tab is ignored there. Left unset, the strip is a nav landmark marking the current tab with aria-current. Any other value is passed through to the element unchanged. |
| overflow | 'auto' \| 'scroll' \| 'visible' | 'auto' | What happens when the tabs are wider than the strip. 'auto' lets the component choose, which today always scrolls. 'scroll' scrolls the tabs horizontally, with edge fades and arrow affordances for pointers that can hover. 'visible' turns overflow handling off and lets the tabs spill out of the strip. The selected tab is always scrolled back into view. |
| children * | ReactNode |  | Tab and TabMenu items to render inside the strip. |
| xstyle | StyleXStyles |  | StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value: not an inline style object like style={{}}. |

### Usage guidance

- Keep tab labels short and descriptive so users can quickly scan available sections.
- Leave overflow handling on: a strip narrower than its tabs scrolls, and the selected tab is kept in view. Use TabMenu when you want a curated group of extra options rather than a scrolling strip.
- When using hasDivider with action buttons alongside tabs, match the Button size to the TabList size (both md, both sm); the divided tab strip reserves space so tabs and same-size buttons align to a shared baseline above the rail.
- Reach for role="tablist" when the strip switches panels in place, and give each tab a panelId pointing at the panel it opens: that link is how a screen reader gets from a tab to its content. Leave it off for navigation between views.
- Set isFullBleed to stretch a tab bar inside a padded LayoutHeader, Card, or Section to the container's inline content edges, instead of reaching for negative-margin CSS.
- Avoid: Use tabs for sequential steps or workflows; use a stepper or wizard pattern instead.
- Avoid: Place more than 6–8 visible tabs before the overflow menu; prioritize the most important categories.
- Avoid: Confuse TabList with SegmentedControl or ToggleButton. TabList is for navigation between views. SegmentedControl and ToggleButton are input controls: SegmentedControl always has exactly one selected option, while ToggleButton can be toggled on or off.

### Theming API

```json
{
  "targets": [
    {
      "className": "astryx-tab-list",
      "visualProps": [
        "size"
      ]
    },
    {
      "className": "astryx-tab-strip"
    },
    {
      "className": "astryx-tab-scroll-button"
    },
    {
      "className": "astryx-tab",
      "states": [
        "selected"
      ]
    },
    {
      "className": "astryx-tab-indicator",
      "states": [
        "selected"
      ]
    },
    {
      "className": "astryx-tab-menu"
    },
    {
      "className": "astryx-tab-menu-dropdown"
    },
    {
      "className": "astryx-tab-menu-item"
    }
  ],
  "vars": [
    {
      "name": "--_tab-indicator-bottom",
      "description": "Vertical offset of the selected-tab indicator from the tab bottom edge. A host that draws its own bottom divider (Toolbar) sets this so the indicator sits on the divider instead of above it.",
      "default": "-1px",
      "private": true
    }
  ]
}
```

## Tab



## TabMenu



### Accessibility

- **Tab label**: Each label must have at least 4.5:1 contrast with the tab surface behind it. For Hover and Pointer down, measure the final background after the overlay layer is applied. — 4.5:1

### Anatomy

- **Left Content**: Most important area; hugs content width.
- **Center-Fill Content**: Stretches to fill available space.
- **Right Content**: Hugs content width.

## Tab Menu

Overflow menu trigger that opens a dropdown of additional tab options, showing the selected option's label as the trigger text.

| Prop | Type | Default | Description |
|---|---|---|---|
| label * | string |  | Label for the trigger button (shown when no option is selected) and the dropdown heading divider. |
| options * | TabMenuOption[] |  | Array of menu options rendered in the dropdown. |


## Examples

- Tab List: 
- Tab Menu: TabMenu is an overflow menu within a TabList that groups additional tab options into a dropdown, showing the selected option's label as the trigger text.
- Tab: Tab is an individual tab item within a TabList, supporting labels, icons, selected icons, and end content slots.
- TabList — Fill Layout: Tabs that stretch to fill the available width with a bottom divider.
- TabList — With Actions: Page header pattern with tabs on the left and action buttons pushed to the right. When hasDivider is true, match the Button size to the TabList size so the tabs and actions align to a shared baseline above the divider.
- TabList — With Badge: Tabs with notification badge counts rendered via endContent. Uses error variant for urgent counts and neutral for informational ones.
- TabList — With Icons: Tabs with leading icons alongside text labels.
- TabList — With Overflow Menu: Tab list with a dropdown menu for additional items that do not fit inline.
- TabList — With Status Dot: Tabs with status dot indicators rendered via endContent to show live environment health at a glance.
- TabMenu — Basic: An overflow menu at the end of a TabList that collects secondary tabs behind a dropdown. Use it when there are more tabs than fit comfortably inline.
- Tab — Selected Icon: A tab that changes its icon when selected.

---

Index of all JGuang resources: https://jiguang132.com/llms.txt
