diff --git a/.eslintrc.js b/.eslintrc.js index d9ec7523..36bad06b 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -17,6 +17,7 @@ module.exports = { 'prefer-destructuring': 0, 'react/no-unused-prop-types': 0, 'max-len': 0, - 'brace-style': 0, + "import/no-extraneous-dependencies": ["error", {"devDependencies": true, "optionalDependencies": false, "peerDependencies": false}], + 'brace-style': 0 }, }; diff --git a/HISTORY.md b/HISTORY.md index c38a3c88..5f3a5f39 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,6 +1,12 @@ # History ---- +## 10.1.0 / 2020-03-17 + +* Add `keyboard` prop. +* `extraContent` don't trigger keyboard navigate now. +* Remove `prop-types` and clean up dependencies. + ## 9.6.0 / 2019-01-16 * ScrollableInkTabBar support render props to customize TabNode diff --git a/README.md b/README.md index d54f1023..75ee5fed 100644 --- a/README.md +++ b/README.md @@ -241,6 +241,12 @@ navWrapper={(content) => {content}} the gap between tabs + + keyboard + boolean + true + whether support keyboard to navigate tabs + diff --git a/package.json b/package.json index 79ebf315..61af744f 100644 --- a/package.json +++ b/package.json @@ -41,12 +41,15 @@ "prepublishOnly": "npm run lint && npm run test && npm run compile && np --no-cleanup --yolo --no-publish" }, "devDependencies": { + "@umijs/fabric": "^2.0.4", "coveralls": "^3.0.6", "cross-env": "^7.0.2", "enzyme": "^3.7.0", "enzyme-adapter-react-16": "^1.7.0", "enzyme-to-json": "^3.3.4", + "eslint": "^6.8.0", "fastclick": "~1.0.6", + "father": "^2.29.2", "history": "^1.17.0", "immutability-helper": "^3.0.1", "less-loader": "^5.0.0", @@ -56,22 +59,16 @@ "react": "^16.0.0", "react-dnd": "^7.0.2", "react-dnd-html5-backend": "^7.0.2", + "react-dom": "^16.0.0", "react-router": "^3.0.0", "react-test-renderer": "^16.0.0", "sortablejs": "^1.7.0" }, - "peerDependencies": { - "react": ">=15.0.0" - }, "dependencies": { - "@umijs/fabric": "^2.0.4", "classnames": "2.x", - "father": "^2.29.2", "lodash": "^4.17.5", - "prop-types": "15.x", "rc-hammerjs": "~0.6.0", "resize-observer-polyfill": "^1.5.1", - "warning": "^4.0.3", - "react-dom": "^16.0.0" + "warning": "^4.0.3" } } diff --git a/src/InkTabBar.js b/src/InkTabBar.js index 605484b7..73325961 100755 --- a/src/InkTabBar.js +++ b/src/InkTabBar.js @@ -1,6 +1,5 @@ /* eslint-disable react/prefer-stateless-function */ import React from 'react'; -import PropTypes from 'prop-types'; import InkTabBarNode from './InkTabBarNode'; import TabBarTabsNode from './TabBarTabsNode'; import TabBarRootNode from './TabBarRootNode'; @@ -21,10 +20,6 @@ export default class InkTabBar extends React.Component { } } -InkTabBar.propTypes = { - onTabClick: PropTypes.func, -}; - InkTabBar.defaultProps = { onTabClick: () => {}, }; diff --git a/src/InkTabBarNode.js b/src/InkTabBarNode.js index 78efd25c..f60eddd6 100644 --- a/src/InkTabBarNode.js +++ b/src/InkTabBarNode.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import classnames from 'classnames'; import { setTransform, @@ -121,14 +120,6 @@ export default class InkTabBarNode extends React.Component { } } -InkTabBarNode.propTypes = { - prefixCls: PropTypes.string, - styles: PropTypes.object, - inkBarAnimated: PropTypes.bool, - saveRef: PropTypes.func, - direction: PropTypes.string, -}; - InkTabBarNode.defaultProps = { prefixCls: '', inkBarAnimated: true, diff --git a/src/SaveRef.js b/src/SaveRef.js index c0acc201..2ba0e7a3 100644 --- a/src/SaveRef.js +++ b/src/SaveRef.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; export default class SaveRef extends React.Component { getRef = name => this[name]; @@ -15,10 +14,6 @@ export default class SaveRef extends React.Component { } } -SaveRef.propTypes = { - children: PropTypes.func, -}; - SaveRef.defaultProps = { children: () => null, }; diff --git a/src/ScrollableInkTabBar.js b/src/ScrollableInkTabBar.js index d60aa8f2..c5c55d03 100755 --- a/src/ScrollableInkTabBar.js +++ b/src/ScrollableInkTabBar.js @@ -1,6 +1,5 @@ /* eslint-disable react/prefer-stateless-function */ import React from 'react'; -import PropTypes from 'prop-types'; import InkTabBarNode from './InkTabBarNode'; import TabBarTabsNode from './TabBarTabsNode'; import TabBarRootNode from './TabBarRootNode'; @@ -28,8 +27,4 @@ export default class ScrollableInkTabBar extends React.Component { ); } -} - -ScrollableInkTabBar.propTypes = { - children: PropTypes.func, -}; +} \ No newline at end of file diff --git a/src/ScrollableTabBarNode.js b/src/ScrollableTabBarNode.js index caafb408..1481f307 100755 --- a/src/ScrollableTabBarNode.js +++ b/src/ScrollableTabBarNode.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import classnames from 'classnames'; import debounce from 'lodash/debounce'; import ResizeObserver from 'resize-observer-polyfill'; @@ -304,22 +303,6 @@ export default class ScrollableTabBarNode extends React.Component { } } -ScrollableTabBarNode.propTypes = { - activeKey: PropTypes.string, - getRef: PropTypes.func.isRequired, - saveRef: PropTypes.func.isRequired, - tabBarPosition: PropTypes.oneOf(['left', 'right', 'top', 'bottom']), - prefixCls: PropTypes.string, - scrollAnimated: PropTypes.bool, - onPrevClick: PropTypes.func, - onNextClick: PropTypes.func, - navWrapper: PropTypes.func, - children: PropTypes.node, - prevIcon: PropTypes.node, - nextIcon: PropTypes.node, - direction: PropTypes.node, -}; - ScrollableTabBarNode.defaultProps = { tabBarPosition: 'left', prefixCls: '', diff --git a/src/SwipeableTabBarNode.js b/src/SwipeableTabBarNode.js index d36c1058..0361d746 100755 --- a/src/SwipeableTabBarNode.js +++ b/src/SwipeableTabBarNode.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import classnames from 'classnames'; import Hammer from 'rc-hammerjs'; import ReactDOM from 'react-dom'; @@ -206,20 +205,6 @@ export default class SwipeableTabBarNode extends React.Component { } } -SwipeableTabBarNode.propTypes = { - activeKey: PropTypes.string, - panels: PropTypes.node, - pageSize: PropTypes.number, - tabBarPosition: PropTypes.oneOf(['left', 'right', 'top', 'bottom']), - prefixCls: PropTypes.string, - children: PropTypes.node, - hammerOptions: PropTypes.object, - speed: PropTypes.number, - saveRef: PropTypes.func, - getRef: PropTypes.func, - direction: PropTypes.string, -}; - SwipeableTabBarNode.defaultProps = { panels: null, tabBarPosition: 'top', diff --git a/src/SwipeableTabContent.js b/src/SwipeableTabContent.js index 0b647d64..c5a3ed62 100755 --- a/src/SwipeableTabContent.js +++ b/src/SwipeableTabContent.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import Hammer from 'rc-hammerjs'; import ReactDOM from 'react-dom'; import TabContent from './TabContent'; @@ -159,15 +158,6 @@ export default class SwipeableTabContent extends React.Component { } } -SwipeableTabContent.propTypes = { - tabBarPosition: PropTypes.string, - onChange: PropTypes.func, - children: PropTypes.node, - hammerOptions: PropTypes.any, - animated: PropTypes.bool, - activeKey: PropTypes.string, -}; - SwipeableTabContent.defaultProps = { animated: true, }; diff --git a/src/TabBarRootNode.js b/src/TabBarRootNode.js index fd4506ae..025a1322 100644 --- a/src/TabBarRootNode.js +++ b/src/TabBarRootNode.js @@ -1,5 +1,4 @@ import React, { cloneElement } from 'react'; -import PropTypes from 'prop-types'; import classnames from 'classnames'; import { getDataAttr } from './utils'; @@ -42,6 +41,7 @@ export default class TabBarRootNode extends React.Component { newChildren = [ cloneElement(extraContent, { key: 'extra', + onKeyDown: e => e.stopPropagation(), style: { ...this.getExtraContentStyle(topOrBottom, direction), ...extraContentStyle, @@ -67,19 +67,6 @@ export default class TabBarRootNode extends React.Component { } } -TabBarRootNode.propTypes = { - prefixCls: PropTypes.string, - className: PropTypes.string, - style: PropTypes.object, - tabBarPosition: PropTypes.oneOf(['left', 'right', 'top', 'bottom']), - children: PropTypes.node, - extraContent: PropTypes.node, - onKeyDown: PropTypes.func, - saveRef: PropTypes.func, - direction: PropTypes.oneOf(['ltr', 'rtl']), - getRef: PropTypes.func, -}; - TabBarRootNode.defaultProps = { prefixCls: '', className: '', diff --git a/src/TabBarSwipeableTabs.js b/src/TabBarSwipeableTabs.js index 095b05cb..cb93938d 100644 --- a/src/TabBarSwipeableTabs.js +++ b/src/TabBarSwipeableTabs.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import classnames from 'classnames'; export default class TabBarSwipeableTabs extends React.Component { @@ -59,17 +58,6 @@ export default class TabBarSwipeableTabs extends React.Component { } } -TabBarSwipeableTabs.propTypes = { - pageSize: PropTypes.number, - onTabClick: PropTypes.func, - saveRef: PropTypes.func, - destroyInactiveTabPane: PropTypes.bool, - prefixCls: PropTypes.string, - activeKey: PropTypes.string, - panels: PropTypes.node, - id: PropTypes.string, -}; - TabBarSwipeableTabs.defaultProps = { pageSize: 5, onTabClick: () => {}, diff --git a/src/TabBarTabsNode.js b/src/TabBarTabsNode.js index 8a5a80bc..7685d1b6 100644 --- a/src/TabBarTabsNode.js +++ b/src/TabBarTabsNode.js @@ -1,6 +1,5 @@ import React from 'react'; import warning from 'warning'; -import PropTypes from 'prop-types'; import { isVertical } from './utils'; export default class TabBarTabsNode extends React.Component { @@ -76,19 +75,6 @@ export default class TabBarTabsNode extends React.Component { } } -TabBarTabsNode.propTypes = { - activeKey: PropTypes.string, - panels: PropTypes.node, - prefixCls: PropTypes.string, - tabBarGutter: PropTypes.number, - onTabClick: PropTypes.func, - saveRef: PropTypes.func, - renderTabBarNode: PropTypes.func, - tabBarPosition: PropTypes.string, - direction: PropTypes.string, - id: PropTypes.string, -}; - TabBarTabsNode.defaultProps = { panels: [], prefixCls: [], diff --git a/src/TabContent.js b/src/TabContent.js index d5bb0e2a..60fc9397 100755 --- a/src/TabContent.js +++ b/src/TabContent.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import classnames from 'classnames'; import { getTransformByIndex, @@ -79,20 +78,6 @@ export default class TabContent extends React.Component { } } -TabContent.propTypes = { - animated: PropTypes.bool, - animatedWithMargin: PropTypes.bool, - prefixCls: PropTypes.string, - children: PropTypes.node, - activeKey: PropTypes.string, - style: PropTypes.any, - tabBarPosition: PropTypes.string, - className: PropTypes.string, - destroyInactiveTabPane: PropTypes.bool, - direction: PropTypes.string, - id: PropTypes.string, -}; - TabContent.defaultProps = { animated: true, }; diff --git a/src/TabPane.js b/src/TabPane.js index 5b2a86b8..01ad2d91 100755 --- a/src/TabPane.js +++ b/src/TabPane.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import classnames from 'classnames'; import { getDataAttr } from './utils'; @@ -48,19 +47,6 @@ export default class TabPane extends React.Component { } } -TabPane.propTypes = { - className: PropTypes.string, - active: PropTypes.bool, - style: PropTypes.any, - destroyInactiveTabPane: PropTypes.bool, - forceRender: PropTypes.bool, - placeholder: PropTypes.node, - rootPrefixCls: PropTypes.string, - children: PropTypes.node, - id: PropTypes.string, - tabKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), -}; - TabPane.defaultProps = { placeholder: null, }; diff --git a/src/Tabs.js b/src/Tabs.js index 24b027de..10240c39 100755 --- a/src/Tabs.js +++ b/src/Tabs.js @@ -1,5 +1,4 @@ import React from 'react'; -import PropTypes from 'prop-types'; import classnames from 'classnames'; import KeyCode from './KeyCode'; import TabPane from './TabPane'; @@ -65,6 +64,10 @@ class Tabs extends React.Component { }; onNavKeyDown = e => { + const { keyboard } = this.props; + if (!keyboard) { + return; + } const eventKeyCode = e.keyCode; if (eventKeyCode === KeyCode.RIGHT || eventKeyCode === KeyCode.DOWN) { e.preventDefault(); @@ -189,27 +192,11 @@ class Tabs extends React.Component { } } -Tabs.propTypes = { - destroyInactiveTabPane: PropTypes.bool, - renderTabBar: PropTypes.func.isRequired, - renderTabContent: PropTypes.func.isRequired, - navWrapper: PropTypes.func, - onChange: PropTypes.func, - children: PropTypes.node, - prefixCls: PropTypes.string, - className: PropTypes.string, - tabBarPosition: PropTypes.string, - style: PropTypes.object, - activeKey: PropTypes.string, - defaultActiveKey: PropTypes.string, - direction: PropTypes.string, - id: PropTypes.string, -}; - Tabs.defaultProps = { prefixCls: 'rc-tabs', destroyInactiveTabPane: false, onChange: noop, + keyboard: true, navWrapper: arg => arg, tabBarPosition: 'top', children: null, diff --git a/tests/__snapshots__/a11y.spec.js.snap b/tests/__snapshots__/a11y.spec.js.snap index 6af300f4..d1273d05 100644 --- a/tests/__snapshots__/a11y.spec.js.snap +++ b/tests/__snapshots__/a11y.spec.js.snap @@ -12,6 +12,10 @@ exports[` should render correctly 1`] = ` role="tablist" tabindex="-1" > +
@@ -172,6 +176,10 @@ exports[` should render correctly 1`] = ` role="tablist" tabindex="-1" > +
@@ -343,6 +351,10 @@ exports[` should render correctly 1`] = role="tablist" tabindex="-1" > +
diff --git a/tests/a11y.spec.js b/tests/a11y.spec.js index 694e62c0..e3428503 100644 --- a/tests/a11y.spec.js +++ b/tests/a11y.spec.js @@ -2,7 +2,6 @@ import React from 'react'; import TestUtils from 'react-dom/test-utils'; import { mount, render } from 'enzyme'; import { renderToJson } from 'enzyme-to-json'; -import PropTypes from 'prop-types'; import KeyCode from '../src/KeyCode'; import Tabs, { TabPane } from '../src'; import TabContent from '../src/TabContent'; @@ -30,7 +29,7 @@ const makeMultiTabPane = (count, withTabKey) => { const TabsComponent = ({ withCustomId, withTabKey }) => (
} + renderTabBar={() => } />} renderTabContent={() => } id={withCustomId && customId} > @@ -39,11 +38,6 @@ const TabsComponent = ({ withCustomId, withTabKey }) => (
); -TabsComponent.propTypes = { - withCustomId: PropTypes.bool, - withTabKey: PropTypes.bool, -}; - TabsComponent.defaults = { withCustomId: false, withTabKey: false, @@ -66,6 +60,15 @@ describe('', () => { expect(renderToJson(render(component))).toMatchSnapshot(); }); + it('extraContent not listen keyboard naviagtion', () => { + wrapper.find('#input').simulate('keyDown', { + keyCode: KeyCode.RIGHT, + which: KeyCode.RIGHT, + }); + expect(tabs.at(0).getDOMNode().className).toContain('rc-tabs-tab-active'); + expect(tabs.at(1).getDOMNode().className).not.toContain('rc-tabs-tab-active'); + }); + it('first tab should be selected by default', () => { const firstTab = tabs.first(); const selectedTab = tabs.find('[aria-selected="true"]');