react-live-data-table 1.0.17 → 1.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-live-data-table",
3
- "version": "1.0.17",
3
+ "version": "1.0.18",
4
4
  "description": "Your React component package with Tailwind",
5
5
  "main": "src/index.js",
6
6
  "module": "dist/index.esm.js",
@@ -19,7 +19,8 @@ function ReactDataTable({
19
19
  selected = {},
20
20
  showSelectAllCheckbox = true,
21
21
  rowStyle = {},
22
- rowClassName = ""
22
+ rowClassName = "",
23
+ columnReorder = false,
23
24
  }) {
24
25
  const tableContainerRef = React.useRef(null);
25
26
  const [data, setData] = React.useState({ pages: [], meta: { totalPages: 1 } });
@@ -32,6 +33,12 @@ function ReactDataTable({
32
33
  const [startX, setStartX] = useState(null);
33
34
  const [initialWidth, setInitialWidth] = useState(null);
34
35
  const [tableWidth, setTableWidth] = useState(0);
36
+
37
+ // Column reordering state - only used when columnReorder is true
38
+ const [orderedColumns, setOrderedColumns] = useState(columns);
39
+ const [draggedColumn, setDraggedColumn] = useState(null);
40
+ const [dragOverColumn, setDragOverColumn] = useState(null);
41
+
35
42
  // Ref to store column widths to ensure persistence during data loading
36
43
  const persistedColumnWidthsRef = React.useRef([]);
37
44
 
@@ -42,6 +49,7 @@ function ReactDataTable({
42
49
  size: 50,
43
50
  minWidth: 50,
44
51
  resizable: false,
52
+ reorderable: false, // Prevent checkbox column from being reordered
45
53
  textAlign: "center",
46
54
  header: ({ data }) => {
47
55
  const allSelected = flatData.length > 0 && flatData.every(row => selectedRows[row.id]);
@@ -105,7 +113,12 @@ function ReactDataTable({
105
113
  }
106
114
  };
107
115
 
108
- const enhancedColumns = showCheckbox ? [checkboxColumn, ...columns] : columns;
116
+ const enhancedColumns = showCheckbox ? [checkboxColumn, ...orderedColumns] : orderedColumns;
117
+
118
+ // Update ordered columns when columns prop changes
119
+ useEffect(() => {
120
+ setOrderedColumns(columns);
121
+ }, [columns]);
109
122
 
110
123
  useEffect(() => {
111
124
  if (JSON.stringify(previousSelected.current) !== JSON.stringify(selected)) {
@@ -116,7 +129,7 @@ function ReactDataTable({
116
129
 
117
130
  // Initialize column widths array only once when component mounts or columns change
118
131
  useEffect(() => {
119
- const allColumns = showCheckbox ? [{ id: 'select', size: 50 }, ...columns] : columns;
132
+ const allColumns = showCheckbox ? [{ id: 'select', size: 50 }, ...orderedColumns] : orderedColumns;
120
133
 
121
134
  // If we have persisted widths and the number of columns matches, use those
122
135
  if (persistedColumnWidthsRef.current.length === allColumns.length) {
@@ -130,7 +143,7 @@ function ReactDataTable({
130
143
  // Store in our ref for persistence
131
144
  persistedColumnWidthsRef.current = [...initialWidths];
132
145
  }
133
- }, [columns, showCheckbox]);
146
+ }, [orderedColumns, showCheckbox]);
134
147
 
135
148
  useEffect(() => {
136
149
  setData({ pages: [], meta: { totalPages: 1 } });
@@ -155,6 +168,61 @@ function ReactDataTable({
155
168
  }
156
169
  }, [dataSource, staticData]);
157
170
 
171
+ // Column reordering handlers - only work when columnReorder is true
172
+ const handleDragStart = (e, columnIndex) => {
173
+ if (!columnReorder || enhancedColumns[columnIndex].reorderable === false) {
174
+ e.preventDefault();
175
+ return;
176
+ }
177
+ setDraggedColumn(columnIndex);
178
+ e.dataTransfer.effectAllowed = 'move';
179
+ };
180
+
181
+ const handleDragOver = (e, columnIndex) => {
182
+ e.preventDefault();
183
+ if (!columnReorder || enhancedColumns[columnIndex].reorderable === false) return;
184
+ setDragOverColumn(columnIndex);
185
+ };
186
+
187
+ const handleDrop = (e, dropIndex) => {
188
+ e.preventDefault();
189
+
190
+ if (!columnReorder || draggedColumn === null || draggedColumn === dropIndex) {
191
+ setDraggedColumn(null);
192
+ setDragOverColumn(null);
193
+ return;
194
+ }
195
+
196
+ if (enhancedColumns[dropIndex].reorderable === false) {
197
+ setDraggedColumn(null);
198
+ setDragOverColumn(null);
199
+ return;
200
+ }
201
+
202
+ const newColumns = [...enhancedColumns];
203
+ const draggedColumnData = newColumns[draggedColumn];
204
+
205
+ newColumns.splice(draggedColumn, 1);
206
+ const adjustedDropIndex = draggedColumn < dropIndex ? dropIndex - 1 : dropIndex;
207
+ newColumns.splice(adjustedDropIndex, 0, draggedColumnData);
208
+
209
+ const updatedOrderedColumns = showCheckbox ? newColumns.slice(1) : newColumns;
210
+ setOrderedColumns(updatedOrderedColumns);
211
+
212
+ // Reorder column widths
213
+ const newColumnWidths = [...columnWidths];
214
+ const draggedWidth = newColumnWidths[draggedColumn];
215
+ newColumnWidths.splice(draggedColumn, 1);
216
+ newColumnWidths.splice(adjustedDropIndex, 0, draggedWidth);
217
+ setColumnWidths(newColumnWidths);
218
+ persistedColumnWidthsRef.current = newColumnWidths;
219
+
220
+ // onColumnReorder?.(updatedOrderedColumns);
221
+
222
+ setDraggedColumn(null);
223
+ setDragOverColumn(null);
224
+ };
225
+
158
226
  const handleMouseMove = useCallback((e) => {
159
227
  if (resizingIndex === null || startX === null || initialWidth === null) return;
160
228
 
@@ -378,22 +446,30 @@ function ReactDataTable({
378
446
  className="sticky top-0 z-10 bg-blue-300"
379
447
  style={{ ...headerProps.style }}
380
448
  >
381
- <tr>
449
+ <tr className='react-live-data-table-row-header'>
382
450
  {enhancedColumns.map((column, columnIndex) => {
383
- // Use persisted column widths to ensure consistency
384
451
  const width = columnWidths[columnIndex] || column.size || column.minWidth || 150;
452
+ const isReorderable = columnReorder && column.reorderable !== false;
453
+ const isDropTarget = dragOverColumn === columnIndex && draggedColumn !== columnIndex;
385
454
 
386
455
  return (
387
456
  <th
388
457
  key={column.accessorKey || column.id}
389
- className={`text-left font-normal h-[40px] border-b border-t border-solid border-[#e4e3e2] relative select-none ${columnIndex < enhancedColumns.length - 1 ? 'border-r' : ''
390
- }`}
458
+ className={`text-left font-normal h-[40px] border-b border-t border-solid border-[#e4e3e2] relative select-none ${
459
+ columnIndex < enhancedColumns.length - 1 ? 'border-r' : ''
460
+ } ${isReorderable ? 'cursor-move' : ''} ${
461
+ isDropTarget ? 'bg-blue-400' : ''
462
+ }`}
391
463
  style={{
392
464
  width: `${width}px`,
393
465
  minWidth: `${width}px`,
394
466
  maxWidth: `${width}px`,
395
467
  textAlign: column.textAlign,
396
468
  }}
469
+ draggable={isReorderable}
470
+ onDragStart={(e) => handleDragStart(e, columnIndex)}
471
+ onDragOver={(e) => handleDragOver(e, columnIndex)}
472
+ onDrop={(e) => handleDrop(e, columnIndex)}
397
473
  >
398
474
  <div className="flex items-center h-full overflow-hidden justify-center pl-[17px]">
399
475
  <span className="truncate">
@@ -404,8 +480,9 @@ function ReactDataTable({
404
480
  {/* Resize handle - Only show if column is resizable */}
405
481
  {column.resizable !== false && (
406
482
  <div
407
- className={`absolute top-0 right-0 h-full w-4 flex items-center justify-center group ${resizingIndex === columnIndex ? 'bg-blue-100' : 'hover:bg-blue-100'
408
- } transition-colors duration-200`}
483
+ className={`absolute top-0 right-0 h-full w-4 flex items-center justify-center group ${
484
+ resizingIndex === columnIndex ? 'bg-blue-100' : 'hover:bg-blue-100'
485
+ } transition-colors duration-200`}
409
486
  onMouseDown={(e) => handleResizeStart(e, columnIndex)}
410
487
  style={{
411
488
  touchAction: 'none',
@@ -427,7 +504,7 @@ function ReactDataTable({
427
504
  return (
428
505
  <tr
429
506
  key={row.id}
430
- className={`border-t ${isLastRow ? 'border-b' : ''} border-gray-200 hover:bg-[#dee1f2] ${selectedRows[row.id] ? 'bg-[#dee1f2]' : ''} ${rowClassName} cursor-pointer`}
507
+ className={`react-live-data-table-row-${index} border-t ${isLastRow ? 'border-b' : ''} border-gray-200 hover:bg-[#dee1f2] ${selectedRows[row.id] ? 'bg-[#dee1f2]' : ''} ${rowClassName} cursor-pointer`}
431
508
  style={{
432
509
  height: `${rowHeights}px`,
433
510
  ...rowStyle,
@@ -436,7 +513,6 @@ function ReactDataTable({
436
513
  onClick={() => handleRowClick(row, rowIndex, flatData)}
437
514
  >
438
515
  {enhancedColumns.map((column, columnIndex) => {
439
- // Use persisted column widths for cells as well
440
516
  const width = columnWidths[columnIndex] || column.size || column.minWidth || 150;
441
517
 
442
518
  return (