react-live-data-table 1.0.15 → 1.0.17
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 +1 -1
- package/readme.md +1 -37
- package/src/ReactDataTable.jsx +323 -110
package/package.json
CHANGED
package/readme.md
CHANGED
@@ -8,7 +8,7 @@ A highly customizable and efficient data grid table for React. It supports featu
|
|
8
8
|
|
9
9
|
To install the package, run one of the following commands:
|
10
10
|
|
11
|
-
|
11
|
+
bash
|
12
12
|
npm install react-data-grid-table
|
13
13
|
|
14
14
|
# React Data Grid
|
@@ -41,40 +41,4 @@ A flexible React data grid component with support for pagination, row selection,
|
|
41
41
|
| `rowHeights` | `number` | `40` | Height of each row |
|
42
42
|
| `headerProps` | `object` | `{}` | Custom header properties |
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
### Column Definition
|
48
|
-
|
49
|
-
```typescript
|
50
|
-
interface ColumnDefinition {
|
51
|
-
field: string; // Key of the data field to display
|
52
|
-
headerName: string; // Text to show in column header
|
53
|
-
width?: number; // Column width in pixels
|
54
|
-
sortable?: boolean; // Enable column sorting
|
55
|
-
render?: (value: any, rowData: Object) => React.ReactNode; // Custom cell renderer
|
56
|
-
|
57
|
-
|
58
44
|
## Basic Usage
|
59
|
-
|
60
|
-
```jsx
|
61
|
-
import { ReactDataTable } from 'react-data-grid';
|
62
|
-
|
63
|
-
const App = () => {
|
64
|
-
const columns = [
|
65
|
-
{ field: 'id', headerName: 'ID' },
|
66
|
-
{ field: 'name', headerName: 'Name' }
|
67
|
-
];
|
68
|
-
|
69
|
-
const data = [
|
70
|
-
{ id: 1, name: 'John' },
|
71
|
-
{ id: 2, name: 'Jane' }
|
72
|
-
];
|
73
|
-
|
74
|
-
return (
|
75
|
-
<ReactDataTable
|
76
|
-
columns={columns}
|
77
|
-
dataSource={data}
|
78
|
-
/>
|
79
|
-
);
|
80
|
-
};
|
package/src/ReactDataTable.jsx
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import React, { useEffect } from 'react';
|
1
|
+
import React, { useEffect, useState, useCallback } from 'react';
|
2
2
|
import "./index.css";
|
3
3
|
|
4
4
|
function ReactDataTable({
|
@@ -15,14 +15,122 @@ function ReactDataTable({
|
|
15
15
|
staticData = null,
|
16
16
|
emptyText,
|
17
17
|
rowHeights = 40,
|
18
|
-
headerProps = {}
|
18
|
+
headerProps = {},
|
19
|
+
selected = {},
|
20
|
+
showSelectAllCheckbox = true,
|
21
|
+
rowStyle = {},
|
22
|
+
rowClassName = ""
|
19
23
|
}) {
|
20
24
|
const tableContainerRef = React.useRef(null);
|
21
25
|
const [data, setData] = React.useState({ pages: [], meta: { totalPages: 1 } });
|
22
26
|
const [isFetching, setIsFetching] = React.useState(false);
|
23
27
|
const [pageParam, setPageParam] = React.useState(1);
|
24
|
-
const [selectedRows, setSelectedRows] = React.useState(
|
28
|
+
const [selectedRows, setSelectedRows] = React.useState(selected);
|
29
|
+
const previousSelected = React.useRef(selected);
|
30
|
+
const [resizingIndex, setResizingIndex] = useState(null);
|
31
|
+
const [columnWidths, setColumnWidths] = useState([]);
|
32
|
+
const [startX, setStartX] = useState(null);
|
33
|
+
const [initialWidth, setInitialWidth] = useState(null);
|
34
|
+
const [tableWidth, setTableWidth] = useState(0);
|
35
|
+
// Ref to store column widths to ensure persistence during data loading
|
36
|
+
const persistedColumnWidthsRef = React.useRef([]);
|
25
37
|
|
38
|
+
const flatData = data.pages.flatMap(page => page.data);
|
39
|
+
|
40
|
+
const checkboxColumn = {
|
41
|
+
id: 'select',
|
42
|
+
size: 50,
|
43
|
+
minWidth: 50,
|
44
|
+
resizable: false,
|
45
|
+
textAlign: "center",
|
46
|
+
header: ({ data }) => {
|
47
|
+
const allSelected = flatData.length > 0 && flatData.every(row => selectedRows[row.id]);
|
48
|
+
const someSelected = flatData.some(row => selectedRows[row.id]) && !allSelected;
|
49
|
+
|
50
|
+
return (
|
51
|
+
<div className="flex items-center justify-center h-[40px]">
|
52
|
+
{showSelectAllCheckbox && (
|
53
|
+
<div className="relative">
|
54
|
+
<input
|
55
|
+
id={data.id}
|
56
|
+
type="checkbox"
|
57
|
+
className='bg-gray-700 rounded-4 border-gray-200 text-blue-400 focus:ring-0 focus:ring-white'
|
58
|
+
checked={allSelected}
|
59
|
+
onChange={(e) => handleSelectAll(e.target.checked, flatData)}
|
60
|
+
/>
|
61
|
+
{allSelected ? (
|
62
|
+
<svg
|
63
|
+
className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-3 h-3 pointer-events-none text-white"
|
64
|
+
viewBox="0 0 20 20"
|
65
|
+
fill="currentColor"
|
66
|
+
>
|
67
|
+
<path
|
68
|
+
fillRule="evenodd"
|
69
|
+
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
70
|
+
clipRule="evenodd"
|
71
|
+
/>
|
72
|
+
</svg>
|
73
|
+
) : (
|
74
|
+
someSelected &&
|
75
|
+
<svg
|
76
|
+
className="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-3 h-3 pointer-events-none "
|
77
|
+
viewBox="0 0 20 20"
|
78
|
+
fill="currentColor"
|
79
|
+
>
|
80
|
+
<path
|
81
|
+
fillRule="evenodd"
|
82
|
+
d="M3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
|
83
|
+
clipRule="evenodd"
|
84
|
+
/>
|
85
|
+
</svg>
|
86
|
+
)}
|
87
|
+
</div>
|
88
|
+
)}
|
89
|
+
</div>
|
90
|
+
);
|
91
|
+
},
|
92
|
+
cell: ({ row }) => {
|
93
|
+
return (
|
94
|
+
<div className="flex items-center justify-center h-[40px]" onClick={(e) => e.stopPropagation()}>
|
95
|
+
<input
|
96
|
+
id={row.id}
|
97
|
+
type="checkbox"
|
98
|
+
className='bg-gray-700 rounded-4 border-gray-200 text-blue-400 focus:ring-0 focus:ring-white'
|
99
|
+
checked={!!selectedRows[row.id]}
|
100
|
+
onClick={(e) => e.stopPropagation()}
|
101
|
+
onChange={(e) => { e.stopPropagation(); handleSelectRow(e.target.checked, row, flatData) }}
|
102
|
+
/>
|
103
|
+
</div>
|
104
|
+
)
|
105
|
+
}
|
106
|
+
};
|
107
|
+
|
108
|
+
const enhancedColumns = showCheckbox ? [checkboxColumn, ...columns] : columns;
|
109
|
+
|
110
|
+
useEffect(() => {
|
111
|
+
if (JSON.stringify(previousSelected.current) !== JSON.stringify(selected)) {
|
112
|
+
setSelectedRows({ ...selected });
|
113
|
+
previousSelected.current = selected;
|
114
|
+
}
|
115
|
+
}, [selected]);
|
116
|
+
|
117
|
+
// Initialize column widths array only once when component mounts or columns change
|
118
|
+
useEffect(() => {
|
119
|
+
const allColumns = showCheckbox ? [{ id: 'select', size: 50 }, ...columns] : columns;
|
120
|
+
|
121
|
+
// If we have persisted widths and the number of columns matches, use those
|
122
|
+
if (persistedColumnWidthsRef.current.length === allColumns.length) {
|
123
|
+
setColumnWidths([...persistedColumnWidthsRef.current]);
|
124
|
+
setTableWidth(persistedColumnWidthsRef.current.reduce((sum, width) => sum + width, 0));
|
125
|
+
} else {
|
126
|
+
// Otherwise initialize with default widths
|
127
|
+
const initialWidths = allColumns.map(column => column.size || column.minWidth || 150);
|
128
|
+
setColumnWidths(initialWidths);
|
129
|
+
setTableWidth(initialWidths.reduce((sum, width) => sum + width, 0));
|
130
|
+
// Store in our ref for persistence
|
131
|
+
persistedColumnWidthsRef.current = [...initialWidths];
|
132
|
+
}
|
133
|
+
}, [columns, showCheckbox]);
|
26
134
|
|
27
135
|
useEffect(() => {
|
28
136
|
setData({ pages: [], meta: { totalPages: 1 } });
|
@@ -47,6 +155,57 @@ function ReactDataTable({
|
|
47
155
|
}
|
48
156
|
}, [dataSource, staticData]);
|
49
157
|
|
158
|
+
const handleMouseMove = useCallback((e) => {
|
159
|
+
if (resizingIndex === null || startX === null || initialWidth === null) return;
|
160
|
+
|
161
|
+
const delta = e.clientX - startX;
|
162
|
+
const newWidth = Math.max(enhancedColumns[resizingIndex]?.minWidth || 80, initialWidth + delta);
|
163
|
+
|
164
|
+
// Create a new array of column widths with the updated width
|
165
|
+
const newColumnWidths = [...columnWidths];
|
166
|
+
newColumnWidths[resizingIndex] = newWidth;
|
167
|
+
|
168
|
+
// Update the column widths state
|
169
|
+
setColumnWidths(newColumnWidths);
|
170
|
+
|
171
|
+
// Update our persisted ref to maintain widths during pagination
|
172
|
+
persistedColumnWidthsRef.current = newColumnWidths;
|
173
|
+
|
174
|
+
// Recalculate table width based on the new column widths
|
175
|
+
const newTableWidth = newColumnWidths.reduce((sum, width) => sum + width, 0);
|
176
|
+
setTableWidth(newTableWidth);
|
177
|
+
}, [resizingIndex, startX, initialWidth, enhancedColumns, columnWidths]);
|
178
|
+
|
179
|
+
const handleMouseUp = useCallback(() => {
|
180
|
+
setResizingIndex(null);
|
181
|
+
setStartX(null);
|
182
|
+
setInitialWidth(null);
|
183
|
+
}, []);
|
184
|
+
|
185
|
+
// Add resize event listeners
|
186
|
+
useEffect(() => {
|
187
|
+
if (resizingIndex !== null) {
|
188
|
+
document.addEventListener('mousemove', handleMouseMove);
|
189
|
+
document.addEventListener('mouseup', handleMouseUp);
|
190
|
+
return () => {
|
191
|
+
document.removeEventListener('mousemove', handleMouseMove);
|
192
|
+
document.removeEventListener('mouseup', handleMouseUp);
|
193
|
+
};
|
194
|
+
}
|
195
|
+
}, [resizingIndex, handleMouseMove, handleMouseUp]);
|
196
|
+
|
197
|
+
const handleResizeStart = (e, index) => {
|
198
|
+
const column = enhancedColumns[index];
|
199
|
+
if (!column.resizable) return;
|
200
|
+
|
201
|
+
e.preventDefault();
|
202
|
+
e.stopPropagation();
|
203
|
+
|
204
|
+
setResizingIndex(index);
|
205
|
+
setStartX(e.clientX);
|
206
|
+
setInitialWidth(columnWidths[index] || column.size || column.minWidth || 150);
|
207
|
+
};
|
208
|
+
|
50
209
|
const loadInitialData = async () => {
|
51
210
|
if (!dataSource) return;
|
52
211
|
|
@@ -71,10 +230,13 @@ function ReactDataTable({
|
|
71
230
|
skip: pageParam * defaultLimit,
|
72
231
|
limit: defaultLimit
|
73
232
|
});
|
233
|
+
|
234
|
+
// Update the data but maintain our column widths
|
74
235
|
setData(prev => ({
|
75
236
|
pages: [...prev.pages, nextData],
|
76
237
|
meta: nextData.meta
|
77
238
|
}));
|
239
|
+
|
78
240
|
setPageParam(prev => prev + 1);
|
79
241
|
} catch (error) {
|
80
242
|
console.error('Error fetching next page:', error);
|
@@ -157,122 +319,173 @@ function ReactDataTable({
|
|
157
319
|
handleScroll(tableContainerRef.current);
|
158
320
|
}, [data]);
|
159
321
|
|
160
|
-
const flatData = data.pages.flatMap(page => page.data);
|
161
|
-
|
162
|
-
const checkboxColumn = {
|
163
|
-
id: 'select',
|
164
|
-
size: 50,
|
165
|
-
minWidth: 50,
|
166
|
-
textAlign: "center",
|
167
|
-
header: ({ data }) => (
|
168
|
-
<div className="flex items-center justify-center h-[40px]">
|
169
|
-
<input
|
170
|
-
type="checkbox"
|
171
|
-
checked={Object.keys(selectedRows).length > 0 && data.every(row => selectedRows[row.id])}
|
172
|
-
onChange={(e) => handleSelectAll(e.target.checked, flatData)}
|
173
|
-
/>
|
174
|
-
</div>
|
175
|
-
),
|
176
|
-
cell: ({ row }) => (
|
177
|
-
<div className="flex items-center justify-center h-[40px]">
|
178
|
-
<input
|
179
|
-
type="checkbox"
|
180
|
-
checked={!!selectedRows[row.id]}
|
181
|
-
onChange={(e) => handleSelectRow(e.target.checked, row, flatData)}
|
182
|
-
/>
|
183
|
-
</div>
|
184
|
-
),
|
185
|
-
};
|
186
|
-
|
187
|
-
const enhancedColumns = showCheckbox ? [checkboxColumn, ...columns] : columns;
|
188
|
-
|
189
322
|
return (
|
190
|
-
<div className="bg-white relative w-full">
|
191
|
-
{loading &&
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
fill="currentColor"
|
203
|
-
/>
|
204
|
-
</svg>
|
205
|
-
</div>
|
206
|
-
</div>}
|
207
|
-
{flatData.length === 0 && !loading ? (
|
208
|
-
<div className="flex items-center justify-center" style={{ height }}>
|
209
|
-
<div className="text-gray-500">
|
210
|
-
{emptyText || 'No data available'}
|
211
|
-
</div>
|
212
|
-
</div>
|
213
|
-
) : (
|
214
|
-
<div className="overflow-hidden">
|
215
|
-
<div
|
216
|
-
ref={tableContainerRef}
|
217
|
-
className="overflow-auto w-full"
|
218
|
-
style={{ maxHeight, height }}
|
219
|
-
onScroll={(e) => handleScroll(e.currentTarget)}
|
323
|
+
<div className="bg-white relative w-full react-live-data-table" >
|
324
|
+
{loading && (
|
325
|
+
<div className="absolute inset-0 bg-white/50 z-20 flex items-center justify-center">
|
326
|
+
<svg
|
327
|
+
style={{
|
328
|
+
animation: 'spin 1s linear infinite',
|
329
|
+
width: '24px',
|
330
|
+
height: '24px'
|
331
|
+
}}
|
332
|
+
viewBox="0 0 24 24"
|
333
|
+
fill="none"
|
334
|
+
xmlns="http://www.w3.org/2000/svg"
|
220
335
|
>
|
221
|
-
<
|
222
|
-
|
223
|
-
|
224
|
-
|
336
|
+
<style>
|
337
|
+
{`@keyframes spin {from {transform: rotate(0deg)} to {transform: rotate(360deg)}}`}
|
338
|
+
</style>
|
339
|
+
<circle
|
340
|
+
style={{ opacity: 0.25 }}
|
341
|
+
cx="12"
|
342
|
+
cy="12"
|
343
|
+
r="10"
|
344
|
+
stroke="currentColor"
|
345
|
+
strokeWidth="4"
|
346
|
+
/>
|
347
|
+
<path
|
348
|
+
style={{ opacity: 0.75 }}
|
349
|
+
fill="currentColor"
|
350
|
+
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
351
|
+
/>
|
352
|
+
</svg>
|
353
|
+
</div>
|
354
|
+
)}
|
355
|
+
|
356
|
+
{
|
357
|
+
flatData.length === 0 && !loading ? (
|
358
|
+
<div className="flex items-center justify-center" style={{ height }}>
|
359
|
+
<div className="text-gray-500">
|
360
|
+
{emptyText || 'No data available'}
|
361
|
+
</div>
|
362
|
+
</div>
|
363
|
+
) : (
|
364
|
+
<div className="overflow-hidden">
|
365
|
+
<div
|
366
|
+
ref={tableContainerRef}
|
367
|
+
className="overflow-auto w-full"
|
368
|
+
style={{ maxHeight, height }}
|
369
|
+
onScroll={(e) => handleScroll(e.currentTarget)}
|
370
|
+
>
|
371
|
+
<table
|
372
|
+
className="w-full border-collapse"
|
373
|
+
style={{
|
374
|
+
tableLayout: 'fixed',
|
375
|
+
}}
|
225
376
|
>
|
226
|
-
<
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
{typeof column.header === 'function' ? column.header({ data: flatData }) : column.header}
|
238
|
-
</th>
|
239
|
-
))}
|
240
|
-
</tr>
|
241
|
-
</thead>
|
242
|
-
<tbody>
|
243
|
-
{flatData.length > 0 ? (
|
244
|
-
flatData.map((row, index) => (
|
245
|
-
<tr
|
246
|
-
key={row.id}
|
247
|
-
className={`border-t border-x border-gray-200 hover:bg-[#dee1f2] h-[${rowHeights}px] ${selectedRows[row.id] ? 'bg-[#dee1f2]' : ''}`}
|
248
|
-
onClick={() => handleRowClick(row, index, flatData)}
|
249
|
-
>
|
250
|
-
{enhancedColumns.map(column => (
|
251
|
-
<td
|
377
|
+
<thead
|
378
|
+
className="sticky top-0 z-10 bg-blue-300"
|
379
|
+
style={{ ...headerProps.style }}
|
380
|
+
>
|
381
|
+
<tr>
|
382
|
+
{enhancedColumns.map((column, columnIndex) => {
|
383
|
+
// Use persisted column widths to ensure consistency
|
384
|
+
const width = columnWidths[columnIndex] || column.size || column.minWidth || 150;
|
385
|
+
|
386
|
+
return (
|
387
|
+
<th
|
252
388
|
key={column.accessorKey || column.id}
|
253
|
-
className={`text-left font-normal border-
|
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
|
+
}`}
|
254
391
|
style={{
|
255
|
-
|
256
|
-
|
257
|
-
|
392
|
+
width: `${width}px`,
|
393
|
+
minWidth: `${width}px`,
|
394
|
+
maxWidth: `${width}px`,
|
395
|
+
textAlign: column.textAlign,
|
258
396
|
}}
|
259
397
|
>
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
398
|
+
<div className="flex items-center h-full overflow-hidden justify-center pl-[17px]">
|
399
|
+
<span className="truncate">
|
400
|
+
{typeof column.header === 'function' ? column.header({ data: flatData }) : column.header}
|
401
|
+
</span>
|
402
|
+
</div>
|
403
|
+
|
404
|
+
{/* Resize handle - Only show if column is resizable */}
|
405
|
+
{column.resizable !== false && (
|
406
|
+
<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`}
|
409
|
+
onMouseDown={(e) => handleResizeStart(e, columnIndex)}
|
410
|
+
style={{
|
411
|
+
touchAction: 'none',
|
412
|
+
userSelect: 'none',
|
413
|
+
cursor: 'col-resize'
|
414
|
+
}}
|
415
|
+
>
|
416
|
+
</div>
|
417
|
+
)}
|
418
|
+
</th>
|
419
|
+
);
|
420
|
+
})}
|
270
421
|
</tr>
|
271
|
-
|
272
|
-
|
273
|
-
|
422
|
+
</thead>
|
423
|
+
<tbody>
|
424
|
+
{flatData.length > 0 ? (
|
425
|
+
flatData.map((row, rowIndex) => {
|
426
|
+
const isLastRow = rowIndex === flatData.length - 1;
|
427
|
+
return (
|
428
|
+
<tr
|
429
|
+
key={row.id}
|
430
|
+
className={`border-t ${isLastRow ? 'border-b' : ''} border-gray-200 hover:bg-[#dee1f2] ${selectedRows[row.id] ? 'bg-[#dee1f2]' : ''} ${rowClassName} cursor-pointer`}
|
431
|
+
style={{
|
432
|
+
height: `${rowHeights}px`,
|
433
|
+
...rowStyle,
|
434
|
+
...(typeof rowStyle === 'function' ? rowStyle(row, rowIndex) : {})
|
435
|
+
}}
|
436
|
+
onClick={() => handleRowClick(row, rowIndex, flatData)}
|
437
|
+
>
|
438
|
+
{enhancedColumns.map((column, columnIndex) => {
|
439
|
+
// Use persisted column widths for cells as well
|
440
|
+
const width = columnWidths[columnIndex] || column.size || column.minWidth || 150;
|
441
|
+
|
442
|
+
return (
|
443
|
+
<td
|
444
|
+
key={column.accessorKey || column.id}
|
445
|
+
className={`text-left font-normal ${columnIndex < enhancedColumns.length - 1 ? 'border-r' : ''
|
446
|
+
} ${column?.cellProps?.className || ''}`}
|
447
|
+
style={{
|
448
|
+
width: `${width}px`,
|
449
|
+
minWidth: `${width}px`,
|
450
|
+
maxWidth: `${width}px`,
|
451
|
+
textAlign: column?.textAlign,
|
452
|
+
...column?.cellProps?.style,
|
453
|
+
overflow: 'hidden',
|
454
|
+
textOverflow: 'ellipsis',
|
455
|
+
whiteSpace: 'nowrap'
|
456
|
+
}}
|
457
|
+
>
|
458
|
+
{typeof column.cell === 'function' ? column.cell({ row }) : null}
|
459
|
+
</td>
|
460
|
+
);
|
461
|
+
})}
|
462
|
+
</tr>
|
463
|
+
);
|
464
|
+
})
|
465
|
+
) : (
|
466
|
+
<tr>
|
467
|
+
<td colSpan={enhancedColumns.length} className="text-center py-4">
|
468
|
+
{emptyText || 'No data available'}
|
469
|
+
</td>
|
470
|
+
</tr>
|
471
|
+
)}
|
472
|
+
</tbody>
|
473
|
+
</table>
|
474
|
+
</div>
|
274
475
|
</div>
|
275
|
-
|
476
|
+
)
|
477
|
+
}
|
478
|
+
|
479
|
+
{/* Resize overlay */}
|
480
|
+
{resizingIndex !== null && (
|
481
|
+
<div
|
482
|
+
className="fixed inset-0 z-40 bg-blue-50/5"
|
483
|
+
style={{
|
484
|
+
pointerEvents: 'none',
|
485
|
+
userSelect: 'none',
|
486
|
+
cursor: 'col-resize'
|
487
|
+
}}
|
488
|
+
/>
|
276
489
|
)}
|
277
490
|
</div>
|
278
491
|
);
|