@arcblock/ux 2.1.25 → 2.1.26

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.
@@ -21,6 +21,8 @@ var _Clear = _interopRequireDefault(require("@mui/icons-material/Clear"));
21
21
 
22
22
  var _styledComponents = _interopRequireDefault(require("styled-components"));
23
23
 
24
+ var _clsx = _interopRequireDefault(require("clsx"));
25
+
24
26
  var _DatatableContext = require("./DatatableContext");
25
27
 
26
28
  var _jsxRuntime = require("react/jsx-runtime");
@@ -36,16 +38,22 @@ function TableSearch(_ref) {
36
38
  searchClose,
37
39
  onSearchOpen
38
40
  } = _ref;
39
- const [inputMode, setInputMode] = (0, _react.useState)(false);
41
+ const {
42
+ searchOpen,
43
+ searchPlaceholder,
44
+ searchAlwaysOpen
45
+ } = options;
46
+ const [inputExpand, setInputExpand] = (0, _react.useState)(searchOpen || false);
40
47
  const [innerSearchText, setInnerSearchText] = (0, _react.useState)('');
41
48
  const inputTimer = (0, _react.useRef)(null);
42
49
  const {
43
50
  loading
44
51
  } = (0, _DatatableContext.useDatatableContext)();
45
52
  const searchDebounceTime = options.serverSide && options.searchDebounceTime;
53
+ const searchExpand = searchAlwaysOpen || inputExpand;
46
54
 
47
55
  const clickSearchIcon = () => {
48
- setInputMode(true);
56
+ setInputExpand(true);
49
57
  onSearchOpen(true);
50
58
  };
51
59
 
@@ -66,14 +74,17 @@ function TableSearch(_ref) {
66
74
  };
67
75
 
68
76
  const clickClose = () => {
69
- setInputMode(false);
77
+ setInputExpand(false);
70
78
  searchClose();
71
79
  setInnerSearchText('');
72
80
  onSearchOpen(false);
73
81
  };
74
82
 
75
83
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(Container, {
76
- children: [inputMode ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
84
+ className: (0, _clsx.default)({
85
+ 'search-always-open': searchAlwaysOpen
86
+ }),
87
+ children: [searchExpand ? /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
77
88
  className: "toolbar-search-icon-placeholder",
78
89
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Search.default, {})
79
90
  }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, {
@@ -87,21 +98,22 @@ function TableSearch(_ref) {
87
98
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Search.default, {})
88
99
  })
89
100
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
90
- className: "toolbar-search-area ".concat(inputMode ? 'toolbar-btn-show' : ''),
91
- children: [inputMode && !loading && /*#__PURE__*/(0, _jsxRuntime.jsx)(_TextField.default, {
101
+ className: "toolbar-search-area ".concat(searchExpand ? 'toolbar-btn-show' : ''),
102
+ children: [searchExpand && !loading && /*#__PURE__*/(0, _jsxRuntime.jsx)(_TextField.default, {
92
103
  variant: "standard",
93
104
  spacing: 2,
94
105
  onChange: onChange,
95
106
  value: searchDebounceTime ? innerSearchText : searchText || '',
96
- autoFocus: true
107
+ placeholder: searchPlaceholder || '',
108
+ autoFocus: !searchAlwaysOpen
97
109
  }), loading && /*#__PURE__*/(0, _jsxRuntime.jsx)(_TextField.default, {
98
110
  disabled: true,
99
111
  variant: "standard",
100
112
  spacing: 2,
101
113
  value: searchDebounceTime ? innerSearchText : searchText || ''
102
114
  })]
103
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
104
- className: "toolbar-search-close ".concat(inputMode ? 'toolbar-btn-show' : ''),
115
+ }), !searchAlwaysOpen && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
116
+ className: "toolbar-search-close ".concat(searchExpand ? 'toolbar-btn-show' : ''),
105
117
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_IconButton.default, {
106
118
  onClick: clickClose,
107
119
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Clear.default, {})
@@ -127,4 +139,4 @@ TableSearch.defaultProps = {
127
139
  const Container = _styledComponents.default.div.withConfig({
128
140
  displayName: "TableSearch__Container",
129
141
  componentId: "sc-43ylue-0"
130
- })(["display:flex;align-items:center;.toolbar-search-area{width:0;transition:all ease 0.3s;overflow:hidden;.MuiFormControl-root{width:inherit;margin:0 12px;}&.toolbar-btn-show{width:260px;padding-left:8px;", "{width:200px;}", "{width:180px;}&.small-textfield{width:200px;}}}.toolbar-search-close{width:0;transition:all ease 0.3s;overflow:hidden;&.toolbar-btn-show{width:40px;}}.toolbar-search-icon-placeholder{display:flex;justify-content:center;align-items:center;width:40px;height:40px;}"], props => props.theme.breakpoints.down('md'), props => props.theme.breakpoints.down('sm'));
142
+ })(["display:flex;align-items:center;.toolbar-search-area{width:0;transition:all ease 0.3s;overflow:hidden;.MuiFormControl-root{width:inherit;margin:0 12px;}&.toolbar-btn-show{width:260px;padding-left:8px;", "{width:200px;}", "{width:180px;}&.small-textfield{width:200px;}}}.toolbar-search-close{width:0;transition:all ease 0.3s;overflow:hidden;&.toolbar-btn-show{width:40px;}}.toolbar-search-icon-placeholder{display:flex;justify-content:center;align-items:center;width:40px;height:40px;}&.search-always-open{.MuiFormControl-root{margin:0 12px 0 0;}.toolbar-btn-show{padding-left:0;}}"], props => props.theme.breakpoints.down('md'), props => props.theme.breakpoints.down('sm'));
@@ -19,15 +19,19 @@ var _cloneDeep = _interopRequireDefault(require("lodash/cloneDeep"));
19
19
 
20
20
  var _get = _interopRequireDefault(require("lodash/get"));
21
21
 
22
+ var _clsx = _interopRequireDefault(require("clsx"));
23
+
22
24
  var _Empty = _interopRequireDefault(require("../Empty"));
23
25
 
26
+ var _Spinner = _interopRequireDefault(require("../Spinner"));
27
+
24
28
  var _CustomToolbar = _interopRequireDefault(require("./CustomToolbar"));
25
29
 
26
30
  var _DatatableContext = require("./DatatableContext");
27
31
 
28
32
  var _jsxRuntime = require("react/jsx-runtime");
29
33
 
30
- const _excluded = ["data", "columns", "locale", "options", "style", "customButtons", "onChange", "loading", "disabled", "stripped"];
34
+ const _excluded = ["data", "columns", "locale", "options", "style", "customButtons", "onChange", "loading", "disabled", "stripped", "verticalKeyWidth", "hideTableHeader", "components", "emptyNode"];
31
35
 
32
36
  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); }
33
37
 
@@ -66,16 +70,20 @@ function ReDatatable(_ref2) {
66
70
  columns: originColumns,
67
71
  locale,
68
72
  options,
73
+ // The options object is usually a property supported by mui-datatable
69
74
  style,
70
75
  customButtons,
71
76
  onChange,
72
77
  loading,
73
78
  disabled,
74
- stripped
79
+ stripped,
80
+ verticalKeyWidth,
81
+ hideTableHeader,
82
+ components,
83
+ emptyNode
75
84
  } = _ref2,
76
85
  rest = _objectWithoutProperties(_ref2, _excluded);
77
86
 
78
- const container = (0, _react.useRef)(null);
79
87
  const oldState = (0, _react.useRef)(null);
80
88
  const {
81
89
  setCustomButtons,
@@ -103,6 +111,11 @@ function ReDatatable(_ref2) {
103
111
 
104
112
  keys.push(tempObj.name);
105
113
 
114
+ if (!tempObj.align) {
115
+ // There must be an align default for setCellRender to take effect, this is a bug in mui-datatable
116
+ tempObj.align = 'left';
117
+ }
118
+
106
119
  if (!tempObj.options) {
107
120
  tempObj.options = {};
108
121
  }
@@ -132,7 +145,11 @@ function ReDatatable(_ref2) {
132
145
  }
133
146
 
134
147
  if (tempObj.align) {
135
- cellProps.className = "pc-align-".concat(tempObj.align);
148
+ cellProps.className = (0, _clsx.default)(cellProps.className, "pc-align-".concat(tempObj.align));
149
+ }
150
+
151
+ if (tempObj.verticalKeyAlign) {
152
+ cellProps.className = (0, _clsx.default)(cellProps.className, "vertical-align-".concat(tempObj.verticalKeyAlign));
136
153
  }
137
154
 
138
155
  return cellProps;
@@ -152,7 +169,11 @@ function ReDatatable(_ref2) {
152
169
  }
153
170
 
154
171
  if (tempObj.align) {
155
- cellProps.className = "pc-align-".concat(tempObj.align);
172
+ cellProps.className = (0, _clsx.default)(cellProps.className, "pc-align-".concat(tempObj.align));
173
+ }
174
+
175
+ if (tempObj.verticalKeyAlign) {
176
+ cellProps.className = (0, _clsx.default)(cellProps.className, "vertical-align-".concat(tempObj.verticalKeyAlign));
156
177
  }
157
178
 
158
179
  return cellProps;
@@ -174,11 +195,25 @@ function ReDatatable(_ref2) {
174
195
  (0, _react.useEffect)(() => setCustomButtons(customButtons || []), [customButtons]);
175
196
  (0, _react.useEffect)(() => setLoading(loading), [loading]);
176
197
  (0, _react.useEffect)(() => setDisabled(disabled), [disabled]);
198
+ let emptyEl;
199
+
200
+ if (loading) {
201
+ emptyEl = /*#__PURE__*/(0, _jsxRuntime.jsx)(_Spinner.default, {});
202
+ } else if ( /*#__PURE__*/(0, _react.isValidElement)(emptyNode)) {
203
+ emptyEl = emptyNode;
204
+ } else if (locale === 'zh') {
205
+ emptyEl = /*#__PURE__*/(0, _jsxRuntime.jsx)(_Empty.default, {
206
+ children: emptyNode || '对不起,没有找到匹配的记录'
207
+ });
208
+ } else {
209
+ emptyEl = /*#__PURE__*/(0, _jsxRuntime.jsx)(_Empty.default, {
210
+ children: emptyNode || 'Sorry, no matching records found'
211
+ });
212
+ }
213
+
177
214
  let textLabels = {
178
215
  body: {
179
- noMatch: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Empty.default, {
180
- children: "Sorry, no matching records found"
181
- }),
216
+ noMatch: emptyEl,
182
217
  toolTip: 'Sort'
183
218
  },
184
219
  pagination: {
@@ -214,9 +249,7 @@ function ReDatatable(_ref2) {
214
249
  if (locale === 'zh') {
215
250
  textLabels = {
216
251
  body: {
217
- noMatch: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Empty.default, {
218
- children: "\u5BF9\u4E0D\u8D77\uFF0C\u6CA1\u6709\u627E\u5230\u5339\u914D\u7684\u8BB0\u5F55"
219
- }),
252
+ noMatch: emptyEl,
220
253
  toolTip: '排序'
221
254
  },
222
255
  pagination: {
@@ -293,38 +326,19 @@ function ReDatatable(_ref2) {
293
326
  const props = _objectSpread(_objectSpread({
294
327
  options: opts
295
328
  }, rest), {}, {
296
- components: {
329
+ components: _objectSpread(_objectSpread({}, components), {}, {
297
330
  TableToolbar: _CustomToolbar.default,
298
331
  TableFooter: WrapTableFooter,
299
332
  TableFilterList: WrapFilterList
300
- }
333
+ })
301
334
  });
302
335
 
303
- ReDatatable.propTypes = {
304
- data: _propTypes.default.array.isRequired,
305
- columns: _propTypes.default.array.isRequired,
306
- options: _propTypes.default.object,
307
- style: _propTypes.default.object,
308
- locale: _propTypes.default.string,
309
- loading: _propTypes.default.bool,
310
- disabled: _propTypes.default.bool,
311
- customButtons: _propTypes.default.array,
312
- onChange: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.string]),
313
- stripped: _propTypes.default.bool
314
- };
315
- ReDatatable.defaultProps = {
316
- options: {},
317
- style: {},
318
- locale: 'en',
319
- loading: false,
320
- disabled: false,
321
- customButtons: [],
322
- onChange: '',
323
- stripped: false
324
- };
325
336
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(TableContainer, {
326
- ref: container,
327
- className: stripped ? 'datatable-stripped' : '',
337
+ verticalKeyWidth: verticalKeyWidth,
338
+ className: (0, _clsx.default)({
339
+ 'datatable-stripped': stripped,
340
+ 'datatable-hide-header': hideTableHeader
341
+ }),
328
342
  style: style,
329
343
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_muiDatatables.default, _objectSpread({
330
344
  data: data,
@@ -333,12 +347,48 @@ function ReDatatable(_ref2) {
333
347
  });
334
348
  }
335
349
 
336
- const alignCss = (0, _styledComponents.css)([".MuiTableCell-head{[class*='MUIDataTableHeadCell-toolButton']{width:100%;> [class*='MUIDataTableHeadCell-sortAction']{width:100%;}}&.pc-align-center{text-align:center;[class*='MUIDataTableHeadCell-toolButton'] > [class*='MUIDataTableHeadCell-sortAction']{justify-content:center;}}&.pc-align-right{text-align:right;[class*='MUIDataTableHeadCell-toolButton']{margin-right:0;padding-right:0;& > [class*='MUIDataTableHeadCell-sortAction']{justify-content:right;}}}}.MuiTableCell-body{&.pc-align-center{text-align:center;}&.pc-align-right{text-align:right;}}"]);
350
+ ReDatatable.propTypes = {
351
+ data: _propTypes.default.array.isRequired,
352
+ columns: _propTypes.default.array.isRequired,
353
+ options: _propTypes.default.object,
354
+ style: _propTypes.default.object,
355
+ locale: _propTypes.default.string,
356
+ loading: _propTypes.default.bool,
357
+ disabled: _propTypes.default.bool,
358
+ customButtons: _propTypes.default.array,
359
+ onChange: _propTypes.default.oneOfType([_propTypes.default.func, _propTypes.default.string]),
360
+ stripped: _propTypes.default.bool,
361
+ verticalKeyWidth: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
362
+ hideTableHeader: _propTypes.default.bool,
363
+ components: _propTypes.default.object,
364
+ emptyNode: _propTypes.default.node
365
+ };
366
+ ReDatatable.defaultProps = {
367
+ options: {},
368
+ style: {},
369
+ locale: 'en',
370
+ loading: false,
371
+ disabled: false,
372
+ customButtons: [],
373
+ onChange: '',
374
+ stripped: false,
375
+ verticalKeyWidth: '',
376
+ hideTableHeader: false,
377
+ components: {},
378
+ emptyNode: ''
379
+ };
380
+ const alignCss = (0, _styledComponents.css)([".MuiTableCell-head{[class*='MUIDataTableHeadCell-toolButton']{width:100%;> [class*='MUIDataTableHeadCell-sortAction']{width:100%;}}&.pc-align-center{text-align:center;[class*='MUIDataTableHeadCell-toolButton'] > [class*='MUIDataTableHeadCell-sortAction']{justify-content:center;}}&.pc-align-right{text-align:right;[class*='MUIDataTableHeadCell-toolButton']{margin-right:0;padding-right:0;& > [class*='MUIDataTableHeadCell-sortAction']{justify-content:flex-end;}}}}.MuiTableCell-body{&.pc-align-center{text-align:center;}&.pc-align-right{text-align:right;}}"]);
337
381
 
338
382
  const TableContainer = _styledComponents.default.div.withConfig({
339
383
  displayName: "Datatable__TableContainer",
340
384
  componentId: "sc-1ju12vq-0"
341
- })(["height:100%;> .MuiPaper-root{display:flex;flex-direction:column;height:100%;box-shadow:none;}", "{[class*='MUIDataTableBody-emptyTitle']{padding-left:16px;width:200%;margin-left:-100%;text-align:center;}[class*='MUIDataTableBodyCell-simpleCell']{[class*='MUIDataTableBody-emptyTitle']{padding-left:16px;width:100%;margin-left:0;text-align:center;}}}", "{[class*='responsiveSimple']{td.MuiTableCell-body{display:flex;padding-right:0;> div{width:auto;flex:1;&:first-child{flex:0;padding-right:16px;}}}}}", "{", "}", "{[class*='responsiveSimple']{", "}}&.datatable-stripped{.MuiTableBody-root{tr:nth-of-type(odd){background-color:", ";}}}"], props => props.theme.breakpoints.down('md'), props => props.theme.breakpoints.down('sm'), props => props.theme.breakpoints.up('md'), alignCss, props => props.theme.breakpoints.up('sm'), alignCss, props => props.theme.palette.action.hover);
385
+ })(["&.datatable-hide-header{thead.MuiTableHead-root{display:none;}}td{&.vertical-align-top{align-items:flex-start;}&.vertical-align-center{align-items:center;}&.vertical-align-bottom{align-items:flex-end;}}height:100%;> .MuiPaper-root{display:flex;flex-direction:column;height:100%;box-shadow:none;}", "{td.MuiTableCell-body{padding-right:0;}[class*='MUIDataTable-responsiveBase']{tr:not([class*='responsiveSimple']){td.MuiTableCell-body{display:flex;> div{width:auto;flex:1;&:first-child{font-weight:bold;font-size:14px;width:auto;flex:0 0 auto;padding-right:16px;&:empty{padding-right:0;}}}}}}}", "{", "}", "{[class*='responsiveSimple']{", "}}", " &.datatable-stripped{.MuiTableBody-root{tr:nth-of-type(odd){background-color:", ";}}}"], props => props.theme.breakpoints.down('md'), props => props.theme.breakpoints.up('md'), alignCss, props => props.theme.breakpoints.up('sm'), alignCss, inProps => {
386
+ if (inProps.verticalKeyWidth) {
387
+ return "\n ".concat(inProps.theme.breakpoints.down('md'), " {\n [class*='MUIDataTable-responsiveBase'] {\n tr:not([class*='responsiveSimple']) {\n td.MuiTableCell-body {\n > div {\n &:first-child {\n width: ").concat(inProps.verticalKeyWidth + (!/\D/.test(inProps.verticalKeyWidth) ? 'px' : ''), ";\n }\n }\n }\n }\n }\n }\n ");
388
+ }
389
+
390
+ return '';
391
+ }, props => props.theme.palette.action.hover);
342
392
 
343
393
  const FilterLine = _styledComponents.default.div.withConfig({
344
394
  displayName: "Datatable__FilterLine",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@arcblock/ux",
3
- "version": "2.1.25",
3
+ "version": "2.1.26",
4
4
  "description": "Common used react components for arcblock products",
5
5
  "keywords": [
6
6
  "react",
@@ -52,10 +52,10 @@
52
52
  "react": ">=18.1.0",
53
53
  "react-ga": "^2.7.0"
54
54
  },
55
- "gitHead": "a01ecf24a8c82fb899716cfbd1de9175166f8a79",
55
+ "gitHead": "5c5282d38dad227f1855d482d7164d07a6b12ff4",
56
56
  "dependencies": {
57
- "@arcblock/icons": "^2.1.25",
58
- "@arcblock/react-hooks": "^2.1.25",
57
+ "@arcblock/icons": "^2.1.26",
58
+ "@arcblock/react-hooks": "^2.1.26",
59
59
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
60
60
  "@emotion/react": "^11.9.0",
61
61
  "@emotion/styled": "^11.8.1",
@@ -6,18 +6,22 @@ import SearchIcon from '@mui/icons-material/Search';
6
6
  import TextField from '@mui/material/TextField';
7
7
  import ClearIcon from '@mui/icons-material/Clear';
8
8
  import styled from 'styled-components';
9
+ import clsx from 'clsx';
9
10
  import { useDatatableContext } from './DatatableContext';
10
11
 
11
12
  export default function TableSearch({ search, options, searchText, searchTextUpdate, searchClose, onSearchOpen }) {
12
- const [inputMode, setInputMode] = useState(false);
13
+ const { searchOpen, searchPlaceholder, searchAlwaysOpen } = options;
14
+ const [inputExpand, setInputExpand] = useState(searchOpen || false);
13
15
  const [innerSearchText, setInnerSearchText] = useState('');
14
16
  const inputTimer = useRef(null);
15
17
  const { loading } = useDatatableContext();
16
18
 
17
19
  const searchDebounceTime = options.serverSide && options.searchDebounceTime;
18
20
 
21
+ const searchExpand = searchAlwaysOpen || inputExpand;
22
+
19
23
  const clickSearchIcon = () => {
20
- setInputMode(true);
24
+ setInputExpand(true);
21
25
  onSearchOpen(true);
22
26
  };
23
27
 
@@ -35,15 +39,18 @@ export default function TableSearch({ search, options, searchText, searchTextUpd
35
39
  };
36
40
 
37
41
  const clickClose = () => {
38
- setInputMode(false);
42
+ setInputExpand(false);
39
43
  searchClose();
40
44
  setInnerSearchText('');
41
45
  onSearchOpen(false);
42
46
  };
43
47
 
44
48
  return (
45
- <Container>
46
- {inputMode ? (
49
+ <Container
50
+ className={clsx({
51
+ 'search-always-open': searchAlwaysOpen,
52
+ })}>
53
+ {searchExpand ? (
47
54
  <div className="toolbar-search-icon-placeholder">
48
55
  <SearchIcon />
49
56
  </div>
@@ -59,14 +66,15 @@ export default function TableSearch({ search, options, searchText, searchTextUpd
59
66
  </Tooltip>
60
67
  )}
61
68
 
62
- <div className={`toolbar-search-area ${inputMode ? 'toolbar-btn-show' : ''}`}>
63
- {inputMode && !loading && (
69
+ <div className={`toolbar-search-area ${searchExpand ? 'toolbar-btn-show' : ''}`}>
70
+ {searchExpand && !loading && (
64
71
  <TextField
65
72
  variant="standard"
66
73
  spacing={2}
67
74
  onChange={onChange}
68
75
  value={searchDebounceTime ? innerSearchText : searchText || ''}
69
- autoFocus
76
+ placeholder={searchPlaceholder || ''}
77
+ autoFocus={!searchAlwaysOpen}
70
78
  />
71
79
  )}
72
80
  {/* loading完成后没办法使用focus方法,所以改用两个 TextField */}
@@ -79,11 +87,13 @@ export default function TableSearch({ search, options, searchText, searchTextUpd
79
87
  />
80
88
  )}
81
89
  </div>
82
- <div className={`toolbar-search-close ${inputMode ? 'toolbar-btn-show' : ''}`}>
83
- <IconButton onClick={clickClose}>
84
- <ClearIcon />
85
- </IconButton>
86
- </div>
90
+ {!searchAlwaysOpen && (
91
+ <div className={`toolbar-search-close ${searchExpand ? 'toolbar-btn-show' : ''}`}>
92
+ <IconButton onClick={clickClose}>
93
+ <ClearIcon />
94
+ </IconButton>
95
+ </div>
96
+ )}
87
97
  </Container>
88
98
  );
89
99
  }
@@ -145,4 +155,12 @@ const Container = styled.div`
145
155
  width: 40px;
146
156
  height: 40px;
147
157
  }
158
+ &.search-always-open {
159
+ .MuiFormControl-root {
160
+ margin: 0 12px 0 0;
161
+ }
162
+ .toolbar-btn-show {
163
+ padding-left: 0;
164
+ }
165
+ }
148
166
  `;
@@ -1,12 +1,14 @@
1
1
  /* eslint-disable react-hooks/exhaustive-deps */
2
- import { useEffect, useRef } from 'react';
2
+ import { useEffect, useRef, isValidElement } from 'react';
3
3
  import PropTypes from 'prop-types';
4
4
  import MUIDataTable, { TableFilterList, TableFooter } from 'mui-datatables';
5
5
  import styled, { css } from 'styled-components';
6
6
  import isObject from 'lodash/isObject';
7
7
  import cloneDeep from 'lodash/cloneDeep';
8
8
  import get from 'lodash/get';
9
+ import clsx from 'clsx';
9
10
  import Empty from '../Empty';
11
+ import Spinner from '../Spinner';
10
12
  import CustomToolbar from './CustomToolbar';
11
13
  import { DatatableProvide, useDatatableContext } from './DatatableContext';
12
14
 
@@ -29,16 +31,19 @@ function ReDatatable({
29
31
  data: originData,
30
32
  columns: originColumns,
31
33
  locale,
32
- options,
34
+ options, // The options object is usually a property supported by mui-datatable
33
35
  style,
34
36
  customButtons,
35
37
  onChange,
36
38
  loading,
37
39
  disabled,
38
40
  stripped,
41
+ verticalKeyWidth,
42
+ hideTableHeader,
43
+ components,
44
+ emptyNode,
39
45
  ...rest
40
46
  }) {
41
- const container = useRef(null);
42
47
  const oldState = useRef(null);
43
48
  const { setCustomButtons, setFilterLabel, setLoading, setDisabled } = useDatatableContext();
44
49
 
@@ -63,6 +68,11 @@ function ReDatatable({
63
68
  }
64
69
  keys.push(tempObj.name);
65
70
 
71
+ if (!tempObj.align) {
72
+ // There must be an align default for setCellRender to take effect, this is a bug in mui-datatable
73
+ tempObj.align = 'left';
74
+ }
75
+
66
76
  if (!tempObj.options) {
67
77
  tempObj.options = {};
68
78
  }
@@ -91,7 +101,11 @@ function ReDatatable({
91
101
  }
92
102
 
93
103
  if (tempObj.align) {
94
- cellProps.className = `pc-align-${tempObj.align}`;
104
+ cellProps.className = clsx(cellProps.className, `pc-align-${tempObj.align}`);
105
+ }
106
+
107
+ if (tempObj.verticalKeyAlign) {
108
+ cellProps.className = clsx(cellProps.className, `vertical-align-${tempObj.verticalKeyAlign}`);
95
109
  }
96
110
 
97
111
  return cellProps;
@@ -115,7 +129,11 @@ function ReDatatable({
115
129
  }
116
130
 
117
131
  if (tempObj.align) {
118
- cellProps.className = `pc-align-${tempObj.align}`;
132
+ cellProps.className = clsx(cellProps.className, `pc-align-${tempObj.align}`);
133
+ }
134
+
135
+ if (tempObj.verticalKeyAlign) {
136
+ cellProps.className = clsx(cellProps.className, `vertical-align-${tempObj.verticalKeyAlign}`);
119
137
  }
120
138
 
121
139
  return cellProps;
@@ -138,9 +156,20 @@ function ReDatatable({
138
156
  useEffect(() => setLoading(loading), [loading]);
139
157
  useEffect(() => setDisabled(disabled), [disabled]);
140
158
 
159
+ let emptyEl;
160
+ if (loading) {
161
+ emptyEl = <Spinner />;
162
+ } else if (isValidElement(emptyNode)) {
163
+ emptyEl = emptyNode;
164
+ } else if (locale === 'zh') {
165
+ emptyEl = <Empty>{emptyNode || '对不起,没有找到匹配的记录'}</Empty>;
166
+ } else {
167
+ emptyEl = <Empty>{emptyNode || 'Sorry, no matching records found'}</Empty>;
168
+ }
169
+
141
170
  let textLabels = {
142
171
  body: {
143
- noMatch: <Empty>Sorry, no matching records found</Empty>,
172
+ noMatch: emptyEl,
144
173
  toolTip: 'Sort',
145
174
  },
146
175
  pagination: {
@@ -164,7 +193,7 @@ function ReDatatable({
164
193
 
165
194
  if (locale === 'zh') {
166
195
  textLabels = {
167
- body: { noMatch: <Empty>对不起,没有找到匹配的记录</Empty>, toolTip: '排序' },
196
+ body: { noMatch: emptyEl, toolTip: '排序' },
168
197
  pagination: {
169
198
  next: '下一页',
170
199
  previous: '上一页',
@@ -226,43 +255,58 @@ function ReDatatable({
226
255
  options: opts,
227
256
  ...rest,
228
257
  components: {
258
+ ...components,
229
259
  TableToolbar: CustomToolbar,
230
260
  TableFooter: WrapTableFooter,
231
261
  TableFilterList: WrapFilterList,
232
262
  },
233
263
  };
234
264
 
235
- ReDatatable.propTypes = {
236
- data: PropTypes.array.isRequired,
237
- columns: PropTypes.array.isRequired,
238
- options: PropTypes.object,
239
- style: PropTypes.object,
240
- locale: PropTypes.string,
241
- loading: PropTypes.bool,
242
- disabled: PropTypes.bool,
243
- customButtons: PropTypes.array,
244
- onChange: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
245
- stripped: PropTypes.bool,
246
- };
247
-
248
- ReDatatable.defaultProps = {
249
- options: {},
250
- style: {},
251
- locale: 'en',
252
- loading: false,
253
- disabled: false,
254
- customButtons: [],
255
- onChange: '',
256
- stripped: false,
257
- };
258
-
259
265
  return (
260
- <TableContainer ref={container} className={stripped ? 'datatable-stripped' : ''} style={style}>
266
+ <TableContainer
267
+ verticalKeyWidth={verticalKeyWidth}
268
+ className={clsx({
269
+ 'datatable-stripped': stripped,
270
+ 'datatable-hide-header': hideTableHeader,
271
+ })}
272
+ style={style}>
261
273
  <MUIDataTable data={data} columns={columns} {...props} />
262
274
  </TableContainer>
263
275
  );
264
276
  }
265
277
 
278
+ ReDatatable.propTypes = {
279
+ data: PropTypes.array.isRequired,
280
+ columns: PropTypes.array.isRequired,
281
+ options: PropTypes.object,
282
+ style: PropTypes.object,
283
+ locale: PropTypes.string,
284
+ loading: PropTypes.bool,
285
+ disabled: PropTypes.bool,
286
+ customButtons: PropTypes.array,
287
+ onChange: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
288
+ stripped: PropTypes.bool,
289
+ verticalKeyWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
290
+ hideTableHeader: PropTypes.bool,
291
+ components: PropTypes.object,
292
+ emptyNode: PropTypes.node,
293
+ };
294
+
295
+ ReDatatable.defaultProps = {
296
+ options: {},
297
+ style: {},
298
+ locale: 'en',
299
+ loading: false,
300
+ disabled: false,
301
+ customButtons: [],
302
+ onChange: '',
303
+ stripped: false,
304
+ verticalKeyWidth: '',
305
+ hideTableHeader: false,
306
+ components: {},
307
+ emptyNode: '',
308
+ };
309
+
266
310
  const alignCss = css`
267
311
  .MuiTableCell-head {
268
312
  [class*='MUIDataTableHeadCell-toolButton'] {
@@ -283,7 +327,7 @@ const alignCss = css`
283
327
  margin-right: 0;
284
328
  padding-right: 0;
285
329
  & > [class*='MUIDataTableHeadCell-sortAction'] {
286
- justify-content: right;
330
+ justify-content: flex-end;
287
331
  }
288
332
  }
289
333
  }
@@ -299,6 +343,24 @@ const alignCss = css`
299
343
  `;
300
344
 
301
345
  const TableContainer = styled.div`
346
+ &.datatable-hide-header {
347
+ thead.MuiTableHead-root {
348
+ display: none;
349
+ }
350
+ }
351
+
352
+ td {
353
+ &.vertical-align-top {
354
+ align-items: flex-start;
355
+ }
356
+ &.vertical-align-center {
357
+ align-items: center;
358
+ }
359
+ &.vertical-align-bottom {
360
+ align-items: flex-end;
361
+ }
362
+ }
363
+
302
364
  height: 100%;
303
365
  > .MuiPaper-root {
304
366
  display: flex;
@@ -307,32 +369,26 @@ const TableContainer = styled.div`
307
369
  box-shadow: none;
308
370
  }
309
371
  ${(props) => props.theme.breakpoints.down('md')} {
310
- [class*='MUIDataTableBody-emptyTitle'] {
311
- padding-left: 16px;
312
- width: 200%;
313
- margin-left: -100%;
314
- text-align: center;
315
- }
316
- [class*='MUIDataTableBodyCell-simpleCell'] {
317
- [class*='MUIDataTableBody-emptyTitle'] {
318
- padding-left: 16px;
319
- width: 100%;
320
- margin-left: 0;
321
- text-align: center;
322
- }
372
+ td.MuiTableCell-body {
373
+ padding-right: 0;
323
374
  }
324
- }
325
- ${(props) => props.theme.breakpoints.down('sm')} {
326
- [class*='responsiveSimple'] {
327
- td.MuiTableCell-body {
328
- display: flex;
329
- padding-right: 0;
330
- > div {
331
- width: auto;
332
- flex: 1;
333
- &:first-child {
334
- flex: 0;
335
- padding-right: 16px;
375
+ [class*='MUIDataTable-responsiveBase'] {
376
+ tr:not([class*='responsiveSimple']) {
377
+ td.MuiTableCell-body {
378
+ display: flex;
379
+ > div {
380
+ width: auto;
381
+ flex: 1;
382
+ &:first-child {
383
+ font-weight: bold;
384
+ font-size: 14px;
385
+ width: auto;
386
+ flex: 0 0 auto;
387
+ padding-right: 16px;
388
+ &:empty {
389
+ padding-right: 0;
390
+ }
391
+ }
336
392
  }
337
393
  }
338
394
  }
@@ -346,6 +402,29 @@ const TableContainer = styled.div`
346
402
  ${alignCss}
347
403
  }
348
404
  }
405
+
406
+ ${(inProps) => {
407
+ if (inProps.verticalKeyWidth) {
408
+ return `
409
+ ${inProps.theme.breakpoints.down('md')} {
410
+ [class*='MUIDataTable-responsiveBase'] {
411
+ tr:not([class*='responsiveSimple']) {
412
+ td.MuiTableCell-body {
413
+ > div {
414
+ &:first-child {
415
+ width: ${inProps.verticalKeyWidth + (!/\D/.test(inProps.verticalKeyWidth) ? 'px' : '')};
416
+ }
417
+ }
418
+ }
419
+ }
420
+ }
421
+ }
422
+ `;
423
+ }
424
+
425
+ return '';
426
+ }}
427
+
349
428
  &.datatable-stripped {
350
429
  .MuiTableBody-root {
351
430
  tr:nth-of-type(odd) {