@alaarab/ogrid 1.5.0 → 1.6.0

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.
@@ -15,7 +15,13 @@ function DataGridTableInner(props) {
15
15
  const tableContainerRef = useRef(null);
16
16
  const state = useDataGridState({ props, wrapperRef });
17
17
  const lastMouseShiftRef = useRef(false);
18
- const { visibleCols, totalColCount, hasCheckboxCol, selectedRowIds, updateSelection, handleRowCheckboxChange, handleSelectAll, allSelected, someSelected, setEditingCell, pendingEditorValue, setPendingEditorValue, setActiveCell, handleCellMouseDown, handleSelectAllCells, contextMenu, handleCellContextMenu, closeContextMenu, canUndo, canRedo, onUndo, onRedo, handleCopy, handleCut, handlePaste, handleGridKeyDown, handleFillHandleMouseDown, containerWidth, minTableWidth, desiredTableWidth, columnSizingOverrides, setColumnSizingOverrides, statusBarConfig, showEmptyInGrid, hasCellSelection, selectionRange, copyRange, cutRange, colOffset, headerFilterInput, cellDescriptorInput, commitCellEdit, cancelPopoverEdit, popoverAnchorEl, setPopoverAnchorEl, } = state;
18
+ const { layout, rowSelection: rowSel, editing, interaction, contextMenu: ctxMenu, viewModels } = state;
19
+ const { visibleCols, totalColCount, hasCheckboxCol, colOffset, containerWidth, minTableWidth, desiredTableWidth, columnSizingOverrides, setColumnSizingOverrides } = layout;
20
+ const { selectedRowIds, updateSelection, handleRowCheckboxChange, handleSelectAll, allSelected, someSelected } = rowSel;
21
+ const { setEditingCell, pendingEditorValue, setPendingEditorValue, commitCellEdit, cancelPopoverEdit, popoverAnchorEl, setPopoverAnchorEl } = editing;
22
+ const { setActiveCell, handleCellMouseDown, handleSelectAllCells, selectionRange, hasCellSelection, handleGridKeyDown, handleFillHandleMouseDown, handleCopy, handleCut, handlePaste, cutRange, copyRange, canUndo, canRedo, onUndo, onRedo } = interaction;
23
+ const { menuPosition, handleCellContextMenu, closeContextMenu } = ctxMenu;
24
+ const { headerFilterInput, cellDescriptorInput, statusBarConfig, showEmptyInGrid } = viewModels;
19
25
  const { items, columns, getRowId, emptyState, layoutMode = 'fill', rowSelection = 'none', freezeRows, freezeCols, suppressHorizontalScroll, isLoading = false, loadingMessage = 'Loading\u2026', 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, visibleColumns, } = props;
20
26
  const headerRows = buildHeaderRows(columns, visibleColumns);
21
27
  const allowOverflowX = !suppressHorizontalScroll && containerWidth > 0 && (minTableWidth > containerWidth || desiredTableWidth > containerWidth);
@@ -106,7 +112,7 @@ function DataGridTableInner(props) {
106
112
  textAlign: col.type === 'numeric' ? 'right' : col.type === 'boolean' ? 'center' : undefined,
107
113
  }, children: renderCellContent(item, col, rowIndex, colIdx) }, col.columnId));
108
114
  })] }, rowIdStr));
109
- }) }))] }), _jsx(MarchingAntsOverlay, { containerRef: tableContainerRef, selectionRange: selectionRange, copyRange: copyRange, cutRange: cutRange, colOffset: colOffset }), 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.') })] })) }) }))] }) }), 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, aggregation: statusBarConfig.aggregation, suppressRowCount: statusBarConfig.suppressRowCount }))] }), contextMenu &&
110
- 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)] }));
115
+ }) }))] }), _jsx(MarchingAntsOverlay, { containerRef: tableContainerRef, selectionRange: selectionRange, copyRange: copyRange, cutRange: cutRange, colOffset: colOffset }), 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.') })] })) }) }))] }) }), 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, aggregation: statusBarConfig.aggregation, suppressRowCount: statusBarConfig.suppressRowCount }))] }), menuPosition &&
116
+ createPortal(_jsx(GridContextMenu, { x: menuPosition.x, y: menuPosition.y, hasSelection: hasCellSelection, canUndo: canUndo, canRedo: canRedo, onUndo: onUndo ?? (() => { }), onRedo: onRedo ?? (() => { }), onCopy: handleCopy, onCut: handleCut, onPaste: () => void handlePaste(), onSelectAll: handleSelectAllCells, onClose: closeContextMenu }), document.body)] }));
111
117
  }
112
118
  export const DataGridTable = React.memo(DataGridTableInner);
@@ -92,6 +92,16 @@
92
92
  background: var(--ogrid-bg, #ffffff);
93
93
  }
94
94
 
95
+ /* Freeze/pinned header cells need top: 0 + z-index: 3 so they stick in BOTH
96
+ directions — left (from .freezeCol/.pinnedCol) AND top (from .stickyHeader).
97
+ Without explicit top, the child's own position: sticky overrides the parent's. */
98
+ .dataTable thead.stickyHeader .freezeColFirst,
99
+ .dataTable thead.stickyHeader .pinnedColLeft,
100
+ .dataTable thead.stickyHeader .pinnedColRight {
101
+ top: 0;
102
+ z-index: 3;
103
+ }
104
+
95
105
  .dataTable thead .freezeColFirst {
96
106
  background: var(--ogrid-bg-subtle, #f3f2f1);
97
107
  }
@@ -6,8 +6,8 @@ import { ColumnChooser } from '../ColumnChooser/ColumnChooser';
6
6
  import { PaginationControls } from '../PaginationControls/PaginationControls';
7
7
  import { useOGrid, OGridLayout, } from '@alaarab/ogrid-core';
8
8
  const OGridInner = forwardRef(function OGridInner(props, ref) {
9
- const { dataGridProps, page, pageSize, displayTotalCount, setPage, setPageSize, columnChooserColumns, visibleColumns, handleVisibilityChange, columnChooserPlacement, title, toolbar, className, entityLabelPlural, pageSizeOptions, sideBarProps, } = useOGrid(props, ref);
10
- return (_jsx(OGridLayout, { className: className, gap: 8, sideBar: sideBarProps, title: title, toolbar: toolbar, toolbarEnd: columnChooserPlacement === 'toolbar' ? (_jsx(ColumnChooser, { columns: columnChooserColumns, visibleColumns: visibleColumns, onVisibilityChange: handleVisibilityChange })) : undefined, pagination: _jsx(PaginationControls, { currentPage: page, pageSize: pageSize, totalCount: displayTotalCount, onPageChange: setPage, onPageSizeChange: (size) => {
9
+ const { dataGridProps, page, pageSize, displayTotalCount, setPage, setPageSize, columnChooserColumns, visibleColumns, handleVisibilityChange, columnChooserPlacement, toolbar, className, entityLabelPlural, pageSizeOptions, sideBarProps, } = useOGrid(props, ref);
10
+ return (_jsx(OGridLayout, { className: className, sideBar: sideBarProps, toolbar: toolbar, toolbarEnd: columnChooserPlacement === 'toolbar' ? (_jsx(ColumnChooser, { columns: columnChooserColumns, visibleColumns: visibleColumns, onVisibilityChange: handleVisibilityChange })) : undefined, pagination: _jsx(PaginationControls, { currentPage: page, pageSize: pageSize, totalCount: displayTotalCount, onPageChange: setPage, onPageSizeChange: (size) => {
11
11
  setPageSize(size);
12
12
  setPage(1);
13
13
  }, pageSizeOptions: pageSizeOptions, entityLabelPlural: entityLabelPlural }), children: _jsx(DataGridTable, { ...dataGridProps }) }));
package/dist/esm/index.js CHANGED
@@ -4,5 +4,5 @@ export { DataGridTable } from './DataGridTable/DataGridTable';
4
4
  export { ColumnChooser } from './ColumnChooser/ColumnChooser';
5
5
  export { ColumnHeaderFilter } from './ColumnHeaderFilter/ColumnHeaderFilter';
6
6
  export { PaginationControls } from './PaginationControls/PaginationControls';
7
- // Re-export from core
8
- export { toUserLike, isInSelectionRange, normalizeSelectionRange, toDataGridFilterProps, useFilterOptions, getCellValue, flattenColumns, escapeCsvValue, buildCsvHeader, buildCsvRows, exportToCsv, triggerCsvDownload, } from '@alaarab/ogrid-core';
7
+ // Re-export everything from core
8
+ export * from '@alaarab/ogrid-core';
@@ -3,4 +3,4 @@ export { DataGridTable, type IDataGridTableProps } from './DataGridTable/DataGri
3
3
  export { ColumnChooser, type IColumnChooserProps } from './ColumnChooser/ColumnChooser';
4
4
  export { ColumnHeaderFilter, type IColumnHeaderFilterProps } from './ColumnHeaderFilter/ColumnHeaderFilter';
5
5
  export { PaginationControls, type IPaginationControlsProps } from './PaginationControls/PaginationControls';
6
- export { type ColumnFilterType, type IColumnFilterDef, type IColumnMeta, type IColumnDef, type IColumnGroupDef, type IColumnDefinition, type ICellValueChangedEvent, type ICellEditorProps, type UserLike, type IFilters, type IFetchParams, type IPageResult, type IDataSource, type IGridColumnState, type IOGridApi, type RowSelectionMode, type IRowSelectionChangeEvent, type StatusBarPanel, type IStatusBarProps, type IActiveCell, type ISelectionRange, toUserLike, isInSelectionRange, normalizeSelectionRange, toDataGridFilterProps, useFilterOptions, type UseFilterOptionsResult, getCellValue, flattenColumns, escapeCsvValue, buildCsvHeader, buildCsvRows, exportToCsv, triggerCsvDownload, type CsvColumn, } from '@alaarab/ogrid-core';
6
+ export * from '@alaarab/ogrid-core';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alaarab/ogrid",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
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",
@@ -41,7 +41,7 @@
41
41
  "node": ">=18"
42
42
  },
43
43
  "dependencies": {
44
- "@alaarab/ogrid-core": "^1.5.0",
44
+ "@alaarab/ogrid-core": "^1.6.0",
45
45
  "@radix-ui/react-checkbox": "^1.1.2",
46
46
  "@radix-ui/react-popover": "^1.1.2"
47
47
  },