Skip to content

Commit 3bf90ed

Browse files
committed
TabsPanel
1 parent 16f5537 commit 3bf90ed

File tree

4 files changed

+56
-126
lines changed

4 files changed

+56
-126
lines changed

packages/react/src/tabs/panel/TabsPanel.tsx

Lines changed: 54 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
'use client';
22
import * as React from 'react';
3-
import { useTabsPanel } from './useTabsPanel';
3+
import { useBaseUiId } from '../../utils/useBaseUiId';
4+
import { useRenderElement } from '../../utils/useRenderElement';
5+
import type { BaseUIComponentProps } from '../../utils/types';
6+
import { useCompositeListItem } from '../../composite/list/useCompositeListItem';
47
import { tabsStyleHookMapping } from '../root/styleHooks';
58
import { useTabsRootContext } from '../root/TabsRootContext';
6-
import { useComponentRenderer } from '../../utils/useComponentRenderer';
7-
import { TabsRoot, type TabValue } from '../root/TabsRoot';
8-
import type { BaseUIComponentProps } from '../../utils/types';
9+
import type { TabsRoot, TabValue } from '../root/TabsRoot';
10+
import { TabsPanelDataAttributes } from './TabsPanelDataAttributes';
11+
12+
export interface TabPanelMetadata {
13+
id?: string;
14+
value: TabValue;
15+
}
916

1017
/**
1118
* A panel displayed when the corresponding tab is active.
@@ -14,10 +21,17 @@ import type { BaseUIComponentProps } from '../../utils/types';
1421
* Documentation: [Base UI Tabs](https://base-ui.com/react/components/tabs)
1522
*/
1623
export const TabsPanel = React.forwardRef(function TabPanel(
17-
props: TabsPanel.Props,
24+
componentProps: TabsPanel.Props,
1825
forwardedRef: React.ForwardedRef<HTMLDivElement>,
1926
) {
20-
const { children, className, value: valueProp, render, keepMounted = false, ...other } = props;
27+
const {
28+
children,
29+
className,
30+
value: valueProp,
31+
render,
32+
keepMounted = false,
33+
...elementProps
34+
} = componentProps;
2135

2236
const {
2337
value: selectedValue,
@@ -26,13 +40,28 @@ export const TabsPanel = React.forwardRef(function TabPanel(
2640
tabActivationDirection,
2741
} = useTabsRootContext();
2842

29-
const { hidden, getRootProps } = useTabsPanel({
30-
getTabIdByPanelValueOrIndex,
31-
rootRef: forwardedRef,
32-
selectedValue,
33-
value: valueProp,
43+
const id = useBaseUiId();
44+
45+
const metadata = React.useMemo(
46+
() => ({
47+
id,
48+
value: valueProp,
49+
}),
50+
[id, valueProp],
51+
);
52+
53+
const { ref: listItemRef, index } = useCompositeListItem<TabPanelMetadata>({
54+
metadata,
3455
});
3556

57+
const tabPanelValue = valueProp ?? index;
58+
59+
const hidden = tabPanelValue !== selectedValue;
60+
61+
const correspondingTabId = React.useMemo(() => {
62+
return getTabIdByPanelValueOrIndex(valueProp, index);
63+
}, [getTabIdByPanelValueOrIndex, index, valueProp]);
64+
3665
const state: TabsPanel.State = React.useMemo(
3766
() => ({
3867
hidden,
@@ -42,12 +71,21 @@ export const TabsPanel = React.forwardRef(function TabPanel(
4271
[hidden, orientation, tabActivationDirection],
4372
);
4473

45-
const { renderElement } = useComponentRenderer({
46-
propGetter: getRootProps,
47-
render: render ?? 'div',
48-
className,
74+
const renderElement = useRenderElement('div', componentProps, {
4975
state,
50-
extraProps: { ...other, children: hidden && !keepMounted ? undefined : children },
76+
ref: [forwardedRef, listItemRef],
77+
props: [
78+
{
79+
'aria-labelledby': correspondingTabId,
80+
hidden,
81+
id: id ?? undefined,
82+
role: 'tabpanel',
83+
tabIndex: hidden ? -1 : 0,
84+
[TabsPanelDataAttributes.index as string]: index,
85+
},
86+
elementProps,
87+
{ children: hidden && !keepMounted ? undefined : children },
88+
],
5189
customStyleHookMapping: tabsStyleHookMapping,
5290
});
5391

packages/react/src/tabs/panel/useTabsPanel.ts

Lines changed: 0 additions & 108 deletions
This file was deleted.

packages/react/src/tabs/root/TabsRoot.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { useDirection } from '../../direction-provider/DirectionContext';
77
import { useTabsRoot } from './useTabsRoot';
88
import { TabsRootContext } from './TabsRootContext';
99
import { tabsStyleHookMapping } from './styleHooks';
10-
import { TabPanelMetadata } from '../panel/useTabsPanel';
10+
import type { TabPanelMetadata } from '../panel/TabsPanel';
1111

1212
/**
1313
* Groups the tabs and the corresponding panels.

packages/react/src/tabs/root/useTabsRoot.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import * as React from 'react';
33
import { useControlled } from '../../utils/useControlled';
44
import type { CompositeMetadata } from '../../composite/list/CompositeList';
5-
import type { TabPanelMetadata } from '../panel/useTabsPanel';
5+
import type { TabPanelMetadata } from '../panel/TabsPanel';
66
import type { TabMetadata } from '../tab/TabsTab';
77
import type { TabActivationDirection, TabValue } from './TabsRoot';
88

0 commit comments

Comments
 (0)