@clayui/tabs 3.86.1 → 3.88.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Content.d.ts +1 -1
- package/lib/Content.js +5 -3
- package/lib/Item.d.ts +4 -0
- package/lib/List.d.ts +5 -4
- package/lib/List.js +32 -5
- package/lib/TabPane.d.ts +1 -1
- package/lib/TabPane.js +3 -2
- package/lib/index.d.ts +5 -5
- package/lib/index.js +4 -2
- package/package.json +3 -3
- package/src/Content.tsx +18 -11
- package/src/Item.tsx +4 -0
- package/src/List.tsx +48 -14
- package/src/TabPane.tsx +50 -44
- package/src/__tests__/index.tsx +21 -0
- package/src/index.tsx +2 -1
package/lib/Content.d.ts
CHANGED
|
@@ -26,5 +26,5 @@ export interface IProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
26
26
|
*/
|
|
27
27
|
tabsId?: string;
|
|
28
28
|
}
|
|
29
|
-
declare const Content:
|
|
29
|
+
declare const Content: React.ForwardRefExoticComponent<IProps & React.RefAttributes<HTMLDivElement>>;
|
|
30
30
|
export default Content;
|
package/lib/Content.js
CHANGED
|
@@ -25,7 +25,7 @@ function _objectWithoutProperties(source, excluded) { if (source == null) return
|
|
|
25
25
|
|
|
26
26
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
27
27
|
|
|
28
|
-
var Content = function Content(_ref) {
|
|
28
|
+
var Content = /*#__PURE__*/_react.default.forwardRef(function Content(_ref, ref) {
|
|
29
29
|
var active = _ref.active,
|
|
30
30
|
_ref$activeIndex = _ref.activeIndex,
|
|
31
31
|
activeIndex = _ref$activeIndex === void 0 ? 0 : _ref$activeIndex,
|
|
@@ -38,7 +38,9 @@ var Content = function Content(_ref) {
|
|
|
38
38
|
|
|
39
39
|
return /*#__PURE__*/_react.default.createElement("div", _extends({
|
|
40
40
|
className: (0, _classnames.default)('tab-content', className)
|
|
41
|
-
}, otherProps
|
|
41
|
+
}, otherProps, {
|
|
42
|
+
ref: ref
|
|
43
|
+
}), _react.default.Children.map(children, function (child, index) {
|
|
42
44
|
if (! /*#__PURE__*/_react.default.isValidElement(child)) {
|
|
43
45
|
return child;
|
|
44
46
|
}
|
|
@@ -51,7 +53,7 @@ var Content = function Content(_ref) {
|
|
|
51
53
|
key: index
|
|
52
54
|
}));
|
|
53
55
|
}));
|
|
54
|
-
};
|
|
56
|
+
});
|
|
55
57
|
|
|
56
58
|
var _default = Content;
|
|
57
59
|
exports.default = _default;
|
package/lib/Item.d.ts
CHANGED
|
@@ -6,6 +6,10 @@ import React from 'react';
|
|
|
6
6
|
export interface IProps extends Omit<React.HTMLAttributes<HTMLLIElement>, 'onClick'> {
|
|
7
7
|
/**
|
|
8
8
|
* Flag to indicate if the component is active or not.
|
|
9
|
+
*
|
|
10
|
+
* OBS: The `active` API in the new pattern has uncontrolled behavior,
|
|
11
|
+
* working just like `defaultActive` as in the prop declared in the
|
|
12
|
+
* root component.
|
|
9
13
|
*/
|
|
10
14
|
active?: boolean;
|
|
11
15
|
/**
|
package/lib/List.d.ts
CHANGED
|
@@ -37,12 +37,13 @@ export interface IProps extends React.HTMLAttributes<HTMLUListElement> {
|
|
|
37
37
|
* @ignore
|
|
38
38
|
*/
|
|
39
39
|
onActiveChange?: InternalDispatch<number>;
|
|
40
|
+
/**
|
|
41
|
+
* @ignore
|
|
42
|
+
*/
|
|
43
|
+
shouldUseActive?: boolean;
|
|
40
44
|
/**
|
|
41
45
|
* @ignore
|
|
42
46
|
*/
|
|
43
47
|
tabsId?: string;
|
|
44
48
|
}
|
|
45
|
-
export declare
|
|
46
|
-
export declare namespace List {
|
|
47
|
-
var displayName: string;
|
|
48
|
-
}
|
|
49
|
+
export declare const List: React.ForwardRefExoticComponent<IProps & React.RefAttributes<HTMLUListElement>>;
|
package/lib/List.js
CHANGED
|
@@ -5,7 +5,7 @@ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" =
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", {
|
|
6
6
|
value: true
|
|
7
7
|
});
|
|
8
|
-
exports.List =
|
|
8
|
+
exports.List = void 0;
|
|
9
9
|
|
|
10
10
|
var _shared = require("@clayui/shared");
|
|
11
11
|
|
|
@@ -13,7 +13,7 @@ var _classnames = _interopRequireDefault(require("classnames"));
|
|
|
13
13
|
|
|
14
14
|
var _react = _interopRequireWildcard(require("react"));
|
|
15
15
|
|
|
16
|
-
var _excluded = ["activation", "active", "children", "className", "displayType", "justified", "modern", "onActiveChange", "tabsId"];
|
|
16
|
+
var _excluded = ["activation", "active", "children", "className", "displayType", "justified", "modern", "onActiveChange", "shouldUseActive", "tabsId"];
|
|
17
17
|
|
|
18
18
|
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
19
19
|
|
|
@@ -33,7 +33,7 @@ function _objectWithoutProperties(source, excluded) { if (source == null) return
|
|
|
33
33
|
|
|
34
34
|
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
|
|
35
35
|
|
|
36
|
-
function List(_ref) {
|
|
36
|
+
var List = /*#__PURE__*/_react.default.forwardRef(function List(_ref, ref) {
|
|
37
37
|
var activation = _ref.activation,
|
|
38
38
|
active = _ref.active,
|
|
39
39
|
children = _ref.children,
|
|
@@ -42,6 +42,8 @@ function List(_ref) {
|
|
|
42
42
|
justified = _ref.justified,
|
|
43
43
|
modern = _ref.modern,
|
|
44
44
|
onActiveChange = _ref.onActiveChange,
|
|
45
|
+
_ref$shouldUseActive = _ref.shouldUseActive,
|
|
46
|
+
shouldUseActive = _ref$shouldUseActive === void 0 ? false : _ref$shouldUseActive,
|
|
45
47
|
tabsId = _ref.tabsId,
|
|
46
48
|
otherProps = _objectWithoutProperties(_ref, _excluded);
|
|
47
49
|
|
|
@@ -54,6 +56,30 @@ function List(_ref) {
|
|
|
54
56
|
}),
|
|
55
57
|
navigationProps = _useNavigation.navigationProps;
|
|
56
58
|
|
|
59
|
+
(0, _react.useImperativeHandle)(ref, function () {
|
|
60
|
+
return tabsRef.current;
|
|
61
|
+
}, [tabsRef]);
|
|
62
|
+
(0, _react.useEffect)(function () {
|
|
63
|
+
// Internal API to maintain compatibility with the old Tabs pattern and to
|
|
64
|
+
// only update the initial state when the component is in
|
|
65
|
+
// uncontrolled mode.
|
|
66
|
+
if (!shouldUseActive) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var childrenArray = _react.default.Children.toArray(children); // The `active` API in the new pattern has uncontrolled behavior, working
|
|
71
|
+
// just like defaultActive as in the prop declared in the root component.
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
for (var index = 0; index < childrenArray.length; index++) {
|
|
75
|
+
var child = childrenArray[index];
|
|
76
|
+
|
|
77
|
+
if ( /*#__PURE__*/_react.default.isValidElement(child) && child.props.active) {
|
|
78
|
+
onActiveChange(index);
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}, []);
|
|
57
83
|
return /*#__PURE__*/_react.default.createElement("ul", _extends({}, otherProps, navigationProps, {
|
|
58
84
|
className: (0, _classnames.default)('nav', {
|
|
59
85
|
'nav-justified': justified
|
|
@@ -74,7 +100,7 @@ function List(_ref) {
|
|
|
74
100
|
}
|
|
75
101
|
|
|
76
102
|
return /*#__PURE__*/_react.default.cloneElement(child, {
|
|
77
|
-
active: child.props.active !== undefined ? child.props.active : active === index,
|
|
103
|
+
active: !shouldUseActive && child.props.active !== undefined ? child.props.active : active === index,
|
|
78
104
|
innerProps: _objectSpread({
|
|
79
105
|
'aria-controls': tabsId && "".concat(tabsId, "-tabpanel-").concat(index),
|
|
80
106
|
id: tabsId && "".concat(tabsId, "-tab-").concat(index)
|
|
@@ -90,6 +116,7 @@ function List(_ref) {
|
|
|
90
116
|
}
|
|
91
117
|
});
|
|
92
118
|
}));
|
|
93
|
-
}
|
|
119
|
+
});
|
|
94
120
|
|
|
121
|
+
exports.List = List;
|
|
95
122
|
List.displayName = 'ClayTabsList';
|
package/lib/TabPane.d.ts
CHANGED
|
@@ -13,5 +13,5 @@ export interface ITabPaneProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
13
13
|
*/
|
|
14
14
|
fade?: boolean;
|
|
15
15
|
}
|
|
16
|
-
declare const TabPane:
|
|
16
|
+
declare const TabPane: React.ForwardRefExoticComponent<ITabPaneProps & React.RefAttributes<HTMLDivElement>>;
|
|
17
17
|
export default TabPane;
|
package/lib/TabPane.js
CHANGED
|
@@ -38,7 +38,7 @@ var delay = function delay(fn) {
|
|
|
38
38
|
}, val);
|
|
39
39
|
};
|
|
40
40
|
|
|
41
|
-
var TabPane = function TabPane(_ref) {
|
|
41
|
+
var TabPane = /*#__PURE__*/_react.default.forwardRef(function TabPane(_ref, ref) {
|
|
42
42
|
var _ref$active = _ref.active,
|
|
43
43
|
active = _ref$active === void 0 ? false : _ref$active,
|
|
44
44
|
children = _ref.children,
|
|
@@ -87,10 +87,11 @@ var TabPane = function TabPane(_ref) {
|
|
|
87
87
|
fade: fade,
|
|
88
88
|
show: internalShow
|
|
89
89
|
}, className),
|
|
90
|
+
ref: ref,
|
|
90
91
|
role: "tabpanel",
|
|
91
92
|
tabIndex: tabIndex
|
|
92
93
|
}), children);
|
|
93
|
-
};
|
|
94
|
+
});
|
|
94
95
|
|
|
95
96
|
var _default = TabPane;
|
|
96
97
|
exports.default = _default;
|
package/lib/index.d.ts
CHANGED
|
@@ -57,11 +57,11 @@ declare function ClayTabs(props: IProps): JSX.Element & {
|
|
|
57
57
|
TabPanel: typeof TabPane;
|
|
58
58
|
};
|
|
59
59
|
declare namespace ClayTabs {
|
|
60
|
-
var Content:
|
|
61
|
-
var Panels:
|
|
60
|
+
var Content: React.ForwardRefExoticComponent<import("./Content").IProps & React.RefAttributes<HTMLDivElement>>;
|
|
61
|
+
var Panels: React.ForwardRefExoticComponent<import("./Content").IProps & React.RefAttributes<HTMLDivElement>>;
|
|
62
62
|
var Item: React.ForwardRefExoticComponent<import("./Item").IProps & React.RefAttributes<any>>;
|
|
63
|
-
var List:
|
|
64
|
-
var TabPane:
|
|
65
|
-
var TabPanel:
|
|
63
|
+
var List: React.ForwardRefExoticComponent<import("./List").IProps & React.RefAttributes<HTMLUListElement>>;
|
|
64
|
+
var TabPane: React.ForwardRefExoticComponent<import("./TabPane").ITabPaneProps & React.RefAttributes<HTMLDivElement>>;
|
|
65
|
+
var TabPanel: React.ForwardRefExoticComponent<import("./TabPane").ITabPaneProps & React.RefAttributes<HTMLDivElement>>;
|
|
66
66
|
}
|
|
67
67
|
export default ClayTabs;
|
package/lib/index.js
CHANGED
|
@@ -66,9 +66,10 @@ function ClayTabs(_ref) {
|
|
|
66
66
|
onChange: onActiveChange,
|
|
67
67
|
value: externalActive
|
|
68
68
|
}),
|
|
69
|
-
_useInternalState2 = _slicedToArray(_useInternalState,
|
|
69
|
+
_useInternalState2 = _slicedToArray(_useInternalState, 3),
|
|
70
70
|
active = _useInternalState2[0],
|
|
71
|
-
setActive = _useInternalState2[1]
|
|
71
|
+
setActive = _useInternalState2[1],
|
|
72
|
+
isUncontrolled = _useInternalState2[2];
|
|
72
73
|
|
|
73
74
|
var _React$Children$toArr = _react.default.Children.toArray(children),
|
|
74
75
|
_React$Children$toArr2 = _slicedToArray(_React$Children$toArr, 2),
|
|
@@ -85,6 +86,7 @@ function ClayTabs(_ref) {
|
|
|
85
86
|
justified: justified,
|
|
86
87
|
modern: modern,
|
|
87
88
|
onActiveChange: setActive,
|
|
89
|
+
shouldUseActive: isUncontrolled,
|
|
88
90
|
tabsId: tabsId
|
|
89
91
|
}), /*#__PURE__*/_react.default.isValidElement(right) && /*#__PURE__*/_react.default.cloneElement(right, {
|
|
90
92
|
active: active,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clayui/tabs",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.88.0",
|
|
4
4
|
"description": "ClayTabs component",
|
|
5
5
|
"license": "BSD-3-Clause",
|
|
6
6
|
"repository": "https://github.com/liferay/clay",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"react"
|
|
27
27
|
],
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@clayui/shared": "^3.
|
|
29
|
+
"@clayui/shared": "^3.88.0",
|
|
30
30
|
"classnames": "^2.2.6"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
@@ -37,5 +37,5 @@
|
|
|
37
37
|
"browserslist": [
|
|
38
38
|
"extends browserslist-config-clay"
|
|
39
39
|
],
|
|
40
|
-
"gitHead": "
|
|
40
|
+
"gitHead": "cf84d2b2f04d7576be26ce3917e40ec9da52bef8"
|
|
41
41
|
}
|
package/src/Content.tsx
CHANGED
|
@@ -34,17 +34,24 @@ export interface IProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
34
34
|
tabsId?: string;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
const Content = (
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
const Content = React.forwardRef<HTMLDivElement, IProps>(function Content(
|
|
38
|
+
{
|
|
39
|
+
active,
|
|
40
|
+
activeIndex = 0,
|
|
41
|
+
children,
|
|
42
|
+
className,
|
|
43
|
+
fade = false,
|
|
44
|
+
tabsId,
|
|
45
|
+
...otherProps
|
|
46
|
+
},
|
|
47
|
+
ref
|
|
48
|
+
) {
|
|
46
49
|
return (
|
|
47
|
-
<div
|
|
50
|
+
<div
|
|
51
|
+
className={classNames('tab-content', className)}
|
|
52
|
+
{...otherProps}
|
|
53
|
+
ref={ref}
|
|
54
|
+
>
|
|
48
55
|
{React.Children.map(children, (child, index) => {
|
|
49
56
|
if (!React.isValidElement(child)) {
|
|
50
57
|
return child;
|
|
@@ -66,6 +73,6 @@ const Content = ({
|
|
|
66
73
|
})}
|
|
67
74
|
</div>
|
|
68
75
|
);
|
|
69
|
-
};
|
|
76
|
+
});
|
|
70
77
|
|
|
71
78
|
export default Content;
|
package/src/Item.tsx
CHANGED
|
@@ -11,6 +11,10 @@ export interface IProps
|
|
|
11
11
|
extends Omit<React.HTMLAttributes<HTMLLIElement>, 'onClick'> {
|
|
12
12
|
/**
|
|
13
13
|
* Flag to indicate if the component is active or not.
|
|
14
|
+
*
|
|
15
|
+
* OBS: The `active` API in the new pattern has uncontrolled behavior,
|
|
16
|
+
* working just like `defaultActive` as in the prop declared in the
|
|
17
|
+
* root component.
|
|
14
18
|
*/
|
|
15
19
|
active?: boolean;
|
|
16
20
|
|
package/src/List.tsx
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import {InternalDispatch, useNavigation} from '@clayui/shared';
|
|
7
7
|
import classNames from 'classnames';
|
|
8
|
-
import React, {useRef} from 'react';
|
|
8
|
+
import React, {useEffect, useImperativeHandle, useRef} from 'react';
|
|
9
9
|
|
|
10
10
|
export interface IProps extends React.HTMLAttributes<HTMLUListElement> {
|
|
11
11
|
/**
|
|
@@ -48,24 +48,33 @@ export interface IProps extends React.HTMLAttributes<HTMLUListElement> {
|
|
|
48
48
|
*/
|
|
49
49
|
onActiveChange?: InternalDispatch<number>;
|
|
50
50
|
|
|
51
|
+
/**
|
|
52
|
+
* @ignore
|
|
53
|
+
*/
|
|
54
|
+
shouldUseActive?: boolean;
|
|
55
|
+
|
|
51
56
|
/**
|
|
52
57
|
* @ignore
|
|
53
58
|
*/
|
|
54
59
|
tabsId?: string;
|
|
55
60
|
}
|
|
56
61
|
|
|
57
|
-
export function List(
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
62
|
+
export const List = React.forwardRef<HTMLUListElement, IProps>(function List(
|
|
63
|
+
{
|
|
64
|
+
activation,
|
|
65
|
+
active,
|
|
66
|
+
children,
|
|
67
|
+
className,
|
|
68
|
+
displayType,
|
|
69
|
+
justified,
|
|
70
|
+
modern,
|
|
71
|
+
onActiveChange,
|
|
72
|
+
shouldUseActive = false,
|
|
73
|
+
tabsId,
|
|
74
|
+
...otherProps
|
|
75
|
+
},
|
|
76
|
+
ref
|
|
77
|
+
) {
|
|
69
78
|
const tabsRef = useRef<HTMLUListElement>(null);
|
|
70
79
|
|
|
71
80
|
const {navigationProps} = useNavigation({
|
|
@@ -74,6 +83,30 @@ export function List({
|
|
|
74
83
|
orientation: 'horizontal',
|
|
75
84
|
});
|
|
76
85
|
|
|
86
|
+
useImperativeHandle(ref, () => tabsRef.current!, [tabsRef]);
|
|
87
|
+
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
// Internal API to maintain compatibility with the old Tabs pattern and to
|
|
90
|
+
// only update the initial state when the component is in
|
|
91
|
+
// uncontrolled mode.
|
|
92
|
+
if (!shouldUseActive) {
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const childrenArray = React.Children.toArray(children);
|
|
97
|
+
|
|
98
|
+
// The `active` API in the new pattern has uncontrolled behavior, working
|
|
99
|
+
// just like defaultActive as in the prop declared in the root component.
|
|
100
|
+
for (let index = 0; index < childrenArray.length; index++) {
|
|
101
|
+
const child = childrenArray[index];
|
|
102
|
+
|
|
103
|
+
if (React.isValidElement(child) && child.props.active) {
|
|
104
|
+
onActiveChange!(index);
|
|
105
|
+
break;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}, []);
|
|
109
|
+
|
|
77
110
|
return (
|
|
78
111
|
<ul
|
|
79
112
|
{...otherProps}
|
|
@@ -103,6 +136,7 @@ export function List({
|
|
|
103
136
|
|
|
104
137
|
return React.cloneElement(child as React.ReactElement, {
|
|
105
138
|
active:
|
|
139
|
+
!shouldUseActive &&
|
|
106
140
|
(child as React.ReactElement).props.active !== undefined
|
|
107
141
|
? (child as React.ReactElement).props.active
|
|
108
142
|
: active === index,
|
|
@@ -127,6 +161,6 @@ export function List({
|
|
|
127
161
|
})}
|
|
128
162
|
</ul>
|
|
129
163
|
);
|
|
130
|
-
}
|
|
164
|
+
});
|
|
131
165
|
|
|
132
166
|
List.displayName = 'ClayTabsList';
|
package/src/TabPane.tsx
CHANGED
|
@@ -23,57 +23,63 @@ const delay = (fn: Function, val: number = 150) =>
|
|
|
23
23
|
fn();
|
|
24
24
|
}, val);
|
|
25
25
|
|
|
26
|
-
const TabPane = (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
26
|
+
const TabPane = React.forwardRef<HTMLDivElement, ITabPaneProps>(
|
|
27
|
+
function TabPane(
|
|
28
|
+
{
|
|
29
|
+
active = false,
|
|
30
|
+
children,
|
|
31
|
+
className,
|
|
32
|
+
fade,
|
|
33
|
+
tabIndex = 0,
|
|
34
|
+
...otherProps
|
|
35
|
+
},
|
|
36
|
+
ref
|
|
37
|
+
) {
|
|
38
|
+
const [internalActive, setInternalActive] = React.useState(active);
|
|
39
|
+
const [internalShow, setInternalShow] = React.useState(active);
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
React.useEffect(() => {
|
|
42
|
+
let delayFn = () => {
|
|
43
|
+
setInternalActive(true);
|
|
40
44
|
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
delay(() => setInternalShow(true), 50);
|
|
46
|
+
};
|
|
43
47
|
|
|
44
|
-
|
|
45
|
-
|
|
48
|
+
if (!active) {
|
|
49
|
+
setInternalShow(false);
|
|
46
50
|
|
|
47
|
-
|
|
48
|
-
|
|
51
|
+
delayFn = () => setInternalActive(false);
|
|
52
|
+
}
|
|
49
53
|
|
|
50
|
-
|
|
54
|
+
const timer = delay(delayFn);
|
|
51
55
|
|
|
52
|
-
|
|
53
|
-
|
|
56
|
+
return () => {
|
|
57
|
+
clearTimeout(timer);
|
|
54
58
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
setInternalShow(false);
|
|
60
|
+
};
|
|
61
|
+
}, [active]);
|
|
58
62
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
63
|
+
return (
|
|
64
|
+
<div
|
|
65
|
+
{...otherProps}
|
|
66
|
+
className={classNames(
|
|
67
|
+
'tab-pane',
|
|
68
|
+
{
|
|
69
|
+
active: internalActive,
|
|
70
|
+
fade,
|
|
71
|
+
show: internalShow,
|
|
72
|
+
},
|
|
73
|
+
className
|
|
74
|
+
)}
|
|
75
|
+
ref={ref}
|
|
76
|
+
role="tabpanel"
|
|
77
|
+
tabIndex={tabIndex}
|
|
78
|
+
>
|
|
79
|
+
{children}
|
|
80
|
+
</div>
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
);
|
|
78
84
|
|
|
79
85
|
export default TabPane;
|
package/src/__tests__/index.tsx
CHANGED
|
@@ -192,4 +192,25 @@ describe('ClayTabs', () => {
|
|
|
192
192
|
expect(getAllByRole('tab').length).toBe(3);
|
|
193
193
|
expect(getAllByRole('tabpanel').length).toBe(3);
|
|
194
194
|
});
|
|
195
|
+
|
|
196
|
+
it('renders the tab item active when `active` is set on uncontrolled state', () => {
|
|
197
|
+
const {getByRole} = render(
|
|
198
|
+
<ClayTabs>
|
|
199
|
+
<ClayTabs.List>
|
|
200
|
+
<ClayTabs.Item>Tab 1</ClayTabs.Item>
|
|
201
|
+
<ClayTabs.Item active>Tab 2</ClayTabs.Item>
|
|
202
|
+
<ClayTabs.Item>Tab 3</ClayTabs.Item>
|
|
203
|
+
</ClayTabs.List>
|
|
204
|
+
<ClayTabs.Panels>
|
|
205
|
+
<ClayTabs.TabPanel>Tab Content 1</ClayTabs.TabPanel>
|
|
206
|
+
<ClayTabs.TabPanel>Tab Content 2</ClayTabs.TabPanel>
|
|
207
|
+
<ClayTabs.TabPanel>Tab Content 3</ClayTabs.TabPanel>
|
|
208
|
+
</ClayTabs.Panels>
|
|
209
|
+
</ClayTabs>
|
|
210
|
+
);
|
|
211
|
+
|
|
212
|
+
const activeTab = getByRole('tab', {selected: true});
|
|
213
|
+
|
|
214
|
+
expect(activeTab.innerHTML).toBe('Tab 2');
|
|
215
|
+
});
|
|
195
216
|
});
|
package/src/index.tsx
CHANGED
|
@@ -82,7 +82,7 @@ function ClayTabs({
|
|
|
82
82
|
onActiveChange,
|
|
83
83
|
...otherProps
|
|
84
84
|
}: IProps) {
|
|
85
|
-
const [active, setActive] = useInternalState({
|
|
85
|
+
const [active, setActive, isUncontrolled] = useInternalState({
|
|
86
86
|
defaultName: 'defaultActive',
|
|
87
87
|
defaultValue: defaultActive,
|
|
88
88
|
handleName: 'onActiveChange',
|
|
@@ -106,6 +106,7 @@ function ClayTabs({
|
|
|
106
106
|
justified,
|
|
107
107
|
modern,
|
|
108
108
|
onActiveChange: setActive,
|
|
109
|
+
shouldUseActive: isUncontrolled,
|
|
109
110
|
tabsId,
|
|
110
111
|
})}
|
|
111
112
|
|