Skip to content

Commit

Permalink
Tabs: replace id with new tabId prop (#56883)
Browse files Browse the repository at this point in the history
* replace `id` with `tabId`

* update stories and tests

* update `ColorGradientControl` implementation

* changelog

* use `tabId` in tests for consistency

* update `ColorPanel` implementation
  • Loading branch information
chad1008 authored Dec 8, 2023
1 parent 7872195 commit 6211c7a
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -141,15 +141,15 @@ function ColorGradientControlInner( {
}
>
<Tabs.TabList>
<Tabs.Tab id={ TAB_IDS.color }>
<Tabs.Tab tabId={ TAB_IDS.color }>
{ __( 'Solid' ) }
</Tabs.Tab>
<Tabs.Tab id={ TAB_IDS.gradient }>
<Tabs.Tab tabId={ TAB_IDS.gradient }>
{ __( 'Gradient' ) }
</Tabs.Tab>
</Tabs.TabList>
<Tabs.TabPanel
id={ TAB_IDS.color }
tabId={ TAB_IDS.color }
className={
'block-editor-color-gradient-control__panel'
}
Expand All @@ -158,7 +158,7 @@ function ColorGradientControlInner( {
{ tabPanels.color }
</Tabs.TabPanel>
<Tabs.TabPanel
id={ TAB_IDS.gradient }
tabId={ TAB_IDS.gradient }
className={
'block-editor-color-gradient-control__panel'
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ function ColorPanelDropdown( {
{ tabs.map( ( tab ) => (
<Tabs.Tab
key={ tab.key }
id={ tab.key }
tabId={ tab.key }
>
{ tab.label }
</Tabs.Tab>
Expand All @@ -274,7 +274,7 @@ function ColorPanelDropdown( {
return (
<Tabs.TabPanel
key={ tab.key }
id={ tab.key }
tabId={ tab.key }
focusable={ false }
>
<ColorPanelTab
Expand Down
4 changes: 4 additions & 0 deletions packages/components/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@

- `DropdownMenuV2Ariakit`: prevent prefix collapsing if all radios or checkboxes are unselected ([#56720](https://github.com/WordPress/gutenberg/pull/56720)).

### Experimental

- `Tabs`: implement new `tabId` prop ([#56883](https://github.com/WordPress/gutenberg/pull/56883)).

## 25.13.0 (2023-11-29)

### Enhancements
Expand Down
8 changes: 4 additions & 4 deletions packages/components/src/tabs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,9 +163,9 @@ The children elements, which should be a series of `Tabs.TabPanel` components.

##### Props

###### `id`: `string`
###### `tabId`: `string`

The id of the tab, which is prepended with the `Tabs` instance ID.
A unique identifier for the tab, which is used to generate a unique id for the underlying element. The value of this prop should match with the value of the `tabId` prop on the corresponding `Tabs.TabPanel` component.

- Required: Yes

Expand Down Expand Up @@ -198,9 +198,9 @@ The children elements, generally the content to display on the tabpanel.

- Required: No

###### `id`: `string`
###### `tabId`: `string`

The id of the tabpanel, which is combined with the `Tabs` instance ID and the suffix `-view`
A unique identifier for the tabpanel, which is used to generate an instanced id for the underlying element. The value of this prop should match with the value of the `tabId` prop on the corresponding `Tabs.Tab` component.

- Required: Yes

Expand Down
96 changes: 48 additions & 48 deletions packages/components/src/tabs/stories/index.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,17 @@ const Template: StoryFn< typeof Tabs > = ( props ) => {
return (
<Tabs { ...props }>
<Tabs.TabList>
<Tabs.Tab id={ 'tab1' }>Tab 1</Tabs.Tab>
<Tabs.Tab id={ 'tab2' }>Tab 2</Tabs.Tab>
<Tabs.Tab id={ 'tab3' }>Tab 3</Tabs.Tab>
<Tabs.Tab tabId="tab1">Tab 1</Tabs.Tab>
<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>
<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
</Tabs.TabList>
<Tabs.TabPanel id={ 'tab1' }>
<Tabs.TabPanel tabId="tab1">
<p>Selected tab: Tab 1</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab2' }>
<Tabs.TabPanel tabId="tab2">
<p>Selected tab: Tab 2</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab3' } focusable={ false }>
<Tabs.TabPanel tabId="tab3" focusable={ false }>
<p>Selected tab: Tab 3</p>
<p>
This tabpanel has its <code>focusable</code> prop set to
Expand All @@ -71,19 +71,19 @@ const DisabledTabTemplate: StoryFn< typeof Tabs > = ( props ) => {
return (
<Tabs { ...props }>
<Tabs.TabList>
<Tabs.Tab id={ 'tab1' } disabled={ true }>
<Tabs.Tab tabId="tab1" disabled={ true }>
Tab 1
</Tabs.Tab>
<Tabs.Tab id={ 'tab2' }>Tab 2</Tabs.Tab>
<Tabs.Tab id={ 'tab3' }>Tab 3</Tabs.Tab>
<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>
<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
</Tabs.TabList>
<Tabs.TabPanel id={ 'tab1' }>
<Tabs.TabPanel tabId="tab1">
<p>Selected tab: Tab 1</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab2' }>
<Tabs.TabPanel tabId="tab2">
<p>Selected tab: Tab 2</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab3' }>
<Tabs.TabPanel tabId="tab3">
<p>Selected tab: Tab 3</p>
</Tabs.TabPanel>
</Tabs>
Expand All @@ -96,31 +96,31 @@ const WithTabIconsAndTooltipsTemplate: StoryFn< typeof Tabs > = ( props ) => {
<Tabs { ...props }>
<Tabs.TabList>
<Tabs.Tab
id={ 'tab1' }
tabId="tab1"
render={
<Button icon={ wordpress } label="Tab 1" showTooltip />
}
/>
<Tabs.Tab
id={ 'tab2' }
tabId="tab2"
render={
<Button icon={ link } label="Tab 2" showTooltip />
}
/>
<Tabs.Tab
id={ 'tab3' }
tabId="tab3"
render={
<Button icon={ more } label="Tab 3" showTooltip />
}
/>
</Tabs.TabList>
<Tabs.TabPanel id={ 'tab1' }>
<Tabs.TabPanel tabId="tab1">
<p>Selected tab: Tab 1</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab2' }>
<Tabs.TabPanel tabId="tab2">
<p>Selected tab: Tab 2</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab3' }>
<Tabs.TabPanel tabId="tab3">
<p>Selected tab: Tab 3</p>
</Tabs.TabPanel>
</Tabs>
Expand All @@ -140,18 +140,18 @@ const UsingSlotFillTemplate: StoryFn< typeof Tabs > = ( props ) => {
<SlotFillProvider>
<Tabs { ...props }>
<Tabs.TabList>
<Tabs.Tab id={ 'tab1' }>Tab 1</Tabs.Tab>
<Tabs.Tab id={ 'tab2' }>Tab 2</Tabs.Tab>
<Tabs.Tab id={ 'tab3' }>Tab 3</Tabs.Tab>
<Tabs.Tab tabId="tab1">Tab 1</Tabs.Tab>
<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>
<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
</Tabs.TabList>
<Fill name="tabs-are-fun">
<Tabs.TabPanel id={ 'tab1' }>
<Tabs.TabPanel tabId="tab1">
<p>Selected tab: Tab 1</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab2' }>
<Tabs.TabPanel tabId="tab2">
<p>Selected tab: Tab 2</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab3' }>
<Tabs.TabPanel tabId="tab3">
<p>Selected tab: Tab 3</p>
</Tabs.TabPanel>
</Fill>
Expand Down Expand Up @@ -196,9 +196,9 @@ const CloseButtonTemplate: StoryFn< typeof Tabs > = ( props ) => {
} }
>
<Tabs.TabList>
<Tabs.Tab id={ 'tab1' }>Tab 1</Tabs.Tab>
<Tabs.Tab id={ 'tab2' }>Tab 2</Tabs.Tab>
<Tabs.Tab id={ 'tab3' }>Tab 3</Tabs.Tab>
<Tabs.Tab tabId="tab1">Tab 1</Tabs.Tab>
<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>
<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
</Tabs.TabList>
<Button
variant={ 'tertiary' }
Expand All @@ -211,13 +211,13 @@ const CloseButtonTemplate: StoryFn< typeof Tabs > = ( props ) => {
Close Tabs
</Button>
</div>
<Tabs.TabPanel id={ 'tab1' }>
<Tabs.TabPanel tabId="tab1">
<p>Selected tab: Tab 1</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab2' }>
<Tabs.TabPanel tabId="tab2">
<p>Selected tab: Tab 2</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab3' }>
<Tabs.TabPanel tabId="tab3">
<p>Selected tab: Tab 3</p>
</Tabs.TabPanel>
</Tabs>
Expand Down Expand Up @@ -251,19 +251,19 @@ const ControlledModeTemplate: StoryFn< typeof Tabs > = ( props ) => {
} }
>
<Tabs.TabList>
<Tabs.Tab id={ 'tab1' }>Tab 1</Tabs.Tab>
<Tabs.Tab tabId="tab1">Tab 1</Tabs.Tab>

<Tabs.Tab id={ 'tab2' }>Tab 2</Tabs.Tab>
<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>

<Tabs.Tab id={ 'tab3' }>Tab 3</Tabs.Tab>
<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
</Tabs.TabList>
<Tabs.TabPanel id={ 'tab1' }>
<Tabs.TabPanel tabId="tab1">
<p>Selected tab: Tab 1</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab2' }>
<Tabs.TabPanel tabId="tab2">
<p>Selected tab: Tab 2</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab3' }>
<Tabs.TabPanel tabId="tab3">
<p>Selected tab: Tab 3</p>
</Tabs.TabPanel>
</Tabs>
Expand Down Expand Up @@ -314,19 +314,19 @@ const TabBecomesDisabledTemplate: StoryFn< typeof Tabs > = ( props ) => {
</Button>
<Tabs { ...props }>
<Tabs.TabList>
<Tabs.Tab id={ 'tab1' }>Tab 1</Tabs.Tab>
<Tabs.Tab id={ 'tab2' } disabled={ disableTab2 }>
<Tabs.Tab tabId="tab1">Tab 1</Tabs.Tab>
<Tabs.Tab tabId="tab2" disabled={ disableTab2 }>
Tab 2
</Tabs.Tab>
<Tabs.Tab id={ 'tab3' }>Tab 3</Tabs.Tab>
<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
</Tabs.TabList>
<Tabs.TabPanel id={ 'tab1' }>
<Tabs.TabPanel tabId="tab1">
<p>Selected tab: Tab 1</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab2' }>
<Tabs.TabPanel tabId="tab2">
<p>Selected tab: Tab 2</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab3' }>
<Tabs.TabPanel tabId="tab3">
<p>Selected tab: Tab 3</p>
</Tabs.TabPanel>
</Tabs>
Expand All @@ -348,17 +348,17 @@ const TabGetsRemovedTemplate: StoryFn< typeof Tabs > = ( props ) => {
</Button>
<Tabs { ...props }>
<Tabs.TabList>
{ ! removeTab1 && <Tabs.Tab id={ 'tab1' }>Tab 1</Tabs.Tab> }
<Tabs.Tab id={ 'tab2' }>Tab 2</Tabs.Tab>
<Tabs.Tab id={ 'tab3' }>Tab 3</Tabs.Tab>
{ ! removeTab1 && <Tabs.Tab tabId="tab1">Tab 1</Tabs.Tab> }
<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>
<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
</Tabs.TabList>
<Tabs.TabPanel id={ 'tab1' }>
<Tabs.TabPanel tabId="tab1">
<p>Selected tab: Tab 1</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab2' }>
<Tabs.TabPanel tabId="tab2">
<p>Selected tab: Tab 2</p>
</Tabs.TabPanel>
<Tabs.TabPanel id={ 'tab3' }>
<Tabs.TabPanel tabId="tab3">
<p>Selected tab: Tab 3</p>
</Tabs.TabPanel>
</Tabs>
Expand Down
6 changes: 3 additions & 3 deletions packages/components/src/tabs/tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ import type { WordPressComponentProps } from '../context';

export const Tab = forwardRef<
HTMLButtonElement,
WordPressComponentProps< TabProps, 'button', false >
>( function Tab( { children, id, disabled, render, ...otherProps }, ref ) {
Omit< WordPressComponentProps< TabProps, 'button', false >, 'id' >
>( function Tab( { children, tabId, disabled, render, ...otherProps }, ref ) {
const context = useTabsContext();
if ( ! context ) {
warning( '`Tabs.Tab` must be wrapped in a `Tabs` component.' );
return null;
}
const { store, instanceId } = context;
const instancedTabId = `${ instanceId }-${ id }`;
const instancedTabId = `${ instanceId }-${ tabId }`;
return (
<StyledTab
ref={ ref }
Expand Down
10 changes: 7 additions & 3 deletions packages/components/src/tabs/tabpanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,24 @@ import type { WordPressComponentProps } from '../context';

export const TabPanel = forwardRef<
HTMLDivElement,
WordPressComponentProps< TabPanelProps, 'div', false >
>( function TabPanel( { children, id, focusable = true, ...otherProps }, ref ) {
Omit< WordPressComponentProps< TabPanelProps, 'div', false >, 'id' >
>( function TabPanel(
{ children, tabId, focusable = true, ...otherProps },
ref
) {
const context = useTabsContext();
if ( ! context ) {
warning( '`Tabs.TabPanel` must be wrapped in a `Tabs` component.' );
return null;
}
const { store, instanceId } = context;
const instancedTabId = `${ instanceId }-${ tabId }`;

return (
<StyledTabPanel
ref={ ref }
store={ store }
id={ `${ instanceId }-${ id }-view` }
id={ instancedTabId }
focusable={ focusable }
{ ...otherProps }
>
Expand Down
Loading

1 comment on commit 6211c7a

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flaky tests detected in 6211c7a.
Some tests passed with failed attempts. The failures may not be related to this commit but are still reported for visibility. See the documentation for more information.

🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/7143801139
📝 Reported issues:

Please sign in to comment.