diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md
index 439c45a312d966..fb5e36f1fb6e61 100644
--- a/packages/components/CHANGELOG.md
+++ b/packages/components/CHANGELOG.md
@@ -9,6 +9,7 @@
### Experimental
- `Tabs`: Add `focusable` prop to the `Tabs.TabPanel` sub-component ([#55287](https://github.com/WordPress/gutenberg/pull/55287))
+- `Tabs`: Update sub-components to accept relevant HTML element props ([#55860](https://github.com/WordPress/gutenberg/pull/55860))
### Enhancements
diff --git a/packages/components/src/tabs/README.md b/packages/components/src/tabs/README.md
index 8fb4e0e73caec2..423216e940584d 100644
--- a/packages/components/src/tabs/README.md
+++ b/packages/components/src/tabs/README.md
@@ -159,19 +159,6 @@ The children elements, which should be a series of `Tabs.TabPanel` components.
- Required: No
-###### `className`: `string`
-
-The class name to apply to the tablist.
-
-- Required: No
-- Default: ''
-
-###### `style`: `React.CSSProperties`
-
-Custom CSS styles for the tablist.
-
-- Required: No
-
#### Tab
##### Props
@@ -182,24 +169,12 @@ The id of the tab, which is prepended with the `Tabs` instance ID.
- Required: Yes
-###### `style`: `React.CSSProperties`
-
-Custom CSS styles for the tab.
-
-- Required: No
-
###### `children`: `React.ReactNode`
The children elements, generally the text to display on the tab.
- Required: No
-###### `className`: `string`
-
-The class name to apply to the tab.
-
-- Required: No
-
###### `disabled`: `boolean`
Determines if the tab button should be disabled.
@@ -229,18 +204,6 @@ The id of the tabpanel, which is combined with the `Tabs` instance ID and the su
- Required: Yes
-###### `className`: `string`
-
-The class name to apply to the tabpanel.
-
-- Required: No
-
-###### `style`: `React.CSSProperties`
-
-Custom CSS styles for the tab.
-
-- Required: No
-
###### `focusable`: `boolean`
Determines whether or not the tabpanel element should be focusable. If `false`, pressing the tab key will skip over the tabpanel, and instead focus on the first focusable element in the panel (if there is one).
diff --git a/packages/components/src/tabs/tab.tsx b/packages/components/src/tabs/tab.tsx
index 75b3df1c1ba01e..03e5d80871c56a 100644
--- a/packages/components/src/tabs/tab.tsx
+++ b/packages/components/src/tabs/tab.tsx
@@ -11,11 +11,12 @@ import type { TabProps } from './types';
import warning from '@wordpress/warning';
import { TabsContext } from './context';
import { Tab as StyledTab } from './styles';
+import type { WordPressComponentProps } from '../context';
-export const Tab = forwardRef< HTMLButtonElement, TabProps >( function Tab(
- { children, id, className, disabled, render, style },
- ref
-) {
+export const Tab = forwardRef<
+ HTMLButtonElement,
+ WordPressComponentProps< TabProps, 'button', false >
+>( function Tab( { children, id, disabled, render, ...otherProps }, ref ) {
const context = useContext( TabsContext );
if ( ! context ) {
warning( '`Tabs.TabList` must be wrapped in a `Tabs` component.' );
@@ -28,10 +29,9 @@ export const Tab = forwardRef< HTMLButtonElement, TabProps >( function Tab(
ref={ ref }
store={ store }
id={ instancedTabId }
- className={ className }
- style={ style }
disabled={ disabled }
render={ render }
+ { ...otherProps }
>
{ children }
diff --git a/packages/components/src/tabs/tablist.tsx b/packages/components/src/tabs/tablist.tsx
index 02255fefd20827..7a53115910796c 100644
--- a/packages/components/src/tabs/tablist.tsx
+++ b/packages/components/src/tabs/tablist.tsx
@@ -16,25 +16,26 @@ import { forwardRef } from '@wordpress/element';
import type { TabListProps } from './types';
import { useTabsContext } from './context';
import { TabListWrapper } from './styles';
+import type { WordPressComponentProps } from '../context';
-export const TabList = forwardRef< HTMLDivElement, TabListProps >(
- function TabList( { children, className, style }, ref ) {
- const context = useTabsContext();
- if ( ! context ) {
- warning( '`Tabs.TabList` must be wrapped in a `Tabs` component.' );
- return null;
- }
- const { store } = context;
- return (
- }
- >
- { children }
-
- );
+export const TabList = forwardRef<
+ HTMLDivElement,
+ WordPressComponentProps< TabListProps, 'div', false >
+>( function TabList( { children, ...otherProps }, ref ) {
+ const context = useTabsContext();
+ if ( ! context ) {
+ warning( '`Tabs.TabList` must be wrapped in a `Tabs` component.' );
+ return null;
}
-);
+ const { store } = context;
+ return (
+ }
+ { ...otherProps }
+ >
+ { children }
+
+ );
+} );
diff --git a/packages/components/src/tabs/tabpanel.tsx b/packages/components/src/tabs/tabpanel.tsx
index b5339141a56eca..f477d1d3b4b437 100644
--- a/packages/components/src/tabs/tabpanel.tsx
+++ b/packages/components/src/tabs/tabpanel.tsx
@@ -16,30 +16,28 @@ import { TabPanel as StyledTabPanel } from './styles';
import warning from '@wordpress/warning';
import { TabsContext } from './context';
+import type { WordPressComponentProps } from '../context';
-export const TabPanel = forwardRef< HTMLDivElement, TabPanelProps >(
- function TabPanel(
- { children, id, className, style, focusable = true },
- ref
- ) {
- const context = useContext( TabsContext );
- if ( ! context ) {
- warning( '`Tabs.TabPanel` must be wrapped in a `Tabs` component.' );
- return null;
- }
- const { store, instanceId } = context;
-
- return (
-
- { children }
-
- );
+export const TabPanel = forwardRef<
+ HTMLDivElement,
+ WordPressComponentProps< TabPanelProps, 'div', false >
+>( function TabPanel( { children, id, focusable = true, ...otherProps }, ref ) {
+ const context = useContext( TabsContext );
+ if ( ! context ) {
+ warning( '`Tabs.TabPanel` must be wrapped in a `Tabs` component.' );
+ return null;
}
-);
+ const { store, instanceId } = context;
+
+ return (
+
+ { children }
+
+ );
+} );
diff --git a/packages/components/src/tabs/test/index.tsx b/packages/components/src/tabs/test/index.tsx
index 67b7bf588e74e8..d2a035e436c194 100644
--- a/packages/components/src/tabs/test/index.tsx
+++ b/packages/components/src/tabs/test/index.tsx
@@ -7,7 +7,6 @@ import userEvent from '@testing-library/user-event';
/**
* WordPress dependencies
*/
-import { wordpress, category, media } from '@wordpress/icons';
import { useState } from '@wordpress/element';
/**
@@ -15,7 +14,6 @@ import { useState } from '@wordpress/element';
*/
import Tabs from '..';
import type { TabsProps } from '../types';
-import type { IconType } from '../../icon';
type Tab = {
id: string;
@@ -23,7 +21,6 @@ type Tab = {
content: React.ReactNode;
tab: {
className?: string;
- icon?: IconType;
disabled?: boolean;
};
tabpanel?: {
@@ -36,19 +33,19 @@ const TABS: Tab[] = [
id: 'alpha',
title: 'Alpha',
content: 'Selected tab: Alpha',
- tab: { className: 'alpha-class', icon: wordpress },
+ tab: { className: 'alpha-class' },
},
{
id: 'beta',
title: 'Beta',
content: 'Selected tab: Beta',
- tab: { className: 'beta-class', icon: category },
+ tab: { className: 'beta-class' },
},
{
id: 'gamma',
title: 'Gamma',
content: 'Selected tab: Gamma',
- tab: { className: 'gamma-class', icon: media },
+ tab: { className: 'gamma-class' },
},
];
@@ -58,17 +55,15 @@ const TABS_WITH_DELTA: Tab[] = [
id: 'delta',
title: 'Delta',
content: 'Selected tab: Delta',
- tab: { className: 'delta-class', icon: media },
+ tab: { className: 'delta-class' },
},
];
const UncontrolledTabs = ( {
tabs,
- showTabIcons = false,
...props
}: Omit< TabsProps, 'children' > & {
tabs: Tab[];
- showTabIcons?: boolean;
} ) => {
return (
@@ -79,9 +74,8 @@ const UncontrolledTabs = ( {
id={ tabObj.id }
className={ tabObj.tab.className }
disabled={ tabObj.tab.disabled }
- icon={ showTabIcons ? tabObj.tab.icon : undefined }
>
- { showTabIcons ? null : tabObj.title }
+ { tabObj.title }
) ) }
@@ -100,11 +94,9 @@ const UncontrolledTabs = ( {
const ControlledTabs = ( {
tabs,
- showTabIcons = false,
...props
}: Omit< TabsProps, 'children' > & {
tabs: Tab[];
- showTabIcons?: boolean;
} ) => {
const [ selectedTabId, setSelectedTabId ] = useState<
string | undefined | null
@@ -126,9 +118,8 @@ const ControlledTabs = ( {
id={ tabObj.id }
className={ tabObj.tab.className }
disabled={ tabObj.tab.disabled }
- icon={ showTabIcons ? tabObj.tab.icon : undefined }
>
- { showTabIcons ? null : tabObj.title }
+ { tabObj.title }
) ) }
diff --git a/packages/components/src/tabs/types.ts b/packages/components/src/tabs/types.ts
index 9874fe6cb6ccfa..8b071937410919 100644
--- a/packages/components/src/tabs/types.ts
+++ b/packages/components/src/tabs/types.ts
@@ -4,11 +4,6 @@
// eslint-disable-next-line no-restricted-imports
import type * as Ariakit from '@ariakit/react';
-/**
- * Internal dependencies
- */
-import type { IconType } from '../icon';
-
export type TabsContextProps =
| {
/**
@@ -78,14 +73,6 @@ export type TabListProps = {
* The children elements, which should be a series of `Tabs.TabPanel` components.
*/
children?: React.ReactNode;
- /**
- * The class name to apply to the tablist.
- */
- className?: string;
- /**
- * Custom CSS styles for the rendered tablist.
- */
- style?: React.CSSProperties;
};
export type TabProps = {
@@ -93,22 +80,10 @@ export type TabProps = {
* The id of the tab, which is prepended with the `Tabs` instanceId.
*/
id: string;
- /**
- * Custom CSS styles for the tab.
- */
- style?: React.CSSProperties;
/**
* The children elements, generally the text to display on the tab.
*/
children?: React.ReactNode;
- /**
- * The class name to apply to the tab button.
- */
- className?: string;
- /**
- * The icon used for the tab button.
- */
- icon?: IconType;
/**
* Determines if the tab button should be disabled.
*
@@ -131,14 +106,6 @@ export type TabPanelProps = {
* A unique identifier for the tabpanel, which is used to generate a unique `id` for the underlying element.
*/
id: string;
- /**
- * The class name to apply to the tabpanel.
- */
- className?: string;
- /**
- * Custom CSS styles for the rendered `TabPanel` component.
- */
- style?: React.CSSProperties;
/**
* Determines whether or not the tabpanel element should be focusable.
* If `false`, pressing the tab key will skip over the tabpanel, and instead