@alaarab/ogrid 1.3.1 → 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,49 +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: [_jsxs("div", { className: styles.tableScrollContent, children: [_jsxs("div", { className: isLoading && items.length > 0 ? styles.loadingOverlayContainer : undefined, 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: 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
- position: 'relative',
98
- }, children: [_jsx(ColumnHeaderFilter, { ...getHeaderFilterConfig(col, headerFilterInput) }), _jsx("div", { className: styles.resizeHandle, onMouseDown: (e) => handleResizeStart(e, col), "aria-label": `Resize ${col.name}` })] }, col.columnId));
99
- })] }) }), !showEmptyInGrid && (_jsx("tbody", { children: items.map((item, rowIndex) => {
100
- const rowIdStr = getRowId(item);
101
- const isSelected = selectedRowIds.has(rowIdStr);
102
- return (_jsxs("tr", { className: isSelected ? styles.selectedRow : '', onClick: () => {
103
- if (rowSelection === 'single') {
104
- const id = getRowId(item);
105
- updateSelection(selectedRowIds.has(id) ? new Set() : new Set([id]));
106
- }
107
- }, 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) => {
108
- const isFreezeCol = freezeCols != null && freezeCols >= 1 && colIdx < freezeCols;
109
- const isPinnedLeft = col.pinned === 'left';
110
- const isPinnedRight = col.pinned === 'right';
111
- const columnWidth = getColumnWidth(col);
112
- const hasExplicitWidth = !!(columnSizingOverrides[col.columnId] || col.idealWidth != null || col.defaultWidth != null);
113
- return (_jsx("td", { className: [
114
- isFreezeCol ? styles.freezeCol : '',
115
- isFreezeCol && colIdx === 0 ? styles.freezeColFirst : '',
116
- isPinnedLeft ? styles.pinnedColLeft : '',
117
- isPinnedRight ? styles.pinnedColRight : '',
118
- ].filter(Boolean).join(' '), style: {
119
- minWidth: col.minWidth ?? 80,
120
- width: hasExplicitWidth ? columnWidth : undefined,
121
- maxWidth: hasExplicitWidth ? columnWidth : undefined,
122
- }, children: renderCellContent(item, col, rowIndex, colIdx) }, col.columnId));
123
- })] }, rowIdStr));
124
- }) }))] }), _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 &&
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 &&
125
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)] }));
126
125
  }
127
126
  export const DataGridTable = React.memo(DataGridTableInner);
@@ -8,6 +8,7 @@
8
8
  }
9
9
 
10
10
  .tableWrapper {
11
+ position: relative;
11
12
  overflow-x: hidden;
12
13
  overflow-y: visible;
13
14
  width: 100%;
@@ -99,14 +100,16 @@
99
100
  background: var(--ogrid-bg-subtle, #f3f2f1);
100
101
  }
101
102
 
102
- /* Pinned columns: sticky positioning based on column pinned property */
103
- .pinnedColLeft {
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 {
104
107
  position: sticky;
105
108
  left: 0;
106
109
  z-index: 2;
107
110
  background: var(--ogrid-bg, #ffffff);
108
111
  }
109
- .pinnedColLeft::after {
112
+ .dataTable .pinnedColLeft::after {
110
113
  content: "";
111
114
  position: absolute;
112
115
  top: 0;
@@ -121,13 +124,13 @@
121
124
  background: var(--ogrid-bg-subtle, #f3f2f1);
122
125
  }
123
126
 
124
- .pinnedColRight {
127
+ .dataTable .pinnedColRight {
125
128
  position: sticky;
126
129
  right: 0;
127
130
  z-index: 2;
128
131
  background: var(--ogrid-bg, #ffffff);
129
132
  }
130
- .pinnedColRight::before {
133
+ .dataTable .pinnedColRight::before {
131
134
  content: "";
132
135
  position: absolute;
133
136
  top: 0;
@@ -221,6 +224,10 @@
221
224
  background: var(--ogrid-bg-range, rgba(33, 115, 70, 0.12)) !important;
222
225
  }
223
226
 
227
+ :global([data-drag-range]) {
228
+ background: var(--ogrid-bg-range, rgba(33, 115, 70, 0.12)) !important;
229
+ }
230
+
224
231
  .cellCut {
225
232
  background: var(--ogrid-bg-hover, rgba(0, 0, 0, 0.04)) !important;
226
233
  opacity: 0.7;
@@ -370,10 +377,6 @@
370
377
  background: var(--ogrid-border, #e0e0e0);
371
378
  }
372
379
 
373
- .loadingOverlayContainer {
374
- position: relative;
375
- }
376
-
377
380
  .loadingOverlay {
378
381
  position: absolute;
379
382
  inset: 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alaarab/ogrid",
3
- "version": "1.3.1",
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",