@arcblock/ux 2.1.6 → 2.1.9
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/Datatable/CustomToolbar.js +350 -0
- package/lib/Datatable/DatatableContext.js +47 -0
- package/lib/Datatable/TableSearch.js +98 -0
- package/lib/Datatable/index.js +338 -0
- package/lib/Datatable/utils.js +154 -0
- package/lib/Layout/dashboard/header.js +1 -1
- package/lib/Layout/dashboard/index.js +1 -1
- package/lib/index.js +8 -0
- package/package.json +5 -4
- package/src/Datatable/CustomToolbar.js +406 -0
- package/src/Datatable/DatatableContext.js +32 -0
- package/src/Datatable/TableSearch.js +130 -0
- package/src/Datatable/index.js +314 -0
- package/src/Datatable/utils.js +165 -0
- package/src/Layout/dashboard/header.js +1 -1
- package/src/Layout/dashboard/index.js +1 -1
- package/src/index.js +2 -0
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
import React, { useState, useRef, useEffect, isValidElement } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { TableFilter, TableViewCol } from 'mui-datatables';
|
|
4
|
+
import styled from 'styled-components';
|
|
5
|
+
import ReactToPrint, { PrintContextConsumer } from 'react-to-print';
|
|
6
|
+
import IconButton from '@mui/material/IconButton';
|
|
7
|
+
import Tooltip from '@mui/material/Tooltip';
|
|
8
|
+
import DownloadIcon from '@mui/icons-material/CloudDownload';
|
|
9
|
+
import PrintIcon from '@mui/icons-material/Print';
|
|
10
|
+
import ViewColumnIcon from '@mui/icons-material/ViewColumn';
|
|
11
|
+
import FilterIcon from '@mui/icons-material/FilterList';
|
|
12
|
+
import Popover from '@mui/material/Popover';
|
|
13
|
+
import MoreVertIcon from '@mui/icons-material/MoreVert';
|
|
14
|
+
import Menu from '@mui/material/Menu';
|
|
15
|
+
import MenuItem from '@mui/material/MenuItem';
|
|
16
|
+
import ListItemIcon from '@mui/material/ListItemIcon';
|
|
17
|
+
import ListItemText from '@mui/material/ListItemText';
|
|
18
|
+
import useMediaQuery from '@mui/material/useMediaQuery';
|
|
19
|
+
import { useTheme } from '@mui/material/styles';
|
|
20
|
+
import LinearProgress from '@mui/material/LinearProgress';
|
|
21
|
+
import { handleCSVDownload } from './utils';
|
|
22
|
+
import TableSearch from './TableSearch';
|
|
23
|
+
import { useDatatableContext } from './DatatableContext';
|
|
24
|
+
|
|
25
|
+
function useMobile() {
|
|
26
|
+
const theme = useTheme();
|
|
27
|
+
return useMediaQuery(theme.breakpoints.down('sm'));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export default function CustomToolbar(props) {
|
|
31
|
+
const [menuIconEl, setMenuIconEl] = useState(null);
|
|
32
|
+
const moreBtn = useRef(null);
|
|
33
|
+
const isMobile = useMobile();
|
|
34
|
+
const toolbarId = useRef(Math.random().toString(32).slice(2));
|
|
35
|
+
const [searchOpened, setSearchOpened] = useState(false);
|
|
36
|
+
const { customButtons, loading, disabled } = useDatatableContext();
|
|
37
|
+
|
|
38
|
+
const {
|
|
39
|
+
data,
|
|
40
|
+
options,
|
|
41
|
+
components,
|
|
42
|
+
columns,
|
|
43
|
+
filterList,
|
|
44
|
+
filterData,
|
|
45
|
+
filterUpdate,
|
|
46
|
+
resetFilters,
|
|
47
|
+
updateFilterByType,
|
|
48
|
+
toggleViewColumn,
|
|
49
|
+
updateColumns,
|
|
50
|
+
title,
|
|
51
|
+
searchText,
|
|
52
|
+
searchTextUpdate,
|
|
53
|
+
searchClose,
|
|
54
|
+
} = props;
|
|
55
|
+
|
|
56
|
+
const customToolbarEle = options.customToolbar ? options.customToolbar(props) : '';
|
|
57
|
+
|
|
58
|
+
const { search, downloadCsv, print, viewColumns, filterTable } = options.textLabels.toolbar;
|
|
59
|
+
|
|
60
|
+
const hideSearch = options.search === false || options.search === 'false';
|
|
61
|
+
const hidePrint = options.print === false || options.print === 'false';
|
|
62
|
+
|
|
63
|
+
const TableFilterComponent = components.TableFilter || TableFilter;
|
|
64
|
+
const TableViewColComponent = components.TableViewCol || TableViewCol;
|
|
65
|
+
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
if (loading || disabled) {
|
|
68
|
+
setAllPopsEl({});
|
|
69
|
+
}
|
|
70
|
+
}, [loading, disabled]);
|
|
71
|
+
|
|
72
|
+
const printArea = func => {
|
|
73
|
+
return (
|
|
74
|
+
<ReactToPrint content={() => props.tableRef()}>
|
|
75
|
+
<PrintContextConsumer>{func}</PrintContextConsumer>
|
|
76
|
+
</ReactToPrint>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const getPopId = key => `toolbar-pop-${toolbarId.current}-${key}`;
|
|
81
|
+
|
|
82
|
+
const defaultButtons = [];
|
|
83
|
+
|
|
84
|
+
// download/viewColumns/filter button behaviours, rendered using custom button logic
|
|
85
|
+
if (!(options.download === false || options.download === 'false')) {
|
|
86
|
+
defaultButtons.push({
|
|
87
|
+
Icon: DownloadIcon,
|
|
88
|
+
title: downloadCsv,
|
|
89
|
+
onClick: () => {
|
|
90
|
+
handleCSVDownload(props);
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (!(options.viewColumns === false || options.viewColumns === 'false')) {
|
|
96
|
+
defaultButtons.push({
|
|
97
|
+
Icon: ViewColumnIcon,
|
|
98
|
+
title: viewColumns,
|
|
99
|
+
popRender() {
|
|
100
|
+
return (
|
|
101
|
+
<TableViewColComponent
|
|
102
|
+
data={data}
|
|
103
|
+
columns={columns}
|
|
104
|
+
options={options}
|
|
105
|
+
onColumnUpdate={toggleViewColumn}
|
|
106
|
+
updateColumns={updateColumns}
|
|
107
|
+
components={components}
|
|
108
|
+
/>
|
|
109
|
+
);
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (!(options.filter === false || options.filter === 'false')) {
|
|
115
|
+
defaultButtons.push({
|
|
116
|
+
Icon: FilterIcon,
|
|
117
|
+
title: filterTable,
|
|
118
|
+
popRender() {
|
|
119
|
+
return (
|
|
120
|
+
<TableFilterComponent
|
|
121
|
+
customFooter={options.customFilterDialogFooter}
|
|
122
|
+
columns={columns}
|
|
123
|
+
options={options}
|
|
124
|
+
filterList={filterList}
|
|
125
|
+
filterData={filterData}
|
|
126
|
+
onFilterUpdate={filterUpdate}
|
|
127
|
+
onFilterReset={resetFilters}
|
|
128
|
+
updateFilterByType={updateFilterByType}
|
|
129
|
+
components={components}
|
|
130
|
+
/>
|
|
131
|
+
);
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const showMore =
|
|
137
|
+
[!hidePrint, ...defaultButtons, ...customButtons].filter(e => !!e).length > 1 && isMobile;
|
|
138
|
+
|
|
139
|
+
const allPops = [];
|
|
140
|
+
const [allPopsEl, setAllPopsEl] = useState({});
|
|
141
|
+
|
|
142
|
+
// Large screens show the toolbar buttons directly, small screens show the drop-down menu style buttons
|
|
143
|
+
// The right-hand button of the form toolbar in desktop mode
|
|
144
|
+
const toolbarButtons = [...defaultButtons, ...customButtons].map((e, index) => {
|
|
145
|
+
if (isValidElement(e)) {
|
|
146
|
+
return e;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const popId = getPopId(index);
|
|
150
|
+
|
|
151
|
+
if (e.Icon) {
|
|
152
|
+
const { Icon, popRender } = e;
|
|
153
|
+
// When popRender is present, clicking the button will bubble up the content returned by the popRender
|
|
154
|
+
if (popRender) {
|
|
155
|
+
allPops.push(
|
|
156
|
+
<Popover
|
|
157
|
+
open={!!allPopsEl[popId]}
|
|
158
|
+
anchorEl={() => allPopsEl[popId]}
|
|
159
|
+
onClose={() => {
|
|
160
|
+
setAllPopsEl({});
|
|
161
|
+
}}
|
|
162
|
+
key={popId}
|
|
163
|
+
anchorOrigin={{
|
|
164
|
+
vertical: 'bottom',
|
|
165
|
+
horizontal: 'right',
|
|
166
|
+
}}>
|
|
167
|
+
<div>{popRender()}</div>
|
|
168
|
+
</Popover>
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return (
|
|
173
|
+
<Tooltip title={e.title} key={popId}>
|
|
174
|
+
<IconButton
|
|
175
|
+
data-testid={`${e.title}-iconButton`}
|
|
176
|
+
id={`btn-${popId}`}
|
|
177
|
+
aria-label={e.title}
|
|
178
|
+
onClick={() => {
|
|
179
|
+
if (e.onClick) {
|
|
180
|
+
e.onClick();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (popRender) {
|
|
184
|
+
// On the large screen, the bubble is positioned at the corresponding button
|
|
185
|
+
setAllPopsEl({
|
|
186
|
+
[popId]: document.getElementById(`btn-${popId}`),
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}}>
|
|
190
|
+
<Icon />
|
|
191
|
+
</IconButton>
|
|
192
|
+
</Tooltip>
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return e;
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
// The toolbar menu in the mobile to replace toolbarButtons
|
|
200
|
+
const menuItems = [...defaultButtons, ...customButtons].map((e, index) => {
|
|
201
|
+
const popId = getPopId(index);
|
|
202
|
+
|
|
203
|
+
let content;
|
|
204
|
+
|
|
205
|
+
if (isValidElement(e)) {
|
|
206
|
+
content = e;
|
|
207
|
+
} else if (e.Icon) {
|
|
208
|
+
const { Icon } = e;
|
|
209
|
+
|
|
210
|
+
content = (
|
|
211
|
+
<>
|
|
212
|
+
<ListItemIcon>
|
|
213
|
+
<Icon fontSize="small" />
|
|
214
|
+
</ListItemIcon>
|
|
215
|
+
<ListItemText>{e.title}</ListItemText>
|
|
216
|
+
</>
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return (
|
|
221
|
+
<MenuItem
|
|
222
|
+
key={popId}
|
|
223
|
+
onClick={() => {
|
|
224
|
+
setMenuIconEl(null);
|
|
225
|
+
if (e.onClick) {
|
|
226
|
+
e.onClick();
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (e.popRender) {
|
|
230
|
+
// On the small screen, the bubbles are positioned at the three dot buttons
|
|
231
|
+
setAllPopsEl({
|
|
232
|
+
[popId]: moreBtn.current,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}}>
|
|
236
|
+
{content}
|
|
237
|
+
</MenuItem>
|
|
238
|
+
);
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
return (
|
|
242
|
+
<div>
|
|
243
|
+
<Container>
|
|
244
|
+
<div
|
|
245
|
+
className={`custom-toobar-title ${
|
|
246
|
+
isMobile && searchOpened && isValidElement(title) ? 'toobar-title-hidden' : ''
|
|
247
|
+
}`}>
|
|
248
|
+
<div className="custom-toobar-title-inner">
|
|
249
|
+
<span>{title}</span>
|
|
250
|
+
</div>
|
|
251
|
+
</div>
|
|
252
|
+
<div className={`custom-toobar-btns ${loading || disabled ? 'toobar-btns-disabled' : ''}`}>
|
|
253
|
+
{!hideSearch && (
|
|
254
|
+
<TableSearch
|
|
255
|
+
search={search}
|
|
256
|
+
options={options}
|
|
257
|
+
searchText={searchText}
|
|
258
|
+
searchTextUpdate={searchTextUpdate}
|
|
259
|
+
searchClose={searchClose}
|
|
260
|
+
onSearchOpen={setSearchOpened}
|
|
261
|
+
/>
|
|
262
|
+
)}
|
|
263
|
+
{!showMore && (
|
|
264
|
+
<>
|
|
265
|
+
{!hidePrint &&
|
|
266
|
+
printArea(({ handlePrint }) => (
|
|
267
|
+
<span>
|
|
268
|
+
<Tooltip title={print}>
|
|
269
|
+
<IconButton
|
|
270
|
+
data-testid={`${print}-iconButton`}
|
|
271
|
+
aria-label={print}
|
|
272
|
+
disabled={options.print === 'disabled'}
|
|
273
|
+
onClick={handlePrint}>
|
|
274
|
+
<PrintIcon />
|
|
275
|
+
</IconButton>
|
|
276
|
+
</Tooltip>
|
|
277
|
+
</span>
|
|
278
|
+
))}
|
|
279
|
+
|
|
280
|
+
{toolbarButtons}
|
|
281
|
+
</>
|
|
282
|
+
)}
|
|
283
|
+
{showMore && (
|
|
284
|
+
<IconButton
|
|
285
|
+
ref={moreBtn}
|
|
286
|
+
aria-haspopup="true"
|
|
287
|
+
aria-expanded={menuIconEl ? 'true' : undefined}
|
|
288
|
+
onClick={event => setMenuIconEl(event.currentTarget)}
|
|
289
|
+
style={{ flexShrink: 0 }}>
|
|
290
|
+
<MoreVertIcon />
|
|
291
|
+
</IconButton>
|
|
292
|
+
)}
|
|
293
|
+
</div>
|
|
294
|
+
{customToolbarEle}
|
|
295
|
+
</Container>
|
|
296
|
+
|
|
297
|
+
<Menu
|
|
298
|
+
anchorEl={menuIconEl}
|
|
299
|
+
open={!!menuIconEl}
|
|
300
|
+
onClose={() => setMenuIconEl(null)}
|
|
301
|
+
MenuListProps={{
|
|
302
|
+
'aria-labelledby': 'more-button',
|
|
303
|
+
}}>
|
|
304
|
+
{!hidePrint &&
|
|
305
|
+
printArea(({ handlePrint }) => (
|
|
306
|
+
<MenuItem
|
|
307
|
+
onClick={() => {
|
|
308
|
+
setMenuIconEl(null);
|
|
309
|
+
handlePrint();
|
|
310
|
+
}}>
|
|
311
|
+
<ListItemIcon>
|
|
312
|
+
<PrintIcon fontSize="small" />
|
|
313
|
+
</ListItemIcon>
|
|
314
|
+
<ListItemText>{print}</ListItemText>
|
|
315
|
+
</MenuItem>
|
|
316
|
+
))}
|
|
317
|
+
{menuItems}
|
|
318
|
+
</Menu>
|
|
319
|
+
{allPops.map((e, index) => (
|
|
320
|
+
<div key={getPopId(index)}>{e}</div>
|
|
321
|
+
))}
|
|
322
|
+
{loading && <LinearProgress />}
|
|
323
|
+
</div>
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
CustomToolbar.propTypes = {
|
|
328
|
+
data: PropTypes.array,
|
|
329
|
+
options: PropTypes.object.isRequired,
|
|
330
|
+
components: PropTypes.object,
|
|
331
|
+
columns: PropTypes.array.isRequired,
|
|
332
|
+
filterList: PropTypes.array,
|
|
333
|
+
filterData: PropTypes.array,
|
|
334
|
+
filterUpdate: PropTypes.func.isRequired,
|
|
335
|
+
resetFilters: PropTypes.func.isRequired,
|
|
336
|
+
updateFilterByType: PropTypes.func.isRequired,
|
|
337
|
+
toggleViewColumn: PropTypes.func.isRequired,
|
|
338
|
+
updateColumns: PropTypes.func.isRequired,
|
|
339
|
+
title: PropTypes.any,
|
|
340
|
+
searchText: PropTypes.any,
|
|
341
|
+
searchTextUpdate: PropTypes.func.isRequired,
|
|
342
|
+
searchClose: PropTypes.func.isRequired,
|
|
343
|
+
tableRef: PropTypes.func.isRequired,
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
CustomToolbar.defaultProps = {
|
|
347
|
+
data: [],
|
|
348
|
+
components: {},
|
|
349
|
+
filterList: [],
|
|
350
|
+
filterData: [],
|
|
351
|
+
title: '',
|
|
352
|
+
searchText: null,
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
const Container = styled.div`
|
|
356
|
+
display: flex;
|
|
357
|
+
align-items: center;
|
|
358
|
+
height: 56px;
|
|
359
|
+
.custom-toobar-title {
|
|
360
|
+
position: relative;
|
|
361
|
+
flex: 1;
|
|
362
|
+
font-size: 18px;
|
|
363
|
+
font-weight: 800;
|
|
364
|
+
height: 56px;
|
|
365
|
+
transition: all ease 0.3s;
|
|
366
|
+
&-inner {
|
|
367
|
+
line-height: 56px;
|
|
368
|
+
width: 100%;
|
|
369
|
+
height: 56px;
|
|
370
|
+
position: absolute;
|
|
371
|
+
left: 0;
|
|
372
|
+
top: 0;
|
|
373
|
+
span {
|
|
374
|
+
display: inline-block;
|
|
375
|
+
max-width: 100%;
|
|
376
|
+
white-space: nowrap;
|
|
377
|
+
text-overflow: ellipsis;
|
|
378
|
+
overflow: hidden;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
.custom-toobar-btns {
|
|
383
|
+
display: flex;
|
|
384
|
+
justify-content: center;
|
|
385
|
+
align-items: center;
|
|
386
|
+
&.toobar-btns-disabled {
|
|
387
|
+
position: relative;
|
|
388
|
+
opacity: 0.5;
|
|
389
|
+
&:after {
|
|
390
|
+
position: absolute;
|
|
391
|
+
display: block;
|
|
392
|
+
z-index: 2;
|
|
393
|
+
width: 100%;
|
|
394
|
+
height: 100%;
|
|
395
|
+
left: 0;
|
|
396
|
+
top: 0;
|
|
397
|
+
content: '';
|
|
398
|
+
cursor: not-allowed;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
.toobar-title-hidden {
|
|
403
|
+
opacity: 0;
|
|
404
|
+
cursor: none;
|
|
405
|
+
}
|
|
406
|
+
`;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React, { createContext, useContext, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
const DatatableContext = createContext({});
|
|
4
|
+
|
|
5
|
+
const { Provider } = DatatableContext;
|
|
6
|
+
|
|
7
|
+
// eslint-disable-next-line react/prop-types
|
|
8
|
+
const DatatableProvide = ({ children }) => {
|
|
9
|
+
const [customButtons, setCustomButtons] = useState([]);
|
|
10
|
+
const [loading, setLoading] = useState(false);
|
|
11
|
+
const [disabled, setDisabled] = useState(false);
|
|
12
|
+
const [filterLabel, setFilterLabel] = useState('Filter');
|
|
13
|
+
|
|
14
|
+
const value = {
|
|
15
|
+
customButtons,
|
|
16
|
+
setCustomButtons,
|
|
17
|
+
filterLabel,
|
|
18
|
+
setFilterLabel,
|
|
19
|
+
loading,
|
|
20
|
+
setLoading,
|
|
21
|
+
disabled,
|
|
22
|
+
setDisabled,
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
return <Provider value={value}>{children}</Provider>;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
function useDatatableContext() {
|
|
29
|
+
return useContext(DatatableContext);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { DatatableProvide, useDatatableContext };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import IconButton from '@mui/material/IconButton';
|
|
4
|
+
import Tooltip from '@mui/material/Tooltip';
|
|
5
|
+
import SearchIcon from '@mui/icons-material/Search';
|
|
6
|
+
import TextField from '@mui/material/TextField';
|
|
7
|
+
import ClearIcon from '@mui/icons-material/Clear';
|
|
8
|
+
import styled from 'styled-components';
|
|
9
|
+
|
|
10
|
+
export default function TableSearch({
|
|
11
|
+
search,
|
|
12
|
+
options,
|
|
13
|
+
searchText,
|
|
14
|
+
searchTextUpdate,
|
|
15
|
+
searchClose,
|
|
16
|
+
onSearchOpen,
|
|
17
|
+
}) {
|
|
18
|
+
const [inputMode, setInputMode] = useState(false);
|
|
19
|
+
|
|
20
|
+
const clickSearchIcon = () => {
|
|
21
|
+
setInputMode(true);
|
|
22
|
+
onSearchOpen(true);
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const onChange = event => {
|
|
26
|
+
searchTextUpdate(event.currentTarget.value);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const clickClose = () => {
|
|
30
|
+
setInputMode(false);
|
|
31
|
+
searchClose();
|
|
32
|
+
onSearchOpen(false);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Container>
|
|
37
|
+
{inputMode ? (
|
|
38
|
+
<div className="toolbar-search-icon-placeholder">
|
|
39
|
+
<SearchIcon />
|
|
40
|
+
</div>
|
|
41
|
+
) : (
|
|
42
|
+
<Tooltip title={search} disableFocusListener>
|
|
43
|
+
<IconButton
|
|
44
|
+
aria-label={search}
|
|
45
|
+
data-testid={`${search}-iconButton`}
|
|
46
|
+
disabled={options.search === 'disabled'}
|
|
47
|
+
onClick={clickSearchIcon}>
|
|
48
|
+
<SearchIcon />
|
|
49
|
+
</IconButton>
|
|
50
|
+
</Tooltip>
|
|
51
|
+
)}
|
|
52
|
+
|
|
53
|
+
<div className={`toolbar-search-area ${inputMode ? 'toolbar-btn-show' : ''}`}>
|
|
54
|
+
{inputMode && (
|
|
55
|
+
<TextField
|
|
56
|
+
variant="standard"
|
|
57
|
+
spacing={2}
|
|
58
|
+
onChange={onChange}
|
|
59
|
+
value={searchText || ''}
|
|
60
|
+
autoFocus
|
|
61
|
+
/>
|
|
62
|
+
)}
|
|
63
|
+
</div>
|
|
64
|
+
<div className={`toolbar-search-close ${inputMode ? 'toolbar-btn-show' : ''}`}>
|
|
65
|
+
<IconButton onClick={clickClose}>
|
|
66
|
+
<ClearIcon />
|
|
67
|
+
</IconButton>
|
|
68
|
+
</div>
|
|
69
|
+
</Container>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
TableSearch.propTypes = {
|
|
74
|
+
search: PropTypes.string,
|
|
75
|
+
searchText: PropTypes.string,
|
|
76
|
+
onSearchOpen: PropTypes.func,
|
|
77
|
+
options: PropTypes.object.isRequired,
|
|
78
|
+
searchTextUpdate: PropTypes.func.isRequired,
|
|
79
|
+
searchClose: PropTypes.func.isRequired,
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
TableSearch.defaultProps = {
|
|
83
|
+
search: '',
|
|
84
|
+
searchText: '',
|
|
85
|
+
onSearchOpen: () => {},
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const Container = styled.div`
|
|
89
|
+
display: flex;
|
|
90
|
+
align-items: center;
|
|
91
|
+
.toolbar-search-area {
|
|
92
|
+
width: 0;
|
|
93
|
+
transition: all ease 0.3s;
|
|
94
|
+
overflow: hidden;
|
|
95
|
+
.MuiFormControl-root {
|
|
96
|
+
width: inherit;
|
|
97
|
+
margin: 0 12px;
|
|
98
|
+
}
|
|
99
|
+
&.toolbar-btn-show {
|
|
100
|
+
width: 260px;
|
|
101
|
+
padding-left: 8px;
|
|
102
|
+
|
|
103
|
+
${props => props.theme.breakpoints.down('md')} {
|
|
104
|
+
width: 200px;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
${props => props.theme.breakpoints.down('sm')} {
|
|
108
|
+
width: 180px;
|
|
109
|
+
}
|
|
110
|
+
&.small-textfield {
|
|
111
|
+
width: 200px;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
.toolbar-search-close {
|
|
116
|
+
width: 0;
|
|
117
|
+
transition: all ease 0.3s;
|
|
118
|
+
overflow: hidden;
|
|
119
|
+
&.toolbar-btn-show {
|
|
120
|
+
width: 40px;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
.toolbar-search-icon-placeholder {
|
|
124
|
+
display: flex;
|
|
125
|
+
justify-content: center;
|
|
126
|
+
align-items: center;
|
|
127
|
+
width: 40px;
|
|
128
|
+
height: 40px;
|
|
129
|
+
}
|
|
130
|
+
`;
|