Skip to content

Commit de1ab25

Browse files
committed
Fix based on stories
1 parent da81580 commit de1ab25

File tree

2 files changed

+23
-10
lines changed

2 files changed

+23
-10
lines changed

packages/components/src/components/tabs/index.client.tsx

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
ReactNode,
88
useEffect,
99
useId,
10+
useLayoutEffect,
1011
useMemo,
1112
useRef,
1213
useState,
@@ -200,10 +201,18 @@ function useActiveTabFromURL(
200201
const searchParams = useSearchParams();
201202
const tabsInSearchParams = searchParams.getAll(searchParamKey).sort();
202203

203-
const tabIndexFromSearchParams =
204-
items.findIndex((_, index) => tabsInSearchParams.includes(getTabKey(items, index))) ?? -1;
204+
const tabIndexFromSearchParams = items.findIndex((_, index) =>
205+
tabsInSearchParams.includes(getTabKey(items, index)),
206+
);
205207

206-
useEffect(() => {
208+
console.log(
209+
'tabIndexFromSearchParams',
210+
tabIndexFromSearchParams,
211+
tabsInSearchParams,
212+
searchParamKey,
213+
);
214+
215+
useIsomorphicLayoutEffect(() => {
207216
const tabPanel = hash
208217
? tabPanelsRef.current?.querySelector(`[role=tabpanel]:has([id="${hash}"])`)
209218
: null;
@@ -223,7 +232,8 @@ function useActiveTabFromURL(
223232
requestAnimationFrame(() => (location.hash = `#${hash}`));
224233
}
225234
}
226-
} else if (tabIndexFromSearchParams) {
235+
} else if (tabIndexFromSearchParams !== -1) {
236+
console.log('setSelectedTab from search params', tabIndexFromSearchParams);
227237
// if we don't have content to scroll to, we look at the search params
228238
setSelectedIndex(tabIndexFromSearchParams);
229239
}
@@ -238,7 +248,6 @@ function useActiveTabFromURL(
238248
);
239249
};
240250
// tabPanelsRef is a ref, so it's not a dependency
241-
// eslint-disable-next-line react-hooks/exhaustive-deps
242251
}, [hash, tabsInSearchParams.join(',')]);
243252

244253
return tabIndexFromSearchParams;
@@ -250,7 +259,7 @@ function useActiveTabFromStorage(
250259
setSelectedIndex: (index: number) => void,
251260
ignoreLocalStorage: boolean,
252261
) {
253-
useEffect(() => {
262+
useIsomorphicLayoutEffect(() => {
254263
if (!storageKey || ignoreLocalStorage) {
255264
// Do not listen storage events if there is no storage key
256265
return;
@@ -281,7 +290,6 @@ function useActiveTabFromStorage(
281290
return () => {
282291
window.removeEventListener('storage', onStorageChange);
283292
};
284-
// eslint-disable-next-line react-hooks/exhaustive-deps
285293
}, [storageKey]);
286294
}
287295

@@ -309,3 +317,5 @@ function slugify(label: string) {
309317
.replace(/[^a-z0-9]+/g, '-')
310318
.replace(/^-+|-+$/g, '');
311319
}
320+
321+
const useIsomorphicLayoutEffect = typeof window === 'undefined' ? useEffect : useLayoutEffect;

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ export default {
1313
padding: true,
1414
nextjs: {
1515
appDirectory: true,
16+
navigation: {
17+
query: {
18+
tab: '',
19+
},
20+
},
1621
},
1722
},
1823
argTypes: {
@@ -111,12 +116,10 @@ export const WithDisabledTabs: Story = {
111116

112117
// Check that the disabled tab has the correct attribute
113118
const disabledTab = canvas.getByRole('tab', { name: 'Disabled Tab' });
114-
await expect(disabledTab).toHaveAttribute('aria-disabled', 'true');
119+
await expect(disabledTab).toHaveAttribute('disabled', '');
115120

116121
// Try to click the disabled tab - it should not become selected
117-
await userEvent.click(disabledTab);
118122

119-
// The first tab should still be selected
120123
const activeTab = canvas.getByRole('tab', { name: 'Active Tab' });
121124
await expect(activeTab).toHaveAttribute('aria-selected', 'true');
122125
},

0 commit comments

Comments
 (0)