jattac.libs.web.responsive-table 0.2.13 → 0.2.15
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/README.md +661 -637
- package/dist/UI/InfiniteTable.d.ts +75 -0
- package/dist/index.js +359 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import React, { Component, ReactNode } from 'react';
|
|
2
|
+
import { IResponsiveTableColumnDefinition } from '../Data/IResponsiveTableColumnDefinition';
|
|
3
|
+
import IFooterRowDefinition from '../Data/IFooterRowDefinition';
|
|
4
|
+
import { IResponsiveTablePlugin } from '../Plugins/IResponsiveTablePlugin';
|
|
5
|
+
export type ColumnDefinition<TData> = IResponsiveTableColumnDefinition<TData> | ((data: TData, rowIndex?: number) => IResponsiveTableColumnDefinition<TData>);
|
|
6
|
+
interface IProps<TData> {
|
|
7
|
+
columnDefinitions: ColumnDefinition<TData>[];
|
|
8
|
+
data: TData[];
|
|
9
|
+
noDataComponent?: ReactNode;
|
|
10
|
+
maxHeight?: string;
|
|
11
|
+
onRowClick?: (item: TData) => void;
|
|
12
|
+
footerRows?: IFooterRowDefinition[];
|
|
13
|
+
mobileBreakpoint?: number;
|
|
14
|
+
plugins?: IResponsiveTablePlugin<TData>[];
|
|
15
|
+
enablePageLevelStickyHeader?: boolean;
|
|
16
|
+
infiniteScrollProps?: {
|
|
17
|
+
enableInfiniteScroll?: boolean;
|
|
18
|
+
onLoadMore?: (currentData: TData[]) => Promise<TData[] | null>;
|
|
19
|
+
hasMore?: boolean;
|
|
20
|
+
loadingMoreComponent?: ReactNode;
|
|
21
|
+
noMoreDataComponent?: ReactNode;
|
|
22
|
+
};
|
|
23
|
+
filterProps?: {
|
|
24
|
+
showFilter?: boolean;
|
|
25
|
+
filterPlaceholder?: string;
|
|
26
|
+
};
|
|
27
|
+
animationProps?: {
|
|
28
|
+
isLoading?: boolean;
|
|
29
|
+
animateOnLoad?: boolean;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
interface IState<TData> {
|
|
33
|
+
isMobile: boolean;
|
|
34
|
+
processedData: TData[];
|
|
35
|
+
isLoadingMore: boolean;
|
|
36
|
+
isHeaderSticky: boolean;
|
|
37
|
+
columnWidths: number[];
|
|
38
|
+
}
|
|
39
|
+
declare class InfiniteTable<TData> extends Component<IProps<TData>, IState<TData>> {
|
|
40
|
+
private debouncedResize;
|
|
41
|
+
private tableContainerRef;
|
|
42
|
+
private headerRef;
|
|
43
|
+
private resizeObserver;
|
|
44
|
+
constructor(props: IProps<TData>);
|
|
45
|
+
private get mobileBreakpoint();
|
|
46
|
+
private debounce;
|
|
47
|
+
private get data();
|
|
48
|
+
private get noDataSvg();
|
|
49
|
+
private get hasData();
|
|
50
|
+
private get noDataComponent();
|
|
51
|
+
componentDidMount(): void;
|
|
52
|
+
componentWillUnmount(): void;
|
|
53
|
+
componentDidUpdate(prevProps: IProps<TData>): void;
|
|
54
|
+
private measureHeader;
|
|
55
|
+
private handleScroll;
|
|
56
|
+
private initializePlugins;
|
|
57
|
+
private processData;
|
|
58
|
+
handleResize: () => void;
|
|
59
|
+
private getColumnDefinition;
|
|
60
|
+
private getRawColumnDefinition;
|
|
61
|
+
private onHeaderClickCallback;
|
|
62
|
+
private getClickableHeaderClassName;
|
|
63
|
+
private getHeaderProps;
|
|
64
|
+
private get rowClickFunction();
|
|
65
|
+
private get rowClickStyle();
|
|
66
|
+
private get tableFooter();
|
|
67
|
+
private get mobileFooter();
|
|
68
|
+
private get skeletonView();
|
|
69
|
+
private get mobileView();
|
|
70
|
+
private get largeScreenView();
|
|
71
|
+
private renderPluginHeaders;
|
|
72
|
+
private renderPluginFooters;
|
|
73
|
+
render(): string | number | boolean | Iterable<React.ReactNode> | React.JSX.Element | null | undefined;
|
|
74
|
+
}
|
|
75
|
+
export default InfiniteTable;
|
package/dist/index.js
CHANGED
|
@@ -980,11 +980,21 @@ var FixedSizeList = /*#__PURE__*/createListComponent({
|
|
|
980
980
|
});
|
|
981
981
|
|
|
982
982
|
// Class component
|
|
983
|
-
class
|
|
983
|
+
class InfiniteTable extends React.Component {
|
|
984
984
|
constructor(props) {
|
|
985
985
|
super(props);
|
|
986
986
|
this.tableContainerRef = React.createRef();
|
|
987
987
|
this.headerRef = React.createRef();
|
|
988
|
+
this.resizeObserver = null;
|
|
989
|
+
this.measureHeader = () => {
|
|
990
|
+
if (this.headerRef.current) {
|
|
991
|
+
const ths = Array.from(this.headerRef.current.querySelectorAll('th'));
|
|
992
|
+
const widths = ths.map((th) => th.getBoundingClientRect().width);
|
|
993
|
+
if (widths.some((w) => w > 0)) {
|
|
994
|
+
this.setState({ columnWidths: widths });
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
};
|
|
988
998
|
this.handleScroll = () => {
|
|
989
999
|
if (this.headerRef.current && !this.props.maxHeight) {
|
|
990
1000
|
const { top } = this.headerRef.current.getBoundingClientRect();
|
|
@@ -1004,6 +1014,7 @@ class ResponsiveTable extends React.Component {
|
|
|
1004
1014
|
processedData: props.data,
|
|
1005
1015
|
isLoadingMore: false,
|
|
1006
1016
|
isHeaderSticky: false,
|
|
1017
|
+
columnWidths: [],
|
|
1007
1018
|
};
|
|
1008
1019
|
this.debouncedResize = this.debounce(this.handleResize, 200);
|
|
1009
1020
|
}
|
|
@@ -1044,18 +1055,29 @@ class ResponsiveTable extends React.Component {
|
|
|
1044
1055
|
window.addEventListener('scroll', this.handleScroll);
|
|
1045
1056
|
}
|
|
1046
1057
|
this.initializePlugins();
|
|
1058
|
+
if (this.headerRef.current) {
|
|
1059
|
+
this.measureHeader();
|
|
1060
|
+
this.resizeObserver = new ResizeObserver(this.measureHeader);
|
|
1061
|
+
this.resizeObserver.observe(this.headerRef.current);
|
|
1062
|
+
}
|
|
1047
1063
|
}
|
|
1048
1064
|
componentWillUnmount() {
|
|
1049
1065
|
window.removeEventListener('resize', this.debouncedResize);
|
|
1050
1066
|
if (this.props.enablePageLevelStickyHeader !== false) {
|
|
1051
1067
|
window.removeEventListener('scroll', this.handleScroll);
|
|
1052
1068
|
}
|
|
1069
|
+
if (this.resizeObserver && this.headerRef.current) {
|
|
1070
|
+
this.resizeObserver.unobserve(this.headerRef.current);
|
|
1071
|
+
}
|
|
1053
1072
|
}
|
|
1054
1073
|
componentDidUpdate(prevProps) {
|
|
1055
1074
|
var _a, _b, _c;
|
|
1056
1075
|
if (prevProps.data !== this.props.data) {
|
|
1057
1076
|
this.processData();
|
|
1058
1077
|
}
|
|
1078
|
+
if (prevProps.columnDefinitions.length !== this.props.columnDefinitions.length) {
|
|
1079
|
+
this.measureHeader();
|
|
1080
|
+
}
|
|
1059
1081
|
// Handle infinite scroll loading
|
|
1060
1082
|
if (((_a = this.props.infiniteScrollProps) === null || _a === void 0 ? void 0 : _a.enableInfiniteScroll) && ((_b = this.props.infiniteScrollProps) === null || _b === void 0 ? void 0 : _b.hasMore) && !this.state.isLoadingMore && ((_c = this.props.infiniteScrollProps) === null || _c === void 0 ? void 0 : _c.onLoadMore)) ;
|
|
1061
1083
|
}
|
|
@@ -1229,19 +1251,340 @@ class ResponsiveTable extends React.Component {
|
|
|
1229
1251
|
this.mobileFooter));
|
|
1230
1252
|
}
|
|
1231
1253
|
get largeScreenView() {
|
|
1232
|
-
var _a;
|
|
1233
1254
|
const useFixedHeaders = this.props.maxHeight ? true : false;
|
|
1234
1255
|
const fixedHeadersStyle = useFixedHeaders
|
|
1235
1256
|
? { maxHeight: this.props.maxHeight, overflowY: 'auto' }
|
|
1236
1257
|
: {};
|
|
1237
|
-
const
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1258
|
+
const itemData = {
|
|
1259
|
+
rows: this.data,
|
|
1260
|
+
columnWidths: this.state.columnWidths,
|
|
1261
|
+
columnDefinitions: this.props.columnDefinitions,
|
|
1262
|
+
animationProps: this.props.animationProps,
|
|
1263
|
+
getColumnDefinition: this.getColumnDefinition.bind(this),
|
|
1264
|
+
rowClickFunction: this.rowClickFunction,
|
|
1265
|
+
rowClickStyle: this.rowClickStyle,
|
|
1266
|
+
};
|
|
1267
|
+
return (React.createElement("div", { style: fixedHeadersStyle, ref: this.tableContainerRef },
|
|
1268
|
+
React.createElement("table", { className: styles['responsiveTable'], style: { tableLayout: 'fixed' } },
|
|
1269
|
+
React.createElement("thead", { ref: this.headerRef, className: this.state.isHeaderSticky ? styles.stickyHeader : '' },
|
|
1270
|
+
React.createElement("tr", null, this.props.columnDefinitions.map((columnDefinition, colIndex) => {
|
|
1271
|
+
const onHeaderClickCallback = this.onHeaderClickCallback(columnDefinition);
|
|
1272
|
+
const clickableHeaderClassName = this.getClickableHeaderClassName(onHeaderClickCallback, columnDefinition);
|
|
1273
|
+
const headerProps = this.getHeaderProps(columnDefinition);
|
|
1274
|
+
// Combine class names: existing clickable, and plugin-provided (mapped to CSS Modules)
|
|
1275
|
+
const combinedClassName = `${clickableHeaderClassName} ${headerProps.className ? styles[headerProps.className] : ''}`.trim();
|
|
1276
|
+
// Remove className from headerProps to avoid duplication
|
|
1277
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1278
|
+
const { className } = headerProps, restHeaderProps = __rest(headerProps, ["className"]);
|
|
1279
|
+
return (React.createElement("th", Object.assign({ key: colIndex, className: combinedClassName }, restHeaderProps, { style: { width: this.state.columnWidths[colIndex], boxSizing: 'border-box' } }),
|
|
1280
|
+
React.createElement("div", { className: styles.headerInnerWrapper },
|
|
1281
|
+
React.createElement("div", { className: styles.headerContent }, this.getColumnDefinition(columnDefinition, 0).displayLabel),
|
|
1282
|
+
React.createElement("span", { className: styles.sortIcon }))));
|
|
1283
|
+
}))),
|
|
1284
|
+
React.createElement(FixedSizeList, { height: fixedHeadersStyle.maxHeight ? (typeof fixedHeadersStyle.maxHeight === 'string' ? parseFloat(fixedHeadersStyle.maxHeight) : fixedHeadersStyle.maxHeight) : 500, itemCount: this.data.length, itemSize: 50, width: '100%', itemData: itemData, outerRef: this.tableContainerRef, outerElementType: React.forwardRef((props, ref) => React.createElement("tbody", Object.assign({ ref: ref }, props))) }, ({ index, style, data }) => {
|
|
1285
|
+
const { rows, columnWidths, getColumnDefinition, rowClickFunction, rowClickStyle, columnDefinitions, animationProps, } = data;
|
|
1286
|
+
const row = rows[index];
|
|
1287
|
+
if (!row)
|
|
1288
|
+
return null;
|
|
1289
|
+
return (React.createElement("tr", { key: index, className: (animationProps === null || animationProps === void 0 ? void 0 : animationProps.animateOnLoad) ? styles.animatedRow : '', style: Object.assign(Object.assign({}, style), { animationDelay: `${index * 0.05}s` }) }, columnDefinitions.map((columnDefinition, colIndex) => (React.createElement("td", { onClick: () => rowClickFunction(row), key: colIndex, style: { width: columnWidths[colIndex], boxSizing: 'border-box' } },
|
|
1290
|
+
React.createElement("span", { style: Object.assign({}, rowClickStyle) }, getColumnDefinition(columnDefinition, index).cellRenderer(row)))))));
|
|
1291
|
+
}),
|
|
1292
|
+
this.tableFooter),
|
|
1293
|
+
this.renderPluginFooters()));
|
|
1294
|
+
}
|
|
1295
|
+
renderPluginHeaders() {
|
|
1296
|
+
if (!this.props.plugins) {
|
|
1297
|
+
return null;
|
|
1298
|
+
}
|
|
1299
|
+
return this.props.plugins.map((plugin) => {
|
|
1300
|
+
if (plugin.renderHeader) {
|
|
1301
|
+
// For sort plugin, only render header in mobile view
|
|
1302
|
+
if (plugin.id === 'sort' && !this.state.isMobile) {
|
|
1303
|
+
return null;
|
|
1304
|
+
}
|
|
1305
|
+
return React.createElement("div", { key: plugin.id }, plugin.renderHeader());
|
|
1306
|
+
}
|
|
1307
|
+
return null;
|
|
1308
|
+
});
|
|
1309
|
+
}
|
|
1310
|
+
renderPluginFooters() {
|
|
1311
|
+
if (!this.props.plugins) {
|
|
1312
|
+
return null;
|
|
1313
|
+
}
|
|
1314
|
+
return this.props.plugins.map((plugin) => {
|
|
1315
|
+
if (plugin.renderFooter) {
|
|
1316
|
+
return React.createElement("div", { key: plugin.id + '-footer' }, plugin.renderFooter());
|
|
1317
|
+
}
|
|
1318
|
+
return null;
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
render() {
|
|
1322
|
+
var _a;
|
|
1323
|
+
if ((_a = this.props.animationProps) === null || _a === void 0 ? void 0 : _a.isLoading) {
|
|
1324
|
+
return this.skeletonView;
|
|
1325
|
+
}
|
|
1326
|
+
return (React.createElement("div", null,
|
|
1327
|
+
this.renderPluginHeaders(),
|
|
1328
|
+
!this.hasData && this.noDataComponent,
|
|
1329
|
+
this.hasData && this.state.isMobile && this.mobileView,
|
|
1330
|
+
this.hasData && !this.state.isMobile && this.largeScreenView));
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
|
|
1334
|
+
// Class component
|
|
1335
|
+
class ResponsiveTable extends React.Component {
|
|
1336
|
+
constructor(props) {
|
|
1337
|
+
super(props);
|
|
1338
|
+
this.tableContainerRef = React.createRef();
|
|
1339
|
+
this.headerRef = React.createRef();
|
|
1340
|
+
this.handleScroll = () => {
|
|
1341
|
+
if (this.headerRef.current && !this.props.maxHeight) {
|
|
1342
|
+
const { top } = this.headerRef.current.getBoundingClientRect();
|
|
1343
|
+
const isSticky = top <= 0;
|
|
1344
|
+
if (isSticky !== this.state.isHeaderSticky) {
|
|
1345
|
+
this.setState({ isHeaderSticky: isSticky });
|
|
1346
|
+
}
|
|
1347
|
+
}
|
|
1244
1348
|
};
|
|
1349
|
+
this.handleResize = () => {
|
|
1350
|
+
this.setState({
|
|
1351
|
+
isMobile: window.innerWidth <= this.mobileBreakpoint,
|
|
1352
|
+
});
|
|
1353
|
+
};
|
|
1354
|
+
this.state = {
|
|
1355
|
+
isMobile: false,
|
|
1356
|
+
processedData: props.data,
|
|
1357
|
+
isLoadingMore: false,
|
|
1358
|
+
isHeaderSticky: false,
|
|
1359
|
+
};
|
|
1360
|
+
this.debouncedResize = this.debounce(this.handleResize, 200);
|
|
1361
|
+
}
|
|
1362
|
+
get mobileBreakpoint() {
|
|
1363
|
+
return this.props.mobileBreakpoint || 600;
|
|
1364
|
+
}
|
|
1365
|
+
debounce(func, delay) {
|
|
1366
|
+
let timeout;
|
|
1367
|
+
return () => {
|
|
1368
|
+
clearTimeout(timeout);
|
|
1369
|
+
timeout = setTimeout(() => func(), delay);
|
|
1370
|
+
};
|
|
1371
|
+
}
|
|
1372
|
+
get data() {
|
|
1373
|
+
if (Array.isArray(this.state.processedData) && this.state.processedData.length > 0) {
|
|
1374
|
+
return this.state.processedData;
|
|
1375
|
+
}
|
|
1376
|
+
else {
|
|
1377
|
+
return [];
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
get noDataSvg() {
|
|
1381
|
+
return (React.createElement("svg", { xmlns: "http://www.w3.org/2000/svg", fill: "#ccc", height: "40", width: "40", viewBox: "0 0 24 24" },
|
|
1382
|
+
React.createElement("path", { d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1-14h2v6h-2zm0 8h2v2h-2z" })));
|
|
1383
|
+
}
|
|
1384
|
+
get hasData() {
|
|
1385
|
+
return this.data.length > 0;
|
|
1386
|
+
}
|
|
1387
|
+
get noDataComponent() {
|
|
1388
|
+
return (this.props.noDataComponent || (React.createElement("div", { className: styles.noDataWrapper },
|
|
1389
|
+
this.noDataSvg,
|
|
1390
|
+
React.createElement("div", { className: styles.noData }, "No data"))));
|
|
1391
|
+
}
|
|
1392
|
+
componentDidMount() {
|
|
1393
|
+
this.handleResize(); // Initial check
|
|
1394
|
+
window.addEventListener('resize', this.debouncedResize);
|
|
1395
|
+
if (this.props.enablePageLevelStickyHeader !== false) {
|
|
1396
|
+
window.addEventListener('scroll', this.handleScroll);
|
|
1397
|
+
}
|
|
1398
|
+
this.initializePlugins();
|
|
1399
|
+
}
|
|
1400
|
+
componentWillUnmount() {
|
|
1401
|
+
window.removeEventListener('resize', this.debouncedResize);
|
|
1402
|
+
if (this.props.enablePageLevelStickyHeader !== false) {
|
|
1403
|
+
window.removeEventListener('scroll', this.handleScroll);
|
|
1404
|
+
}
|
|
1405
|
+
}
|
|
1406
|
+
componentDidUpdate(prevProps) {
|
|
1407
|
+
var _a, _b, _c;
|
|
1408
|
+
if (prevProps.data !== this.props.data) {
|
|
1409
|
+
this.processData();
|
|
1410
|
+
}
|
|
1411
|
+
// Handle infinite scroll loading
|
|
1412
|
+
if (((_a = this.props.infiniteScrollProps) === null || _a === void 0 ? void 0 : _a.enableInfiniteScroll) && ((_b = this.props.infiniteScrollProps) === null || _b === void 0 ? void 0 : _b.hasMore) && !this.state.isLoadingMore && ((_c = this.props.infiniteScrollProps) === null || _c === void 0 ? void 0 : _c.onLoadMore)) ;
|
|
1413
|
+
}
|
|
1414
|
+
initializePlugins() {
|
|
1415
|
+
var _a, _b;
|
|
1416
|
+
const activePlugins = [];
|
|
1417
|
+
// Add explicitly provided plugins first
|
|
1418
|
+
if (this.props.plugins) {
|
|
1419
|
+
activePlugins.push(...this.props.plugins);
|
|
1420
|
+
}
|
|
1421
|
+
// Automatically add FilterPlugin if filterProps are provided and not already present
|
|
1422
|
+
if (((_a = this.props.filterProps) === null || _a === void 0 ? void 0 : _a.showFilter) && !activePlugins.some(p => p.id === 'filter')) {
|
|
1423
|
+
activePlugins.push(new FilterPlugin());
|
|
1424
|
+
}
|
|
1425
|
+
// Automatically add InfiniteScrollPlugin if infiniteScrollProps are provided and not already present
|
|
1426
|
+
if (((_b = this.props.infiniteScrollProps) === null || _b === void 0 ? void 0 : _b.enableInfiniteScroll) && !activePlugins.some(p => p.id === 'infinite-scroll')) {
|
|
1427
|
+
activePlugins.push(new InfiniteScrollPlugin());
|
|
1428
|
+
}
|
|
1429
|
+
activePlugins.forEach((plugin) => {
|
|
1430
|
+
if (plugin.onPluginInit) {
|
|
1431
|
+
plugin.onPluginInit({
|
|
1432
|
+
getData: () => this.props.data,
|
|
1433
|
+
forceUpdate: () => this.processData(),
|
|
1434
|
+
getScrollableElement: () => this.tableContainerRef.current,
|
|
1435
|
+
infiniteScrollProps: this.props.infiniteScrollProps,
|
|
1436
|
+
filterProps: this.props.filterProps,
|
|
1437
|
+
columnDefinitions: this.props.columnDefinitions,
|
|
1438
|
+
});
|
|
1439
|
+
}
|
|
1440
|
+
});
|
|
1441
|
+
// Process data with all active plugins
|
|
1442
|
+
let processedData = [...this.props.data];
|
|
1443
|
+
activePlugins.forEach((plugin) => {
|
|
1444
|
+
if (plugin.processData) {
|
|
1445
|
+
processedData = plugin.processData(processedData);
|
|
1446
|
+
}
|
|
1447
|
+
});
|
|
1448
|
+
this.setState({ processedData });
|
|
1449
|
+
}
|
|
1450
|
+
processData() {
|
|
1451
|
+
let processedData = [...this.props.data];
|
|
1452
|
+
if (this.props.plugins) {
|
|
1453
|
+
this.props.plugins.forEach((plugin) => {
|
|
1454
|
+
if (plugin.processData) {
|
|
1455
|
+
processedData = plugin.processData(processedData);
|
|
1456
|
+
}
|
|
1457
|
+
});
|
|
1458
|
+
}
|
|
1459
|
+
this.setState({ processedData });
|
|
1460
|
+
}
|
|
1461
|
+
getColumnDefinition(columnDefinition, rowIndex) {
|
|
1462
|
+
if (!this.hasData) {
|
|
1463
|
+
return { displayLabel: '', cellRenderer: () => '' };
|
|
1464
|
+
}
|
|
1465
|
+
return columnDefinition instanceof Function ? columnDefinition(this.data[0], rowIndex) : columnDefinition;
|
|
1466
|
+
}
|
|
1467
|
+
getRawColumnDefinition(columnDefinition) {
|
|
1468
|
+
let rawColumnDefinition = {};
|
|
1469
|
+
if (columnDefinition instanceof Function) {
|
|
1470
|
+
rawColumnDefinition = columnDefinition(this.data[0], 0);
|
|
1471
|
+
}
|
|
1472
|
+
else {
|
|
1473
|
+
rawColumnDefinition = columnDefinition;
|
|
1474
|
+
}
|
|
1475
|
+
return rawColumnDefinition;
|
|
1476
|
+
}
|
|
1477
|
+
onHeaderClickCallback(columnDefinition) {
|
|
1478
|
+
const rawColumnDefinition = this.getRawColumnDefinition(columnDefinition);
|
|
1479
|
+
if (rawColumnDefinition.interactivity && rawColumnDefinition.interactivity.onHeaderClick) {
|
|
1480
|
+
return rawColumnDefinition.interactivity.onHeaderClick;
|
|
1481
|
+
}
|
|
1482
|
+
else {
|
|
1483
|
+
return undefined;
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1486
|
+
getClickableHeaderClassName(onHeaderClickCallback, colDef) {
|
|
1487
|
+
const rawColumnDefinition = this.getRawColumnDefinition(colDef);
|
|
1488
|
+
const clickableHeaderClassName = onHeaderClickCallback
|
|
1489
|
+
? rawColumnDefinition.interactivity.className || styles.clickableHeader
|
|
1490
|
+
: '';
|
|
1491
|
+
return clickableHeaderClassName;
|
|
1492
|
+
}
|
|
1493
|
+
getHeaderProps(columnDefinition) {
|
|
1494
|
+
const headerProps = {};
|
|
1495
|
+
if (this.props.plugins) {
|
|
1496
|
+
this.props.plugins.forEach((plugin) => {
|
|
1497
|
+
if (plugin.getHeaderProps) {
|
|
1498
|
+
Object.assign(headerProps, plugin.getHeaderProps(this.getRawColumnDefinition(columnDefinition)));
|
|
1499
|
+
}
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1502
|
+
return headerProps;
|
|
1503
|
+
}
|
|
1504
|
+
get rowClickFunction() {
|
|
1505
|
+
if (this.props.onRowClick) {
|
|
1506
|
+
return this.props.onRowClick;
|
|
1507
|
+
}
|
|
1508
|
+
else {
|
|
1509
|
+
return () => { };
|
|
1510
|
+
}
|
|
1511
|
+
}
|
|
1512
|
+
get rowClickStyle() {
|
|
1513
|
+
if (this.props.onRowClick) {
|
|
1514
|
+
return { cursor: 'pointer' };
|
|
1515
|
+
}
|
|
1516
|
+
else {
|
|
1517
|
+
return {};
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
get tableFooter() {
|
|
1521
|
+
if (!this.props.footerRows || this.props.footerRows.length === 0) {
|
|
1522
|
+
return null;
|
|
1523
|
+
}
|
|
1524
|
+
return (React.createElement("tfoot", null, this.props.footerRows.map((row, rowIndex) => (React.createElement("tr", { key: rowIndex }, row.columns.map((col, colIndex) => (React.createElement("td", { key: colIndex, colSpan: col.colSpan, className: `${styles.footerCell} ${col.className || ''} ${col.onCellClick ? styles.clickableFooterCell : ''}`, onClick: col.onCellClick }, col.cellRenderer()))))))));
|
|
1525
|
+
}
|
|
1526
|
+
get mobileFooter() {
|
|
1527
|
+
if (!this.props.footerRows || this.props.footerRows.length === 0) {
|
|
1528
|
+
return null;
|
|
1529
|
+
}
|
|
1530
|
+
return (React.createElement("div", { className: styles.footerCard },
|
|
1531
|
+
React.createElement("div", { className: styles['footer-card-body'] }, this.props.footerRows.map((row, rowIndex) => {
|
|
1532
|
+
let currentColumnIndex = 0;
|
|
1533
|
+
return (React.createElement("div", { key: rowIndex }, row.columns.map((col, colIndex) => {
|
|
1534
|
+
let label = col.displayLabel;
|
|
1535
|
+
if (!label && col.colSpan === 1) {
|
|
1536
|
+
const header = this.props.columnDefinitions[currentColumnIndex];
|
|
1537
|
+
if (header) {
|
|
1538
|
+
label = this.getRawColumnDefinition(header).displayLabel;
|
|
1539
|
+
}
|
|
1540
|
+
}
|
|
1541
|
+
currentColumnIndex += col.colSpan;
|
|
1542
|
+
return (React.createElement("p", { key: colIndex, className: `${styles['footer-card-row']} ${col.className || ''} ${col.onCellClick ? styles.clickableFooterCell : ''}`, onClick: col.onCellClick },
|
|
1543
|
+
label && React.createElement("span", { className: styles['card-label'] }, label),
|
|
1544
|
+
React.createElement("span", { className: styles['card-value'] }, col.cellRenderer())));
|
|
1545
|
+
})));
|
|
1546
|
+
}))));
|
|
1547
|
+
}
|
|
1548
|
+
get skeletonView() {
|
|
1549
|
+
const skeletonRowCount = 5; // Or make this configurable
|
|
1550
|
+
const columnCount = this.props.columnDefinitions.length;
|
|
1551
|
+
if (this.state.isMobile) {
|
|
1552
|
+
return (React.createElement("div", null, [...Array(skeletonRowCount)].map((_, i) => (React.createElement("div", { key: i, className: styles.skeletonCard }, [...Array(columnCount)].map((_, j) => (React.createElement("div", { key: j, className: `${styles.skeleton} ${styles.skeletonText}`, style: { marginBottom: '0.5rem' } }))))))));
|
|
1553
|
+
}
|
|
1554
|
+
return (React.createElement("table", { className: styles.responsiveTable },
|
|
1555
|
+
React.createElement("thead", null,
|
|
1556
|
+
React.createElement("tr", null, [...Array(columnCount)].map((_, i) => (React.createElement("th", { key: i },
|
|
1557
|
+
React.createElement("div", { className: `${styles.skeleton} ${styles.skeletonText}` })))))),
|
|
1558
|
+
React.createElement("tbody", null, [...Array(skeletonRowCount)].map((_, i) => (React.createElement("tr", { key: i }, [...Array(columnCount)].map((_, j) => (React.createElement("td", { key: j },
|
|
1559
|
+
React.createElement("div", { className: `${styles.skeleton} ${styles.skeletonText}` }))))))))));
|
|
1560
|
+
}
|
|
1561
|
+
get mobileView() {
|
|
1562
|
+
return (React.createElement("div", null,
|
|
1563
|
+
this.data.map((row, rowIndex) => {
|
|
1564
|
+
var _a;
|
|
1565
|
+
return (React.createElement("div", { key: rowIndex, className: `${styles['card']} ${((_a = this.props.animationProps) === null || _a === void 0 ? void 0 : _a.animateOnLoad) ? styles.animatedRow : ''}`, style: { animationDelay: `${rowIndex * 0.05}s` }, onClick: (e) => {
|
|
1566
|
+
this.rowClickFunction(row);
|
|
1567
|
+
e.stopPropagation();
|
|
1568
|
+
e.preventDefault();
|
|
1569
|
+
} },
|
|
1570
|
+
React.createElement("div", { className: styles['card-header'] }, " "),
|
|
1571
|
+
React.createElement("div", { className: styles['card-body'] }, this.props.columnDefinitions.map((columnDefinition, colIndex) => {
|
|
1572
|
+
const colDef = this.getColumnDefinition(columnDefinition, rowIndex);
|
|
1573
|
+
const onHeaderClickCallback = this.onHeaderClickCallback(colDef);
|
|
1574
|
+
const clickableHeaderClassName = this.getClickableHeaderClassName(onHeaderClickCallback, colDef);
|
|
1575
|
+
return (React.createElement("div", { key: colIndex, className: styles['card-row'] },
|
|
1576
|
+
React.createElement("p", null,
|
|
1577
|
+
React.createElement("span", { className: `${styles['card-label']} ${clickableHeaderClassName}`, onClick: onHeaderClickCallback ? () => onHeaderClickCallback(colDef.interactivity.id) : undefined }, colDef.displayLabel),
|
|
1578
|
+
React.createElement("span", { className: styles['card-value'] }, colDef.cellRenderer(row)))));
|
|
1579
|
+
}))));
|
|
1580
|
+
}),
|
|
1581
|
+
this.mobileFooter));
|
|
1582
|
+
}
|
|
1583
|
+
get largeScreenView() {
|
|
1584
|
+
const useFixedHeaders = this.props.maxHeight ? true : false;
|
|
1585
|
+
const fixedHeadersStyle = useFixedHeaders
|
|
1586
|
+
? { maxHeight: this.props.maxHeight, overflowY: 'auto' }
|
|
1587
|
+
: {};
|
|
1245
1588
|
return (React.createElement("div", { style: fixedHeadersStyle, ref: this.tableContainerRef },
|
|
1246
1589
|
React.createElement("table", { className: styles['responsiveTable'] },
|
|
1247
1590
|
React.createElement("thead", { ref: this.headerRef, className: this.state.isHeaderSticky ? styles.stickyHeader : '' },
|
|
@@ -1259,11 +1602,11 @@ class ResponsiveTable extends React.Component {
|
|
|
1259
1602
|
React.createElement("div", { className: styles.headerContent }, this.getColumnDefinition(columnDefinition, 0).displayLabel),
|
|
1260
1603
|
React.createElement("span", { className: styles.sortIcon }))));
|
|
1261
1604
|
}))),
|
|
1262
|
-
|
|
1605
|
+
React.createElement("tbody", null, this.data.map((row, rowIndex) => {
|
|
1263
1606
|
var _a;
|
|
1264
1607
|
return (React.createElement("tr", { key: rowIndex, className: ((_a = this.props.animationProps) === null || _a === void 0 ? void 0 : _a.animateOnLoad) ? styles.animatedRow : '', style: { animationDelay: `${rowIndex * 0.05}s` } }, this.props.columnDefinitions.map((columnDefinition, colIndex) => (React.createElement("td", { onClick: () => this.rowClickFunction(row), key: colIndex },
|
|
1265
1608
|
React.createElement("span", { style: Object.assign({}, this.rowClickStyle) }, this.getColumnDefinition(columnDefinition, rowIndex).cellRenderer(row)))))));
|
|
1266
|
-
}))
|
|
1609
|
+
})),
|
|
1267
1610
|
this.tableFooter),
|
|
1268
1611
|
this.renderPluginFooters()));
|
|
1269
1612
|
}
|
|
@@ -1294,8 +1637,11 @@ class ResponsiveTable extends React.Component {
|
|
|
1294
1637
|
});
|
|
1295
1638
|
}
|
|
1296
1639
|
render() {
|
|
1297
|
-
var _a;
|
|
1298
|
-
if ((_a = this.props.
|
|
1640
|
+
var _a, _b;
|
|
1641
|
+
if ((_a = this.props.infiniteScrollProps) === null || _a === void 0 ? void 0 : _a.enableInfiniteScroll) {
|
|
1642
|
+
return React.createElement(InfiniteTable, Object.assign({}, this.props));
|
|
1643
|
+
}
|
|
1644
|
+
if ((_b = this.props.animationProps) === null || _b === void 0 ? void 0 : _b.isLoading) {
|
|
1299
1645
|
return this.skeletonView;
|
|
1300
1646
|
}
|
|
1301
1647
|
return (React.createElement("div", null,
|