@instructure/ui-table 9.6.1-snapshot-2 → 9.7.2
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 +23 -1
- package/es/Table/Body/index.js +12 -7
- package/es/Table/Row/index.js +17 -7
- package/es/Table/__new-tests__/Table.test.js +10 -1
- package/es/Table/index.js +19 -15
- package/lib/Table/Body/index.js +11 -6
- package/lib/Table/Row/index.js +17 -5
- package/lib/Table/__new-tests__/Table.test.js +10 -1
- package/lib/Table/index.js +18 -14
- package/package.json +17 -17
- package/src/Table/Body/index.tsx +12 -9
- package/src/Table/Row/index.tsx +25 -7
- package/src/Table/__new-tests__/Table.test.tsx +36 -0
- package/src/Table/index.tsx +20 -26
- package/tsconfig.build.tsbuildinfo +1 -1
- package/types/Table/Body/index.d.ts.map +1 -1
- package/types/Table/Row/index.d.ts.map +1 -1
- package/types/Table/index.d.ts +1 -1
- package/types/Table/index.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
@@ -3,7 +3,29 @@
|
|
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.
|
6
|
+
## [9.7.2](https://github.com/instructure/instructure-ui/compare/v9.7.0...v9.7.2) (2024-10-10)
|
7
|
+
|
8
|
+
|
9
|
+
### Bug Fixes
|
10
|
+
|
11
|
+
* **ui-table:** non standrd Row children props ([700e462](https://github.com/instructure/instructure-ui/commit/700e462cc8de0cfb68f0ed8a442dcd23961e4b77))
|
12
|
+
|
13
|
+
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
## [9.7.1](https://github.com/instructure/instructure-ui/compare/v9.7.0...v9.7.1) (2024-10-10)
|
18
|
+
|
19
|
+
|
20
|
+
### Bug Fixes
|
21
|
+
|
22
|
+
* **ui-table:** non standrd Row children props ([700e462](https://github.com/instructure/instructure-ui/commit/700e462cc8de0cfb68f0ed8a442dcd23961e4b77))
|
23
|
+
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
# [9.7.0](https://github.com/instructure/instructure-ui/compare/v9.6.0...v9.7.0) (2024-09-23)
|
7
29
|
|
8
30
|
**Note:** Version bump only for package @instructure/ui-table
|
9
31
|
|
package/es/Table/Body/index.js
CHANGED
@@ -24,7 +24,7 @@ var _dec, _class, _Body;
|
|
24
24
|
*/
|
25
25
|
|
26
26
|
/** @jsx jsx */
|
27
|
-
import { Component, Children } from 'react';
|
27
|
+
import { Component, Children, isValidElement } from 'react';
|
28
28
|
import { safeCloneElement, omitProps } from '@instructure/ui-react-utils';
|
29
29
|
import { View } from '@instructure/ui-view';
|
30
30
|
import { withStyle, jsx } from '@instructure/emotion';
|
@@ -58,12 +58,17 @@ let Body = (_dec = withStyle(generateStyle, generateComponentTheme), _dec(_class
|
|
58
58
|
as: isStacked ? 'div' : 'tbody',
|
59
59
|
css: styles === null || styles === void 0 ? void 0 : styles.body,
|
60
60
|
role: isStacked ? 'rowgroup' : void 0
|
61
|
-
}), Children.map(children, child =>
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
61
|
+
}), Children.map(children, child => {
|
62
|
+
if ( /*#__PURE__*/isValidElement(child)) {
|
63
|
+
return safeCloneElement(child, {
|
64
|
+
key: child.props.name,
|
65
|
+
isStacked,
|
66
|
+
hover,
|
67
|
+
headers
|
68
|
+
});
|
69
|
+
}
|
70
|
+
return child;
|
71
|
+
}));
|
67
72
|
}
|
68
73
|
}, _Body.displayName = "Body", _Body.componentId = 'Table.Body', _Body.allowedProps = allowedProps, _Body.propTypes = propTypes, _Body.defaultProps = {
|
69
74
|
children: null
|
package/es/Table/Row/index.js
CHANGED
@@ -25,13 +25,14 @@ var _dec, _class, _Row;
|
|
25
25
|
|
26
26
|
/** @jsx jsx */
|
27
27
|
import { Component, Children } from 'react';
|
28
|
-
import { omitProps, safeCloneElement } from '@instructure/ui-react-utils';
|
28
|
+
import { omitProps, safeCloneElement, matchComponentTypes } from '@instructure/ui-react-utils';
|
29
29
|
import { View } from '@instructure/ui-view';
|
30
30
|
import { withStyle, jsx } from '@instructure/emotion';
|
31
31
|
import generateStyle from './styles';
|
32
32
|
import generateComponentTheme from './theme';
|
33
|
+
import { Cell } from '../Cell';
|
34
|
+
import { RowHeader } from '../RowHeader';
|
33
35
|
import { allowedProps, propTypes } from './props';
|
34
|
-
|
35
36
|
/**
|
36
37
|
---
|
37
38
|
parent: Table
|
@@ -58,11 +59,20 @@ let Row = (_dec = withStyle(generateStyle, generateComponentTheme), _dec(_class
|
|
58
59
|
css: styles === null || styles === void 0 ? void 0 : styles.row,
|
59
60
|
role: isStacked ? 'row' : void 0
|
60
61
|
}), Children.toArray(children).filter(Boolean).map((child, index) => {
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
62
|
+
if (matchComponentTypes(child, [RowHeader])) {
|
63
|
+
return safeCloneElement(child, {
|
64
|
+
key: index,
|
65
|
+
isStacked
|
66
|
+
});
|
67
|
+
}
|
68
|
+
if (matchComponentTypes(child, [Cell])) {
|
69
|
+
return safeCloneElement(child, {
|
70
|
+
key: index,
|
71
|
+
isStacked,
|
72
|
+
header: headers && headers[index]
|
73
|
+
});
|
74
|
+
}
|
75
|
+
return child;
|
66
76
|
}));
|
67
77
|
}
|
68
78
|
}, _Row.displayName = "Row", _Row.componentId = 'Table.Row', _Row.allowedProps = allowedProps, _Row.propTypes = propTypes, _Row.defaultProps = {
|
@@ -1,4 +1,4 @@
|
|
1
|
-
var _Table$Head, _Table$Body, _Table, _Table2, _Table3, _Table$Body2;
|
1
|
+
var _Table$Head, _Table$Body, _Table, _Table2, _Table3, _span, _Table$Row, _span2, _span3, _Table$Row2, _Table$Body2;
|
2
2
|
/*
|
3
3
|
* The MIT License (MIT)
|
4
4
|
*
|
@@ -127,6 +127,15 @@ describe('<Table />', async () => {
|
|
127
127
|
expect(stackedTable).toBeInTheDocument();
|
128
128
|
expect(stackedTable).not.toHaveTextContent('Foo');
|
129
129
|
});
|
130
|
+
it('does not crash for invalid children', async () => {
|
131
|
+
render( /*#__PURE__*/React.createElement(Table, {
|
132
|
+
caption: "Test table",
|
133
|
+
layout: "stacked"
|
134
|
+
}, /*#__PURE__*/React.createElement(Table.Head, null, _span || (_span = /*#__PURE__*/React.createElement("span", null, "test")), "test2", _Table$Row || (_Table$Row = /*#__PURE__*/React.createElement(Table.Row, null, "test3", /*#__PURE__*/React.createElement("span", null, "test"), /*#__PURE__*/React.createElement(Table.Cell, null, "Foo"))), "test4", _span2 || (_span2 = /*#__PURE__*/React.createElement("span", null, "test"))), "test5", /*#__PURE__*/React.createElement(Table.Body, null, "test", _span3 || (_span3 = /*#__PURE__*/React.createElement("span", null, "test")), _Table$Row2 || (_Table$Row2 = /*#__PURE__*/React.createElement(Table.Row, null, "test", /*#__PURE__*/React.createElement("span", null, "test"), /*#__PURE__*/React.createElement(Table.Cell, null, "Foo"), "test", /*#__PURE__*/React.createElement("span", null, "test"))))));
|
135
|
+
const table = screen.getByRole('table');
|
136
|
+
expect(table).toBeInTheDocument();
|
137
|
+
expect(table).toHaveTextContent('Foo');
|
138
|
+
});
|
130
139
|
describe('when table is sortable', async () => {
|
131
140
|
const renderSortableTable = (props, handlers = {}, layout = 'auto') => render( /*#__PURE__*/React.createElement(Table, {
|
132
141
|
caption: "Sortable table",
|
package/es/Table/index.js
CHANGED
@@ -25,7 +25,7 @@ var _dec, _class, _Table;
|
|
25
25
|
*/
|
26
26
|
|
27
27
|
/** @jsx jsx */
|
28
|
-
import { Component, Children } from 'react';
|
28
|
+
import { Component, Children, isValidElement } from 'react';
|
29
29
|
import { safeCloneElement, omitProps } from '@instructure/ui-react-utils';
|
30
30
|
import { View } from '@instructure/ui-view';
|
31
31
|
import { ScreenReaderContent } from '@instructure/ui-a11y-content';
|
@@ -66,15 +66,16 @@ let Table = (_dec = withStyle(generateStyle, generateComponentTheme), _dec(_clas
|
|
66
66
|
(_this$props$makeStyle2 = (_this$props2 = this.props).makeStyles) === null || _this$props$makeStyle2 === void 0 ? void 0 : _this$props$makeStyle2.call(_this$props2);
|
67
67
|
}
|
68
68
|
getHeaders() {
|
69
|
-
const
|
70
|
-
const _ref = Children.toArray(children),
|
71
|
-
_ref2 = _slicedToArray(_ref, 1),
|
72
|
-
head = _ref2[0];
|
73
|
-
const _Children$toArray = Children.toArray(head.props.children),
|
69
|
+
const _Children$toArray = Children.toArray(this.props.children),
|
74
70
|
_Children$toArray2 = _slicedToArray(_Children$toArray, 1),
|
75
|
-
|
76
|
-
if (!
|
77
|
-
|
71
|
+
headChild = _Children$toArray2[0];
|
72
|
+
if (!headChild || ! /*#__PURE__*/isValidElement(headChild)) return void 0;
|
73
|
+
const _Children$toArray3 = Children.toArray(headChild.props.children),
|
74
|
+
_Children$toArray4 = _slicedToArray(_Children$toArray3, 1),
|
75
|
+
firstRow = _Children$toArray4[0];
|
76
|
+
if (!firstRow || ! /*#__PURE__*/isValidElement(firstRow)) return void 0;
|
77
|
+
return Children.map(firstRow.props.children, colHeader => {
|
78
|
+
if (! /*#__PURE__*/isValidElement(colHeader)) return void 0;
|
78
79
|
return colHeader.props.children;
|
79
80
|
});
|
80
81
|
}
|
@@ -96,12 +97,15 @@ let Table = (_dec = withStyle(generateStyle, generateComponentTheme), _dec(_clas
|
|
96
97
|
role: isStacked ? 'table' : void 0,
|
97
98
|
"aria-label": isStacked ? caption : void 0
|
98
99
|
}), !isStacked && jsx("caption", null, jsx(ScreenReaderContent, null, caption)), Children.map(children, child => {
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
100
|
+
if ( /*#__PURE__*/isValidElement(child)) {
|
101
|
+
return safeCloneElement(child, {
|
102
|
+
key: child.props.name,
|
103
|
+
isStacked,
|
104
|
+
hover,
|
105
|
+
headers
|
106
|
+
});
|
107
|
+
}
|
108
|
+
return child;
|
105
109
|
}));
|
106
110
|
}
|
107
111
|
}, _Table.displayName = "Table", _Table.componentId = 'Table', _Table.allowedProps = allowedProps, _Table.propTypes = propTypes, _Table.defaultProps = {
|
package/lib/Table/Body/index.js
CHANGED
@@ -64,12 +64,17 @@ let Body = exports.Body = (_dec = (0, _emotion.withStyle)(_styles.default, _them
|
|
64
64
|
as: isStacked ? 'div' : 'tbody',
|
65
65
|
css: styles === null || styles === void 0 ? void 0 : styles.body,
|
66
66
|
role: isStacked ? 'rowgroup' : void 0
|
67
|
-
}), _react.Children.map(children, child =>
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
67
|
+
}), _react.Children.map(children, child => {
|
68
|
+
if ( /*#__PURE__*/(0, _react.isValidElement)(child)) {
|
69
|
+
return (0, _safeCloneElement.safeCloneElement)(child, {
|
70
|
+
key: child.props.name,
|
71
|
+
isStacked,
|
72
|
+
hover,
|
73
|
+
headers
|
74
|
+
});
|
75
|
+
}
|
76
|
+
return child;
|
77
|
+
}));
|
73
78
|
}
|
74
79
|
}, _Body.displayName = "Body", _Body.componentId = 'Table.Body', _Body.allowedProps = _props.allowedProps, _Body.propTypes = _props.propTypes, _Body.defaultProps = {
|
75
80
|
children: null
|
package/lib/Table/Row/index.js
CHANGED
@@ -8,10 +8,13 @@ exports.default = exports.Row = void 0;
|
|
8
8
|
var _react = require("react");
|
9
9
|
var _omitProps = require("@instructure/ui-react-utils/lib/omitProps.js");
|
10
10
|
var _safeCloneElement = require("@instructure/ui-react-utils/lib/safeCloneElement.js");
|
11
|
+
var _matchComponentTypes = require("@instructure/ui-react-utils/lib/matchComponentTypes.js");
|
11
12
|
var _View = require("@instructure/ui-view/lib/View");
|
12
13
|
var _emotion = require("@instructure/emotion");
|
13
14
|
var _styles = _interopRequireDefault(require("./styles"));
|
14
15
|
var _theme = _interopRequireDefault(require("./theme"));
|
16
|
+
var _Cell = require("../Cell");
|
17
|
+
var _RowHeader = require("../RowHeader");
|
15
18
|
var _props = require("./props");
|
16
19
|
var _dec, _class, _Row;
|
17
20
|
/*
|
@@ -64,11 +67,20 @@ let Row = exports.Row = (_dec = (0, _emotion.withStyle)(_styles.default, _theme.
|
|
64
67
|
css: styles === null || styles === void 0 ? void 0 : styles.row,
|
65
68
|
role: isStacked ? 'row' : void 0
|
66
69
|
}), _react.Children.toArray(children).filter(Boolean).map((child, index) => {
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
70
|
+
if ((0, _matchComponentTypes.matchComponentTypes)(child, [_RowHeader.RowHeader])) {
|
71
|
+
return (0, _safeCloneElement.safeCloneElement)(child, {
|
72
|
+
key: index,
|
73
|
+
isStacked
|
74
|
+
});
|
75
|
+
}
|
76
|
+
if ((0, _matchComponentTypes.matchComponentTypes)(child, [_Cell.Cell])) {
|
77
|
+
return (0, _safeCloneElement.safeCloneElement)(child, {
|
78
|
+
key: index,
|
79
|
+
isStacked,
|
80
|
+
header: headers && headers[index]
|
81
|
+
});
|
82
|
+
}
|
83
|
+
return child;
|
72
84
|
}));
|
73
85
|
}
|
74
86
|
}, _Row.displayName = "Row", _Row.componentId = 'Table.Row', _Row.allowedProps = _props.allowedProps, _Row.propTypes = _props.propTypes, _Row.defaultProps = {
|
@@ -8,7 +8,7 @@ var _userEvent = require("@testing-library/user-event");
|
|
8
8
|
require("@testing-library/jest-dom");
|
9
9
|
var _index = require("../index");
|
10
10
|
var _runAxeCheck = require("@instructure/ui-axe-check/lib/runAxeCheck.js");
|
11
|
-
var _Table$Head, _Table$Body, _Table, _Table2, _Table3, _Table$Body2;
|
11
|
+
var _Table$Head, _Table$Body, _Table, _Table2, _Table3, _span, _Table$Row, _span2, _span3, _Table$Row2, _Table$Body2;
|
12
12
|
/*
|
13
13
|
* The MIT License (MIT)
|
14
14
|
*
|
@@ -129,6 +129,15 @@ describe('<Table />', async () => {
|
|
129
129
|
expect(stackedTable).toBeInTheDocument();
|
130
130
|
expect(stackedTable).not.toHaveTextContent('Foo');
|
131
131
|
});
|
132
|
+
it('does not crash for invalid children', async () => {
|
133
|
+
(0, _react2.render)( /*#__PURE__*/_react.default.createElement(_index.Table, {
|
134
|
+
caption: "Test table",
|
135
|
+
layout: "stacked"
|
136
|
+
}, /*#__PURE__*/_react.default.createElement(_index.Table.Head, null, _span || (_span = /*#__PURE__*/_react.default.createElement("span", null, "test")), "test2", _Table$Row || (_Table$Row = /*#__PURE__*/_react.default.createElement(_index.Table.Row, null, "test3", /*#__PURE__*/_react.default.createElement("span", null, "test"), /*#__PURE__*/_react.default.createElement(_index.Table.Cell, null, "Foo"))), "test4", _span2 || (_span2 = /*#__PURE__*/_react.default.createElement("span", null, "test"))), "test5", /*#__PURE__*/_react.default.createElement(_index.Table.Body, null, "test", _span3 || (_span3 = /*#__PURE__*/_react.default.createElement("span", null, "test")), _Table$Row2 || (_Table$Row2 = /*#__PURE__*/_react.default.createElement(_index.Table.Row, null, "test", /*#__PURE__*/_react.default.createElement("span", null, "test"), /*#__PURE__*/_react.default.createElement(_index.Table.Cell, null, "Foo"), "test", /*#__PURE__*/_react.default.createElement("span", null, "test"))))));
|
137
|
+
const table = _react2.screen.getByRole('table');
|
138
|
+
expect(table).toBeInTheDocument();
|
139
|
+
expect(table).toHaveTextContent('Foo');
|
140
|
+
});
|
132
141
|
describe('when table is sortable', async () => {
|
133
142
|
const renderSortableTable = (props, handlers = {}, layout = 'auto') => (0, _react2.render)( /*#__PURE__*/_react.default.createElement(_index.Table, {
|
134
143
|
caption: "Sortable table",
|
package/lib/Table/index.js
CHANGED
@@ -72,15 +72,16 @@ let Table = exports.Table = (_dec = (0, _emotion.withStyle)(_styles.default, _th
|
|
72
72
|
(_this$props$makeStyle2 = (_this$props2 = this.props).makeStyles) === null || _this$props$makeStyle2 === void 0 ? void 0 : _this$props$makeStyle2.call(_this$props2);
|
73
73
|
}
|
74
74
|
getHeaders() {
|
75
|
-
const
|
76
|
-
const _ref = _react.Children.toArray(children),
|
77
|
-
_ref2 = (0, _slicedToArray2.default)(_ref, 1),
|
78
|
-
head = _ref2[0];
|
79
|
-
const _Children$toArray = _react.Children.toArray(head.props.children),
|
75
|
+
const _Children$toArray = _react.Children.toArray(this.props.children),
|
80
76
|
_Children$toArray2 = (0, _slicedToArray2.default)(_Children$toArray, 1),
|
81
|
-
|
82
|
-
if (!
|
83
|
-
|
77
|
+
headChild = _Children$toArray2[0];
|
78
|
+
if (!headChild || ! /*#__PURE__*/(0, _react.isValidElement)(headChild)) return void 0;
|
79
|
+
const _Children$toArray3 = _react.Children.toArray(headChild.props.children),
|
80
|
+
_Children$toArray4 = (0, _slicedToArray2.default)(_Children$toArray3, 1),
|
81
|
+
firstRow = _Children$toArray4[0];
|
82
|
+
if (!firstRow || ! /*#__PURE__*/(0, _react.isValidElement)(firstRow)) return void 0;
|
83
|
+
return _react.Children.map(firstRow.props.children, colHeader => {
|
84
|
+
if (! /*#__PURE__*/(0, _react.isValidElement)(colHeader)) return void 0;
|
84
85
|
return colHeader.props.children;
|
85
86
|
});
|
86
87
|
}
|
@@ -102,12 +103,15 @@ let Table = exports.Table = (_dec = (0, _emotion.withStyle)(_styles.default, _th
|
|
102
103
|
role: isStacked ? 'table' : void 0,
|
103
104
|
"aria-label": isStacked ? caption : void 0
|
104
105
|
}), !isStacked && (0, _emotion.jsx)("caption", null, (0, _emotion.jsx)(_ScreenReaderContent.ScreenReaderContent, null, caption)), _react.Children.map(children, child => {
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
106
|
+
if ( /*#__PURE__*/(0, _react.isValidElement)(child)) {
|
107
|
+
return (0, _safeCloneElement.safeCloneElement)(child, {
|
108
|
+
key: child.props.name,
|
109
|
+
isStacked,
|
110
|
+
hover,
|
111
|
+
headers
|
112
|
+
});
|
113
|
+
}
|
114
|
+
return child;
|
111
115
|
}));
|
112
116
|
}
|
113
117
|
}, _Table.displayName = "Table", _Table.componentId = 'Table', _Table.allowedProps = _props.allowedProps, _Table.propTypes = _props.propTypes, _Table.defaultProps = {
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@instructure/ui-table",
|
3
|
-
"version": "9.
|
3
|
+
"version": "9.7.2",
|
4
4
|
"description": "A styled HTML table component",
|
5
5
|
"author": "Instructure, Inc. Engineering and Product Design",
|
6
6
|
"module": "./es/index.js",
|
@@ -23,11 +23,11 @@
|
|
23
23
|
},
|
24
24
|
"license": "MIT",
|
25
25
|
"devDependencies": {
|
26
|
-
"@instructure/ui-axe-check": "9.
|
27
|
-
"@instructure/ui-babel-preset": "9.
|
28
|
-
"@instructure/ui-color-utils": "9.
|
29
|
-
"@instructure/ui-test-utils": "9.
|
30
|
-
"@instructure/ui-themes": "9.
|
26
|
+
"@instructure/ui-axe-check": "9.7.2",
|
27
|
+
"@instructure/ui-babel-preset": "9.7.2",
|
28
|
+
"@instructure/ui-color-utils": "9.7.2",
|
29
|
+
"@instructure/ui-test-utils": "9.7.2",
|
30
|
+
"@instructure/ui-themes": "9.7.2",
|
31
31
|
"@testing-library/jest-dom": "^6.4.6",
|
32
32
|
"@testing-library/react": "^15.0.7",
|
33
33
|
"@testing-library/user-event": "^14.5.2",
|
@@ -35,17 +35,17 @@
|
|
35
35
|
},
|
36
36
|
"dependencies": {
|
37
37
|
"@babel/runtime": "^7.24.5",
|
38
|
-
"@instructure/console": "9.
|
39
|
-
"@instructure/emotion": "9.
|
40
|
-
"@instructure/shared-types": "9.
|
41
|
-
"@instructure/ui-a11y-content": "9.
|
42
|
-
"@instructure/ui-icons": "9.
|
43
|
-
"@instructure/ui-prop-types": "9.
|
44
|
-
"@instructure/ui-react-utils": "9.
|
45
|
-
"@instructure/ui-simple-select": "9.
|
46
|
-
"@instructure/ui-testable": "9.
|
47
|
-
"@instructure/ui-utils": "9.
|
48
|
-
"@instructure/ui-view": "9.
|
38
|
+
"@instructure/console": "9.7.2",
|
39
|
+
"@instructure/emotion": "9.7.2",
|
40
|
+
"@instructure/shared-types": "9.7.2",
|
41
|
+
"@instructure/ui-a11y-content": "9.7.2",
|
42
|
+
"@instructure/ui-icons": "9.7.2",
|
43
|
+
"@instructure/ui-prop-types": "9.7.2",
|
44
|
+
"@instructure/ui-react-utils": "9.7.2",
|
45
|
+
"@instructure/ui-simple-select": "9.7.2",
|
46
|
+
"@instructure/ui-testable": "9.7.2",
|
47
|
+
"@instructure/ui-utils": "9.7.2",
|
48
|
+
"@instructure/ui-view": "9.7.2",
|
49
49
|
"prop-types": "^15.8.1"
|
50
50
|
},
|
51
51
|
"peerDependencies": {
|
package/src/Table/Body/index.tsx
CHANGED
@@ -23,7 +23,7 @@
|
|
23
23
|
*/
|
24
24
|
|
25
25
|
/** @jsx jsx */
|
26
|
-
import { Component, Children } from 'react'
|
26
|
+
import { Component, Children, isValidElement } from 'react'
|
27
27
|
|
28
28
|
import { safeCloneElement, omitProps } from '@instructure/ui-react-utils'
|
29
29
|
import { View } from '@instructure/ui-view'
|
@@ -70,14 +70,17 @@ class Body extends Component<TableBodyProps> {
|
|
70
70
|
css={styles?.body}
|
71
71
|
role={isStacked ? 'rowgroup' : undefined}
|
72
72
|
>
|
73
|
-
{Children.map(children as RowChild[], (child) =>
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
73
|
+
{Children.map(children as RowChild[], (child) => {
|
74
|
+
if (isValidElement(child)) {
|
75
|
+
return safeCloneElement(child, {
|
76
|
+
key: child.props.name,
|
77
|
+
isStacked,
|
78
|
+
hover,
|
79
|
+
headers
|
80
|
+
})
|
81
|
+
}
|
82
|
+
return child
|
83
|
+
})}
|
81
84
|
</View>
|
82
85
|
)
|
83
86
|
}
|
package/src/Table/Row/index.tsx
CHANGED
@@ -25,7 +25,11 @@
|
|
25
25
|
/** @jsx jsx */
|
26
26
|
import { Component, Children } from 'react'
|
27
27
|
|
28
|
-
import {
|
28
|
+
import {
|
29
|
+
omitProps,
|
30
|
+
safeCloneElement,
|
31
|
+
matchComponentTypes
|
32
|
+
} from '@instructure/ui-react-utils'
|
29
33
|
import { View } from '@instructure/ui-view'
|
30
34
|
|
31
35
|
import { withStyle, jsx } from '@instructure/emotion'
|
@@ -33,8 +37,12 @@ import { withStyle, jsx } from '@instructure/emotion'
|
|
33
37
|
import generateStyle from './styles'
|
34
38
|
import generateComponentTheme from './theme'
|
35
39
|
|
40
|
+
import { Cell } from '../Cell'
|
41
|
+
import { RowHeader } from '../RowHeader'
|
42
|
+
|
36
43
|
import type { TableRowProps } from './props'
|
37
44
|
import { allowedProps, propTypes } from './props'
|
45
|
+
import type { RowHeaderChild, CellChild } from '../props'
|
38
46
|
|
39
47
|
/**
|
40
48
|
---
|
@@ -73,12 +81,22 @@ class Row extends Component<TableRowProps> {
|
|
73
81
|
>
|
74
82
|
{Children.toArray(children)
|
75
83
|
.filter(Boolean)
|
76
|
-
.map((child
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
84
|
+
.map((child, index) => {
|
85
|
+
if (matchComponentTypes<RowHeaderChild>(child, [RowHeader])) {
|
86
|
+
return safeCloneElement(child, {
|
87
|
+
key: index,
|
88
|
+
isStacked
|
89
|
+
})
|
90
|
+
}
|
91
|
+
if (matchComponentTypes<CellChild>(child, [Cell])) {
|
92
|
+
return safeCloneElement(child, {
|
93
|
+
key: index,
|
94
|
+
isStacked,
|
95
|
+
header: headers && headers[index]
|
96
|
+
})
|
97
|
+
}
|
98
|
+
|
99
|
+
return child
|
82
100
|
})}
|
83
101
|
</View>
|
84
102
|
)
|
@@ -167,6 +167,42 @@ describe('<Table />', async () => {
|
|
167
167
|
expect(stackedTable).not.toHaveTextContent('Foo')
|
168
168
|
})
|
169
169
|
|
170
|
+
it('does not crash for invalid children', async () => {
|
171
|
+
render(
|
172
|
+
<Table caption="Test table" layout="stacked">
|
173
|
+
<Table.Head>
|
174
|
+
<span>test</span>
|
175
|
+
test2
|
176
|
+
{/* @ts-ignore error is normal here */}
|
177
|
+
<Table.Row>
|
178
|
+
test3
|
179
|
+
<span>test</span>
|
180
|
+
<Table.Cell>Foo</Table.Cell>
|
181
|
+
</Table.Row>
|
182
|
+
test4
|
183
|
+
<span>test</span>
|
184
|
+
</Table.Head>
|
185
|
+
test5
|
186
|
+
<Table.Body>
|
187
|
+
test
|
188
|
+
<span>test</span>
|
189
|
+
{/* @ts-ignore error is normal here */}
|
190
|
+
<Table.Row>
|
191
|
+
test
|
192
|
+
<span>test</span>
|
193
|
+
<Table.Cell>Foo</Table.Cell>
|
194
|
+
test
|
195
|
+
<span>test</span>
|
196
|
+
</Table.Row>
|
197
|
+
</Table.Body>
|
198
|
+
</Table>
|
199
|
+
)
|
200
|
+
const table = screen.getByRole('table')
|
201
|
+
|
202
|
+
expect(table).toBeInTheDocument()
|
203
|
+
expect(table).toHaveTextContent('Foo')
|
204
|
+
})
|
205
|
+
|
170
206
|
describe('when table is sortable', async () => {
|
171
207
|
const renderSortableTable = (
|
172
208
|
props: TableColHeaderProps | null,
|
package/src/Table/index.tsx
CHANGED
@@ -23,7 +23,7 @@
|
|
23
23
|
*/
|
24
24
|
|
25
25
|
/** @jsx jsx */
|
26
|
-
import { Component, Children } from 'react'
|
26
|
+
import { Component, Children, isValidElement } from 'react'
|
27
27
|
|
28
28
|
import { safeCloneElement, omitProps } from '@instructure/ui-react-utils'
|
29
29
|
import { View } from '@instructure/ui-view'
|
@@ -41,13 +41,7 @@ import { ColHeader } from './ColHeader'
|
|
41
41
|
import { RowHeader } from './RowHeader'
|
42
42
|
import { Cell } from './Cell'
|
43
43
|
|
44
|
-
import type {
|
45
|
-
TableProps,
|
46
|
-
HeadChild,
|
47
|
-
ColHeaderChild,
|
48
|
-
RowHeaderChild,
|
49
|
-
CellChild
|
50
|
-
} from './props'
|
44
|
+
import type { TableProps } from './props'
|
51
45
|
|
52
46
|
import { allowedProps, propTypes } from './props'
|
53
47
|
|
@@ -97,17 +91,14 @@ class Table extends Component<TableProps> {
|
|
97
91
|
}
|
98
92
|
|
99
93
|
getHeaders() {
|
100
|
-
const
|
101
|
-
|
102
|
-
const [
|
103
|
-
if (!
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
return colHeader.props.children
|
109
|
-
}
|
110
|
-
)
|
94
|
+
const [headChild] = Children.toArray(this.props.children)
|
95
|
+
if (!headChild || !isValidElement(headChild)) return undefined
|
96
|
+
const [firstRow] = Children.toArray(headChild.props.children)
|
97
|
+
if (!firstRow || !isValidElement(firstRow)) return undefined
|
98
|
+
return Children.map(firstRow.props.children, (colHeader) => {
|
99
|
+
if (!isValidElement<{ children?: any }>(colHeader)) return undefined
|
100
|
+
return colHeader.props.children
|
101
|
+
})
|
111
102
|
}
|
112
103
|
|
113
104
|
render() {
|
@@ -133,13 +124,16 @@ class Table extends Component<TableProps> {
|
|
133
124
|
<ScreenReaderContent>{caption}</ScreenReaderContent>
|
134
125
|
</caption>
|
135
126
|
)}
|
136
|
-
{Children.map(children, (child
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
127
|
+
{Children.map(children, (child) => {
|
128
|
+
if (isValidElement(child)) {
|
129
|
+
return safeCloneElement(child, {
|
130
|
+
key: child.props.name,
|
131
|
+
isStacked,
|
132
|
+
hover,
|
133
|
+
headers
|
134
|
+
})
|
135
|
+
}
|
136
|
+
return child
|
143
137
|
})}
|
144
138
|
</View>
|
145
139
|
)
|