mui / mui/base-ui

[tabs] Consider generic value typing for Root

Open
#5,516 1 comment 0 reactions 0 assignees View on GitHub
component: tabs status: waiting for maintainer
Dominant language
TypeScript
Stars
10.9k
Forks
543
Avg merge
1d 20h
Merged PRs (30d)
101

Description

# Feature request

## Summary

`Tabs.Root` currently uses `Tabs.Tab.Value` for `value`, `defaultValue`, and `onValueChange`. Since `Tabs.Tab.Value` is `any | null`, these props effectively use `any` and lose their shared value type.

A Root-only generic could preserve that relationship:

```ts
interface TabsRootProps {
value?: Value | null;
defaultValue?: Value | null;
onValueChange?: (
value: Value | null,
eventDetails: TabsRoot.ChangeEventDetails,
) => void;
}
```

This would support inference and explicit value types without attempting to propagate the generic to `Tabs.Tab` or `Tabs.Panel`, which TypeScript cannot automatically connect to the parent generic.

One tradeoff is nullability. Uncontrolled Tabs can notify `null` when no enabled fallback exists, while controlled Tabs do not perform these automatic fallback updates. Should `onValueChange` use a uniform `Value | null` type, or should controlled and uncontrolled props be typed separately?

## Examples in other libraries

Base UI already uses Root-only generic value typing with `Value | null` for [`NavigationMenu.Root`](https://github.com/mui/base-ui/pull/4328).

Related discussions:

- https://github.com/mui/base-ui/issues/81#issuecomment-2166741362
- https://github.com/mui/base-ui/issues/1076

## Motivation

Consumers commonly use string unions or enums for Tabs state. Generic Root typing would preserve that domain across `value`, `defaultValue`, and `onValueChange` instead of losing it to `any`.

I would like to confirm whether a Root-only generic with a nullable callback is the preferred direction.

Contributor guide

Open the contributing guide

Research direction

Start at the Tabs.Root props and trace how value, defaultValue, and onValueChange are currently typed. Compare the proposed Root-only generic and nullable callback with the linked NavigationMenu.Root approach and related discussions; done means the generic and controlled versus uncontrolled nullability direction is agreed and reflected in the component types.

Written by the indexing model from the issue text.

Assessment

Tech stack
react, typescript
Domain
frontend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.