Skip to content

Commit 2ecc712

Browse files
committed
feat(tabs): add "selected" shorthand
1 parent e13d808 commit 2ecc712

File tree

4 files changed

+20
-7
lines changed

4 files changed

+20
-7
lines changed

packages/kit-headless/src/components/tabs/tab-panel.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { tabsContextId } from './tabs-context-id';
1313
export type TabPanelProps = {
1414
/** Optional tab contents. */
1515
label?: QwikIntrinsicElements['div']['children'];
16+
selected?: boolean;
1617

1718
/** @deprecated Internal use only */
1819
_tabId?: string;

packages/kit-headless/src/components/tabs/tab.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export const TAB_ID_PREFIX = '_tab_';
1818

1919
export type TabProps = {
2020
disabled?: boolean;
21+
selected?: boolean;
2122
selectedClassName?: string;
2223

2324
/** @deprecated Internal use only */

packages/kit-headless/src/components/tabs/tabs.spec.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,13 +699,15 @@ describe('Tabs', () => {
699699
<Tab>Tab 1</Tab>
700700
<TabPanel>Panel 1</TabPanel>
701701
<TabPanel label="Tab 2">Panel 2</TabPanel>
702-
<TabPanel>Panel 3</TabPanel>
702+
<TabPanel selected>Panel 3</TabPanel>
703703
<Tab>Tab 3</Tab>
704704
</Tabs>
705705
);
706706

707707
cy.get('[role="tab"]').should('have.length', 3);
708708

709+
cy.findByRole('tabpanel').should('contain', 'Panel 3');
710+
709711
cy.findByRole('tab', { name: /Tab 2/i }).click();
710712

711713
cy.findByRole('tabpanel').should('contain', 'Panel 2');

packages/kit-headless/src/components/tabs/tabs.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,8 @@ import { TabList } from './tabs-list';
2626
* aria Tabs Pattern https://www.w3.org/WAI/ARIA/apg/patterns/tabs/
2727
* a11y lint plugin https://www.npmjs.com/package/eslint-plugin-jsx-a11y
2828
29-
* POST Alpha
30-
* Add a way to add a default tab class from the root (for styling all the tabs in one place)
31-
3229
* POST Beta
3330
* Add automated tests for preventDefault on end, home, pageDown, pageUp
34-
* Add automated tests for SSR indexing behavior (and in general)
35-
3631
3732
* POST V1:
3833
* - RTL
@@ -120,6 +115,7 @@ export const Tabs: FunctionComponent<TabsProps> = (props) => {
120115
const panelComponents: JSXNode[] = [];
121116
const tabs: TabInfo[] = [];
122117
let panelIndex = 0;
118+
let selectedIndex;
123119

124120
// Extract the Tab related components from the children
125121
while (childrenToProcess.length) {
@@ -143,17 +139,26 @@ export const Tabs: FunctionComponent<TabsProps> = (props) => {
143139
break;
144140
}
145141
case Tab: {
142+
if (child.props.selected) {
143+
selectedIndex = tabComponents.length;
144+
child.props.selected = undefined;
145+
}
146146
tabComponents.push(child);
147147
break;
148148
}
149149
case TabPanel: {
150-
const { label } = child.props;
150+
const { label, selected } = child.props;
151151
// The consumer must provide a key if they change the order
152152
const tabId = child.key || `${panelIndex}`;
153153

154154
if (label) {
155155
tabComponents.push(<Tab>{label}</Tab>);
156156
}
157+
if (selected) {
158+
selectedIndex = panelIndex;
159+
child.props.selected = undefined;
160+
}
161+
157162
// Always assign a key
158163
child.key = tabId;
159164
// Add props but don't replace the object
@@ -198,6 +203,10 @@ export const Tabs: FunctionComponent<TabsProps> = (props) => {
198203
tabListElement = <TabList>{tabComponents}</TabList>;
199204
}
200205

206+
if (typeof selectedIndex === 'number') {
207+
rest.selectedIndex = selectedIndex;
208+
}
209+
201210
return (
202211
<TabsImpl tabs={tabs} {...rest}>
203212
{tabListElement}

0 commit comments

Comments
 (0)