Skip to content

Commit

Permalink
fix(Tabs): reset active index to selected index for manual activation (
Browse files Browse the repository at this point in the history
…#17831)

* refactor(Tabs): rename internal vars

* fix(Tabs): reset active index to selected index for manual activation

* test(Tabs): test manual activation blur handler
  • Loading branch information
emyarod authored Oct 23, 2024
1 parent 43d0c9f commit 5f4f0a6
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 6 deletions.
38 changes: 32 additions & 6 deletions packages/react/src/components/Tabs/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -531,9 +531,9 @@ function TabList({
) {
event.preventDefault();

const filtredTabs = tabs.current.filter((tab) => tab !== null);
const filteredTabs = tabs.current.filter((tab) => tab !== null);

const activeTabs: TabElement[] = filtredTabs.filter(
const activeTabs: TabElement[] = filteredTabs.filter(
(tab) => !tab.disabled
);

Expand All @@ -553,6 +553,18 @@ function TabList({
}
}

function handleBlur({
relatedTarget: currentActiveNode,
}: React.FocusEvent<HTMLDivElement>) {
if (ref.current?.contains(currentActiveNode)) {
return;
}
// reset active index to selected tab index for manual activation
if (activation === 'manual') {
setActiveIndex(selectedIndex);
}
}

useEffectOnce(() => {
const tab = tabs.current[selectedIndex];
if (scrollIntoView && tab) {
Expand Down Expand Up @@ -706,7 +718,8 @@ function TabList({
role="tablist"
className={`${prefix}--tab--list`}
onScroll={debouncedOnScroll}
onKeyDown={onKeyDown}>
onKeyDown={onKeyDown}
onBlur={handleBlur}>
{React.Children.map(children, (child, index) => {
return !isElement(child) ? null : (
<TabContext.Provider
Expand Down Expand Up @@ -876,9 +889,9 @@ function TabListVertical({
if (matches(event, [keys.ArrowDown, keys.ArrowUp, keys.Home, keys.End])) {
event.preventDefault();

const filtredTabs = tabs.current.filter((tab) => tab !== null);
const filteredTabs = tabs.current.filter((tab) => tab !== null);

const activeTabs: TabElement[] = filtredTabs.filter(
const activeTabs: TabElement[] = filteredTabs.filter(
(tab) => !tab.disabled
);

Expand All @@ -898,6 +911,18 @@ function TabListVertical({
}
}

function handleBlur({
relatedTarget: currentActiveNode,
}: React.FocusEvent<HTMLDivElement>) {
if (ref.current?.contains(currentActiveNode)) {
return;
}
// reset active index to selected tab index for manual activation
if (activation === 'manual') {
setActiveIndex(selectedIndex);
}
}

useEffectOnce(() => {
if (tabs.current[selectedIndex]?.disabled) {
const activeTabs = tabs.current.filter((tab) => {
Expand Down Expand Up @@ -991,7 +1016,8 @@ function TabListVertical({
ref={ref}
role="tablist"
className={`${prefix}--tab--list`}
onKeyDown={onKeyDown}>
onKeyDown={onKeyDown}
onBlur={handleBlur}>
{React.Children.map(children, (child, index) => {
return !isElement(child) ? null : (
<TabContext.Provider
Expand Down
24 changes: 24 additions & 0 deletions packages/react/src/components/Tabs/__tests__/Tabs-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,30 @@ describe('Tab', () => {
);
});

it('should reset focus to the active tab on blur in manual activation', async () => {
render(
<Tabs>
<TabList aria-label="List of tabs" activation="manual">
<Tab data-testid="tab-testid-1">Tab Label 1</Tab>
<Tab data-testid="tab-testid-2">Tab Label 2</Tab>
<Tab data-testid="tab-testid-3">Tab Label 3</Tab>
</TabList>
<TabPanels>
<TabPanel>Tab Panel 1</TabPanel>
<TabPanel>Tab Panel 2</TabPanel>
<TabPanel>Tab Panel 3</TabPanel>
</TabPanels>
</Tabs>
);

await userEvent.tab();
await userEvent.keyboard('[ArrowRight]');
expect(screen.getByTestId('tab-testid-2')).toHaveFocus();
await userEvent.keyboard('[Tab]');
await userEvent.keyboard('[Shift][Tab]');
expect(screen.getByTestId('tab-testid-1')).toHaveFocus();
});

it('should render close icon if dismissable', () => {
render(
<Tabs dismissable onTabCloseRequest={() => {}}>
Expand Down

0 comments on commit 5f4f0a6

Please sign in to comment.