@instructure/ui-tabs 9.0.2-snapshot-11 → 9.0.2-snapshot-13
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/CHANGELOG.md +6 -1
- package/es/Tabs/Panel/index.js +33 -22
- package/es/Tabs/Panel/props.js +3 -2
- package/es/Tabs/Panel/styles.js +5 -1
- package/es/Tabs/index.js +4 -5
- package/lib/Tabs/Panel/index.js +33 -22
- package/lib/Tabs/Panel/props.js +3 -2
- package/lib/Tabs/Panel/styles.js +5 -1
- package/lib/Tabs/index.js +3 -4
- package/package.json +20 -20
- package/src/Tabs/Panel/index.tsx +13 -7
- package/src/Tabs/Panel/props.ts +8 -2
- package/src/Tabs/Panel/styles.ts +6 -1
- package/src/Tabs/README.md +73 -0
- package/src/Tabs/index.tsx +16 -19
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/Tabs/Panel/index.d.ts +4 -0
- package/types/Tabs/Panel/index.d.ts.map +1 -1
- package/types/Tabs/Panel/props.d.ts +4 -0
- package/types/Tabs/Panel/props.d.ts.map +1 -1
- package/types/Tabs/Panel/styles.d.ts +3 -1
- package/types/Tabs/Panel/styles.d.ts.map +1 -1
- package/types/Tabs/index.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
-
## [9.0.2-snapshot-
|
|
6
|
+
## [9.0.2-snapshot-13](https://github.com/instructure/instructure-ui/compare/v9.0.1...v9.0.2-snapshot-13) (2024-06-13)
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
### Bug Fixes
|
|
@@ -11,6 +11,11 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline
|
|
|
11
11
|
* **ui-tabs:** fix id generation when null is present as children ([85765ae](https://github.com/instructure/instructure-ui/commit/85765ae3183ac121714cd814a322dcc012ed2f72))
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* **ui-tabs:** add option for persisting tabpanels ([6fe73a3](https://github.com/instructure/instructure-ui/commit/6fe73a3ec76c88fcc7baf2f587276de595316dbc))
|
|
17
|
+
|
|
18
|
+
|
|
14
19
|
|
|
15
20
|
|
|
16
21
|
|
package/es/Tabs/Panel/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
|
|
2
|
-
const _excluded = ["labelledBy", "variant", "id", "maxHeight", "minHeight", "padding", "textAlign", "children", "elementRef", "isDisabled", "isSelected", "styles", "active"];
|
|
2
|
+
const _excluded = ["labelledBy", "variant", "id", "maxHeight", "minHeight", "padding", "textAlign", "children", "elementRef", "isDisabled", "isSelected", "styles", "active", "unmountOnExit"];
|
|
3
3
|
var _dec, _class, _Panel;
|
|
4
4
|
/*
|
|
5
5
|
* The MIT License (MIT)
|
|
@@ -55,40 +55,50 @@ let Panel = (_dec = withStyle(generateStyle, generateComponentTheme), _dec(_clas
|
|
|
55
55
|
}
|
|
56
56
|
componentDidMount() {
|
|
57
57
|
var _this$props$makeStyle, _this$props;
|
|
58
|
-
(_this$props$makeStyle = (_this$props = this.props).makeStyles) === null || _this$props$makeStyle === void 0 ? void 0 : _this$props$makeStyle.call(_this$props
|
|
58
|
+
(_this$props$makeStyle = (_this$props = this.props).makeStyles) === null || _this$props$makeStyle === void 0 ? void 0 : _this$props$makeStyle.call(_this$props, {
|
|
59
|
+
isHidden: this.isHidden
|
|
60
|
+
});
|
|
59
61
|
}
|
|
60
62
|
componentDidUpdate() {
|
|
61
63
|
var _this$props$makeStyle2, _this$props2;
|
|
62
|
-
(_this$props$makeStyle2 = (_this$props2 = this.props).makeStyles) === null || _this$props$makeStyle2 === void 0 ? void 0 : _this$props$makeStyle2.call(_this$props2
|
|
64
|
+
(_this$props$makeStyle2 = (_this$props2 = this.props).makeStyles) === null || _this$props$makeStyle2 === void 0 ? void 0 : _this$props$makeStyle2.call(_this$props2, {
|
|
65
|
+
isHidden: this.isHidden
|
|
66
|
+
});
|
|
63
67
|
}
|
|
64
|
-
|
|
68
|
+
get isHidden() {
|
|
65
69
|
const _this$props3 = this.props,
|
|
66
|
-
labelledBy = _this$props3.labelledBy,
|
|
67
|
-
variant = _this$props3.variant,
|
|
68
|
-
id = _this$props3.id,
|
|
69
|
-
maxHeight = _this$props3.maxHeight,
|
|
70
|
-
minHeight = _this$props3.minHeight,
|
|
71
|
-
padding = _this$props3.padding,
|
|
72
|
-
textAlign = _this$props3.textAlign,
|
|
73
|
-
children = _this$props3.children,
|
|
74
|
-
elementRef = _this$props3.elementRef,
|
|
75
70
|
isDisabled = _this$props3.isDisabled,
|
|
76
|
-
isSelected = _this$props3.isSelected
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const
|
|
71
|
+
isSelected = _this$props3.isSelected;
|
|
72
|
+
return !isSelected || !!isDisabled;
|
|
73
|
+
}
|
|
74
|
+
render() {
|
|
75
|
+
const _this$props4 = this.props,
|
|
76
|
+
labelledBy = _this$props4.labelledBy,
|
|
77
|
+
variant = _this$props4.variant,
|
|
78
|
+
id = _this$props4.id,
|
|
79
|
+
maxHeight = _this$props4.maxHeight,
|
|
80
|
+
minHeight = _this$props4.minHeight,
|
|
81
|
+
padding = _this$props4.padding,
|
|
82
|
+
textAlign = _this$props4.textAlign,
|
|
83
|
+
children = _this$props4.children,
|
|
84
|
+
elementRef = _this$props4.elementRef,
|
|
85
|
+
isDisabled = _this$props4.isDisabled,
|
|
86
|
+
isSelected = _this$props4.isSelected,
|
|
87
|
+
styles = _this$props4.styles,
|
|
88
|
+
active = _this$props4.active,
|
|
89
|
+
unmountOnExit = _this$props4.unmountOnExit,
|
|
90
|
+
props = _objectWithoutProperties(_this$props4, _excluded);
|
|
81
91
|
return jsx("div", Object.assign({}, passthroughProps(props), {
|
|
82
92
|
css: styles === null || styles === void 0 ? void 0 : styles.panel,
|
|
83
93
|
role: "tabpanel",
|
|
84
94
|
id: id,
|
|
85
95
|
"aria-labelledby": labelledBy,
|
|
86
|
-
"aria-hidden": isHidden ? 'true' : void 0,
|
|
96
|
+
"aria-hidden": this.isHidden ? 'true' : void 0,
|
|
87
97
|
ref: this.handleRef
|
|
88
98
|
}), jsx(Transition, {
|
|
89
99
|
type: "fade",
|
|
90
|
-
in: !isHidden,
|
|
91
|
-
unmountOnExit:
|
|
100
|
+
in: !this.isHidden,
|
|
101
|
+
unmountOnExit: unmountOnExit,
|
|
92
102
|
transitionExit: false
|
|
93
103
|
}, jsx(View, {
|
|
94
104
|
css: styles === null || styles === void 0 ? void 0 : styles.content,
|
|
@@ -105,7 +115,8 @@ let Panel = (_dec = withStyle(generateStyle, generateComponentTheme), _dec(_clas
|
|
|
105
115
|
variant: 'default',
|
|
106
116
|
isSelected: false,
|
|
107
117
|
padding: 'small',
|
|
108
|
-
active: false
|
|
118
|
+
active: false,
|
|
119
|
+
unmountOnExit: true
|
|
109
120
|
}, _Panel)) || _class);
|
|
110
121
|
export default Panel;
|
|
111
122
|
export { Panel };
|
package/es/Tabs/Panel/props.js
CHANGED
|
@@ -37,7 +37,8 @@ const propTypes = {
|
|
|
37
37
|
padding: ThemeablePropTypes.spacing,
|
|
38
38
|
textAlign: PropTypes.oneOf(['start', 'center', 'end']),
|
|
39
39
|
elementRef: PropTypes.func,
|
|
40
|
-
active: PropTypes.bool
|
|
40
|
+
active: PropTypes.bool,
|
|
41
|
+
unmountOnExit: PropTypes.bool
|
|
41
42
|
};
|
|
42
|
-
const allowedProps = ['renderTitle', 'children', 'variant', 'isSelected', 'isDisabled', 'maxHeight', 'minHeight', 'id', 'labelledBy', 'padding', 'textAlign', 'elementRef', 'active'];
|
|
43
|
+
const allowedProps = ['renderTitle', 'children', 'variant', 'isSelected', 'isDisabled', 'maxHeight', 'minHeight', 'id', 'labelledBy', 'padding', 'textAlign', 'elementRef', 'active', 'unmountOnExit'];
|
|
43
44
|
export { propTypes, allowedProps };
|
package/es/Tabs/Panel/styles.js
CHANGED
|
@@ -32,9 +32,10 @@
|
|
|
32
32
|
* @param {Object} state the state of the component, the style is applied to
|
|
33
33
|
* @return {Object} The final style object, which will be used in the component
|
|
34
34
|
*/
|
|
35
|
-
const generateStyle = (componentTheme, props) => {
|
|
35
|
+
const generateStyle = (componentTheme, props, state) => {
|
|
36
36
|
const maxHeight = props.maxHeight,
|
|
37
37
|
isSelected = props.isSelected;
|
|
38
|
+
const isHidden = state.isHidden;
|
|
38
39
|
return {
|
|
39
40
|
panel: {
|
|
40
41
|
label: 'panel',
|
|
@@ -48,6 +49,9 @@ const generateStyle = (componentTheme, props) => {
|
|
|
48
49
|
...(isSelected && {
|
|
49
50
|
flexGrow: 1,
|
|
50
51
|
height: '100%'
|
|
52
|
+
}),
|
|
53
|
+
...(isHidden && {
|
|
54
|
+
display: 'none'
|
|
51
55
|
})
|
|
52
56
|
},
|
|
53
57
|
content: {
|
package/es/Tabs/index.js
CHANGED
|
@@ -26,7 +26,7 @@ var _dec, _dec2, _class, _Tabs;
|
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
28
|
/** @jsx jsx */
|
|
29
|
-
import React, { Component
|
|
29
|
+
import React, { Component } from 'react';
|
|
30
30
|
import keycode from 'keycode';
|
|
31
31
|
import { View } from '@instructure/ui-view';
|
|
32
32
|
import { matchComponentTypes, safeCloneElement, passthroughProps } from '@instructure/ui-react-utils';
|
|
@@ -256,18 +256,17 @@ let Tabs = (_dec = withStyle(generateStyle, generateComponentTheme), _dec2 = tes
|
|
|
256
256
|
}
|
|
257
257
|
createTab(index, generatedId, selected, panel) {
|
|
258
258
|
const id = panel.props.id || generatedId;
|
|
259
|
-
return
|
|
259
|
+
return jsx(Tab, {
|
|
260
260
|
variant: this.props.variant,
|
|
261
261
|
key: `tab-${index}`,
|
|
262
262
|
id: `tab-${id}`,
|
|
263
263
|
controls: panel.props.id || `panel-${id}`,
|
|
264
|
-
index,
|
|
264
|
+
index: index,
|
|
265
265
|
isSelected: selected,
|
|
266
266
|
isDisabled: panel.props.isDisabled,
|
|
267
|
-
children: panel.props.renderTitle,
|
|
268
267
|
onClick: this.handleTabClick,
|
|
269
268
|
onKeyDown: this.handleTabKeyDown
|
|
270
|
-
});
|
|
269
|
+
}, panel.props.renderTitle);
|
|
271
270
|
}
|
|
272
271
|
clonePanel(index, generatedId, selected, panel, activePanel) {
|
|
273
272
|
const id = panel.props.id || generatedId;
|
package/lib/Tabs/Panel/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var _emotion = require("@instructure/emotion");
|
|
|
14
14
|
var _styles = _interopRequireDefault(require("./styles"));
|
|
15
15
|
var _theme = _interopRequireDefault(require("./theme"));
|
|
16
16
|
var _props = require("./props");
|
|
17
|
-
const _excluded = ["labelledBy", "variant", "id", "maxHeight", "minHeight", "padding", "textAlign", "children", "elementRef", "isDisabled", "isSelected", "styles", "active"];
|
|
17
|
+
const _excluded = ["labelledBy", "variant", "id", "maxHeight", "minHeight", "padding", "textAlign", "children", "elementRef", "isDisabled", "isSelected", "styles", "active", "unmountOnExit"];
|
|
18
18
|
var _dec, _class, _Panel;
|
|
19
19
|
/*
|
|
20
20
|
* The MIT License (MIT)
|
|
@@ -60,40 +60,50 @@ let Panel = exports.Panel = (_dec = (0, _emotion.withStyle)(_styles.default, _th
|
|
|
60
60
|
}
|
|
61
61
|
componentDidMount() {
|
|
62
62
|
var _this$props$makeStyle, _this$props;
|
|
63
|
-
(_this$props$makeStyle = (_this$props = this.props).makeStyles) === null || _this$props$makeStyle === void 0 ? void 0 : _this$props$makeStyle.call(_this$props
|
|
63
|
+
(_this$props$makeStyle = (_this$props = this.props).makeStyles) === null || _this$props$makeStyle === void 0 ? void 0 : _this$props$makeStyle.call(_this$props, {
|
|
64
|
+
isHidden: this.isHidden
|
|
65
|
+
});
|
|
64
66
|
}
|
|
65
67
|
componentDidUpdate() {
|
|
66
68
|
var _this$props$makeStyle2, _this$props2;
|
|
67
|
-
(_this$props$makeStyle2 = (_this$props2 = this.props).makeStyles) === null || _this$props$makeStyle2 === void 0 ? void 0 : _this$props$makeStyle2.call(_this$props2
|
|
69
|
+
(_this$props$makeStyle2 = (_this$props2 = this.props).makeStyles) === null || _this$props$makeStyle2 === void 0 ? void 0 : _this$props$makeStyle2.call(_this$props2, {
|
|
70
|
+
isHidden: this.isHidden
|
|
71
|
+
});
|
|
68
72
|
}
|
|
69
|
-
|
|
73
|
+
get isHidden() {
|
|
70
74
|
const _this$props3 = this.props,
|
|
71
|
-
labelledBy = _this$props3.labelledBy,
|
|
72
|
-
variant = _this$props3.variant,
|
|
73
|
-
id = _this$props3.id,
|
|
74
|
-
maxHeight = _this$props3.maxHeight,
|
|
75
|
-
minHeight = _this$props3.minHeight,
|
|
76
|
-
padding = _this$props3.padding,
|
|
77
|
-
textAlign = _this$props3.textAlign,
|
|
78
|
-
children = _this$props3.children,
|
|
79
|
-
elementRef = _this$props3.elementRef,
|
|
80
75
|
isDisabled = _this$props3.isDisabled,
|
|
81
|
-
isSelected = _this$props3.isSelected
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const
|
|
76
|
+
isSelected = _this$props3.isSelected;
|
|
77
|
+
return !isSelected || !!isDisabled;
|
|
78
|
+
}
|
|
79
|
+
render() {
|
|
80
|
+
const _this$props4 = this.props,
|
|
81
|
+
labelledBy = _this$props4.labelledBy,
|
|
82
|
+
variant = _this$props4.variant,
|
|
83
|
+
id = _this$props4.id,
|
|
84
|
+
maxHeight = _this$props4.maxHeight,
|
|
85
|
+
minHeight = _this$props4.minHeight,
|
|
86
|
+
padding = _this$props4.padding,
|
|
87
|
+
textAlign = _this$props4.textAlign,
|
|
88
|
+
children = _this$props4.children,
|
|
89
|
+
elementRef = _this$props4.elementRef,
|
|
90
|
+
isDisabled = _this$props4.isDisabled,
|
|
91
|
+
isSelected = _this$props4.isSelected,
|
|
92
|
+
styles = _this$props4.styles,
|
|
93
|
+
active = _this$props4.active,
|
|
94
|
+
unmountOnExit = _this$props4.unmountOnExit,
|
|
95
|
+
props = (0, _objectWithoutProperties2.default)(_this$props4, _excluded);
|
|
86
96
|
return (0, _emotion.jsx)("div", Object.assign({}, (0, _passthroughProps.passthroughProps)(props), {
|
|
87
97
|
css: styles === null || styles === void 0 ? void 0 : styles.panel,
|
|
88
98
|
role: "tabpanel",
|
|
89
99
|
id: id,
|
|
90
100
|
"aria-labelledby": labelledBy,
|
|
91
|
-
"aria-hidden": isHidden ? 'true' : void 0,
|
|
101
|
+
"aria-hidden": this.isHidden ? 'true' : void 0,
|
|
92
102
|
ref: this.handleRef
|
|
93
103
|
}), (0, _emotion.jsx)(_Transition.Transition, {
|
|
94
104
|
type: "fade",
|
|
95
|
-
in: !isHidden,
|
|
96
|
-
unmountOnExit:
|
|
105
|
+
in: !this.isHidden,
|
|
106
|
+
unmountOnExit: unmountOnExit,
|
|
97
107
|
transitionExit: false
|
|
98
108
|
}, (0, _emotion.jsx)(_View.View, {
|
|
99
109
|
css: styles === null || styles === void 0 ? void 0 : styles.content,
|
|
@@ -110,6 +120,7 @@ let Panel = exports.Panel = (_dec = (0, _emotion.withStyle)(_styles.default, _th
|
|
|
110
120
|
variant: 'default',
|
|
111
121
|
isSelected: false,
|
|
112
122
|
padding: 'small',
|
|
113
|
-
active: false
|
|
123
|
+
active: false,
|
|
124
|
+
unmountOnExit: true
|
|
114
125
|
}, _Panel)) || _class);
|
|
115
126
|
var _default = exports.default = Panel;
|
package/lib/Tabs/Panel/props.js
CHANGED
|
@@ -44,6 +44,7 @@ const propTypes = exports.propTypes = {
|
|
|
44
44
|
padding: _emotion.ThemeablePropTypes.spacing,
|
|
45
45
|
textAlign: _propTypes.default.oneOf(['start', 'center', 'end']),
|
|
46
46
|
elementRef: _propTypes.default.func,
|
|
47
|
-
active: _propTypes.default.bool
|
|
47
|
+
active: _propTypes.default.bool,
|
|
48
|
+
unmountOnExit: _propTypes.default.bool
|
|
48
49
|
};
|
|
49
|
-
const allowedProps = exports.allowedProps = ['renderTitle', 'children', 'variant', 'isSelected', 'isDisabled', 'maxHeight', 'minHeight', 'id', 'labelledBy', 'padding', 'textAlign', 'elementRef', 'active'];
|
|
50
|
+
const allowedProps = exports.allowedProps = ['renderTitle', 'children', 'variant', 'isSelected', 'isDisabled', 'maxHeight', 'minHeight', 'id', 'labelledBy', 'padding', 'textAlign', 'elementRef', 'active', 'unmountOnExit'];
|
package/lib/Tabs/Panel/styles.js
CHANGED
|
@@ -38,9 +38,10 @@ exports.default = void 0;
|
|
|
38
38
|
* @param {Object} state the state of the component, the style is applied to
|
|
39
39
|
* @return {Object} The final style object, which will be used in the component
|
|
40
40
|
*/
|
|
41
|
-
const generateStyle = (componentTheme, props) => {
|
|
41
|
+
const generateStyle = (componentTheme, props, state) => {
|
|
42
42
|
const maxHeight = props.maxHeight,
|
|
43
43
|
isSelected = props.isSelected;
|
|
44
|
+
const isHidden = state.isHidden;
|
|
44
45
|
return {
|
|
45
46
|
panel: {
|
|
46
47
|
label: 'panel',
|
|
@@ -54,6 +55,9 @@ const generateStyle = (componentTheme, props) => {
|
|
|
54
55
|
...(isSelected && {
|
|
55
56
|
flexGrow: 1,
|
|
56
57
|
height: '100%'
|
|
58
|
+
}),
|
|
59
|
+
...(isHidden && {
|
|
60
|
+
display: 'none'
|
|
57
61
|
})
|
|
58
62
|
},
|
|
59
63
|
content: {
|
package/lib/Tabs/index.js
CHANGED
|
@@ -271,18 +271,17 @@ let Tabs = exports.Tabs = (_dec = (0, _emotion.withStyle)(_styles.default, _them
|
|
|
271
271
|
}
|
|
272
272
|
createTab(index, generatedId, selected, panel) {
|
|
273
273
|
const id = panel.props.id || generatedId;
|
|
274
|
-
return
|
|
274
|
+
return (0, _emotion.jsx)(_Tab.Tab, {
|
|
275
275
|
variant: this.props.variant,
|
|
276
276
|
key: `tab-${index}`,
|
|
277
277
|
id: `tab-${id}`,
|
|
278
278
|
controls: panel.props.id || `panel-${id}`,
|
|
279
|
-
index,
|
|
279
|
+
index: index,
|
|
280
280
|
isSelected: selected,
|
|
281
281
|
isDisabled: panel.props.isDisabled,
|
|
282
|
-
children: panel.props.renderTitle,
|
|
283
282
|
onClick: this.handleTabClick,
|
|
284
283
|
onKeyDown: this.handleTabKeyDown
|
|
285
|
-
});
|
|
284
|
+
}, panel.props.renderTitle);
|
|
286
285
|
}
|
|
287
286
|
clonePanel(index, generatedId, selected, panel, activePanel) {
|
|
288
287
|
const id = panel.props.id || generatedId;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@instructure/ui-tabs",
|
|
3
|
-
"version": "9.0.2-snapshot-
|
|
3
|
+
"version": "9.0.2-snapshot-13",
|
|
4
4
|
"description": "A UI component library made by Instructure Inc.",
|
|
5
5
|
"author": "Instructure, Inc. Engineering and Product Design",
|
|
6
6
|
"module": "./es/index.js",
|
|
@@ -23,30 +23,30 @@
|
|
|
23
23
|
},
|
|
24
24
|
"license": "MIT",
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@instructure/ui-babel-preset": "9.0.2-snapshot-
|
|
27
|
-
"@instructure/ui-color-utils": "9.0.2-snapshot-
|
|
28
|
-
"@instructure/ui-test-locator": "9.0.2-snapshot-
|
|
29
|
-
"@instructure/ui-test-utils": "9.0.2-snapshot-
|
|
30
|
-
"@instructure/ui-themes": "9.0.2-snapshot-
|
|
26
|
+
"@instructure/ui-babel-preset": "9.0.2-snapshot-13",
|
|
27
|
+
"@instructure/ui-color-utils": "9.0.2-snapshot-13",
|
|
28
|
+
"@instructure/ui-test-locator": "9.0.2-snapshot-13",
|
|
29
|
+
"@instructure/ui-test-utils": "9.0.2-snapshot-13",
|
|
30
|
+
"@instructure/ui-themes": "9.0.2-snapshot-13",
|
|
31
31
|
"@testing-library/jest-dom": "^6.4.5",
|
|
32
32
|
"@testing-library/react": "^15.0.7"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@babel/runtime": "^7.24.5",
|
|
36
|
-
"@instructure/console": "9.0.2-snapshot-
|
|
37
|
-
"@instructure/debounce": "9.0.2-snapshot-
|
|
38
|
-
"@instructure/emotion": "9.0.2-snapshot-
|
|
39
|
-
"@instructure/shared-types": "9.0.2-snapshot-
|
|
40
|
-
"@instructure/ui-dom-utils": "9.0.2-snapshot-
|
|
41
|
-
"@instructure/ui-focusable": "9.0.2-snapshot-
|
|
42
|
-
"@instructure/ui-i18n": "9.0.2-snapshot-
|
|
43
|
-
"@instructure/ui-motion": "9.0.2-snapshot-
|
|
44
|
-
"@instructure/ui-prop-types": "9.0.2-snapshot-
|
|
45
|
-
"@instructure/ui-react-utils": "9.0.2-snapshot-
|
|
46
|
-
"@instructure/ui-testable": "9.0.2-snapshot-
|
|
47
|
-
"@instructure/ui-utils": "9.0.2-snapshot-
|
|
48
|
-
"@instructure/ui-view": "9.0.2-snapshot-
|
|
49
|
-
"@instructure/uid": "9.0.2-snapshot-
|
|
36
|
+
"@instructure/console": "9.0.2-snapshot-13",
|
|
37
|
+
"@instructure/debounce": "9.0.2-snapshot-13",
|
|
38
|
+
"@instructure/emotion": "9.0.2-snapshot-13",
|
|
39
|
+
"@instructure/shared-types": "9.0.2-snapshot-13",
|
|
40
|
+
"@instructure/ui-dom-utils": "9.0.2-snapshot-13",
|
|
41
|
+
"@instructure/ui-focusable": "9.0.2-snapshot-13",
|
|
42
|
+
"@instructure/ui-i18n": "9.0.2-snapshot-13",
|
|
43
|
+
"@instructure/ui-motion": "9.0.2-snapshot-13",
|
|
44
|
+
"@instructure/ui-prop-types": "9.0.2-snapshot-13",
|
|
45
|
+
"@instructure/ui-react-utils": "9.0.2-snapshot-13",
|
|
46
|
+
"@instructure/ui-testable": "9.0.2-snapshot-13",
|
|
47
|
+
"@instructure/ui-utils": "9.0.2-snapshot-13",
|
|
48
|
+
"@instructure/ui-view": "9.0.2-snapshot-13",
|
|
49
|
+
"@instructure/uid": "9.0.2-snapshot-13",
|
|
50
50
|
"keycode": "^2.2.1",
|
|
51
51
|
"prop-types": "^15.8.1"
|
|
52
52
|
},
|
package/src/Tabs/Panel/index.tsx
CHANGED
|
@@ -55,19 +55,25 @@ class Panel extends Component<TabsPanelProps> {
|
|
|
55
55
|
variant: 'default',
|
|
56
56
|
isSelected: false,
|
|
57
57
|
padding: 'small',
|
|
58
|
-
active: false
|
|
58
|
+
active: false,
|
|
59
|
+
unmountOnExit: true
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
componentDidMount() {
|
|
62
|
-
this.props.makeStyles?.()
|
|
63
|
+
this.props.makeStyles?.({ isHidden: this.isHidden })
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
componentDidUpdate() {
|
|
66
|
-
this.props.makeStyles?.()
|
|
67
|
+
this.props.makeStyles?.({ isHidden: this.isHidden })
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
ref: HTMLDivElement | null = null
|
|
70
71
|
|
|
72
|
+
get isHidden() {
|
|
73
|
+
const { isDisabled, isSelected } = this.props
|
|
74
|
+
return !isSelected || !!isDisabled
|
|
75
|
+
}
|
|
76
|
+
|
|
71
77
|
handleRef = (el: HTMLDivElement | null) => {
|
|
72
78
|
const { elementRef } = this.props
|
|
73
79
|
|
|
@@ -93,9 +99,9 @@ class Panel extends Component<TabsPanelProps> {
|
|
|
93
99
|
isSelected,
|
|
94
100
|
styles,
|
|
95
101
|
active,
|
|
102
|
+
unmountOnExit,
|
|
96
103
|
...props
|
|
97
104
|
} = this.props
|
|
98
|
-
const isHidden = !isSelected || !!isDisabled
|
|
99
105
|
|
|
100
106
|
return (
|
|
101
107
|
<div
|
|
@@ -104,13 +110,13 @@ class Panel extends Component<TabsPanelProps> {
|
|
|
104
110
|
role="tabpanel"
|
|
105
111
|
id={id}
|
|
106
112
|
aria-labelledby={labelledBy}
|
|
107
|
-
aria-hidden={isHidden ? 'true' : undefined}
|
|
113
|
+
aria-hidden={this.isHidden ? 'true' : undefined}
|
|
108
114
|
ref={this.handleRef}
|
|
109
115
|
>
|
|
110
116
|
<Transition
|
|
111
117
|
type="fade"
|
|
112
|
-
in={!isHidden}
|
|
113
|
-
unmountOnExit
|
|
118
|
+
in={!this.isHidden}
|
|
119
|
+
unmountOnExit={unmountOnExit}
|
|
114
120
|
transitionExit={false}
|
|
115
121
|
>
|
|
116
122
|
<View
|
package/src/Tabs/Panel/props.ts
CHANGED
|
@@ -63,6 +63,10 @@ type TabsPanelOwnProps = {
|
|
|
63
63
|
* for all the `<Tabs.Panel />`s.
|
|
64
64
|
*/
|
|
65
65
|
active?: boolean
|
|
66
|
+
/**
|
|
67
|
+
* When set to false, the tabPanel only will be hidden, but not dismounted when not active
|
|
68
|
+
*/
|
|
69
|
+
unmountOnExit?: boolean
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
type PropKeys = keyof TabsPanelOwnProps
|
|
@@ -88,7 +92,8 @@ const propTypes: PropValidators<PropKeys> = {
|
|
|
88
92
|
padding: ThemeablePropTypes.spacing,
|
|
89
93
|
textAlign: PropTypes.oneOf(['start', 'center', 'end']),
|
|
90
94
|
elementRef: PropTypes.func,
|
|
91
|
-
active: PropTypes.bool
|
|
95
|
+
active: PropTypes.bool,
|
|
96
|
+
unmountOnExit: PropTypes.bool
|
|
92
97
|
}
|
|
93
98
|
|
|
94
99
|
const allowedProps: AllowedPropKeys = [
|
|
@@ -104,7 +109,8 @@ const allowedProps: AllowedPropKeys = [
|
|
|
104
109
|
'padding',
|
|
105
110
|
'textAlign',
|
|
106
111
|
'elementRef',
|
|
107
|
-
'active'
|
|
112
|
+
'active',
|
|
113
|
+
'unmountOnExit'
|
|
108
114
|
]
|
|
109
115
|
|
|
110
116
|
export type { TabsPanelProps, TabsPanelStyle }
|
package/src/Tabs/Panel/styles.ts
CHANGED
|
@@ -37,9 +37,11 @@ import type { TabsPanelProps, TabsPanelStyle } from './props'
|
|
|
37
37
|
*/
|
|
38
38
|
const generateStyle = (
|
|
39
39
|
componentTheme: TabsPanelTheme,
|
|
40
|
-
props: TabsPanelProps
|
|
40
|
+
props: TabsPanelProps,
|
|
41
|
+
state: { isHidden: boolean }
|
|
41
42
|
): TabsPanelStyle => {
|
|
42
43
|
const { maxHeight, isSelected } = props
|
|
44
|
+
const { isHidden } = state
|
|
43
45
|
|
|
44
46
|
return {
|
|
45
47
|
panel: {
|
|
@@ -54,6 +56,9 @@ const generateStyle = (
|
|
|
54
56
|
...(isSelected && {
|
|
55
57
|
flexGrow: 1,
|
|
56
58
|
height: '100%'
|
|
59
|
+
}),
|
|
60
|
+
...(isHidden && {
|
|
61
|
+
display: 'none'
|
|
57
62
|
})
|
|
58
63
|
},
|
|
59
64
|
content: {
|
package/src/Tabs/README.md
CHANGED
|
@@ -322,6 +322,79 @@ class Example extends React.Component {
|
|
|
322
322
|
render(<Example />)
|
|
323
323
|
```
|
|
324
324
|
|
|
325
|
+
### Persisting the selected tab
|
|
326
|
+
|
|
327
|
+
If you need to persist the rendered content of the tabpanels between tabbing, you can set the `unmountOnExit` prop to `false` on the `<Tabs.Panel>` component. It works case by case, so you can set it to `false` only on the tabpanels you want to persist.
|
|
328
|
+
|
|
329
|
+
```js
|
|
330
|
+
---
|
|
331
|
+
type: example
|
|
332
|
+
---
|
|
333
|
+
class Counter extends React.Component{
|
|
334
|
+
state = {
|
|
335
|
+
counter: 0
|
|
336
|
+
}
|
|
337
|
+
handleIncrement = () => {
|
|
338
|
+
this.setState({
|
|
339
|
+
counter: this.state.counter + 1
|
|
340
|
+
})
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
render () {
|
|
344
|
+
return (
|
|
345
|
+
<div>
|
|
346
|
+
<Button onClick={this.handleIncrement}>Increment</Button>
|
|
347
|
+
<hr/>
|
|
348
|
+
<Text>{this.state.counter}</Text>
|
|
349
|
+
</div>
|
|
350
|
+
)
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
class Example extends React.Component {
|
|
354
|
+
state = {
|
|
355
|
+
selectedIndex: 0
|
|
356
|
+
}
|
|
357
|
+
handleTabChange = (event, { index, id }) => {
|
|
358
|
+
this.setState({
|
|
359
|
+
selectedIndex: index
|
|
360
|
+
})
|
|
361
|
+
}
|
|
362
|
+
render () {
|
|
363
|
+
const { selectedIndex } = this.state
|
|
364
|
+
return (
|
|
365
|
+
<Tabs
|
|
366
|
+
margin="large auto"
|
|
367
|
+
padding="medium"
|
|
368
|
+
onRequestTabChange={this.handleTabChange}
|
|
369
|
+
>
|
|
370
|
+
<Tabs.Panel
|
|
371
|
+
id="tabA"
|
|
372
|
+
renderTitle="I will persist"
|
|
373
|
+
textAlign="center"
|
|
374
|
+
padding="large"
|
|
375
|
+
isSelected={selectedIndex === 0}
|
|
376
|
+
unmountOnExit={false}
|
|
377
|
+
>
|
|
378
|
+
<Counter/>
|
|
379
|
+
</Tabs.Panel>
|
|
380
|
+
<Tabs.Panel id="tabB" renderTitle="I will unmount" isSelected={selectedIndex === 1} textAlign="center"
|
|
381
|
+
padding="large">
|
|
382
|
+
<Counter/>
|
|
383
|
+
</Tabs.Panel>
|
|
384
|
+
<Tabs.Panel id="tabC" renderTitle="Tab C" isSelected={selectedIndex === 2}>
|
|
385
|
+
Tab C
|
|
386
|
+
</Tabs.Panel>
|
|
387
|
+
<Tabs.Panel id="tabD" renderTitle="Tab D" isSelected={selectedIndex === 3}>
|
|
388
|
+
Tab D
|
|
389
|
+
</Tabs.Panel>
|
|
390
|
+
</Tabs>
|
|
391
|
+
)
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
render(<Example />)
|
|
396
|
+
```
|
|
397
|
+
|
|
325
398
|
### Guidelines
|
|
326
399
|
|
|
327
400
|
```js
|
package/src/Tabs/index.tsx
CHANGED
|
@@ -23,13 +23,7 @@
|
|
|
23
23
|
*/
|
|
24
24
|
|
|
25
25
|
/** @jsx jsx */
|
|
26
|
-
import React, {
|
|
27
|
-
Component,
|
|
28
|
-
ComponentClass,
|
|
29
|
-
ComponentElement,
|
|
30
|
-
createElement,
|
|
31
|
-
ReactElement
|
|
32
|
-
} from 'react'
|
|
26
|
+
import React, { Component, ComponentElement, ReactElement } from 'react'
|
|
33
27
|
|
|
34
28
|
import keycode from 'keycode'
|
|
35
29
|
|
|
@@ -341,18 +335,21 @@ class Tabs extends Component<TabsProps, TabsState> {
|
|
|
341
335
|
): TabChild {
|
|
342
336
|
const id = panel.props.id || generatedId
|
|
343
337
|
|
|
344
|
-
return
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
338
|
+
return (
|
|
339
|
+
<Tab
|
|
340
|
+
variant={this.props.variant}
|
|
341
|
+
key={`tab-${index}`}
|
|
342
|
+
id={`tab-${id}`}
|
|
343
|
+
controls={panel.props.id || `panel-${id}`}
|
|
344
|
+
index={index}
|
|
345
|
+
isSelected={selected}
|
|
346
|
+
isDisabled={panel.props.isDisabled}
|
|
347
|
+
onClick={this.handleTabClick}
|
|
348
|
+
onKeyDown={this.handleTabKeyDown}
|
|
349
|
+
>
|
|
350
|
+
{panel.props.renderTitle}
|
|
351
|
+
</Tab>
|
|
352
|
+
)
|
|
356
353
|
}
|
|
357
354
|
|
|
358
355
|
clonePanel(
|