qbs-react-grid 2.2.16 → 2.2.18

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.
Files changed (79) hide show
  1. package/dist/css/qbs-react-grid.css +1 -1
  2. package/dist/css/qbs-react-grid.min.css +1 -1
  3. package/dist/css/qbs-react-grid.min.css.map +1 -1
  4. package/es/Cell.js +2 -1
  5. package/es/Pagination.d.ts +3 -0
  6. package/es/Pagination.js +8 -3
  7. package/es/Table.d.ts +3 -0
  8. package/es/Table.js +18 -12
  9. package/es/index.d.ts +1 -1
  10. package/es/index.js +1 -1
  11. package/es/less/pagination.less +9 -9
  12. package/es/less/qbs-table.less +1 -2
  13. package/es/qbsTable/QbsTable.js +110 -73
  14. package/es/qbsTable/TableCardList.js +2 -0
  15. package/es/qbsTable/Toolbar.js +6 -3
  16. package/es/qbsTable/commontypes.d.ts +21 -12
  17. package/es/qbsTable/labels.d.ts +6 -2
  18. package/es/qbsTable/labels.js +10 -1
  19. package/es/qbsTable/utilities/CardComponent.d.ts +2 -0
  20. package/es/qbsTable/utilities/CardComponent.js +7 -3
  21. package/es/qbsTable/utilities/CardMenuDropdown.d.ts +2 -0
  22. package/es/qbsTable/utilities/CardMenuDropdown.js +7 -7
  23. package/es/qbsTable/utilities/SearchInput.d.ts +1 -0
  24. package/es/qbsTable/utilities/SearchInput.js +3 -1
  25. package/es/qbsTable/utilities/empty.js +1 -1
  26. package/es/qbsTable/utilities/tablecalc.d.ts +1 -1
  27. package/es/qbsTable/utilities/tablecalc.js +7 -2
  28. package/es/utils/useCellDescriptor.js +0 -1
  29. package/es/utils/useScrollListener.d.ts +1 -0
  30. package/es/utils/useScrollListener.js +5 -3
  31. package/lib/Cell.js +2 -1
  32. package/lib/Pagination.d.ts +3 -0
  33. package/lib/Pagination.js +8 -3
  34. package/lib/Table.d.ts +3 -0
  35. package/lib/Table.js +18 -12
  36. package/lib/index.d.ts +1 -1
  37. package/lib/index.js +3 -1
  38. package/lib/less/pagination.less +9 -9
  39. package/lib/less/qbs-table.less +1 -2
  40. package/lib/qbsTable/QbsTable.js +110 -73
  41. package/lib/qbsTable/TableCardList.js +2 -0
  42. package/lib/qbsTable/Toolbar.js +6 -3
  43. package/lib/qbsTable/commontypes.d.ts +21 -12
  44. package/lib/qbsTable/labels.d.ts +6 -2
  45. package/lib/qbsTable/labels.js +13 -2
  46. package/lib/qbsTable/utilities/CardComponent.d.ts +2 -0
  47. package/lib/qbsTable/utilities/CardComponent.js +7 -3
  48. package/lib/qbsTable/utilities/CardMenuDropdown.d.ts +2 -0
  49. package/lib/qbsTable/utilities/CardMenuDropdown.js +6 -5
  50. package/lib/qbsTable/utilities/SearchInput.d.ts +1 -0
  51. package/lib/qbsTable/utilities/SearchInput.js +3 -1
  52. package/lib/qbsTable/utilities/empty.js +1 -1
  53. package/lib/qbsTable/utilities/tablecalc.d.ts +1 -1
  54. package/lib/qbsTable/utilities/tablecalc.js +7 -2
  55. package/lib/utils/useCellDescriptor.js +0 -1
  56. package/lib/utils/useScrollListener.d.ts +1 -0
  57. package/lib/utils/useScrollListener.js +5 -3
  58. package/package.json +2 -2
  59. package/src/Cell.tsx +3 -1
  60. package/src/HeaderCell.tsx +0 -1
  61. package/src/Pagination.tsx +10 -3
  62. package/src/Table.tsx +23 -10
  63. package/src/customSelect.tsx +88 -88
  64. package/src/index.ts +2 -0
  65. package/src/less/pagination.less +9 -9
  66. package/src/less/qbs-table.less +1 -2
  67. package/src/qbsTable/QbsTable.tsx +84 -39
  68. package/src/qbsTable/TableCardList.tsx +2 -0
  69. package/src/qbsTable/Toolbar.tsx +4 -2
  70. package/src/qbsTable/commontypes.ts +21 -12
  71. package/src/qbsTable/labels.ts +9 -2
  72. package/src/qbsTable/utilities/CardComponent.tsx +7 -2
  73. package/src/qbsTable/utilities/CardMenuDropdown.tsx +11 -6
  74. package/src/qbsTable/utilities/SearchInput.tsx +3 -1
  75. package/src/qbsTable/utilities/empty.tsx +2 -2
  76. package/src/qbsTable/utilities/tablecalc.ts +8 -2
  77. package/src/utils/useCellDescriptor.ts +0 -1
  78. package/src/utils/useScrollListener.ts +13 -3
  79. package/src/utils/useTableRows.ts +1 -1
@@ -6,6 +6,7 @@ import ColumnGroup from '../ColumnGroup';
6
6
  import HeaderCell from '../HeaderCell';
7
7
  import Pagination from '../Pagination';
8
8
  import Table from '../Table';
9
+ import isRTL from '../utils/isRTL';
9
10
  import useResponsiveStore from '../utils/useResponsiveStore';
10
11
  import { QbsColumnProps, QbsTableProps } from './commontypes';
11
12
  import { mergeQbsTableLabels } from './labels';
@@ -31,6 +32,7 @@ import '../../dist/css/qbs-react-grid.css';
31
32
 
32
33
  const CHECKBOX_LINE_HEIGHT = '36px';
33
34
  const COLUMN_WIDTH = 250;
35
+ let REFRESH_KEY = 0;
34
36
  const QbsTable: React.FC<QbsTableProps> = ({
35
37
  handleColumnSort,
36
38
  data,
@@ -52,7 +54,7 @@ const QbsTable: React.FC<QbsTableProps> = ({
52
54
  minHeight,
53
55
  height = 630,
54
56
  onExpandChange,
55
- wordWrap,
57
+ wordWrap: propsWordWrap,
56
58
  dataRowKey = 'id',
57
59
  defaultExpandAllRows,
58
60
  handleRowExpanded,
@@ -60,6 +62,7 @@ const QbsTable: React.FC<QbsTableProps> = ({
60
62
  rowExpand = false,
61
63
  actionProps = [],
62
64
  theme,
65
+ rtl: rtlProp,
63
66
  handleMenuActions,
64
67
  onRowClick,
65
68
  expandedRowKeys,
@@ -93,33 +96,42 @@ const QbsTable: React.FC<QbsTableProps> = ({
93
96
  isCustomTableCardView = false,
94
97
  handleTableCardView,
95
98
  handleCustomCardLoader,
96
- dropType,
97
- labels: labelsProp,
98
- rtl = false,
99
+ hasMoreData,
100
+ loadMoreData,
101
+ infiniteLoading,
102
+ infiniteScroll = false,
99
103
  rowViewToggle = false,
100
104
  defaultRowView = true,
101
105
  fullWidthView = false,
102
106
  setTableFullView,
103
107
  setRowViewToggle,
104
- isFullScreen = false,
108
+ dropType = 'horizondal',
105
109
  rowHeight,
110
+ isFullScreen,
106
111
  showHeader = true,
112
+ labels: labelsProp
107
113
  }) => {
108
114
  const labels = useMemo(() => mergeQbsTableLabels(labelsProp), [labelsProp]);
109
- const effectiveWordWrap = useMemo(() => {
110
- if (!rowViewToggle) return wordWrap;
111
- return defaultRowView ? false : 'break-word';
112
- }, [rowViewToggle, defaultRowView, wordWrap]);
115
+ const [rowViewRefreshKey, setRowViewRefreshKey] = useState(0);
113
116
  const [loading, setLoading] = useState(false);
114
117
  const [columns, setColumns] = useState(propColumn);
115
118
  const [checkedKeys, setCheckedKeys] = useState<(number | string)[]>([]);
116
- const dataTheme = useMemo(() => localStorage.getItem('theme') ?? theme, [theme]);
119
+ const dataTheme = useMemo(
120
+ () => theme ?? (typeof localStorage !== 'undefined' ? localStorage.getItem('theme') : null) ?? 'light',
121
+ [theme]
122
+ );
123
+ const rtl = rtlProp ?? isRTL();
117
124
  const [isOpen, setIsOpen] = useState(false);
118
125
  const prevColumns = useRef<any | null>(null);
119
126
  const [tableViewToggle, setTableViewToggle] = useState(tableView);
120
127
  const isMobile = useResponsiveStore();
121
128
  const tableBodyRef = useRef<HTMLDivElement>(null);
122
- const [rowViewRefreshKey, setRowViewRefreshKey] = useState(0);
129
+ const wheelWrapperRef = useRef<HTMLDivElement>(null);
130
+ const [wordWrap, setWordWrap] = useState(propsWordWrap ?? false);
131
+ const effectiveWordWrap = useMemo(() => {
132
+ if (!rowViewToggle) return wordWrap;
133
+ return defaultRowView ? false : 'break-word';
134
+ }, [rowViewToggle, defaultRowView, wordWrap]);
123
135
 
124
136
  useEffect(() => {
125
137
  if (rowViewToggle) {
@@ -178,16 +190,6 @@ const QbsTable: React.FC<QbsTableProps> = ({
178
190
  [checkedKeys]
179
191
  );
180
192
 
181
- const rowKeyField = dataRowKey ?? 'id';
182
- const getRowClassName = useCallback(
183
- (rowData: Record<string, unknown>) => {
184
- if (!selection) return '';
185
- const key = rowData?.[rowKeyField] as string | number | undefined;
186
- return key !== undefined && checkedKeys?.includes(key) ? 'qbs-table-row-checked' : '';
187
- },
188
- [selection, checkedKeys, rowKeyField]
189
- );
190
-
191
193
  const handleToggle = useCallback(
192
194
  (columnName: string) => {
193
195
  let lastVisibleColumn: any = null;
@@ -223,6 +225,7 @@ const QbsTable: React.FC<QbsTableProps> = ({
223
225
 
224
226
  const handleColumnWidth = useCallback((newWidth?: number, dataKey?: any) => {
225
227
  if (newWidth === undefined || dataKey === undefined) return;
228
+ REFRESH_KEY = REFRESH_KEY + 1;
226
229
  setColumns(prevColumns =>
227
230
  prevColumns.map(column =>
228
231
  column.field === dataKey ? { ...column, colWidth: newWidth } : column
@@ -239,6 +242,14 @@ const QbsTable: React.FC<QbsTableProps> = ({
239
242
  );
240
243
  }
241
244
  }, [wordWrap]);
245
+ useEffect(() => {
246
+ if (!defaultRowView) {
247
+ setWordWrap('break-word');
248
+ } else {
249
+ setWordWrap(false);
250
+ }
251
+ REFRESH_KEY = REFRESH_KEY + 1;
252
+ }, [defaultRowView]);
242
253
 
243
254
  const onReorder = useCallback((columns: QbsColumnProps[]) => {
244
255
  setColumns(columns);
@@ -246,7 +257,6 @@ const QbsTable: React.FC<QbsTableProps> = ({
246
257
 
247
258
  // useEffect(() => {
248
259
  // }, [columns]);
249
-
250
260
  const handleClear = ([]) => {
251
261
  setCheckedKeys([]);
252
262
  handleChecked([]);
@@ -277,18 +287,31 @@ const QbsTable: React.FC<QbsTableProps> = ({
277
287
  setTableViewToggle: setTableViewToggle,
278
288
  tableViewToggle: tableViewToggle,
279
289
  enableTableToggle: enableTableToggle,
280
- rowViewToggle,
281
- defaultRowView,
282
- fullWidthView,
283
- setTableFullView,
284
- setRowViewToggle,
285
- isFullScreen,
290
+ rowViewToggle: rowViewToggle,
291
+ defaultRowView: defaultRowView,
292
+ fullWidthView: fullWidthView,
293
+ setTableFullView: setTableFullView,
294
+ setRowViewToggle: setRowViewToggle,
295
+ isFullScreen: isFullScreen,
286
296
  labels,
287
297
  rtl,
288
298
  };
289
- const themeToggle = useMemo(() => document.getElementById('themeToggle') as HTMLInputElement, []);
290
299
 
291
300
  useEffect(() => {
301
+ if (!dataTheme || typeof document === 'undefined') return;
302
+
303
+ document.body.setAttribute('data-theme', dataTheme === 'dark' ? 'dark' : 'light');
304
+ document.documentElement.dataset.theme = dataTheme;
305
+ }, [dataTheme]);
306
+
307
+ const themeToggle = useMemo(
308
+ () => (typeof document !== 'undefined' ? document.getElementById('themeToggle') : null),
309
+ []
310
+ ) as HTMLInputElement | null;
311
+
312
+ useEffect(() => {
313
+ if (theme || typeof document === 'undefined') return;
314
+
292
315
  const handleThemeToggle = () => {
293
316
  if (themeToggle?.checked) {
294
317
  document.body.setAttribute('data-theme', 'dark');
@@ -313,11 +336,10 @@ const QbsTable: React.FC<QbsTableProps> = ({
313
336
  themeToggle?.removeEventListener('change', handleThemeToggle);
314
337
  document.removeEventListener('DOMContentLoaded', handleDOMContentLoaded);
315
338
  };
316
- }, [themeToggle]);
339
+ }, [theme, themeToggle]);
317
340
 
318
341
  const handleExpanded = useCallback(
319
342
  (rowData: any) => {
320
- console.log(rowData);
321
343
  const keyValue = dataRowKey as string;
322
344
  const key = rowData[keyValue];
323
345
 
@@ -607,8 +629,25 @@ const QbsTable: React.FC<QbsTableProps> = ({
607
629
  [columns, dataTheme]
608
630
  );
609
631
 
632
+ const handleInfiniteScroll = (scroll: number) => {
633
+ if (!infiniteScroll) return;
634
+ const wrapper = wheelWrapperRef.current;
635
+ if (!wrapper || !hasMoreData || infiniteLoading) return;
636
+
637
+ const { scrollTop, clientHeight } = wrapper;
638
+ const scrollHeight = Math.abs(scroll) + (height - headerHeight);
639
+ // Trigger fetch when user scrolls within 100px of bottom
640
+ if (scrollTop + clientHeight >= scrollHeight - 70) {
641
+ loadMoreData?.(); // fetch next page here
642
+ }
643
+ };
644
+
610
645
  return (
611
- <div className={`qbs-table ${classes.tableContainerClass}`} data-theme={dataTheme}>
646
+ <div
647
+ className={`qbs-table ${classes.tableContainerClass}`}
648
+ data-theme={dataTheme}
649
+ dir={rtl ? 'rtl' : 'ltr'}
650
+ >
612
651
  {toolbar && <ToolBar {...toolbarProps} />}
613
652
  <div className="qbs-table-border-wrap">
614
653
  {tableViewToggle ? (
@@ -616,16 +655,20 @@ const QbsTable: React.FC<QbsTableProps> = ({
616
655
  height={autoHeight ? undefined : height}
617
656
  key={`${tableKey}-${rowViewRefreshKey}`}
618
657
  tableKey={tableKey}
619
- rtl={rtl}
620
658
  data={data}
659
+ rtl={rtl}
621
660
  tableBodyRef={tableBodyRef as React.RefObject<HTMLDivElement>}
622
661
  dataTheme={dataTheme}
623
662
  wordWrap={effectiveWordWrap}
663
+ wheelWrapperRef={wheelWrapperRef}
664
+ rowHeight={rowHeight}
624
665
  autoHeight={autoHeight}
666
+ handleInfiniteScroll={handleInfiniteScroll}
625
667
  sortColumn={sortColumn}
626
668
  style={{ position: 'relative' }}
627
669
  sortType={sortType}
628
670
  onSortColumn={handleSortColumn}
671
+ infiniteLoading={infiniteLoading}
629
672
  onRowClick={onRowClick}
630
673
  tableBodyHeight={tableBodyHeight}
631
674
  cellBordered={cellBordered}
@@ -634,13 +677,12 @@ const QbsTable: React.FC<QbsTableProps> = ({
634
677
  renderEmpty ? (
635
678
  renderEmpty(info)
636
679
  ) : (
637
- <NoData title={emptyTitle ?? 'No Data Found'} subtitle={emptySubTitle} />
680
+ <NoData title={emptyTitle ?? labels.noDataFound} subtitle={emptySubTitle} />
638
681
  )
639
682
  }
640
683
  columns={columns}
641
684
  minHeight={minHeight}
642
685
  headerHeight={headerHeight}
643
- rowHeight={rowHeight}
644
686
  rowExpandedHeight={rowExpandedHeight}
645
687
  loading={isLoading ?? loading}
646
688
  showHeader={showHeader}
@@ -648,7 +690,6 @@ const QbsTable: React.FC<QbsTableProps> = ({
648
690
  expandedRowKeys={expandedRowKeys}
649
691
  onExpandChange={onExpandChange}
650
692
  rowKey={dataRowKey ?? 'id'}
651
- rowClassName={selection ? getRowClassName : undefined}
652
693
  defaultExpandAllRows={defaultExpandAllRows}
653
694
  shouldUpdateScroll={shouldUpdateScroll}
654
695
  renderRowExpanded={rowData => {
@@ -790,11 +831,12 @@ const QbsTable: React.FC<QbsTableProps> = ({
790
831
  </HeaderCell>
791
832
  <ActionCell
792
833
  tableBodyRef={tableBodyRef}
834
+ dropType={dropType}
835
+ wheelWrapperRef={wheelWrapperRef}
793
836
  actionProps={actionProps}
794
837
  className={`${classes.cellClass} ${classes.actionCellClass}`}
795
838
  handleMenuActions={handleMenuActions}
796
839
  dataTheme={dataTheme}
797
- dropType={dropType}
798
840
  />
799
841
  </Column>
800
842
  )}
@@ -816,7 +858,7 @@ const QbsTable: React.FC<QbsTableProps> = ({
816
858
  >
817
859
  {(data?.length === 0 || !data) && !isLoading && (
818
860
  <div className="flex flex-col gap-2 p-2 mt-6 card-empty-container">
819
- <NoData title={emptyTitle ?? 'No Data Found'} subtitle={emptySubTitle} />
861
+ <NoData title={emptyTitle ?? labels.noDataFound} subtitle={emptySubTitle} />
820
862
  </div>
821
863
  )}
822
864
  {isLoading ? (
@@ -843,6 +885,7 @@ const QbsTable: React.FC<QbsTableProps> = ({
843
885
  columns={columns}
844
886
  tableBodyRef={tableBodyRef}
845
887
  actionProps={actionProps}
888
+ labels={labels}
846
889
  />
847
890
  )}
848
891
  </div>
@@ -851,7 +894,9 @@ const QbsTable: React.FC<QbsTableProps> = ({
851
894
  </div>
852
895
  )}
853
896
  <div>
854
- {pagination && data?.length > 0 && <Pagination paginationProps={paginationProps} />}
897
+ {pagination && data?.length > 0 && (
898
+ <Pagination paginationProps={paginationProps} labels={labels} dataTheme={dataTheme} />
899
+ )}
855
900
  </div>
856
901
  </div>
857
902
  </div>
@@ -106,6 +106,7 @@ const QbsTable: React.FC<QbsTableProps> = ({
106
106
  const [isOpen, setIsOpen] = useState(false);
107
107
  const prevColumns = useRef<any | null>(null);
108
108
  const tableBodyRef = useRef<HTMLDivElement>(null);
109
+ const wheelWrapperRef = useRef<HTMLDivElement>(null);
109
110
  const handleSortColumn = useCallback(
110
111
  (sortColumn: any, sortType: any) => {
111
112
  setLoading(true);
@@ -481,6 +482,7 @@ const QbsTable: React.FC<QbsTableProps> = ({
481
482
  rtl={rtl}
482
483
  data={data}
483
484
  tableBodyRef={tableBodyRef as React.RefObject<HTMLDivElement>}
485
+ wheelWrapperRef={wheelWrapperRef}
484
486
  dataTheme={dataTheme}
485
487
  wordWrap={effectiveWordWrap}
486
488
  autoHeight={autoHeight}
@@ -230,11 +230,12 @@ const ToolBar: React.FC<QbsTableToolbarProps> = ({
230
230
  {handleHide(actions) && (
231
231
  <button
232
232
  type="button"
233
- className="btn"
233
+ className={`btn ${actions?.buttonClassName ?? ''}`}
234
234
  disabled={actions.disabled}
235
235
  onClick={() => actions?.action(checkedKeys)}
236
236
  >
237
- {actions.actionTitle}
237
+ {actions?.icon && <span className="mr-2">{actions.icon}</span>}
238
+ <span>{actions.actionTitle}</span>
238
239
  </button>
239
240
  )}
240
241
  </React.Fragment>
@@ -249,6 +250,7 @@ const ToolBar: React.FC<QbsTableToolbarProps> = ({
249
250
  paginationProps.total ?? 0,
250
251
  paginationProps.rowsPerPage ?? 0,
251
252
  paginationProps.currentPage ?? 0,
253
+ labels.showingRange,
252
254
  )}
253
255
  </div>
254
256
  )}
@@ -45,7 +45,7 @@ export interface PaginationProps {
45
45
  export interface ActionProps {
46
46
  title?: string;
47
47
  action?: (row: any) => void;
48
- icon: React.ReactNode;
48
+ icon?: React.ReactNode;
49
49
  toolTip?: string;
50
50
  hidden?: boolean;
51
51
  hide?: (data: any, index?: number) => boolean;
@@ -76,6 +76,7 @@ export interface QbsTableProps {
76
76
  searchValue?: string;
77
77
  handleSearchValue?: (value?: string) => void;
78
78
  theme?: string;
79
+ rtl?: boolean;
79
80
  onRowClick?: (data: any) => void;
80
81
  cellBordered?: boolean;
81
82
  bordered?: boolean;
@@ -89,9 +90,8 @@ export interface QbsTableProps {
89
90
  expandedRowKeys?: readonly number[];
90
91
  setExpandedRowKeys?: (value: readonly number[]) => void;
91
92
  handleMenuActions?: (actions: ActionProps, rowData: any) => void;
92
- dropType?: 'vertical' | string;
93
+ dropType?: 'horizondal' | 'vertical' | string;
93
94
  labels?: QbsTableLabels;
94
- rtl?: boolean;
95
95
  handleRowExpanded?: (rowData: any) => React.ReactNode;
96
96
  shouldUpdateScroll?: boolean;
97
97
  rowExpand?: boolean;
@@ -105,6 +105,8 @@ export interface QbsTableProps {
105
105
  disabled?: boolean;
106
106
  hidden?: boolean;
107
107
  customHide?: string;
108
+ buttonClassName?: string;
109
+ icon?: ReactElement | ReactNode;
108
110
  }[];
109
111
  selectedRows?: (number | string)[];
110
112
  classes?: { [key: string]: any };
@@ -135,13 +137,18 @@ export interface QbsTableProps {
135
137
  handleTableCardView?: (data: any) => React.ReactNode;
136
138
  isCustomTableCardView?: boolean;
137
139
  handleCustomCardLoader?: () => React.ReactNode;
140
+ hasMoreData?: boolean;
141
+ loadMoreData?: () => void;
142
+ infiniteScroll?: boolean;
143
+ infiniteLoading?: boolean;
144
+ viewMode?: string;
138
145
  rowViewToggle?: boolean;
139
146
  defaultRowView?: boolean;
140
147
  fullWidthView?: boolean;
141
148
  setTableFullView?: (value: boolean) => void;
142
149
  setRowViewToggle?: (value: boolean) => void;
143
- isFullScreen?: boolean;
144
150
  rowHeight?: number;
151
+ isFullScreen?: boolean;
145
152
  showHeader?: boolean;
146
153
  }
147
154
 
@@ -168,23 +175,25 @@ export interface QbsTableToolbarProps {
168
175
  dataLength: number;
169
176
  headerHeight?: number;
170
177
  searchPlaceholder?: string;
178
+ labels?: QbsTableLabels;
179
+ rtl?: boolean;
171
180
  tableView?: boolean;
172
181
  enableTableToggle?: boolean;
173
182
  tableViewToggle?: boolean;
174
183
  setTableViewToggle?: (value: boolean) => void;
175
- rowViewToggle?: boolean;
176
- defaultRowView?: boolean;
177
- fullWidthView?: boolean;
178
- setTableFullView?: (value: boolean) => void;
179
- setRowViewToggle?: (value: boolean) => void;
180
- isFullScreen?: boolean;
181
- labels?: QbsTableLabels;
182
- rtl?: boolean;
183
184
  selectedRowActions?: {
184
185
  actionTitle?: string;
185
186
  action: (checked: (number | string)[]) => void;
186
187
  disabled?: boolean;
187
188
  hidden?: boolean;
188
189
  customHide?: string;
190
+ buttonClassName?: string;
191
+ icon?: ReactElement | ReactNode;
189
192
  }[];
193
+ rowViewToggle?: boolean;
194
+ defaultRowView?: boolean;
195
+ fullWidthView?: boolean;
196
+ setTableFullView?: (value: boolean) => void;
197
+ setRowViewToggle?: (value: boolean) => void;
198
+ isFullScreen?: boolean;
190
199
  }
@@ -1,4 +1,4 @@
1
- export type QbsTableLabels = {
1
+ export interface QbsTableLabels {
2
2
  search?: string;
3
3
  searchAriaLabel?: string;
4
4
  clear?: string;
@@ -19,7 +19,7 @@ export type QbsTableLabels = {
19
19
  viewMore?: string;
20
20
  viewLess?: string;
21
21
  actions?: string;
22
- };
22
+ }
23
23
 
24
24
  export const defaultQbsTableLabels: QbsTableLabels = {
25
25
  search: 'Search',
@@ -44,11 +44,18 @@ export const defaultQbsTableLabels: QbsTableLabels = {
44
44
  actions: 'Actions',
45
45
  };
46
46
 
47
+ /** @deprecated Use defaultQbsTableLabels */
48
+ export const DEFAULT_QBS_TABLE_LABELS = defaultQbsTableLabels;
49
+
47
50
  export const mergeQbsTableLabels = (overrides?: QbsTableLabels): QbsTableLabels => ({
48
51
  ...defaultQbsTableLabels,
49
52
  ...overrides,
53
+ showingRange: overrides?.showingRange ?? defaultQbsTableLabels.showingRange,
50
54
  });
51
55
 
56
+ /** @deprecated Use mergeQbsTableLabels */
57
+ export const mergeLabels = mergeQbsTableLabels;
58
+
52
59
  export const formatSelectedItems = (count: number, labels?: QbsTableLabels): string => {
53
60
  const merged = mergeQbsTableLabels(labels);
54
61
  return `${merged.selectedItems} (${count})`;
@@ -1,6 +1,7 @@
1
1
  import React, { useRef, useState } from 'react';
2
2
 
3
3
  import { QbsColumnProps } from '../commontypes';
4
+ import { mergeLabels, type QbsTableLabels } from '../labels';
4
5
  import CardMenuDropdown from './CardMenuDropdown';
5
6
  import { handleCellFormat } from './handleFormatCell';
6
7
  import { ArrowUpIcon } from './icons';
@@ -17,6 +18,7 @@ type Props = {
17
18
  handleMenuActions?: () => void;
18
19
  cardColumLimit?: number;
19
20
  childDetailHeading?: string;
21
+ labels?: QbsTableLabels;
20
22
  };
21
23
 
22
24
  const CardComponent: React.FC<Props> = ({
@@ -27,8 +29,10 @@ const CardComponent: React.FC<Props> = ({
27
29
  index,
28
30
  cardColumLimit = 5,
29
31
  handleMenuActions,
30
- childDetailHeading = ''
32
+ childDetailHeading = '',
33
+ labels: labelsProp
31
34
  }) => {
35
+ const labels = mergeLabels(labelsProp);
32
36
  const [viewMore, setViewMore] = useState(false);
33
37
  const initialDisplayCount = cardColumLimit;
34
38
 
@@ -102,13 +106,14 @@ const CardComponent: React.FC<Props> = ({
102
106
  iconName="more"
103
107
  rowIndex={index}
104
108
  handleMenuActions={handleMenuActions}
109
+ labels={labels}
105
110
  />
106
111
  </div>
107
112
 
108
113
  {columns.length > initialDisplayCount && (
109
114
  <TooltipComponent
110
115
  tableBodyRef={useCardRef}
111
- title={viewMore ? ' View Less' : 'View More'}
116
+ title={viewMore ? labels.viewLess : labels.viewMore}
112
117
  enabled={false}
113
118
  >
114
119
  <button
@@ -1,7 +1,6 @@
1
- import { useEffect, useRef, useState } from 'react';
2
- import React from 'react';
3
-
1
+ import React, { useEffect, useRef, useState } from 'react';
4
2
  import { ActionProps } from '../commontypes';
3
+ import { mergeLabels, type QbsTableLabels } from '../labels';
5
4
  import { ThreeDotIcon } from './icons';
6
5
  import TooltipComponent from './ToolTip';
7
6
 
@@ -13,9 +12,16 @@ type Props = {
13
12
  dataTheme?: string;
14
13
  tableBodyRef: React.RefObject<HTMLDivElement>;
15
14
  rowIndex?: number;
15
+ labels?: QbsTableLabels;
16
16
  };
17
17
 
18
- const CardMenuDropdown: React.FC<Props> = ({ actionDropDown, handleMenuActions, rowData }) => {
18
+ const CardMenuDropdown: React.FC<Props> = ({
19
+ actionDropDown,
20
+ handleMenuActions,
21
+ rowData,
22
+ labels: labelsProp
23
+ }) => {
24
+ const labels = mergeLabels(labelsProp);
19
25
  const [openMenu, setOpenMenu] = useState(false);
20
26
  const [menuPositionStyles, setMenuPositionStyles] = useState<{
21
27
  top?: string;
@@ -46,7 +52,6 @@ const CardMenuDropdown: React.FC<Props> = ({ actionDropDown, handleMenuActions,
46
52
  const dropdownHeight = 200; // Adjust this if your dropdown height varies
47
53
  const spaceBelow = window.innerHeight - buttonRect.bottom;
48
54
  const spaceAbove = buttonRect.top;
49
- console.log(spaceAbove, spaceBelow, dropdownHeight);
50
55
  if (spaceBelow < dropdownHeight && spaceAbove > spaceBelow) {
51
56
  setMenuPositionStyles({
52
57
  bottom: '30px',
@@ -76,7 +81,7 @@ const CardMenuDropdown: React.FC<Props> = ({ actionDropDown, handleMenuActions,
76
81
  return (
77
82
  <div className="dropdown text-black dark:text-white dark:bg-[#424242] bg-white" ref={menuRef}>
78
83
  <button className="dropdown-toggle" onClick={toggleMenu} ref={menuButtonRef}>
79
- <TooltipComponent title="Actions" enabled={false} ref={menuButtonRef}>
84
+ <TooltipComponent title={labels.actions} enabled={false}>
80
85
  <ThreeDotIcon />
81
86
  </TooltipComponent>
82
87
  </button>
@@ -2,12 +2,14 @@ import React, { memo, useCallback } from 'react';
2
2
 
3
3
  export interface SearchProps {
4
4
  placeholder: string;
5
+ searchAriaLabel?: string;
5
6
  handleChange: (value: string) => void;
6
7
  searchValue: string | undefined;
7
8
  handleSearch: (value?: string) => void;
8
9
  }
9
10
  const SearchInput: React.FC<SearchProps> = ({
10
11
  placeholder,
12
+ searchAriaLabel = 'Search',
11
13
  handleChange,
12
14
  searchValue,
13
15
  handleSearch
@@ -37,7 +39,7 @@ const SearchInput: React.FC<SearchProps> = ({
37
39
  placeholder={placeholder}
38
40
  value={searchValue ?? ''}
39
41
  onChange={handleInputChange}
40
- aria-label="Search"
42
+ aria-label={searchAriaLabel}
41
43
  />
42
44
  <button
43
45
  className="search-button absolute left-1 bottom-1.5 bg-white text-grey-dark"
@@ -18,7 +18,7 @@ const NoData: React.FC<props> = ({ title, subtitle }) => {
18
18
  }}
19
19
  >
20
20
  <div style={{ width: 145, marginBottom: 20 }} className="nodata-img">
21
- <svg
21
+ <svg
22
22
  xmlns="http://www.w3.org/2000/svg"
23
23
  width="148"
24
24
  height="132"
@@ -71,7 +71,7 @@ const NoData: React.FC<props> = ({ title, subtitle }) => {
71
71
  fill="#797979"
72
72
  d="M47.365 57.417a.926.926 0 00.926-.927v-1.777a.926.926 0 10-1.852 0v1.777c0 .512.415.927.926.927zM104.183 57.417a.926.926 0 00.926-.927v-1.777a.926.926 0 00-1.852 0v1.777c0 .512.414.927.926.927zM47.365 52.974a.926.926 0 00.926-.927V50.27a.926.926 0 00-1.852 0v1.777c0 .512.415.927.926.927zM104.183 52.974a.926.926 0 00.926-.927V50.27a.926.926 0 00-1.852 0v1.777c0 .512.414.927.926.927zM47.365 44.088a.926.926 0 00.926-.927v-1.777a.926.926 0 10-1.852 0v1.777c0 .512.415.927.926.927zM104.183 44.088a.926.926 0 00.926-.927v-1.777a.926.926 0 00-1.852 0v1.777c0 .512.414.927.926.927zM47.365 39.645a.926.926 0 00.926-.927v-1.777a.926.926 0 10-1.852 0v1.777c0 .512.415.927.926.927zM104.183 39.645a.926.926 0 00.926-.927v-1.777a.926.926 0 00-1.852 0v1.777c0 .512.414.927.926.927zM47.365 35.202a.926.926 0 00.926-.927v-1.777a.926.926 0 10-1.852 0v1.777c0 .512.415.927.926.927zM104.183 35.202a.926.926 0 00.926-.927v-1.777a.926.926 0 00-1.852 0v1.777c0 .512.414.927.926.927zM47.365 30.758a.926.926 0 00.926-.926v-.888c0-.248.02-.49.057-.726a.926.926 0 00-1.83-.288c-.052.33-.08.67-.08 1.014v.888c0 .512.416.926.927.926zM104.183 30.758a.926.926 0 00.926-.926v-.888c0-.345-.027-.683-.079-1.014a.926.926 0 10-1.83.288c.037.236.057.478.057.726v.888c0 .512.414.926.926.926zM47.881 26.426a.926.926 0 001.294-.204c.286-.394.633-.74 1.026-1.026a.926.926 0 00-1.09-1.498c-.55.4-1.034.884-1.434 1.434a.926.926 0 00.204 1.294zM103.667 26.426a.926.926 0 00.204-1.294 6.509 6.509 0 00-1.434-1.434.926.926 0 00-1.09 1.498c.393.286.74.632 1.026 1.026a.926.926 0 001.294.204zM51.138 23.597c.08.506.554.851 1.059.772a4.67 4.67 0 01.726-.057h.914a.926.926 0 000-1.852h-.914c-.344 0-.683.026-1.014.078a.926.926 0 00-.77 1.06zM100.41 23.597a.927.927 0 00-.771-1.059 6.522 6.522 0 00-1.014-.078h-.914a.926.926 0 100 1.852h.914c.248 0 .49.02.726.057a.926.926 0 001.059-.772zM55.653 23.386c0 .511.415.926.926.926h1.828a.926.926 0 000-1.852H56.58a.926.926 0 00-.926.926zM60.223 23.386c0 .511.415.926.926.926h1.828a.926.926 0 000-1.852H61.15a.926.926 0 00-.926.926zM64.793 23.386c0 .511.415.926.926.926h1.829a.926.926 0 000-1.852h-1.829a.926.926 0 00-.926.926zM69.364 23.386c0 .511.414.926.926.926h1.828a.926.926 0 000-1.852H70.29a.926.926 0 00-.927.926zM73.934 23.386c0 .511.414.926.926.926h1.828a.926.926 0 000-1.852H74.86a.926.926 0 00-.926.926zM78.504 23.386c0 .511.415.926.926.926h1.828a.926.926 0 000-1.852H79.43a.926.926 0 00-.926.926zM83.074 23.386c0 .511.415.926.927.926h1.828a.926.926 0 000-1.852H84a.926.926 0 00-.927.926zM87.644 23.386c0 .511.415.926.927.926h1.828a.926.926 0 000-1.852H88.57a.926.926 0 00-.927.926zM92.215 23.386c0 .511.414.926.926.926h1.828a.926.926 0 000-1.852h-1.828a.926.926 0 00-.926.926zM72.178 36.453a1.39 1.39 0 10-1.965 1.965l3.797 3.797-3.797 3.798a1.39 1.39 0 001.965 1.965l3.797-3.798 3.798 3.798a1.39 1.39 0 001.965-1.965l-3.798-3.798 3.798-3.797a1.39 1.39 0 10-1.965-1.965l-3.798 3.797-3.797-3.797z"
73
73
  ></path>
74
- </svg> {' '}
74
+ </svg>{' '}
75
75
  </div>
76
76
  <p className="text-center text-common font-bold text-blackAlt nodata-title">{title}</p>
77
77
  <span className="text-xxs font-medium text-grey-medium nodata-sub-title">{subtitle}</span>
@@ -1,6 +1,12 @@
1
- export function getRowDisplayRange(totalRows: number, rowsPerPage: number, pageNumber: number) {
1
+ export function getRowDisplayRange(
2
+ totalRows: number,
3
+ rowsPerPage: number,
4
+ pageNumber: number,
5
+ formatRange: (start: number, end: number, total: number) => string = (start, end, total) =>
6
+ `Showing ${start} to ${end} of ${total}`
7
+ ) {
2
8
  const start = (pageNumber - 1) * rowsPerPage + 1;
3
9
  const end = Math.min(pageNumber * rowsPerPage, totalRows);
4
10
 
5
- return `Showing ${start ?? 0} to ${end ?? 0} of ${totalRows ?? 0}`;
11
+ return formatRange(start ?? 0, end ?? 0, totalRows ?? 0);
6
12
  }
@@ -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);
@@ -187,6 +190,15 @@ const useScrollListener = (props: ScrollListenerProps) => {
187
190
  setScrollX(x);
188
191
  setScrollY(y);
189
192
 
193
+ if (
194
+ typeof handleInfiniteScroll === 'function' &&
195
+ deltaY !== 0 &&
196
+ !loading &&
197
+ Math.abs(y) + getTableHeight() >= contentHeight.current - 12
198
+ ) {
199
+ handleInfiniteScroll(scrollY.current);
200
+ }
201
+
190
202
  onScroll?.(Math.abs(x), Math.abs(y));
191
203
 
192
204
  if (virtualized) {
@@ -297,7 +309,6 @@ const useScrollListener = (props: ScrollListenerProps) => {
297
309
  if (!isTouching.current) {
298
310
  return;
299
311
  }
300
- console.log('handleTouchMove');
301
312
 
302
313
  const { pageX, pageY } = event.touches[0];
303
314
  const deltaX = touchX.current - pageX;
@@ -338,7 +349,6 @@ const useScrollListener = (props: ScrollListenerProps) => {
338
349
  if (!isTouching.current) {
339
350
  return;
340
351
  }
341
- console.log('handleTouchEnd');
342
352
  isTouching.current = false;
343
353
  const touchDuration = new Date().getTime() - momentumStartTime.current;
344
354
  const absDeltaY = Math.abs(scrollY.current - momentumStartY.current);