@alaarab/ogrid 1.3.0 → 1.3.2
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.
|
@@ -79,47 +79,48 @@ function DataGridTableInner(props) {
|
|
|
79
79
|
['--data-table-width']: showEmptyInGrid ? '100%' : allowOverflowX ? 'fit-content' : fitToContent ? 'fit-content' : '100%',
|
|
80
80
|
['--data-table-min-width']: showEmptyInGrid ? '100%' : allowOverflowX ? 'max-content' : fitToContent ? 'max-content' : '100%',
|
|
81
81
|
['--data-table-total-min-width']: `${minTableWidth}px`,
|
|
82
|
-
}, children: [
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
})
|
|
82
|
+
}, children: [isLoading && items.length > 0 && (_jsx("div", { className: styles.loadingOverlay, "aria-live": "polite", children: _jsxs("div", { className: styles.loadingOverlayContent, children: [_jsx("div", { className: styles.spinner }), _jsx("span", { className: styles.loadingOverlayText, children: loadingMessage })] }) })), _jsx("div", { className: styles.tableScrollContent, children: _jsx("div", { className: isLoading && items.length > 0 ? styles.loadingDimmed : undefined, children: _jsxs("div", { className: styles.tableWidthAnchor, ref: tableContainerRef, children: [_jsxs("table", { className: styles.dataTable, children: [_jsx("thead", { className: freezeRows != null && freezeRows >= 1 ? styles.stickyHeader : undefined, children: _jsxs("tr", { children: [hasCheckboxCol && (_jsx("th", { className: styles.selectionHeaderCell, scope: "col", children: _jsx("div", { className: styles.selectionHeaderCellInner, children: _jsx(Checkbox.Root, { className: styles.rowCheckbox, checked: allSelected ? true : someSelected ? 'indeterminate' : false, onCheckedChange: (c) => handleSelectAll(!!c), "aria-label": "Select all rows", children: _jsx(Checkbox.Indicator, { className: styles.rowCheckboxIndicator, children: someSelected && !allSelected ? '–' : '✓' }) }) }) })), visibleCols.map((col, colIdx) => {
|
|
83
|
+
const isFreezeCol = freezeCols != null && freezeCols >= 1 && colIdx < freezeCols;
|
|
84
|
+
const isPinnedLeft = col.pinned === 'left';
|
|
85
|
+
const isPinnedRight = col.pinned === 'right';
|
|
86
|
+
const columnWidth = getColumnWidth(col);
|
|
87
|
+
const hasExplicitWidth = !!(columnSizingOverrides[col.columnId] || col.idealWidth != null || col.defaultWidth != null);
|
|
88
|
+
return (_jsxs("th", { scope: "col", "data-column-id": col.columnId, className: [
|
|
89
|
+
isFreezeCol ? styles.freezeCol : '',
|
|
90
|
+
isFreezeCol && colIdx === 0 ? styles.freezeColFirst : '',
|
|
91
|
+
isPinnedLeft ? styles.pinnedColLeft : '',
|
|
92
|
+
isPinnedRight ? styles.pinnedColRight : '',
|
|
93
|
+
].filter(Boolean).join(' '), style: {
|
|
94
|
+
minWidth: col.minWidth ?? 80,
|
|
95
|
+
width: hasExplicitWidth ? columnWidth : undefined,
|
|
96
|
+
maxWidth: hasExplicitWidth ? columnWidth : undefined,
|
|
97
|
+
}, children: [_jsx(ColumnHeaderFilter, { ...getHeaderFilterConfig(col, headerFilterInput) }), _jsx("div", { className: styles.resizeHandle, onMouseDown: (e) => handleResizeStart(e, col), "aria-label": `Resize ${col.name}` })] }, col.columnId));
|
|
98
|
+
})] }) }), !showEmptyInGrid && (_jsx("tbody", { children: items.map((item, rowIndex) => {
|
|
99
|
+
const rowIdStr = getRowId(item);
|
|
100
|
+
const isSelected = selectedRowIds.has(rowIdStr);
|
|
101
|
+
return (_jsxs("tr", { className: isSelected ? styles.selectedRow : '', onClick: () => {
|
|
102
|
+
if (rowSelection === 'single') {
|
|
103
|
+
const id = getRowId(item);
|
|
104
|
+
updateSelection(selectedRowIds.has(id) ? new Set() : new Set([id]));
|
|
105
|
+
}
|
|
106
|
+
}, children: [hasCheckboxCol && (_jsx("td", { className: styles.selectionCell, children: _jsx("div", { className: styles.selectionCellInner, "data-row-index": rowIndex, "data-col-index": 0, onClick: (e) => e.stopPropagation(), children: _jsx(Checkbox.Root, { className: styles.rowCheckbox, checked: selectedRowIds.has(rowIdStr), onCheckedChange: (c) => handleRowCheckboxChange(rowIdStr, !!c, rowIndex, lastMouseShiftRef.current), "aria-label": `Select row ${rowIndex + 1}`, children: _jsx(Checkbox.Indicator, { className: styles.rowCheckboxIndicator, children: "\u2713" }) }) }) })), visibleCols.map((col, colIdx) => {
|
|
107
|
+
const isFreezeCol = freezeCols != null && freezeCols >= 1 && colIdx < freezeCols;
|
|
108
|
+
const isPinnedLeft = col.pinned === 'left';
|
|
109
|
+
const isPinnedRight = col.pinned === 'right';
|
|
110
|
+
const columnWidth = getColumnWidth(col);
|
|
111
|
+
const hasExplicitWidth = !!(columnSizingOverrides[col.columnId] || col.idealWidth != null || col.defaultWidth != null);
|
|
112
|
+
return (_jsx("td", { className: [
|
|
113
|
+
isFreezeCol ? styles.freezeCol : '',
|
|
114
|
+
isFreezeCol && colIdx === 0 ? styles.freezeColFirst : '',
|
|
115
|
+
isPinnedLeft ? styles.pinnedColLeft : '',
|
|
116
|
+
isPinnedRight ? styles.pinnedColRight : '',
|
|
117
|
+
].filter(Boolean).join(' '), style: {
|
|
118
|
+
minWidth: col.minWidth ?? 80,
|
|
119
|
+
width: hasExplicitWidth ? columnWidth : undefined,
|
|
120
|
+
maxWidth: hasExplicitWidth ? columnWidth : undefined,
|
|
121
|
+
}, children: renderCellContent(item, col, rowIndex, colIdx) }, col.columnId));
|
|
122
|
+
})] }, rowIdStr));
|
|
123
|
+
}) }))] }), _jsx(MarchingAntsOverlay, { containerRef: tableContainerRef, selectionRange: selectionRange, copyRange: copyRange, cutRange: cutRange, colOffset: colOffset }), statusBarConfig && (_jsx(StatusBar, { totalCount: statusBarConfig.totalCount, filteredCount: statusBarConfig.filteredCount, selectedCount: statusBarConfig.selectedCount ?? selectedRowIds.size, selectedCellCount: selectionRange ? (Math.abs(selectionRange.endRow - selectionRange.startRow) + 1) * (Math.abs(selectionRange.endCol - selectionRange.startCol) + 1) : undefined })), showEmptyInGrid && emptyState && (_jsx("div", { className: styles.emptyStateInGrid, children: _jsx("div", { children: emptyState.render ? (emptyState.render()) : (_jsxs(_Fragment, { children: [_jsx("div", { className: styles.emptyStateInGridTitle, children: "No results found" }), _jsx("div", { className: styles.emptyStateInGridMessage, children: emptyState.message != null ? (emptyState.message) : emptyState.hasActiveFilters ? (_jsxs(_Fragment, { children: ["No items match your current filters. Try adjusting your search or", ' ', _jsx("button", { type: "button", className: styles.emptyStateInGridLink, onClick: emptyState.onClearAll, children: "clear all filters" }), ' ', "to see all items."] })) : ('There are no items available at this time.') })] })) }) }))] }) }) }), contextMenu &&
|
|
123
124
|
createPortal(_jsx(GridContextMenu, { x: contextMenu.x, y: contextMenu.y, hasSelection: hasCellSelection, canUndo: canUndo, canRedo: canRedo, onUndo: onUndo ?? (() => { }), onRedo: onRedo ?? (() => { }), onCopy: handleCopy, onCut: handleCut, onPaste: () => void handlePaste(), onSelectAll: handleSelectAllCells, onClose: closeContextMenu }), document.body)] }));
|
|
124
125
|
}
|
|
125
126
|
export const DataGridTable = React.memo(DataGridTableInner);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
@charset "UTF-8";
|
|
1
2
|
.tableScrollContent {
|
|
2
3
|
display: flex;
|
|
3
4
|
flex-direction: column;
|
|
@@ -7,12 +8,12 @@
|
|
|
7
8
|
}
|
|
8
9
|
|
|
9
10
|
.tableWrapper {
|
|
11
|
+
position: relative;
|
|
10
12
|
overflow-x: hidden;
|
|
11
13
|
overflow-y: visible;
|
|
12
14
|
width: 100%;
|
|
13
15
|
min-width: 0;
|
|
14
16
|
max-width: 100%;
|
|
15
|
-
margin-bottom: 15px;
|
|
16
17
|
border-radius: 6px;
|
|
17
18
|
box-sizing: border-box;
|
|
18
19
|
}
|
|
@@ -26,7 +27,8 @@
|
|
|
26
27
|
.tableWidthAnchor {
|
|
27
28
|
position: relative;
|
|
28
29
|
width: max-content;
|
|
29
|
-
min-width:
|
|
30
|
+
/* No min-width: 100% — anchor sizes to grid content so status bar aligns with the table border.
|
|
31
|
+
.tableScrollContent provides the full-width background so no gap is visible. */
|
|
30
32
|
background: var(--ogrid-bg, #fff);
|
|
31
33
|
}
|
|
32
34
|
|
|
@@ -98,14 +100,16 @@
|
|
|
98
100
|
background: var(--ogrid-bg-subtle, #f3f2f1);
|
|
99
101
|
}
|
|
100
102
|
|
|
101
|
-
/* Pinned columns: sticky positioning based on column pinned property
|
|
102
|
-
.
|
|
103
|
+
/* Pinned columns: sticky positioning based on column pinned property.
|
|
104
|
+
Selectors use .dataTable qualifier to beat .dataTable thead th / .dataTable tbody td
|
|
105
|
+
which set position: relative. */
|
|
106
|
+
.dataTable .pinnedColLeft {
|
|
103
107
|
position: sticky;
|
|
104
108
|
left: 0;
|
|
105
109
|
z-index: 2;
|
|
106
110
|
background: var(--ogrid-bg, #ffffff);
|
|
107
111
|
}
|
|
108
|
-
.pinnedColLeft::after {
|
|
112
|
+
.dataTable .pinnedColLeft::after {
|
|
109
113
|
content: "";
|
|
110
114
|
position: absolute;
|
|
111
115
|
top: 0;
|
|
@@ -120,13 +124,13 @@
|
|
|
120
124
|
background: var(--ogrid-bg-subtle, #f3f2f1);
|
|
121
125
|
}
|
|
122
126
|
|
|
123
|
-
.pinnedColRight {
|
|
127
|
+
.dataTable .pinnedColRight {
|
|
124
128
|
position: sticky;
|
|
125
129
|
right: 0;
|
|
126
130
|
z-index: 2;
|
|
127
131
|
background: var(--ogrid-bg, #ffffff);
|
|
128
132
|
}
|
|
129
|
-
.pinnedColRight::before {
|
|
133
|
+
.dataTable .pinnedColRight::before {
|
|
130
134
|
content: "";
|
|
131
135
|
position: absolute;
|
|
132
136
|
top: 0;
|
|
@@ -220,6 +224,10 @@
|
|
|
220
224
|
background: var(--ogrid-bg-range, rgba(33, 115, 70, 0.12)) !important;
|
|
221
225
|
}
|
|
222
226
|
|
|
227
|
+
:global([data-drag-range]) {
|
|
228
|
+
background: var(--ogrid-bg-range, rgba(33, 115, 70, 0.12)) !important;
|
|
229
|
+
}
|
|
230
|
+
|
|
223
231
|
.cellCut {
|
|
224
232
|
background: var(--ogrid-bg-hover, rgba(0, 0, 0, 0.04)) !important;
|
|
225
233
|
opacity: 0.7;
|
|
@@ -289,6 +297,7 @@
|
|
|
289
297
|
gap: 16px;
|
|
290
298
|
width: 100%;
|
|
291
299
|
padding: 6px 12px;
|
|
300
|
+
box-sizing: border-box;
|
|
292
301
|
font-size: 12px;
|
|
293
302
|
color: var(--ogrid-muted, #616161);
|
|
294
303
|
background: var(--ogrid-bg-subtle, #f3f2f1);
|
|
@@ -368,10 +377,6 @@
|
|
|
368
377
|
background: var(--ogrid-border, #e0e0e0);
|
|
369
378
|
}
|
|
370
379
|
|
|
371
|
-
.loadingOverlayContainer {
|
|
372
|
-
position: relative;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
380
|
.loadingOverlay {
|
|
376
381
|
position: absolute;
|
|
377
382
|
inset: 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alaarab/ogrid",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.2",
|
|
4
4
|
"description": "OGrid default (Radix) – Data grid with sorting, filtering, pagination, column chooser, and CSV export. Packed with Radix UI; no Fluent or Material required.",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|