qbs-react-grid 2.0.2 → 2.0.4

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/es/Table.d.ts CHANGED
@@ -96,9 +96,12 @@ export interface TableProps<Row, Key> extends Omit<StandardProps, 'onScroll'> {
96
96
  virtualized?: boolean;
97
97
  /**Theme Change */
98
98
  dataTheme?: string;
99
+ /** Refresh Row */
100
+ refreshRow?: number;
99
101
  /** Tree table, the callback function in the expanded node */
100
102
  renderTreeToggle?: (expandButton: React.ReactNode, rowData?: Row, expanded?: boolean) => React.ReactNode;
101
103
  tableKey?: string;
104
+ infiniteLoading?: boolean;
102
105
  /** Customize what you can do to expand a zone */
103
106
  renderRowExpanded?: (rowData?: Row) => React.ReactNode;
104
107
  /** Custom row element */
@@ -123,6 +126,7 @@ export interface TableProps<Row, Key> extends Omit<StandardProps, 'onScroll'> {
123
126
  onTouchMove?: (event: React.TouchEvent) => void;
124
127
  /** Callback for the `touchend` event. */
125
128
  onTouchEnd?: (event: React.TouchEvent) => void;
129
+ handleInfiniteScroll?: (value: number) => void;
126
130
  /**
127
131
  * Callback after table data update.
128
132
  * @deprecated use `shouldUpdateScroll` instead
@@ -132,6 +136,7 @@ export interface TableProps<Row, Key> extends Omit<StandardProps, 'onScroll'> {
132
136
  y: number;
133
137
  }) => void) => void;
134
138
  tableBodyRef: React.RefObject<HTMLDivElement>;
139
+ wheelWrapperRef: React.RefObject<HTMLDivElement | null>;
135
140
  bodyRef?: (ref: HTMLElement) => void;
136
141
  }
137
142
  export interface TableInstance<Row, Key> extends React.FunctionComponent<TableProps<Row, Key>> {
package/es/Table.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/esm/extends";
2
2
  import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
3
- var _excluded = ["affixHeader", "children", "classPrefix", "className", "data", "defaultSortType", "width", "expandedRowKeys", "defaultExpandAllRows", "defaultExpandedRowKeys", "style", "id", "isTree", "hover", "bordered", "cellBordered", "wordWrap", "loading", "locale", "showHeader", "pagination", "paginationProps", "sortColumn", "rowHeight", "sortType", "headerHeight", "minHeight", "height", "autoHeight", "fillHeight", "rtl", "translate3d", "rowKey", "virtualized", "rowClassName", "rowExpandedHeight", "disabledScroll", "affixHorizontalScrollbar", "loadAnimation", "shouldUpdateScroll", "renderRow", "renderRowExpanded", "renderLoading", "renderEmpty", "onSortColumn", "onScroll", "renderTreeToggle", "onRowClick", "onRowContextMenu", "onExpandChange", "onTouchStart", "onTouchMove", "onTouchEnd", "dataTheme", "tableBodyHeight", "columns", "tableBodyRef", "tableKey"],
3
+ var _excluded = ["affixHeader", "children", "classPrefix", "className", "data", "defaultSortType", "width", "expandedRowKeys", "defaultExpandAllRows", "defaultExpandedRowKeys", "style", "id", "isTree", "hover", "bordered", "cellBordered", "wordWrap", "loading", "locale", "showHeader", "pagination", "paginationProps", "sortColumn", "rowHeight", "sortType", "headerHeight", "minHeight", "height", "autoHeight", "fillHeight", "rtl", "translate3d", "rowKey", "virtualized", "rowClassName", "rowExpandedHeight", "disabledScroll", "affixHorizontalScrollbar", "loadAnimation", "shouldUpdateScroll", "renderRow", "renderRowExpanded", "renderLoading", "renderEmpty", "onSortColumn", "onScroll", "renderTreeToggle", "onRowClick", "onRowContextMenu", "onExpandChange", "onTouchStart", "onTouchMove", "onTouchEnd", "dataTheme", "tableBodyHeight", "columns", "tableBodyRef", "tableKey", "handleInfiniteScroll", "infiniteLoading", "wheelWrapperRef"],
4
4
  _excluded2 = ["depth", "rowIndex"],
5
5
  _excluded3 = ["cellHeight"];
6
6
  import { getTranslateDOMPositionXY } from 'dom-lib/translateDOMPositionXY';
@@ -116,13 +116,15 @@ var Table = /*#__PURE__*/React.forwardRef(function (props, ref) {
116
116
  columns = props.columns,
117
117
  tableBodyRef = props.tableBodyRef,
118
118
  tableKey = props.tableKey,
119
+ handleInfiniteScroll = props.handleInfiniteScroll,
120
+ infiniteLoading = props.infiniteLoading,
121
+ wheelWrapperRef = props.wheelWrapperRef,
119
122
  rest = _objectWithoutPropertiesLoose(props, _excluded);
120
123
  var _useClassNames = useClassNames(classPrefix, typeof classPrefix !== 'undefined'),
121
124
  withClassPrefix = _useClassNames.withClassPrefix,
122
125
  mergeCls = _useClassNames.merge,
123
126
  prefix = _useClassNames.prefix;
124
127
  var childTableRef = useRef(null);
125
-
126
128
  // Use `forceUpdate` to force the component to re-render after manipulating the DOM.
127
129
  var _useReducer = useReducer(function (x) {
128
130
  return x + 1;
@@ -181,7 +183,6 @@ var Table = /*#__PURE__*/React.forwardRef(function (props, ref) {
181
183
  var affixHeaderWrapperRef = useRef(null);
182
184
  var headerWrapperRef = useRef(null);
183
185
  // const tableBodyRef = useRef<HTMLDivElement>(null);
184
- var wheelWrapperRef = useRef(null);
185
186
  var scrollbarXRef = useRef(null);
186
187
  var scrollbarYRef = useRef(null);
187
188
  var handleTableResizeChange = function handleTableResizeChange(_prevSize, event) {
@@ -293,7 +294,8 @@ var Table = /*#__PURE__*/React.forwardRef(function (props, ref) {
293
294
  onScroll: onScroll,
294
295
  onTouchStart: onTouchStart,
295
296
  onTouchMove: onTouchMove,
296
- onTouchEnd: onTouchEnd
297
+ onTouchEnd: onTouchEnd,
298
+ handleInfiniteScroll: handleInfiniteScroll
297
299
  }),
298
300
  isScrolling = _useScrollListener.isScrolling,
299
301
  isChildFocused = _useScrollListener.isChildFocused,
@@ -617,7 +619,9 @@ var Table = /*#__PURE__*/React.forwardRef(function (props, ref) {
617
619
  width: tableWidth.current
618
620
  },
619
621
  length: tableWidth.current,
620
- onScroll: onScrollHorizontal,
622
+ onScroll: function onScroll(delta) {
623
+ onScrollHorizontal(delta), console.log('onScrollHorizontal', delta);
624
+ },
621
625
  scrollLength: contentWidth.current,
622
626
  ref: scrollbarXRef
623
627
  }));
@@ -781,7 +785,9 @@ var Table = /*#__PURE__*/React.forwardRef(function (props, ref) {
781
785
  role: "rowgroup",
782
786
  className: prefix('body-row-wrapper'),
783
787
  style: bodyStyles,
784
- onScroll: onScrollBody
788
+ onScroll: function onScroll(e) {
789
+ onScrollBody === null || onScrollBody === void 0 ? void 0 : onScrollBody(e); // existing handler
790
+ }
785
791
  }, !loading && /*#__PURE__*/React.createElement("div", {
786
792
  style: wheelStyles,
787
793
  className: prefix('body-wheel-area'),
@@ -792,7 +798,12 @@ var Table = /*#__PURE__*/React.forwardRef(function (props, ref) {
792
798
  }) : null, visibleRows.current, bottomHideHeight ? /*#__PURE__*/React.createElement(Row, {
793
799
  style: bottomRowStyles,
794
800
  className: "virtualized"
795
- }) : null), /*#__PURE__*/React.createElement(EmptyMessage, {
801
+ }) : null, infiniteLoading && /*#__PURE__*/React.createElement("div", {
802
+ style: {
803
+ padding: 12,
804
+ textAlign: 'center'
805
+ }
806
+ }, /*#__PURE__*/React.createElement("span", null, "Loading more rows\u2026"))), /*#__PURE__*/React.createElement(EmptyMessage, {
796
807
  locale: locale,
797
808
  renderEmpty: renderEmpty,
798
809
  addPrefix: prefix,
@@ -22,6 +22,7 @@ import { SettingsIcon } from './utilities/icons';
22
22
  import '../../dist/css/qbs-react-grid.css';
23
23
  var CHECKBOX_LINE_HEIGHT = '36px';
24
24
  var COLUMN_WIDTH = 250;
25
+ var REFRESH_KEY = 0;
25
26
  var QbsTable = function QbsTable(_ref) {
26
27
  var _Object$keys;
27
28
  var handleColumnSort = _ref.handleColumnSort,
@@ -52,7 +53,7 @@ var QbsTable = function QbsTable(_ref) {
52
53
  _ref$height = _ref.height,
53
54
  height = _ref$height === void 0 ? 630 : _ref$height,
54
55
  onExpandChange = _ref.onExpandChange,
55
- wordWrap = _ref.wordWrap,
56
+ propsWordWrap = _ref.wordWrap,
56
57
  _ref$dataRowKey = _ref.dataRowKey,
57
58
  dataRowKey = _ref$dataRowKey === void 0 ? 'id' : _ref$dataRowKey,
58
59
  defaultExpandAllRows = _ref.defaultExpandAllRows,
@@ -106,7 +107,13 @@ var QbsTable = function QbsTable(_ref) {
106
107
  _ref$isCustomTableCar = _ref.isCustomTableCardView,
107
108
  isCustomTableCardView = _ref$isCustomTableCar === void 0 ? false : _ref$isCustomTableCar,
108
109
  handleTableCardView = _ref.handleTableCardView,
109
- handleCustomCardLoader = _ref.handleCustomCardLoader;
110
+ handleCustomCardLoader = _ref.handleCustomCardLoader,
111
+ hasMoreData = _ref.hasMoreData,
112
+ loadMoreData = _ref.loadMoreData,
113
+ infiniteLoading = _ref.infiniteLoading,
114
+ _ref$infiniteScroll = _ref.infiniteScroll,
115
+ infiniteScroll = _ref$infiniteScroll === void 0 ? false : _ref$infiniteScroll,
116
+ propsViewMode = _ref.viewMode;
110
117
  var _useState = useState(false),
111
118
  loading = _useState[0],
112
119
  setLoading = _useState[1];
@@ -129,6 +136,13 @@ var QbsTable = function QbsTable(_ref) {
129
136
  setTableViewToggle = _useState5[1];
130
137
  var isMobile = useResponsiveStore();
131
138
  var tableBodyRef = useRef(null);
139
+ var wheelWrapperRef = useRef(null);
140
+ var _useState6 = useState(propsViewMode != null ? propsViewMode : 'expanded'),
141
+ viewMode = _useState6[0],
142
+ setViewMode = _useState6[1];
143
+ var _useState7 = useState(propsWordWrap != null ? propsWordWrap : false),
144
+ wordWrap = _useState7[0],
145
+ setWordWrap = _useState7[1];
132
146
  var handleSortColumn = useCallback(function (sortColumn, sortType) {
133
147
  setLoading(true);
134
148
  setTimeout(function () {
@@ -198,6 +212,7 @@ var QbsTable = function QbsTable(_ref) {
198
212
  }, [columns]);
199
213
  var handleColumnWidth = useCallback(function (newWidth, dataKey) {
200
214
  if (newWidth === undefined || dataKey === undefined) return;
215
+ REFRESH_KEY = REFRESH_KEY + 1;
201
216
  setColumns(function (prevColumns) {
202
217
  return prevColumns.map(function (column) {
203
218
  return column.field === dataKey ? _extends({}, column, {
@@ -217,13 +232,21 @@ var QbsTable = function QbsTable(_ref) {
217
232
  });
218
233
  }
219
234
  }, [wordWrap]);
235
+ useEffect(function () {
236
+ if (viewMode === 'expanded') {
237
+ setWordWrap('break-word');
238
+ } else {
239
+ setWordWrap(false);
240
+ }
241
+ REFRESH_KEY = REFRESH_KEY + 1;
242
+ }, [viewMode]);
220
243
  var onReorder = useCallback(function (columns) {
221
244
  setColumns(columns);
222
245
  }, []);
223
246
 
224
247
  // useEffect(() => {
225
248
  // }, [columns]);
226
-
249
+ console.log(viewMode);
227
250
  var handleClear = function handleClear(_ref2) {
228
251
  setCheckedKeys([]);
229
252
  handleChecked([]);
@@ -544,6 +567,19 @@ var QbsTable = function QbsTable(_ref) {
544
567
  },
545
568
  // ✅ Fix: Type assertion to ReactElement[]
546
569
  [columns, dataTheme]);
570
+ var handleInfiniteScroll = function handleInfiniteScroll(scroll) {
571
+ if (!infiniteScroll) return;
572
+ var wrapper = wheelWrapperRef.current;
573
+ if (!wrapper || !hasMoreData || infiniteLoading) return;
574
+ var scrollTop = wrapper.scrollTop,
575
+ clientHeight = wrapper.clientHeight;
576
+ var scrollHeight = Math.abs(scroll) + (height - headerHeight);
577
+
578
+ // Trigger fetch when user scrolls within 100px of bottom
579
+ if (scrollTop + clientHeight >= scrollHeight - 70) {
580
+ loadMoreData === null || loadMoreData === void 0 ? void 0 : loadMoreData(); // fetch next page here
581
+ }
582
+ };
547
583
  return /*#__PURE__*/React.createElement("div", {
548
584
  className: "qbs-table " + classes.tableContainerClass,
549
585
  "data-theme": dataTheme
@@ -551,19 +587,23 @@ var QbsTable = function QbsTable(_ref) {
551
587
  className: "qbs-table-border-wrap"
552
588
  }, tableViewToggle ? /*#__PURE__*/React.createElement(Table, {
553
589
  height: autoHeight ? undefined : height,
554
- key: tableKey,
590
+ key: tableKey + REFRESH_KEY,
555
591
  tableKey: tableKey,
556
592
  data: data,
593
+ refreshRow: REFRESH_KEY,
557
594
  tableBodyRef: tableBodyRef,
558
595
  dataTheme: dataTheme,
559
596
  wordWrap: wordWrap,
597
+ wheelWrapperRef: wheelWrapperRef,
560
598
  autoHeight: autoHeight,
599
+ handleInfiniteScroll: handleInfiniteScroll,
561
600
  sortColumn: sortColumn,
562
601
  style: {
563
602
  position: 'relative'
564
603
  },
565
604
  sortType: sortType,
566
605
  onSortColumn: handleSortColumn,
606
+ infiniteLoading: infiniteLoading,
567
607
  onRowClick: onRowClick,
568
608
  tableBodyHeight: tableBodyHeight,
569
609
  cellBordered: cellBordered,
@@ -672,6 +712,8 @@ var QbsTable = function QbsTable(_ref) {
672
712
  onReorder: onReorder,
673
713
  isOpen: isOpen,
674
714
  tableHeight: height,
715
+ viewMode: viewMode,
716
+ setViewMode: setViewMode,
675
717
  setIsOpen: setIsOpen,
676
718
  handleResetColumns: handleResetColumns,
677
719
  handleColumnToggle: handleColumnToggle
@@ -688,6 +730,8 @@ var QbsTable = function QbsTable(_ref) {
688
730
  onToggle: handleToggle,
689
731
  tableHeight: height,
690
732
  onReorder: onReorder,
733
+ viewMode: viewMode,
734
+ setViewMode: setViewMode,
691
735
  isOpen: isOpen,
692
736
  setIsOpen: setIsOpen,
693
737
  handleResetColumns: handleResetColumns,
@@ -110,6 +110,7 @@ var QbsTable = function QbsTable(_ref) {
110
110
  setIsOpen = _useState4[1];
111
111
  var prevColumns = useRef(null);
112
112
  var tableBodyRef = useRef(null);
113
+ var wheelWrapperRef = useRef(null);
113
114
  var handleSortColumn = useCallback(function (sortColumn, sortType) {
114
115
  setLoading(true);
115
116
  setTimeout(function () {
@@ -418,6 +419,7 @@ var QbsTable = function QbsTable(_ref) {
418
419
  wordWrap: wordWrap,
419
420
  autoHeight: autoHeight,
420
421
  sortColumn: sortColumn,
422
+ wheelWrapperRef: wheelWrapperRef,
421
423
  style: {
422
424
  position: 'relative'
423
425
  },
@@ -127,6 +127,11 @@ export interface QbsTableProps {
127
127
  handleTableCardView?: (data: any) => React.ReactNode;
128
128
  isCustomTableCardView?: boolean;
129
129
  handleCustomCardLoader?: () => React.ReactNode;
130
+ hasMoreData?: boolean;
131
+ loadMoreData?: () => void;
132
+ infiniteScroll?: boolean;
133
+ infiniteLoading?: boolean;
134
+ viewMode?: string;
130
135
  }
131
136
  export interface QbsTableToolbarProps {
132
137
  title?: string;
@@ -9,6 +9,8 @@ interface ColumnToggleProps {
9
9
  handleColumnToggle?: (columns: QbsColumnProps[]) => void;
10
10
  handleResetColumns?: () => void;
11
11
  tableHeight?: number;
12
+ viewMode?: string;
13
+ setViewMode?: (value: string) => void;
12
14
  }
13
15
  declare const ColumnToggle: React.FC<ColumnToggleProps>;
14
16
  export default ColumnToggle;
@@ -9,7 +9,9 @@ var ColumnToggle = function ColumnToggle(_ref) {
9
9
  handleResetColumns = _ref.handleResetColumns,
10
10
  handleColumnToggle = _ref.handleColumnToggle,
11
11
  _ref$tableHeight = _ref.tableHeight,
12
- tableHeight = _ref$tableHeight === void 0 ? 450 : _ref$tableHeight;
12
+ tableHeight = _ref$tableHeight === void 0 ? 450 : _ref$tableHeight,
13
+ viewMode = _ref.viewMode,
14
+ setViewMode = _ref.setViewMode;
13
15
  var _useState = useState(null),
14
16
  draggedItem = _useState[0],
15
17
  setDraggedItem = _useState[1];
@@ -215,6 +217,26 @@ var ColumnToggle = function ColumnToggle(_ref) {
215
217
  onClick: function onClick() {
216
218
  return handleColToggle();
217
219
  }
218
- }, "Save"))))));
220
+ }, "Save"))), /*#__PURE__*/React.createElement("div", {
221
+ className: "qbs-table-popup-item"
222
+ }, /*#__PURE__*/React.createElement("label", {
223
+ className: "flex items-center gap-2"
224
+ }, /*#__PURE__*/React.createElement("input", {
225
+ type: "radio",
226
+ value: "compact",
227
+ checked: viewMode === 'compact',
228
+ onChange: function onChange() {
229
+ return setViewMode === null || setViewMode === void 0 ? void 0 : setViewMode('compact');
230
+ }
231
+ }), "Compact View"), /*#__PURE__*/React.createElement("label", {
232
+ className: "flex items-center gap-2"
233
+ }, /*#__PURE__*/React.createElement("input", {
234
+ type: "radio",
235
+ value: "expanded",
236
+ checked: viewMode === 'expanded',
237
+ onChange: function onChange() {
238
+ return setViewMode === null || setViewMode === void 0 ? void 0 : setViewMode('expanded');
239
+ }
240
+ }), "Default View")))));
219
241
  };
220
242
  export default ColumnToggle;
@@ -151,7 +151,6 @@ var useCellDescriptor = function useCellDescriptor(props) {
151
151
  if (treeCol) {
152
152
  hasCustomTreeCol = true;
153
153
  }
154
- console.log(columns);
155
154
  if ((columnChildren === null || columnChildren === void 0 ? void 0 : columnChildren.length) !== 2) {
156
155
  throw new Error("Component <HeaderCell> and <Cell> is required, column index: " + index + " ");
157
156
  }
@@ -31,6 +31,7 @@ interface ScrollListenerProps {
31
31
  onTouchStart?: (event: React.TouchEvent) => void;
32
32
  onTouchMove?: (event: React.TouchEvent) => void;
33
33
  onTouchEnd?: (event: React.TouchEvent) => void;
34
+ handleInfiniteScroll?: (value: number) => void;
34
35
  }
35
36
  /**
36
37
  * Add scroll, touch, and wheel monitoring events to the table,
@@ -68,7 +68,8 @@ var useScrollListener = function useScrollListener(props) {
68
68
  contentHeight = props.contentHeight,
69
69
  headerHeight = props.headerHeight,
70
70
  rtl = props.rtl,
71
- tableKey = props.tableKey;
71
+ tableKey = props.tableKey,
72
+ handleInfiniteScroll = props.handleInfiniteScroll;
72
73
  var wheelListener = useRef(null);
73
74
  var touchStartListener = useRef(null);
74
75
  var touchMoveListener = useRef(null);
@@ -130,6 +131,10 @@ var useScrollListener = function useScrollListener(props) {
130
131
  var x = Math.min(0, nextScrollX < minScrollX.current ? minScrollX.current : nextScrollX);
131
132
  setScrollX(x);
132
133
  setScrollY(y);
134
+ console.log(scrollY.current, contentHeight.current, nextScrollY, minScrollY.current, 'scrolllistner');
135
+ if (typeof handleInfiniteScroll === 'function' && deltaY !== 0 && !loading && Math.abs(y) + getTableHeight() >= contentHeight.current - 12) {
136
+ handleInfiniteScroll(scrollY.current);
137
+ }
133
138
  onScroll === null || onScroll === void 0 ? void 0 : onScroll(Math.abs(x), Math.abs(y));
134
139
  if (virtualized) {
135
140
  // Add a state to the table during virtualized scrolling.
@@ -207,7 +212,6 @@ var useScrollListener = function useScrollListener(props) {
207
212
  if (!isTouching.current) {
208
213
  return;
209
214
  }
210
- console.log('handleTouchMove');
211
215
  var _event$touches$2 = event.touches[0],
212
216
  pageX = _event$touches$2.pageX,
213
217
  pageY = _event$touches$2.pageY;
package/lib/Table.d.ts CHANGED
@@ -96,9 +96,12 @@ export interface TableProps<Row, Key> extends Omit<StandardProps, 'onScroll'> {
96
96
  virtualized?: boolean;
97
97
  /**Theme Change */
98
98
  dataTheme?: string;
99
+ /** Refresh Row */
100
+ refreshRow?: number;
99
101
  /** Tree table, the callback function in the expanded node */
100
102
  renderTreeToggle?: (expandButton: React.ReactNode, rowData?: Row, expanded?: boolean) => React.ReactNode;
101
103
  tableKey?: string;
104
+ infiniteLoading?: boolean;
102
105
  /** Customize what you can do to expand a zone */
103
106
  renderRowExpanded?: (rowData?: Row) => React.ReactNode;
104
107
  /** Custom row element */
@@ -123,6 +126,7 @@ export interface TableProps<Row, Key> extends Omit<StandardProps, 'onScroll'> {
123
126
  onTouchMove?: (event: React.TouchEvent) => void;
124
127
  /** Callback for the `touchend` event. */
125
128
  onTouchEnd?: (event: React.TouchEvent) => void;
129
+ handleInfiniteScroll?: (value: number) => void;
126
130
  /**
127
131
  * Callback after table data update.
128
132
  * @deprecated use `shouldUpdateScroll` instead
@@ -132,6 +136,7 @@ export interface TableProps<Row, Key> extends Omit<StandardProps, 'onScroll'> {
132
136
  y: number;
133
137
  }) => void) => void;
134
138
  tableBodyRef: React.RefObject<HTMLDivElement>;
139
+ wheelWrapperRef: React.RefObject<HTMLDivElement | null>;
135
140
  bodyRef?: (ref: HTMLElement) => void;
136
141
  }
137
142
  export interface TableInstance<Row, Key> extends React.FunctionComponent<TableProps<Row, Key>> {
package/lib/Table.js CHANGED
@@ -20,7 +20,7 @@ var _Row = _interopRequireDefault(require("./Row"));
20
20
  var _Scrollbar = _interopRequireDefault(require("./Scrollbar"));
21
21
  var _TableContext = _interopRequireDefault(require("./TableContext"));
22
22
  var _utils = require("./utils");
23
- var _excluded = ["affixHeader", "children", "classPrefix", "className", "data", "defaultSortType", "width", "expandedRowKeys", "defaultExpandAllRows", "defaultExpandedRowKeys", "style", "id", "isTree", "hover", "bordered", "cellBordered", "wordWrap", "loading", "locale", "showHeader", "pagination", "paginationProps", "sortColumn", "rowHeight", "sortType", "headerHeight", "minHeight", "height", "autoHeight", "fillHeight", "rtl", "translate3d", "rowKey", "virtualized", "rowClassName", "rowExpandedHeight", "disabledScroll", "affixHorizontalScrollbar", "loadAnimation", "shouldUpdateScroll", "renderRow", "renderRowExpanded", "renderLoading", "renderEmpty", "onSortColumn", "onScroll", "renderTreeToggle", "onRowClick", "onRowContextMenu", "onExpandChange", "onTouchStart", "onTouchMove", "onTouchEnd", "dataTheme", "tableBodyHeight", "columns", "tableBodyRef", "tableKey"],
23
+ var _excluded = ["affixHeader", "children", "classPrefix", "className", "data", "defaultSortType", "width", "expandedRowKeys", "defaultExpandAllRows", "defaultExpandedRowKeys", "style", "id", "isTree", "hover", "bordered", "cellBordered", "wordWrap", "loading", "locale", "showHeader", "pagination", "paginationProps", "sortColumn", "rowHeight", "sortType", "headerHeight", "minHeight", "height", "autoHeight", "fillHeight", "rtl", "translate3d", "rowKey", "virtualized", "rowClassName", "rowExpandedHeight", "disabledScroll", "affixHorizontalScrollbar", "loadAnimation", "shouldUpdateScroll", "renderRow", "renderRowExpanded", "renderLoading", "renderEmpty", "onSortColumn", "onScroll", "renderTreeToggle", "onRowClick", "onRowContextMenu", "onExpandChange", "onTouchStart", "onTouchMove", "onTouchEnd", "dataTheme", "tableBodyHeight", "columns", "tableBodyRef", "tableKey", "handleInfiniteScroll", "infiniteLoading", "wheelWrapperRef"],
24
24
  _excluded2 = ["depth", "rowIndex"],
25
25
  _excluded3 = ["cellHeight"];
26
26
  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); }
@@ -123,13 +123,15 @@ var Table = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
123
123
  columns = props.columns,
124
124
  tableBodyRef = props.tableBodyRef,
125
125
  tableKey = props.tableKey,
126
+ handleInfiniteScroll = props.handleInfiniteScroll,
127
+ infiniteLoading = props.infiniteLoading,
128
+ wheelWrapperRef = props.wheelWrapperRef,
126
129
  rest = (0, _objectWithoutPropertiesLoose2["default"])(props, _excluded);
127
130
  var _useClassNames = (0, _utils.useClassNames)(classPrefix, typeof classPrefix !== 'undefined'),
128
131
  withClassPrefix = _useClassNames.withClassPrefix,
129
132
  mergeCls = _useClassNames.merge,
130
133
  prefix = _useClassNames.prefix;
131
134
  var childTableRef = (0, _react.useRef)(null);
132
-
133
135
  // Use `forceUpdate` to force the component to re-render after manipulating the DOM.
134
136
  var _useReducer = (0, _react.useReducer)(function (x) {
135
137
  return x + 1;
@@ -188,7 +190,6 @@ var Table = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
188
190
  var affixHeaderWrapperRef = (0, _react.useRef)(null);
189
191
  var headerWrapperRef = (0, _react.useRef)(null);
190
192
  // const tableBodyRef = useRef<HTMLDivElement>(null);
191
- var wheelWrapperRef = (0, _react.useRef)(null);
192
193
  var scrollbarXRef = (0, _react.useRef)(null);
193
194
  var scrollbarYRef = (0, _react.useRef)(null);
194
195
  var handleTableResizeChange = function handleTableResizeChange(_prevSize, event) {
@@ -300,7 +301,8 @@ var Table = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
300
301
  onScroll: onScroll,
301
302
  onTouchStart: onTouchStart,
302
303
  onTouchMove: onTouchMove,
303
- onTouchEnd: onTouchEnd
304
+ onTouchEnd: onTouchEnd,
305
+ handleInfiniteScroll: handleInfiniteScroll
304
306
  }),
305
307
  isScrolling = _useScrollListener.isScrolling,
306
308
  isChildFocused = _useScrollListener.isChildFocused,
@@ -624,7 +626,9 @@ var Table = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
624
626
  width: tableWidth.current
625
627
  },
626
628
  length: tableWidth.current,
627
- onScroll: onScrollHorizontal,
629
+ onScroll: function onScroll(delta) {
630
+ onScrollHorizontal(delta), console.log('onScrollHorizontal', delta);
631
+ },
628
632
  scrollLength: contentWidth.current,
629
633
  ref: scrollbarXRef
630
634
  }));
@@ -788,7 +792,9 @@ var Table = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
788
792
  role: "rowgroup",
789
793
  className: prefix('body-row-wrapper'),
790
794
  style: bodyStyles,
791
- onScroll: onScrollBody
795
+ onScroll: function onScroll(e) {
796
+ onScrollBody === null || onScrollBody === void 0 ? void 0 : onScrollBody(e); // existing handler
797
+ }
792
798
  }, !loading && /*#__PURE__*/_react["default"].createElement("div", {
793
799
  style: wheelStyles,
794
800
  className: prefix('body-wheel-area'),
@@ -799,7 +805,12 @@ var Table = /*#__PURE__*/_react["default"].forwardRef(function (props, ref) {
799
805
  }) : null, visibleRows.current, bottomHideHeight ? /*#__PURE__*/_react["default"].createElement(_Row["default"], {
800
806
  style: bottomRowStyles,
801
807
  className: "virtualized"
802
- }) : null), /*#__PURE__*/_react["default"].createElement(_EmptyMessage["default"], {
808
+ }) : null, infiniteLoading && /*#__PURE__*/_react["default"].createElement("div", {
809
+ style: {
810
+ padding: 12,
811
+ textAlign: 'center'
812
+ }
813
+ }, /*#__PURE__*/_react["default"].createElement("span", null, "Loading more rows\u2026"))), /*#__PURE__*/_react["default"].createElement(_EmptyMessage["default"], {
803
814
  locale: locale,
804
815
  renderEmpty: renderEmpty,
805
816
  addPrefix: prefix,
@@ -28,6 +28,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj &&
28
28
 
29
29
  var CHECKBOX_LINE_HEIGHT = '36px';
30
30
  var COLUMN_WIDTH = 250;
31
+ var REFRESH_KEY = 0;
31
32
  var QbsTable = function QbsTable(_ref) {
32
33
  var _Object$keys;
33
34
  var handleColumnSort = _ref.handleColumnSort,
@@ -58,7 +59,7 @@ var QbsTable = function QbsTable(_ref) {
58
59
  _ref$height = _ref.height,
59
60
  height = _ref$height === void 0 ? 630 : _ref$height,
60
61
  onExpandChange = _ref.onExpandChange,
61
- wordWrap = _ref.wordWrap,
62
+ propsWordWrap = _ref.wordWrap,
62
63
  _ref$dataRowKey = _ref.dataRowKey,
63
64
  dataRowKey = _ref$dataRowKey === void 0 ? 'id' : _ref$dataRowKey,
64
65
  defaultExpandAllRows = _ref.defaultExpandAllRows,
@@ -112,7 +113,13 @@ var QbsTable = function QbsTable(_ref) {
112
113
  _ref$isCustomTableCar = _ref.isCustomTableCardView,
113
114
  isCustomTableCardView = _ref$isCustomTableCar === void 0 ? false : _ref$isCustomTableCar,
114
115
  handleTableCardView = _ref.handleTableCardView,
115
- handleCustomCardLoader = _ref.handleCustomCardLoader;
116
+ handleCustomCardLoader = _ref.handleCustomCardLoader,
117
+ hasMoreData = _ref.hasMoreData,
118
+ loadMoreData = _ref.loadMoreData,
119
+ infiniteLoading = _ref.infiniteLoading,
120
+ _ref$infiniteScroll = _ref.infiniteScroll,
121
+ infiniteScroll = _ref$infiniteScroll === void 0 ? false : _ref$infiniteScroll,
122
+ propsViewMode = _ref.viewMode;
116
123
  var _useState = (0, _react.useState)(false),
117
124
  loading = _useState[0],
118
125
  setLoading = _useState[1];
@@ -135,6 +142,13 @@ var QbsTable = function QbsTable(_ref) {
135
142
  setTableViewToggle = _useState5[1];
136
143
  var isMobile = (0, _useResponsiveStore["default"])();
137
144
  var tableBodyRef = (0, _react.useRef)(null);
145
+ var wheelWrapperRef = (0, _react.useRef)(null);
146
+ var _useState6 = (0, _react.useState)(propsViewMode != null ? propsViewMode : 'expanded'),
147
+ viewMode = _useState6[0],
148
+ setViewMode = _useState6[1];
149
+ var _useState7 = (0, _react.useState)(propsWordWrap != null ? propsWordWrap : false),
150
+ wordWrap = _useState7[0],
151
+ setWordWrap = _useState7[1];
138
152
  var handleSortColumn = (0, _react.useCallback)(function (sortColumn, sortType) {
139
153
  setLoading(true);
140
154
  setTimeout(function () {
@@ -204,6 +218,7 @@ var QbsTable = function QbsTable(_ref) {
204
218
  }, [columns]);
205
219
  var handleColumnWidth = (0, _react.useCallback)(function (newWidth, dataKey) {
206
220
  if (newWidth === undefined || dataKey === undefined) return;
221
+ REFRESH_KEY = REFRESH_KEY + 1;
207
222
  setColumns(function (prevColumns) {
208
223
  return prevColumns.map(function (column) {
209
224
  return column.field === dataKey ? (0, _extends2["default"])({}, column, {
@@ -223,13 +238,21 @@ var QbsTable = function QbsTable(_ref) {
223
238
  });
224
239
  }
225
240
  }, [wordWrap]);
241
+ (0, _react.useEffect)(function () {
242
+ if (viewMode === 'expanded') {
243
+ setWordWrap('break-word');
244
+ } else {
245
+ setWordWrap(false);
246
+ }
247
+ REFRESH_KEY = REFRESH_KEY + 1;
248
+ }, [viewMode]);
226
249
  var onReorder = (0, _react.useCallback)(function (columns) {
227
250
  setColumns(columns);
228
251
  }, []);
229
252
 
230
253
  // useEffect(() => {
231
254
  // }, [columns]);
232
-
255
+ console.log(viewMode);
233
256
  var handleClear = function handleClear(_ref2) {
234
257
  setCheckedKeys([]);
235
258
  handleChecked([]);
@@ -550,6 +573,19 @@ var QbsTable = function QbsTable(_ref) {
550
573
  },
551
574
  // ✅ Fix: Type assertion to ReactElement[]
552
575
  [columns, dataTheme]);
576
+ var handleInfiniteScroll = function handleInfiniteScroll(scroll) {
577
+ if (!infiniteScroll) return;
578
+ var wrapper = wheelWrapperRef.current;
579
+ if (!wrapper || !hasMoreData || infiniteLoading) return;
580
+ var scrollTop = wrapper.scrollTop,
581
+ clientHeight = wrapper.clientHeight;
582
+ var scrollHeight = Math.abs(scroll) + (height - headerHeight);
583
+
584
+ // Trigger fetch when user scrolls within 100px of bottom
585
+ if (scrollTop + clientHeight >= scrollHeight - 70) {
586
+ loadMoreData === null || loadMoreData === void 0 ? void 0 : loadMoreData(); // fetch next page here
587
+ }
588
+ };
553
589
  return /*#__PURE__*/_react["default"].createElement("div", {
554
590
  className: "qbs-table " + classes.tableContainerClass,
555
591
  "data-theme": dataTheme
@@ -557,19 +593,23 @@ var QbsTable = function QbsTable(_ref) {
557
593
  className: "qbs-table-border-wrap"
558
594
  }, tableViewToggle ? /*#__PURE__*/_react["default"].createElement(_Table["default"], {
559
595
  height: autoHeight ? undefined : height,
560
- key: tableKey,
596
+ key: tableKey + REFRESH_KEY,
561
597
  tableKey: tableKey,
562
598
  data: data,
599
+ refreshRow: REFRESH_KEY,
563
600
  tableBodyRef: tableBodyRef,
564
601
  dataTheme: dataTheme,
565
602
  wordWrap: wordWrap,
603
+ wheelWrapperRef: wheelWrapperRef,
566
604
  autoHeight: autoHeight,
605
+ handleInfiniteScroll: handleInfiniteScroll,
567
606
  sortColumn: sortColumn,
568
607
  style: {
569
608
  position: 'relative'
570
609
  },
571
610
  sortType: sortType,
572
611
  onSortColumn: handleSortColumn,
612
+ infiniteLoading: infiniteLoading,
573
613
  onRowClick: onRowClick,
574
614
  tableBodyHeight: tableBodyHeight,
575
615
  cellBordered: cellBordered,
@@ -678,6 +718,8 @@ var QbsTable = function QbsTable(_ref) {
678
718
  onReorder: onReorder,
679
719
  isOpen: isOpen,
680
720
  tableHeight: height,
721
+ viewMode: viewMode,
722
+ setViewMode: setViewMode,
681
723
  setIsOpen: setIsOpen,
682
724
  handleResetColumns: handleResetColumns,
683
725
  handleColumnToggle: handleColumnToggle
@@ -694,6 +736,8 @@ var QbsTable = function QbsTable(_ref) {
694
736
  onToggle: handleToggle,
695
737
  tableHeight: height,
696
738
  onReorder: onReorder,
739
+ viewMode: viewMode,
740
+ setViewMode: setViewMode,
697
741
  isOpen: isOpen,
698
742
  setIsOpen: setIsOpen,
699
743
  handleResetColumns: handleResetColumns,
@@ -116,6 +116,7 @@ var QbsTable = function QbsTable(_ref) {
116
116
  setIsOpen = _useState4[1];
117
117
  var prevColumns = (0, _react.useRef)(null);
118
118
  var tableBodyRef = (0, _react.useRef)(null);
119
+ var wheelWrapperRef = (0, _react.useRef)(null);
119
120
  var handleSortColumn = (0, _react.useCallback)(function (sortColumn, sortType) {
120
121
  setLoading(true);
121
122
  setTimeout(function () {
@@ -424,6 +425,7 @@ var QbsTable = function QbsTable(_ref) {
424
425
  wordWrap: wordWrap,
425
426
  autoHeight: autoHeight,
426
427
  sortColumn: sortColumn,
428
+ wheelWrapperRef: wheelWrapperRef,
427
429
  style: {
428
430
  position: 'relative'
429
431
  },
@@ -127,6 +127,11 @@ export interface QbsTableProps {
127
127
  handleTableCardView?: (data: any) => React.ReactNode;
128
128
  isCustomTableCardView?: boolean;
129
129
  handleCustomCardLoader?: () => React.ReactNode;
130
+ hasMoreData?: boolean;
131
+ loadMoreData?: () => void;
132
+ infiniteScroll?: boolean;
133
+ infiniteLoading?: boolean;
134
+ viewMode?: string;
130
135
  }
131
136
  export interface QbsTableToolbarProps {
132
137
  title?: string;
@@ -9,6 +9,8 @@ interface ColumnToggleProps {
9
9
  handleColumnToggle?: (columns: QbsColumnProps[]) => void;
10
10
  handleResetColumns?: () => void;
11
11
  tableHeight?: number;
12
+ viewMode?: string;
13
+ setViewMode?: (value: string) => void;
12
14
  }
13
15
  declare const ColumnToggle: React.FC<ColumnToggleProps>;
14
16
  export default ColumnToggle;
@@ -15,7 +15,9 @@ var ColumnToggle = function ColumnToggle(_ref) {
15
15
  handleResetColumns = _ref.handleResetColumns,
16
16
  handleColumnToggle = _ref.handleColumnToggle,
17
17
  _ref$tableHeight = _ref.tableHeight,
18
- tableHeight = _ref$tableHeight === void 0 ? 450 : _ref$tableHeight;
18
+ tableHeight = _ref$tableHeight === void 0 ? 450 : _ref$tableHeight,
19
+ viewMode = _ref.viewMode,
20
+ setViewMode = _ref.setViewMode;
19
21
  var _useState = (0, _react.useState)(null),
20
22
  draggedItem = _useState[0],
21
23
  setDraggedItem = _useState[1];
@@ -221,7 +223,27 @@ var ColumnToggle = function ColumnToggle(_ref) {
221
223
  onClick: function onClick() {
222
224
  return handleColToggle();
223
225
  }
224
- }, "Save"))))));
226
+ }, "Save"))), /*#__PURE__*/_react["default"].createElement("div", {
227
+ className: "qbs-table-popup-item"
228
+ }, /*#__PURE__*/_react["default"].createElement("label", {
229
+ className: "flex items-center gap-2"
230
+ }, /*#__PURE__*/_react["default"].createElement("input", {
231
+ type: "radio",
232
+ value: "compact",
233
+ checked: viewMode === 'compact',
234
+ onChange: function onChange() {
235
+ return setViewMode === null || setViewMode === void 0 ? void 0 : setViewMode('compact');
236
+ }
237
+ }), "Compact View"), /*#__PURE__*/_react["default"].createElement("label", {
238
+ className: "flex items-center gap-2"
239
+ }, /*#__PURE__*/_react["default"].createElement("input", {
240
+ type: "radio",
241
+ value: "expanded",
242
+ checked: viewMode === 'expanded',
243
+ onChange: function onChange() {
244
+ return setViewMode === null || setViewMode === void 0 ? void 0 : setViewMode('expanded');
245
+ }
246
+ }), "Default View")))));
225
247
  };
226
248
  var _default = ColumnToggle;
227
249
  exports["default"] = _default;
@@ -158,7 +158,6 @@ var useCellDescriptor = function useCellDescriptor(props) {
158
158
  if (treeCol) {
159
159
  hasCustomTreeCol = true;
160
160
  }
161
- console.log(columns);
162
161
  if ((columnChildren === null || columnChildren === void 0 ? void 0 : columnChildren.length) !== 2) {
163
162
  throw new Error("Component <HeaderCell> and <Cell> is required, column index: " + index + " ");
164
163
  }
@@ -31,6 +31,7 @@ interface ScrollListenerProps {
31
31
  onTouchStart?: (event: React.TouchEvent) => void;
32
32
  onTouchMove?: (event: React.TouchEvent) => void;
33
33
  onTouchEnd?: (event: React.TouchEvent) => void;
34
+ handleInfiniteScroll?: (value: number) => void;
34
35
  }
35
36
  /**
36
37
  * Add scroll, touch, and wheel monitoring events to the table,
@@ -72,7 +72,8 @@ var useScrollListener = function useScrollListener(props) {
72
72
  contentHeight = props.contentHeight,
73
73
  headerHeight = props.headerHeight,
74
74
  rtl = props.rtl,
75
- tableKey = props.tableKey;
75
+ tableKey = props.tableKey,
76
+ handleInfiniteScroll = props.handleInfiniteScroll;
76
77
  var wheelListener = (0, _react.useRef)(null);
77
78
  var touchStartListener = (0, _react.useRef)(null);
78
79
  var touchMoveListener = (0, _react.useRef)(null);
@@ -134,6 +135,10 @@ var useScrollListener = function useScrollListener(props) {
134
135
  var x = Math.min(0, nextScrollX < minScrollX.current ? minScrollX.current : nextScrollX);
135
136
  setScrollX(x);
136
137
  setScrollY(y);
138
+ console.log(scrollY.current, contentHeight.current, nextScrollY, minScrollY.current, 'scrolllistner');
139
+ if (typeof handleInfiniteScroll === 'function' && deltaY !== 0 && !loading && Math.abs(y) + getTableHeight() >= contentHeight.current - 12) {
140
+ handleInfiniteScroll(scrollY.current);
141
+ }
137
142
  onScroll === null || onScroll === void 0 ? void 0 : onScroll(Math.abs(x), Math.abs(y));
138
143
  if (virtualized) {
139
144
  // Add a state to the table during virtualized scrolling.
@@ -211,7 +216,6 @@ var useScrollListener = function useScrollListener(props) {
211
216
  if (!isTouching.current) {
212
217
  return;
213
218
  }
214
- console.log('handleTouchMove');
215
219
  var _event$touches$2 = event.touches[0],
216
220
  pageX = _event$touches$2.pageX,
217
221
  pageY = _event$touches$2.pageY;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qbs-react-grid",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "A React table component",
5
5
  "main": "lib/index.js",
6
6
  "typings": "lib/index.d.ts",
@@ -72,7 +72,7 @@
72
72
  "@commitlint/cli": "^13.1.0",
73
73
  "@commitlint/config-conventional": "^13.1.0",
74
74
  "@faker-js/faker": "^7.6.0",
75
- "@testing-library/react": "^13.4.0",
75
+ "@testing-library/react": "^16.2.0",
76
76
  "@types/lodash": "^4.14.165",
77
77
  "@types/prop-types": "^15.7.1",
78
78
  "@types/react": "^19.0.11",
@@ -97,7 +97,6 @@ const HeaderCell = React.forwardRef((props: HeaderCellProps, ref: React.Ref<HTML
97
97
  onSortColumn?.(sortKey ?? dataKey);
98
98
  }
99
99
  }, [dataKey, onSortColumn, sortable, sortKey]);
100
-
101
100
  const handleColumnResizeStart = useCallback(() => {
102
101
  onColumnResizeStart?.(columnWidth, left, !!fixed);
103
102
  }, [columnWidth, fixed, left, onColumnResizeStart]);
package/src/Table.tsx CHANGED
@@ -216,7 +216,8 @@ export interface TableProps<Row, Key> extends Omit<StandardProps, 'onScroll'> {
216
216
 
217
217
  /**Theme Change */
218
218
  dataTheme?: string;
219
-
219
+ /** Refresh Row */
220
+ refreshRow?: number;
220
221
  /** Tree table, the callback function in the expanded node */
221
222
  renderTreeToggle?: (
222
223
  expandButton: React.ReactNode,
@@ -224,6 +225,7 @@ export interface TableProps<Row, Key> extends Omit<StandardProps, 'onScroll'> {
224
225
  expanded?: boolean
225
226
  ) => React.ReactNode;
226
227
  tableKey?: string;
228
+ infiniteLoading?: boolean;
227
229
  /** Customize what you can do to expand a zone */
228
230
  renderRowExpanded?: (rowData?: Row) => React.ReactNode;
229
231
 
@@ -259,13 +261,16 @@ export interface TableProps<Row, Key> extends Omit<StandardProps, 'onScroll'> {
259
261
 
260
262
  /** Callback for the `touchend` event. */
261
263
  onTouchEnd?: (event: React.TouchEvent) => void;
262
-
264
+ handleInfiniteScroll?: (value: number) => void;
263
265
  /**
264
266
  * Callback after table data update.
265
267
  * @deprecated use `shouldUpdateScroll` instead
266
268
  **/
267
269
  onDataUpdated?: (nextData: Row[], scrollTo: (coord: { x: number; y: number }) => void) => void;
268
270
  tableBodyRef: React.RefObject<HTMLDivElement>;
271
+
272
+ wheelWrapperRef: React.RefObject<HTMLDivElement | null>;
273
+
269
274
  bodyRef?: (ref: HTMLElement) => void;
270
275
  }
271
276
 
@@ -340,6 +345,9 @@ const Table = React.forwardRef(<Row extends RowDataType, Key>(props: TableProps<
340
345
  columns,
341
346
  tableBodyRef,
342
347
  tableKey,
348
+ handleInfiniteScroll,
349
+ infiniteLoading,
350
+ wheelWrapperRef,
343
351
  ...rest
344
352
  } = props;
345
353
 
@@ -349,7 +357,6 @@ const Table = React.forwardRef(<Row extends RowDataType, Key>(props: TableProps<
349
357
  prefix
350
358
  } = useClassNames(classPrefix, typeof classPrefix !== 'undefined');
351
359
  const childTableRef = useRef<HTMLDivElement>(null);
352
-
353
360
  // Use `forceUpdate` to force the component to re-render after manipulating the DOM.
354
361
  const [, forceUpdate] = useReducer(x => x + 1, 0);
355
362
  const [expandedRowKeys, setExpandedRowKeys] = useControlled(
@@ -408,7 +415,6 @@ const Table = React.forwardRef(<Row extends RowDataType, Key>(props: TableProps<
408
415
  const affixHeaderWrapperRef = useRef<HTMLDivElement>(null);
409
416
  const headerWrapperRef = useRef<HTMLDivElement>(null);
410
417
  // const tableBodyRef = useRef<HTMLDivElement>(null);
411
- const wheelWrapperRef = useRef<HTMLDivElement>(null);
412
418
  const scrollbarXRef = useRef<ScrollbarInstance>(null);
413
419
  const scrollbarYRef = useRef<ScrollbarInstance>(null);
414
420
 
@@ -533,7 +539,8 @@ const Table = React.forwardRef(<Row extends RowDataType, Key>(props: TableProps<
533
539
  onScroll,
534
540
  onTouchStart,
535
541
  onTouchMove,
536
- onTouchEnd
542
+ onTouchEnd,
543
+ handleInfiniteScroll
537
544
  });
538
545
 
539
546
  const { headerCells, bodyCells, allColumnsWidth, hasCustomTreeCol } = useCellDescriptor({
@@ -953,7 +960,9 @@ const Table = React.forwardRef(<Row extends RowDataType, Key>(props: TableProps<
953
960
  tableId={id}
954
961
  style={{ width: tableWidth.current }}
955
962
  length={tableWidth.current}
956
- onScroll={onScrollHorizontal}
963
+ onScroll={delta => {
964
+ onScrollHorizontal(delta), console.log('onScrollHorizontal', delta);
965
+ }}
957
966
  scrollLength={contentWidth.current}
958
967
  ref={scrollbarXRef}
959
968
  />
@@ -1132,13 +1141,21 @@ const Table = React.forwardRef(<Row extends RowDataType, Key>(props: TableProps<
1132
1141
  role="rowgroup"
1133
1142
  className={prefix('body-row-wrapper')}
1134
1143
  style={bodyStyles}
1135
- onScroll={onScrollBody}
1144
+ onScroll={e => {
1145
+ onScrollBody?.(e); // existing handler
1146
+ }}
1136
1147
  >
1137
1148
  {!loading && (
1138
1149
  <div style={wheelStyles} className={prefix('body-wheel-area')} ref={wheelWrapperRef}>
1139
1150
  {topHideHeight ? <Row style={topRowStyles} className="virtualized" /> : null}
1140
1151
  {visibleRows.current}
1141
1152
  {bottomHideHeight ? <Row style={bottomRowStyles} className="virtualized" /> : null}
1153
+
1154
+ {infiniteLoading && (
1155
+ <div style={{ padding: 12, textAlign: 'center' }}>
1156
+ <span>Loading more rows…</span>
1157
+ </div>
1158
+ )}
1142
1159
  </div>
1143
1160
  )}
1144
1161
 
@@ -30,6 +30,7 @@ import '../../dist/css/qbs-react-grid.css';
30
30
 
31
31
  const CHECKBOX_LINE_HEIGHT = '36px';
32
32
  const COLUMN_WIDTH = 250;
33
+ let REFRESH_KEY = 0;
33
34
  const QbsTable: React.FC<QbsTableProps> = ({
34
35
  handleColumnSort,
35
36
  data,
@@ -51,7 +52,7 @@ const QbsTable: React.FC<QbsTableProps> = ({
51
52
  minHeight,
52
53
  height = 630,
53
54
  onExpandChange,
54
- wordWrap,
55
+ wordWrap: propsWordWrap,
55
56
  dataRowKey = 'id',
56
57
  defaultExpandAllRows,
57
58
  handleRowExpanded,
@@ -91,7 +92,12 @@ const QbsTable: React.FC<QbsTableProps> = ({
91
92
  childDetailHeading = '',
92
93
  isCustomTableCardView = false,
93
94
  handleTableCardView,
94
- handleCustomCardLoader
95
+ handleCustomCardLoader,
96
+ hasMoreData,
97
+ loadMoreData,
98
+ infiniteLoading,
99
+ infiniteScroll = false,
100
+ viewMode: propsViewMode
95
101
  }) => {
96
102
  const [loading, setLoading] = useState(false);
97
103
  const [columns, setColumns] = useState(propColumn);
@@ -102,6 +108,9 @@ const QbsTable: React.FC<QbsTableProps> = ({
102
108
  const [tableViewToggle, setTableViewToggle] = useState(tableView);
103
109
  const isMobile = useResponsiveStore();
104
110
  const tableBodyRef = useRef<HTMLDivElement>(null);
111
+ const wheelWrapperRef = useRef<HTMLDivElement>(null);
112
+ const [viewMode, setViewMode] = useState(propsViewMode ?? 'expanded');
113
+ const [wordWrap, setWordWrap] = useState(propsWordWrap ?? false);
105
114
  const handleSortColumn = useCallback(
106
115
  (sortColumn: any, sortType: any) => {
107
116
  setLoading(true);
@@ -188,6 +197,7 @@ const QbsTable: React.FC<QbsTableProps> = ({
188
197
 
189
198
  const handleColumnWidth = useCallback((newWidth?: number, dataKey?: any) => {
190
199
  if (newWidth === undefined || dataKey === undefined) return;
200
+ REFRESH_KEY = REFRESH_KEY + 1;
191
201
  setColumns(prevColumns =>
192
202
  prevColumns.map(column =>
193
203
  column.field === dataKey ? { ...column, colWidth: newWidth } : column
@@ -204,14 +214,21 @@ const QbsTable: React.FC<QbsTableProps> = ({
204
214
  );
205
215
  }
206
216
  }, [wordWrap]);
207
-
217
+ useEffect(() => {
218
+ if (viewMode === 'expanded') {
219
+ setWordWrap('break-word');
220
+ } else {
221
+ setWordWrap(false);
222
+ }
223
+ REFRESH_KEY = REFRESH_KEY + 1;
224
+ }, [viewMode]);
208
225
  const onReorder = useCallback((columns: QbsColumnProps[]) => {
209
226
  setColumns(columns);
210
227
  }, []);
211
228
 
212
229
  // useEffect(() => {
213
230
  // }, [columns]);
214
-
231
+ console.log(viewMode);
215
232
  const handleClear = ([]) => {
216
233
  setCheckedKeys([]);
217
234
  handleChecked([]);
@@ -564,6 +581,20 @@ const QbsTable: React.FC<QbsTableProps> = ({
564
581
  [columns, dataTheme]
565
582
  );
566
583
 
584
+ const handleInfiniteScroll = (scroll: number) => {
585
+ if (!infiniteScroll) return;
586
+ const wrapper = wheelWrapperRef.current;
587
+ if (!wrapper || !hasMoreData || infiniteLoading) return;
588
+
589
+ const { scrollTop, clientHeight } = wrapper;
590
+ const scrollHeight = Math.abs(scroll) + (height - headerHeight);
591
+
592
+ // Trigger fetch when user scrolls within 100px of bottom
593
+ if (scrollTop + clientHeight >= scrollHeight - 70) {
594
+ loadMoreData?.(); // fetch next page here
595
+ }
596
+ };
597
+
567
598
  return (
568
599
  <div className={`qbs-table ${classes.tableContainerClass}`} data-theme={dataTheme}>
569
600
  {toolbar && <ToolBar {...toolbarProps} />}
@@ -571,17 +602,21 @@ const QbsTable: React.FC<QbsTableProps> = ({
571
602
  {tableViewToggle ? (
572
603
  <Table
573
604
  height={autoHeight ? undefined : height}
574
- key={tableKey}
605
+ key={tableKey + REFRESH_KEY}
575
606
  tableKey={tableKey}
576
607
  data={data}
608
+ refreshRow={REFRESH_KEY}
577
609
  tableBodyRef={tableBodyRef as React.RefObject<HTMLDivElement>}
578
610
  dataTheme={dataTheme}
579
611
  wordWrap={wordWrap}
612
+ wheelWrapperRef={wheelWrapperRef}
580
613
  autoHeight={autoHeight}
614
+ handleInfiniteScroll={handleInfiniteScroll}
581
615
  sortColumn={sortColumn}
582
616
  style={{ position: 'relative' }}
583
617
  sortType={sortType}
584
618
  onSortColumn={handleSortColumn}
619
+ infiniteLoading={infiniteLoading}
585
620
  onRowClick={onRowClick}
586
621
  tableBodyHeight={tableBodyHeight}
587
622
  cellBordered={cellBordered}
@@ -707,6 +742,8 @@ const QbsTable: React.FC<QbsTableProps> = ({
707
742
  onReorder={onReorder}
708
743
  isOpen={isOpen}
709
744
  tableHeight={height}
745
+ viewMode={viewMode}
746
+ setViewMode={setViewMode}
710
747
  setIsOpen={setIsOpen}
711
748
  handleResetColumns={handleResetColumns}
712
749
  handleColumnToggle={handleColumnToggle}
@@ -731,6 +768,8 @@ const QbsTable: React.FC<QbsTableProps> = ({
731
768
  onToggle={handleToggle}
732
769
  tableHeight={height}
733
770
  onReorder={onReorder}
771
+ viewMode={viewMode}
772
+ setViewMode={setViewMode}
734
773
  isOpen={isOpen}
735
774
  setIsOpen={setIsOpen}
736
775
  handleResetColumns={handleResetColumns}
@@ -90,6 +90,7 @@ const QbsTable: React.FC<QbsTableProps> = ({
90
90
  const [isOpen, setIsOpen] = useState(false);
91
91
  const prevColumns = useRef<any | null>(null);
92
92
  const tableBodyRef = useRef<HTMLDivElement>(null);
93
+ const wheelWrapperRef = useRef<HTMLDivElement>(null);
93
94
  const handleSortColumn = useCallback(
94
95
  (sortColumn: any, sortType: any) => {
95
96
  setLoading(true);
@@ -450,6 +451,7 @@ const QbsTable: React.FC<QbsTableProps> = ({
450
451
  wordWrap={wordWrap}
451
452
  autoHeight={autoHeight}
452
453
  sortColumn={sortColumn}
454
+ wheelWrapperRef={wheelWrapperRef}
453
455
  style={{ position: 'relative' }}
454
456
  sortType={sortType}
455
457
  onSortColumn={handleSortColumn}
@@ -130,6 +130,12 @@ export interface QbsTableProps {
130
130
  handleTableCardView?: (data: any) => React.ReactNode;
131
131
  isCustomTableCardView?: boolean;
132
132
  handleCustomCardLoader?: () => React.ReactNode;
133
+ hasMoreData?: boolean
134
+ loadMoreData?: ()=> void
135
+ infiniteScroll?: boolean
136
+ infiniteLoading?:boolean
137
+ viewMode?:string
138
+
133
139
  }
134
140
 
135
141
  export interface QbsTableToolbarProps {
@@ -12,6 +12,8 @@ interface ColumnToggleProps {
12
12
  handleColumnToggle?: (columns: QbsColumnProps[]) => void;
13
13
  handleResetColumns?: () => void;
14
14
  tableHeight?: number;
15
+ viewMode?: string;
16
+ setViewMode?: (value: string) => void;
15
17
  }
16
18
 
17
19
  const ColumnToggle: React.FC<ColumnToggleProps> = ({
@@ -22,7 +24,9 @@ const ColumnToggle: React.FC<ColumnToggleProps> = ({
22
24
  setIsOpen,
23
25
  handleResetColumns,
24
26
  handleColumnToggle,
25
- tableHeight = 450
27
+ tableHeight = 450,
28
+ viewMode,
29
+ setViewMode
26
30
  }) => {
27
31
  const [draggedItem, setDraggedItem] = useState<number | null>(null);
28
32
  const popupRef = useRef<HTMLDivElement | null>(null);
@@ -239,6 +243,27 @@ const ColumnToggle: React.FC<ColumnToggleProps> = ({
239
243
  </div>
240
244
  </>
241
245
  )}
246
+ <div className="qbs-table-popup-item">
247
+ <label className="flex items-center gap-2">
248
+ <input
249
+ type="radio"
250
+ value="compact"
251
+ checked={viewMode === 'compact'}
252
+ onChange={() => setViewMode?.('compact')}
253
+ />
254
+ Compact View
255
+ </label>
256
+
257
+ <label className="flex items-center gap-2">
258
+ <input
259
+ type="radio"
260
+ value="expanded"
261
+ checked={viewMode === 'expanded'}
262
+ onChange={() => setViewMode?.('expanded')}
263
+ />
264
+ Default View
265
+ </label>
266
+ </div>
242
267
  </div>
243
268
  </div>
244
269
  )}
@@ -205,7 +205,6 @@ const useCellDescriptor = <Row extends RowDataType>(
205
205
  if (treeCol) {
206
206
  hasCustomTreeCol = true;
207
207
  }
208
- console.log(columns);
209
208
 
210
209
  if (columnChildren?.length !== 2) {
211
210
  throw new Error(`Component <HeaderCell> and <Cell> is required, column index: ${index} `);
@@ -4,6 +4,7 @@ import scrollLeft from 'dom-lib/scrollLeft';
4
4
  import scrollTop from 'dom-lib/scrollTop';
5
5
  import WheelHandler from 'dom-lib/WheelHandler';
6
6
  import React, { useCallback, useEffect, useRef, useState } from 'react';
7
+
7
8
  import type { ListenerCallback, RowDataType } from '../@types/common';
8
9
  import { BEZIER, SCROLLBAR_WIDTH, TRANSITION_DURATION } from '../constants';
9
10
  import type { ScrollbarInstance } from '../Scrollbar';
@@ -50,6 +51,7 @@ interface ScrollListenerProps {
50
51
  onTouchStart?: (event: React.TouchEvent) => void;
51
52
  onTouchMove?: (event: React.TouchEvent) => void;
52
53
  onTouchEnd?: (event: React.TouchEvent) => void;
54
+ handleInfiniteScroll?: (value: number) => void;
53
55
  }
54
56
 
55
57
  /**
@@ -106,7 +108,8 @@ const useScrollListener = (props: ScrollListenerProps) => {
106
108
  contentHeight,
107
109
  headerHeight,
108
110
  rtl,
109
- tableKey
111
+ tableKey,
112
+ handleInfiniteScroll
110
113
  } = props;
111
114
 
112
115
  const wheelListener = useRef<ListenerCallback>(null);
@@ -186,6 +189,21 @@ const useScrollListener = (props: ScrollListenerProps) => {
186
189
 
187
190
  setScrollX(x);
188
191
  setScrollY(y);
192
+ console.log(
193
+ scrollY.current,
194
+ contentHeight.current,
195
+ nextScrollY,
196
+ minScrollY.current,
197
+ 'scrolllistner'
198
+ );
199
+ if (
200
+ typeof handleInfiniteScroll === 'function' &&
201
+ deltaY !== 0 &&
202
+ !loading &&
203
+ Math.abs(y) + getTableHeight() >= contentHeight.current - 12
204
+ ) {
205
+ handleInfiniteScroll(scrollY.current);
206
+ }
189
207
 
190
208
  onScroll?.(Math.abs(x), Math.abs(y));
191
209
 
@@ -297,7 +315,6 @@ const useScrollListener = (props: ScrollListenerProps) => {
297
315
  if (!isTouching.current) {
298
316
  return;
299
317
  }
300
- console.log('handleTouchMove');
301
318
 
302
319
  const { pageX, pageY } = event.touches[0];
303
320
  const deltaX = touchX.current - pageX;