Skip to content

Commit 7e06be8

Browse files
committed
fix: preserve default className when className is null or undefined
1 parent c97f954 commit 7e06be8

File tree

2 files changed

+76
-18
lines changed

2 files changed

+76
-18
lines changed

src/components/UncontrolledTabs.jsx

Lines changed: 40 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -373,27 +373,49 @@ const UncontrolledTabs = (props) => {
373373
return false;
374374
}
375375
const {
376-
children, // unused
377-
className,
378-
disabledTabClassName, // unused
376+
className: propClassName,
379377
domRef,
380-
focus, // unused
381-
forceRenderTabPanel, // unused
382-
onSelect, // unused
383-
selectedIndex, // unused
384-
selectedTabClassName, // unused
385-
selectedTabPanelClassName, // unused
386-
environment, // unused
387-
disableUpDownKeys, // unused
388-
disableLeftRightKeys, // unused
389-
...attributes
390-
} = {
391-
...defaultProps,
392-
...props,
393-
};
378+
children, // unused here
379+
disabledTabClassName, // unused here
380+
focus, // unused here
381+
forceRenderTabPanel, // unused here
382+
onSelect, // unused here
383+
selectedIndex, // unused here
384+
selectedTabClassName, // unused here
385+
selectedTabPanelClassName, // unused here
386+
environment, // unused here
387+
disableUpDownKeys, // unused here
388+
disableLeftRightKeys, // unused here
389+
...restProps
390+
} = props;
391+
392+
// Only pass valid DOM attributes and data- attributes
393+
const domAttributes = {};
394+
Object.keys(restProps).forEach((key) => {
395+
if (
396+
key.startsWith('data-') ||
397+
key === 'id' ||
398+
key === 'style' ||
399+
key === 'title' ||
400+
key === 'role' ||
401+
key === 'tabIndex' ||
402+
key === 'aria-label' ||
403+
key === 'aria-labelledby' ||
404+
key === 'aria-describedby' ||
405+
key === 'aria-controls' ||
406+
key === 'aria-selected' ||
407+
key === 'aria-disabled'
408+
) {
409+
domAttributes[key] = restProps[key];
410+
}
411+
});
412+
413+
const className =
414+
propClassName == null ? defaultProps.className : propClassName;
415+
394416
return (
395417
<div
396-
{...attributes}
418+
{...domAttributes}
397419
className={cx(className)}
398420
onClick={handleClick}
399421
onKeyDown={handleKeyDown}

src/components/__tests__/Tabs-test.jsx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from 'react';
33
import { cleanup, render, screen, within } from '@testing-library/react';
44
import { userEvent } from '@testing-library/user-event';
55
import '@testing-library/jest-dom/vitest';
6+
import UncontrolledTabs from '../UncontrolledTabs';
67
import Tab from '../Tab';
78
import TabList from '../TabList';
89
import TabPanel from '../TabPanel';
@@ -651,3 +652,38 @@ describe('<Tabs />', () => {
651652
assertTabSelected(1);
652653
});
653654
});
655+
656+
657+
test('preserves default className when className is undefined', () => {
658+
const { container } = render(
659+
<UncontrolledTabs
660+
className={undefined}
661+
selectedIndex={0}
662+
onSelect={() => {}}
663+
>
664+
<TabList>
665+
<Tab>Tab</Tab>
666+
</TabList>
667+
<TabPanel>Panel</TabPanel>
668+
</UncontrolledTabs>
669+
);
670+
671+
expect(container.firstChild).toHaveClass('react-tabs');
672+
});
673+
674+
test('preserves default className when className is null', () => {
675+
const { container } = render(
676+
<UncontrolledTabs
677+
className={null}
678+
selectedIndex={0}
679+
onSelect={() => {}}
680+
>
681+
<TabList>
682+
<Tab>Tab</Tab>
683+
</TabList>
684+
<TabPanel>Panel</TabPanel>
685+
</UncontrolledTabs>
686+
);
687+
688+
expect(container.firstChild).toHaveClass('react-tabs');
689+
});

0 commit comments

Comments
 (0)