Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

fix: migrate from defaultProps to default parameters in all components #587

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
alowelter wants to merge 5 commits into reactjs:main
base: main
Choose a base branch
Loading
from alowelter:main
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 13 additions & 25 deletions src/components/Tab.jsx
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@ import React, { useEffect, useRef } from 'react';
import cx from 'clsx';

const DEFAULT_CLASS = 'react-tabs__tab';
const defaultProps = {
className: DEFAULT_CLASS,
disabledClassName: `${DEFAULT_CLASS}--disabled`,
focus: false,
id: null,
selected: false,
selectedClassName: `${DEFAULT_CLASS}--selected`,
};

/*
Left for TS migration
Expand All @@ -34,24 +26,20 @@ const propTypes = {
tabRef: PropTypes.func, // private
};*/

const Tab = (props) => {
const Tab = ({
children,
className = DEFAULT_CLASS,
disabled,
disabledClassName = `${DEFAULT_CLASS}--disabled`,
focus = false,
id = null,
selected = false,
selectedClassName = `${DEFAULT_CLASS}--selected`,
tabIndex,
tabRef,
...attributes
}) => {
let nodeRef = useRef();
const {
children,
className,
disabled,
disabledClassName,
focus,
id,
selected,
selectedClassName,
tabIndex,
tabRef,
...attributes
} = {
...defaultProps,
...props,
};

useEffect(() => {
if (selected && focus) {
Expand Down
14 changes: 5 additions & 9 deletions src/components/TabList.jsx
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import React from 'react';
import cx from 'clsx';

const defaultProps = {
className: 'react-tabs__tab-list',
};

/*
Left for TS migration
const propTypes = {
Expand All @@ -15,12 +11,12 @@ const propTypes = {
PropTypes.object,
]),
};*/
const TabList = (props) => {
const { children, className, ...attributes } = {
...defaultProps,
...props,
};

const TabList = ({
children,
className = 'react-tabs__tab-list',
...attributes
}) => {
return (
<ul {...attributes} className={cx(className)} role="tablist">
{children}
Expand Down
27 changes: 9 additions & 18 deletions src/components/TabPanel.jsx
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import React from 'react';
import cx from 'clsx';

const DEFAULT_CLASS = 'react-tabs__tab-panel';
const defaultProps = {
className: DEFAULT_CLASS,
forceRender: false,
selectedClassName: `${DEFAULT_CLASS}--selected`,
};

/*
Left for TS migration
Expand All @@ -23,20 +18,16 @@ const propTypes = {
selectedClassName: PropTypes.string,
};
*/
const TabPanel = (props) => {
const {
children,
className,
forceRender,
id,
selected,
selectedClassName,
...attributes
} = {
...defaultProps,
...props,
};

const TabPanel = ({
children,
className = DEFAULT_CLASS,
forceRender = false,
selectedClassName = `${DEFAULT_CLASS}--selected`,
id,
selected,
...attributes
}) => {
return (
<div
{...attributes}
Expand Down
97 changes: 46 additions & 51 deletions src/components/Tabs.jsx
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,11 @@ import { getTabsCount } from '../helpers/count';

const MODE_CONTROLLED = 0;
const MODE_UNCONTROLLED = 1;

const propTypes = {
children: childrenPropType,
onSelect: onSelectPropType,
selectedIndex: selectedIndexPropType,
/*
Left for TS migration
className: PropTypes.oneOfType([
PropTypes.string,
PropTypes.array,
PropTypes.object,
]),
defaultFocus: PropTypes.bool,
defaultIndex: PropTypes.number,
direction: PropTypes.oneOf(['rtl', 'ltr']),
disabledTabClassName: PropTypes.string,
disableUpDownKeys: PropTypes.bool,
disableLeftRightKeys: PropTypes.bool,
domRef: PropTypes.func,
environment: PropTypes.object,
focusTabOnClick: PropTypes.bool,
forceRenderTabPanel: PropTypes.bool,
selectedTabClassName: PropTypes.string,
selectedTabPanelClassName: PropTypes.string,*/
};
const defaultProps = {
defaultFocus: false,
focusTabOnClick: true,
forceRenderTabPanel: false,
selectedIndex: null,
defaultIndex: null,
environment: null,
disableUpDownKeys: false,
disableLeftRightKeys: false,
};

const getModeFromProps = (props) => {
Expand All @@ -69,23 +41,32 @@ For more information about controlled and uncontrolled mode of react-tabs see ht
* focus: Because we never remove focus from the Tabs this state is only used to indicate that we should focus the current tab.
* It is initialized from the prop defaultFocus, and after the first render it is reset back to false. Later it can become true again when using keys to navigate the tabs.
*/
const Tabs = (props) => {
checkPropTypes(propTypes, props, 'prop', 'Tabs');
const {
children,
defaultFocus,
defaultIndex,
focusTabOnClick,
onSelect,
...attributes
} = {
...defaultProps,
...props,
};
const Tabs = ({
children,
defaultFocus = false,
defaultIndex = null,
focusTabOnClick = true,
forceRenderTabPanel = false,
selectedIndex = null,
environment = null,
disableUpDownKeys = false,
disableLeftRightKeys = false,
onSelect,
...attributes
}) => {
checkPropTypes(propTypes, { children, onSelect, selectedIndex }, 'prop', 'Tabs');
Copy link
Collaborator

@danez danez Sep 15, 2025
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defaultIndex seems missing here. OR was there a reason to no supply all props?


// Check for conflicting props
if (process.env.NODE_ENV !== 'production' && selectedIndex !== null && defaultIndex !== null) {
console.error(
'The prop `selectedIndex` cannot be used together with `defaultIndex` in `Tabs`.\n' +
'Either remove `selectedIndex` to let `Tabs` handle the selected tab internally or remove `defaultIndex` to handle it yourself.'
);
}
Comment on lines +60 to +65
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this added? Maybe this conversation from proptypes here should be done in a separate PR.


const [focus, setFocus] = useState(defaultFocus);
const [mode] = useState(getModeFromProps(attributes));
const [selectedIndex, setSelectedIndex] = useState(
const [mode] = useState(getModeFromProps({ selectedIndex }));
const [selectedIndexState, setSelectedIndexState] = useState(
mode === MODE_UNCONTROLLED ? defaultIndex || 0 : null,
);

Expand All @@ -98,14 +79,14 @@ const Tabs = (props) => {
// Ensure that we handle removed tabs and don't let selectedIndex get out of bounds
const tabsCount = getTabsCount(children);
useEffect(() => {
if (selectedIndex != null) {
if (selectedIndexState != null) {
const maxTabIndex = Math.max(0, tabsCount - 1);
setSelectedIndex(Math.min(selectedIndex, maxTabIndex));
setSelectedIndexState(Math.min(selectedIndexState, maxTabIndex));
}
}, [tabsCount]);
}

checkForIllegalModeChange(attributes, mode);
checkForIllegalModeChange({ selectedIndex }, mode);

const handleSelected = (index, last, event) => {
// Call change event handler
Expand All @@ -121,21 +102,35 @@ const Tabs = (props) => {

if (mode === MODE_UNCONTROLLED) {
// Update selected index
setSelectedIndex(index);
setSelectedIndexState(index);
}
};

let subProps = { ...props, ...attributes };
let subProps = {
children,
defaultFocus,
defaultIndex,
focusTabOnClick,
forceRenderTabPanel,
selectedIndex,
environment,
disableUpDownKeys,
disableLeftRightKeys,
onSelect,
...attributes
};

subProps.focus = focus;
subProps.onSelect = handleSelected;

if (selectedIndex != null) {
subProps.selectedIndex = selectedIndex;
if (selectedIndexState != null) {
subProps.selectedIndex = selectedIndexState;
}

delete subProps.defaultFocus;
delete subProps.defaultIndex;
delete subProps.focusTabOnClick;

return <UncontrolledTabs {...subProps}>{children}</UncontrolledTabs>;
};

Expand Down
Loading

AltStyle によって変換されたページ (->オリジナル) /