# TabListNode

Container cho danh sách tab headers. Chỉ chấp nhận `TabNode` children.

Đây là node giữ toàn bộ cấu hình layout của thanh tab (`align`, `overflowBehavior`, `indicator`) và style dùng chung cho mọi `TabNode` con (`tabConfig`).

## Resolved name

`TabList`

## Configurable props

### Top-level props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `align` | `'start' \| 'center' \| 'end'` | `'start'` | Căn các tab trong thanh tab |
| `overflowBehavior` | `'scroll' \| 'wrap'` | `'scroll'` | Khi tab tràn ngang: cuộn ngang hoặc xuống dòng |
| `indicator` | `false \| { size?: number; sx?: StyledCSS }` | — | Thanh chỉ báo tab đang active. `false` = tắt |
| `tabConfig` | `{ sx?: StyledCSS; states?: { active?: { sx?: StyledCSS } } }` | — | Style áp cho tất cả `TabNode` con |

### `sx` props

```ts
sx?: {
  // spacing giữa các tab
  columnGap?: number
  rowGap?: number

  // spacing
  paddingTop?: number
  paddingRight?: number
  paddingBottom?: number
  paddingLeft?: number

  // border
  borderStyle?: string
  borderColor?: string
  borderTopWidth?: number
  borderRightWidth?: number
  borderBottomWidth?: number
  borderLeftWidth?: number
  borderTopLeftRadius?: number | string
  borderTopRightRadius?: number | string
  borderBottomRightRadius?: number | string
  borderBottomLeftRadius?: number | string

  // responsive overrides
  sm?: { /* same keys above */ }
  md?: { /* same keys above */ }
  lg?: { /* same keys above */ }
}
```

### `tabConfig`

`tabConfig` là nơi duy nhất để style các tab — `TabNode` không style riêng lẻ.

```ts
tabConfig?: {
  // normal state
  sx?: {
    minWidth?: number | string
    height?: number | string
    paddingTop?: number
    paddingRight?: number
    paddingBottom?: number
    paddingLeft?: number
    borderStyle?: string
    borderColor?: string
    borderTopWidth?: number
    borderRightWidth?: number
    borderBottomWidth?: number
    borderLeftWidth?: number
    borderTopLeftRadius?: number | string
    borderTopRightRadius?: number | string
    borderBottomRightRadius?: number | string
    borderBottomLeftRadius?: number | string
    color?: string
    backgroundColor?: string
    ':hover'?: { backgroundColor?: string }
  }

  // active state — chỉ override những gì cần khác normal
  states?: {
    active?: {
      sx?: {
        color?: string
        backgroundColor?: string
        borderColor?: string
        ':hover'?: { backgroundColor?: string }
      }
    }
  }
}
```

Các thuộc tính kích thước (`minWidth`, `height`, `padding*`, `border*Width`, `border*Radius`) đặt ở `tabConfig.sx` và dùng chung cho mọi state — inspector gom vào nhóm **Shared (all states)**. Chỉ màu sắc (`color`, `backgroundColor`, `borderColor`, `:hover`) mới tách theo state.

Không có state `hover` riêng ở upstream — hover được biểu diễn bằng pseudo-selector `sx[':hover']` trong từng state.

## Usage

```tsx
import { TabListNode, TabNode } from '@janbox/storefront-builder';

<TabListNode
  align="center"
  overflowBehavior="wrap"
  indicator={{ size: 2, sx: { backgroundColor: 'var(--color-primary-600)' } }}
  sx={{ columnGap: 8, rowGap: 8 }}
  tabConfig={{
    sx: {
      minWidth: 120,
      paddingTop: 8,
      paddingBottom: 8,
      color: 'var(--color-neutral-600)',
      ':hover': { backgroundColor: 'var(--color-neutral-100)' },
    },
    states: {
      active: {
        sx: { color: 'var(--color-primary-600)' },
      },
    },
  }}
>
  <TabNode>Tab 1</TabNode>
  <TabNode>Tab 2</TabNode>
  <TabNode>Tab 3</TabNode>
</TabListNode>
```

## Hook

```tsx
import { useTabListNodeProps } from '@janbox/storefront-builder';

// gọi trong context của TabsNode — tự resolve TabList node con
const { nodeProps, setNodeProps } = useTabListNodeProps();
```

Chỉ dùng được khi node hiện tại là `TabsNode`; nếu không tìm thấy `TabList` con sẽ throw `Missing tab list node`.

## Rules

- **Canvas**: yes — chứa `TabNode` children.
- **Selectable**: no.
- **canMoveIn**: chỉ chấp nhận `TabNode`.
- **Parent**: phải là `TabsNode`.

## Related nodes

- [`TabsNode`](../tabs/README.md) — root container
- [`TabNode`](../tab/README.md) — tab header button
