Skip to content

Commit af318fb

Browse files
chad1008pull[bot]
authored andcommitted
Tabs: replace id with new tabId prop (#56883)
* replace `id` with `tabId` * update stories and tests * update `ColorGradientControl` implementation * changelog * use `tabId` in tests for consistency * update `ColorPanel` implementation
1 parent a696bfe commit af318fb

9 files changed

Lines changed: 104 additions & 91 deletions

File tree

packages/block-editor/src/components/colors-gradients/control.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,15 +141,15 @@ function ColorGradientControlInner( {
141141
}
142142
>
143143
<Tabs.TabList>
144-
<Tabs.Tab id={ TAB_IDS.color }>
144+
<Tabs.Tab tabId={ TAB_IDS.color }>
145145
{ __( 'Solid' ) }
146146
</Tabs.Tab>
147-
<Tabs.Tab id={ TAB_IDS.gradient }>
147+
<Tabs.Tab tabId={ TAB_IDS.gradient }>
148148
{ __( 'Gradient' ) }
149149
</Tabs.Tab>
150150
</Tabs.TabList>
151151
<Tabs.TabPanel
152-
id={ TAB_IDS.color }
152+
tabId={ TAB_IDS.color }
153153
className={
154154
'block-editor-color-gradient-control__panel'
155155
}
@@ -158,7 +158,7 @@ function ColorGradientControlInner( {
158158
{ tabPanels.color }
159159
</Tabs.TabPanel>
160160
<Tabs.TabPanel
161-
id={ TAB_IDS.gradient }
161+
tabId={ TAB_IDS.gradient }
162162
className={
163163
'block-editor-color-gradient-control__panel'
164164
}

packages/block-editor/src/components/global-styles/color-panel.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ function ColorPanelDropdown( {
263263
{ tabs.map( ( tab ) => (
264264
<Tabs.Tab
265265
key={ tab.key }
266-
id={ tab.key }
266+
tabId={ tab.key }
267267
>
268268
{ tab.label }
269269
</Tabs.Tab>
@@ -274,7 +274,7 @@ function ColorPanelDropdown( {
274274
return (
275275
<Tabs.TabPanel
276276
key={ tab.key }
277-
id={ tab.key }
277+
tabId={ tab.key }
278278
focusable={ false }
279279
>
280280
<ColorPanelTab

packages/components/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222

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

25+
### Experimental
26+
27+
- `Tabs`: implement new `tabId` prop ([#56883](https://github.com/WordPress/gutenberg/pull/56883)).
28+
2529
## 25.13.0 (2023-11-29)
2630

2731
### Enhancements

packages/components/src/tabs/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,9 @@ The children elements, which should be a series of `Tabs.TabPanel` components.
163163

164164
##### Props
165165

166-
###### `id`: `string`
166+
###### `tabId`: `string`
167167

168-
The id of the tab, which is prepended with the `Tabs` instance ID.
168+
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.
169169

170170
- Required: Yes
171171

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

199199
- Required: No
200200

201-
###### `id`: `string`
201+
###### `tabId`: `string`
202202

203-
The id of the tabpanel, which is combined with the `Tabs` instance ID and the suffix `-view`
203+
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.
204204

205205
- Required: Yes
206206

packages/components/src/tabs/stories/index.story.tsx

Lines changed: 48 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,17 @@ const Template: StoryFn< typeof Tabs > = ( props ) => {
4040
return (
4141
<Tabs { ...props }>
4242
<Tabs.TabList>
43-
<Tabs.Tab id={ 'tab1' }>Tab 1</Tabs.Tab>
44-
<Tabs.Tab id={ 'tab2' }>Tab 2</Tabs.Tab>
45-
<Tabs.Tab id={ 'tab3' }>Tab 3</Tabs.Tab>
43+
<Tabs.Tab tabId="tab1">Tab 1</Tabs.Tab>
44+
<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>
45+
<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
4646
</Tabs.TabList>
47-
<Tabs.TabPanel id={ 'tab1' }>
47+
<Tabs.TabPanel tabId="tab1">
4848
<p>Selected tab: Tab 1</p>
4949
</Tabs.TabPanel>
50-
<Tabs.TabPanel id={ 'tab2' }>
50+
<Tabs.TabPanel tabId="tab2">
5151
<p>Selected tab: Tab 2</p>
5252
</Tabs.TabPanel>
53-
<Tabs.TabPanel id={ 'tab3' } focusable={ false }>
53+
<Tabs.TabPanel tabId="tab3" focusable={ false }>
5454
<p>Selected tab: Tab 3</p>
5555
<p>
5656
This tabpanel has its <code>focusable</code> prop set to
@@ -71,19 +71,19 @@ const DisabledTabTemplate: StoryFn< typeof Tabs > = ( props ) => {
7171
return (
7272
<Tabs { ...props }>
7373
<Tabs.TabList>
74-
<Tabs.Tab id={ 'tab1' } disabled={ true }>
74+
<Tabs.Tab tabId="tab1" disabled={ true }>
7575
Tab 1
7676
</Tabs.Tab>
77-
<Tabs.Tab id={ 'tab2' }>Tab 2</Tabs.Tab>
78-
<Tabs.Tab id={ 'tab3' }>Tab 3</Tabs.Tab>
77+
<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>
78+
<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
7979
</Tabs.TabList>
80-
<Tabs.TabPanel id={ 'tab1' }>
80+
<Tabs.TabPanel tabId="tab1">
8181
<p>Selected tab: Tab 1</p>
8282
</Tabs.TabPanel>
83-
<Tabs.TabPanel id={ 'tab2' }>
83+
<Tabs.TabPanel tabId="tab2">
8484
<p>Selected tab: Tab 2</p>
8585
</Tabs.TabPanel>
86-
<Tabs.TabPanel id={ 'tab3' }>
86+
<Tabs.TabPanel tabId="tab3">
8787
<p>Selected tab: Tab 3</p>
8888
</Tabs.TabPanel>
8989
</Tabs>
@@ -96,31 +96,31 @@ const WithTabIconsAndTooltipsTemplate: StoryFn< typeof Tabs > = ( props ) => {
9696
<Tabs { ...props }>
9797
<Tabs.TabList>
9898
<Tabs.Tab
99-
id={ 'tab1' }
99+
tabId="tab1"
100100
render={
101101
<Button icon={ wordpress } label="Tab 1" showTooltip />
102102
}
103103
/>
104104
<Tabs.Tab
105-
id={ 'tab2' }
105+
tabId="tab2"
106106
render={
107107
<Button icon={ link } label="Tab 2" showTooltip />
108108
}
109109
/>
110110
<Tabs.Tab
111-
id={ 'tab3' }
111+
tabId="tab3"
112112
render={
113113
<Button icon={ more } label="Tab 3" showTooltip />
114114
}
115115
/>
116116
</Tabs.TabList>
117-
<Tabs.TabPanel id={ 'tab1' }>
117+
<Tabs.TabPanel tabId="tab1">
118118
<p>Selected tab: Tab 1</p>
119119
</Tabs.TabPanel>
120-
<Tabs.TabPanel id={ 'tab2' }>
120+
<Tabs.TabPanel tabId="tab2">
121121
<p>Selected tab: Tab 2</p>
122122
</Tabs.TabPanel>
123-
<Tabs.TabPanel id={ 'tab3' }>
123+
<Tabs.TabPanel tabId="tab3">
124124
<p>Selected tab: Tab 3</p>
125125
</Tabs.TabPanel>
126126
</Tabs>
@@ -140,18 +140,18 @@ const UsingSlotFillTemplate: StoryFn< typeof Tabs > = ( props ) => {
140140
<SlotFillProvider>
141141
<Tabs { ...props }>
142142
<Tabs.TabList>
143-
<Tabs.Tab id={ 'tab1' }>Tab 1</Tabs.Tab>
144-
<Tabs.Tab id={ 'tab2' }>Tab 2</Tabs.Tab>
145-
<Tabs.Tab id={ 'tab3' }>Tab 3</Tabs.Tab>
143+
<Tabs.Tab tabId="tab1">Tab 1</Tabs.Tab>
144+
<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>
145+
<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
146146
</Tabs.TabList>
147147
<Fill name="tabs-are-fun">
148-
<Tabs.TabPanel id={ 'tab1' }>
148+
<Tabs.TabPanel tabId="tab1">
149149
<p>Selected tab: Tab 1</p>
150150
</Tabs.TabPanel>
151-
<Tabs.TabPanel id={ 'tab2' }>
151+
<Tabs.TabPanel tabId="tab2">
152152
<p>Selected tab: Tab 2</p>
153153
</Tabs.TabPanel>
154-
<Tabs.TabPanel id={ 'tab3' }>
154+
<Tabs.TabPanel tabId="tab3">
155155
<p>Selected tab: Tab 3</p>
156156
</Tabs.TabPanel>
157157
</Fill>
@@ -196,9 +196,9 @@ const CloseButtonTemplate: StoryFn< typeof Tabs > = ( props ) => {
196196
} }
197197
>
198198
<Tabs.TabList>
199-
<Tabs.Tab id={ 'tab1' }>Tab 1</Tabs.Tab>
200-
<Tabs.Tab id={ 'tab2' }>Tab 2</Tabs.Tab>
201-
<Tabs.Tab id={ 'tab3' }>Tab 3</Tabs.Tab>
199+
<Tabs.Tab tabId="tab1">Tab 1</Tabs.Tab>
200+
<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>
201+
<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
202202
</Tabs.TabList>
203203
<Button
204204
variant={ 'tertiary' }
@@ -211,13 +211,13 @@ const CloseButtonTemplate: StoryFn< typeof Tabs > = ( props ) => {
211211
Close Tabs
212212
</Button>
213213
</div>
214-
<Tabs.TabPanel id={ 'tab1' }>
214+
<Tabs.TabPanel tabId="tab1">
215215
<p>Selected tab: Tab 1</p>
216216
</Tabs.TabPanel>
217-
<Tabs.TabPanel id={ 'tab2' }>
217+
<Tabs.TabPanel tabId="tab2">
218218
<p>Selected tab: Tab 2</p>
219219
</Tabs.TabPanel>
220-
<Tabs.TabPanel id={ 'tab3' }>
220+
<Tabs.TabPanel tabId="tab3">
221221
<p>Selected tab: Tab 3</p>
222222
</Tabs.TabPanel>
223223
</Tabs>
@@ -251,19 +251,19 @@ const ControlledModeTemplate: StoryFn< typeof Tabs > = ( props ) => {
251251
} }
252252
>
253253
<Tabs.TabList>
254-
<Tabs.Tab id={ 'tab1' }>Tab 1</Tabs.Tab>
254+
<Tabs.Tab tabId="tab1">Tab 1</Tabs.Tab>
255255

256-
<Tabs.Tab id={ 'tab2' }>Tab 2</Tabs.Tab>
256+
<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>
257257

258-
<Tabs.Tab id={ 'tab3' }>Tab 3</Tabs.Tab>
258+
<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
259259
</Tabs.TabList>
260-
<Tabs.TabPanel id={ 'tab1' }>
260+
<Tabs.TabPanel tabId="tab1">
261261
<p>Selected tab: Tab 1</p>
262262
</Tabs.TabPanel>
263-
<Tabs.TabPanel id={ 'tab2' }>
263+
<Tabs.TabPanel tabId="tab2">
264264
<p>Selected tab: Tab 2</p>
265265
</Tabs.TabPanel>
266-
<Tabs.TabPanel id={ 'tab3' }>
266+
<Tabs.TabPanel tabId="tab3">
267267
<p>Selected tab: Tab 3</p>
268268
</Tabs.TabPanel>
269269
</Tabs>
@@ -314,19 +314,19 @@ const TabBecomesDisabledTemplate: StoryFn< typeof Tabs > = ( props ) => {
314314
</Button>
315315
<Tabs { ...props }>
316316
<Tabs.TabList>
317-
<Tabs.Tab id={ 'tab1' }>Tab 1</Tabs.Tab>
318-
<Tabs.Tab id={ 'tab2' } disabled={ disableTab2 }>
317+
<Tabs.Tab tabId="tab1">Tab 1</Tabs.Tab>
318+
<Tabs.Tab tabId="tab2" disabled={ disableTab2 }>
319319
Tab 2
320320
</Tabs.Tab>
321-
<Tabs.Tab id={ 'tab3' }>Tab 3</Tabs.Tab>
321+
<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
322322
</Tabs.TabList>
323-
<Tabs.TabPanel id={ 'tab1' }>
323+
<Tabs.TabPanel tabId="tab1">
324324
<p>Selected tab: Tab 1</p>
325325
</Tabs.TabPanel>
326-
<Tabs.TabPanel id={ 'tab2' }>
326+
<Tabs.TabPanel tabId="tab2">
327327
<p>Selected tab: Tab 2</p>
328328
</Tabs.TabPanel>
329-
<Tabs.TabPanel id={ 'tab3' }>
329+
<Tabs.TabPanel tabId="tab3">
330330
<p>Selected tab: Tab 3</p>
331331
</Tabs.TabPanel>
332332
</Tabs>
@@ -348,17 +348,17 @@ const TabGetsRemovedTemplate: StoryFn< typeof Tabs > = ( props ) => {
348348
</Button>
349349
<Tabs { ...props }>
350350
<Tabs.TabList>
351-
{ ! removeTab1 && <Tabs.Tab id={ 'tab1' }>Tab 1</Tabs.Tab> }
352-
<Tabs.Tab id={ 'tab2' }>Tab 2</Tabs.Tab>
353-
<Tabs.Tab id={ 'tab3' }>Tab 3</Tabs.Tab>
351+
{ ! removeTab1 && <Tabs.Tab tabId="tab1">Tab 1</Tabs.Tab> }
352+
<Tabs.Tab tabId="tab2">Tab 2</Tabs.Tab>
353+
<Tabs.Tab tabId="tab3">Tab 3</Tabs.Tab>
354354
</Tabs.TabList>
355-
<Tabs.TabPanel id={ 'tab1' }>
355+
<Tabs.TabPanel tabId="tab1">
356356
<p>Selected tab: Tab 1</p>
357357
</Tabs.TabPanel>
358-
<Tabs.TabPanel id={ 'tab2' }>
358+
<Tabs.TabPanel tabId="tab2">
359359
<p>Selected tab: Tab 2</p>
360360
</Tabs.TabPanel>
361-
<Tabs.TabPanel id={ 'tab3' }>
361+
<Tabs.TabPanel tabId="tab3">
362362
<p>Selected tab: Tab 3</p>
363363
</Tabs.TabPanel>
364364
</Tabs>

packages/components/src/tabs/tab.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@ import type { WordPressComponentProps } from '../context';
1515

1616
export const Tab = forwardRef<
1717
HTMLButtonElement,
18-
WordPressComponentProps< TabProps, 'button', false >
19-
>( function Tab( { children, id, disabled, render, ...otherProps }, ref ) {
18+
Omit< WordPressComponentProps< TabProps, 'button', false >, 'id' >
19+
>( function Tab( { children, tabId, disabled, render, ...otherProps }, ref ) {
2020
const context = useTabsContext();
2121
if ( ! context ) {
2222
warning( '`Tabs.Tab` must be wrapped in a `Tabs` component.' );
2323
return null;
2424
}
2525
const { store, instanceId } = context;
26-
const instancedTabId = `${ instanceId }-${ id }`;
26+
const instancedTabId = `${ instanceId }-${ tabId }`;
2727
return (
2828
<StyledTab
2929
ref={ ref }

packages/components/src/tabs/tabpanel.tsx

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,24 @@ import type { WordPressComponentProps } from '../context';
2020

2121
export const TabPanel = forwardRef<
2222
HTMLDivElement,
23-
WordPressComponentProps< TabPanelProps, 'div', false >
24-
>( function TabPanel( { children, id, focusable = true, ...otherProps }, ref ) {
23+
Omit< WordPressComponentProps< TabPanelProps, 'div', false >, 'id' >
24+
>( function TabPanel(
25+
{ children, tabId, focusable = true, ...otherProps },
26+
ref
27+
) {
2528
const context = useTabsContext();
2629
if ( ! context ) {
2730
warning( '`Tabs.TabPanel` must be wrapped in a `Tabs` component.' );
2831
return null;
2932
}
3033
const { store, instanceId } = context;
34+
const instancedTabId = `${ instanceId }-${ tabId }`;
3135

3236
return (
3337
<StyledTabPanel
3438
ref={ ref }
3539
store={ store }
36-
id={ `${ instanceId }-${ id }-view` }
40+
id={ instancedTabId }
3741
focusable={ focusable }
3842
{ ...otherProps }
3943
>

0 commit comments

Comments
 (0)