@alaarab/ogrid-js 2.6.0 → 2.7.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.
@@ -221,6 +221,8 @@
221
221
  border-right: 1px solid var(--ogrid-border, #e0e0e0);
222
222
  font-size: 13px;
223
223
  vertical-align: middle;
224
+ user-select: none;
225
+ -webkit-user-select: none;
224
226
  }
225
227
 
226
228
  .ogrid-table th:last-of-type,
@@ -286,6 +288,12 @@
286
288
  font-variant-numeric: tabular-nums;
287
289
  }
288
290
 
291
+ .ogrid-row-number-header,
292
+ .ogrid-row-number-cell {
293
+ user-select: none;
294
+ -webkit-user-select: none;
295
+ }
296
+
289
297
  /* ── Resize Handle ── */
290
298
 
291
299
  .ogrid-resize-handle {
@@ -580,6 +588,54 @@
580
588
  color: var(--ogrid-fg, #242424);
581
589
  }
582
590
 
591
+ /* ── Sheet tabs ── */
592
+
593
+ .ogrid-sheet-tabs-container:empty {
594
+ display: none;
595
+ }
596
+
597
+ .ogrid-sheet-tabs {
598
+ display: flex;
599
+ align-items: center;
600
+ border-top: 1px solid var(--ogrid-border, #e0e0e0);
601
+ background: var(--ogrid-header-bg, #f5f5f5);
602
+ min-height: 30px;
603
+ overflow-x: auto;
604
+ overflow-y: hidden;
605
+ gap: 0;
606
+ font-size: 12px;
607
+ }
608
+
609
+ .ogrid-sheet-tabs__add-btn {
610
+ background: none;
611
+ border: none;
612
+ cursor: pointer;
613
+ padding: 4px 10px;
614
+ font-size: 16px;
615
+ line-height: 22px;
616
+ color: var(--ogrid-fg-secondary, #666);
617
+ flex-shrink: 0;
618
+ }
619
+
620
+ .ogrid-sheet-tabs__tab {
621
+ background: none;
622
+ border: none;
623
+ border-bottom: 2px solid transparent;
624
+ cursor: pointer;
625
+ padding: 4px 16px;
626
+ font-size: 12px;
627
+ line-height: 22px;
628
+ color: var(--ogrid-fg, #242424);
629
+ white-space: nowrap;
630
+ position: relative;
631
+ }
632
+
633
+ .ogrid-sheet-tabs__tab--active {
634
+ font-weight: 600;
635
+ border-bottom-color: var(--ogrid-primary, #217346);
636
+ background: var(--ogrid-bg, #fff);
637
+ }
638
+
583
639
  /* ── Pagination ── */
584
640
 
585
641
  .ogrid-pagination-container {
@@ -123,10 +123,13 @@ export declare class OGrid<T> {
123
123
  private formulaEngine;
124
124
  private formulaBar;
125
125
  private formulaBarContainer;
126
+ private sheetTabs;
127
+ private sheetTabsContainer;
126
128
  /** Tracks the text currently displayed/edited in the formula bar. */
127
129
  private formulaBarText;
128
130
  /** Whether the formula bar input is currently in editing mode. */
129
131
  private formulaBarEditing;
132
+ private activeSheetId;
130
133
  private events;
131
134
  private unsubscribes;
132
135
  private containerEl;
@@ -138,6 +141,12 @@ export declare class OGrid<T> {
138
141
  private isFullScreen;
139
142
  private fullscreenBtn;
140
143
  private nameBoxEl;
144
+ private lastPage;
145
+ private lastPageSize;
146
+ private lastSort;
147
+ private lastFilters;
148
+ private lastColumnOrder;
149
+ private lastPinnedColumns;
141
150
  private renderingHelper;
142
151
  private eventWiringHelper;
143
152
  /** The imperative grid API (extends React's IOGridApi with JS-specific methods). */
@@ -149,23 +158,28 @@ export declare class OGrid<T> {
149
158
  private handleCellMouseDown;
150
159
  private handleCellContextMenu;
151
160
  private showContextMenu;
161
+ private applyCellValueChange;
152
162
  private toggleBooleanCell;
153
163
  private startCellEdit;
154
164
  private buildFilterConfigs;
155
165
  private handleFilterIconClick;
156
166
  /** Build a grid data accessor for the formula engine from current state. */
157
167
  private buildFormulaAccessor;
168
+ /** Count leading non-data columns that appear inside the grid table. */
169
+ private getGridColumnOffset;
170
+ private getColumnDateFormat;
171
+ private getFormulaBarPlaceholder;
172
+ private normalizeFormulaBarValue;
158
173
  private handleFormulaBarCommit;
159
174
  private handleFormulaBarCancel;
160
175
  private handleFormulaBarStartEditing;
161
- /** Set which columns to group by. Pass empty array to clear grouping. */
162
- setGroupBy(columnIds: string[]): void;
163
- /** Toggle a group open/closed by its key. */
164
- toggleGroup(groupKey: string): void;
165
- /** Expand all groups. */
166
- expandAllGroups(): void;
167
- /** Collapse all groups. */
168
- collapseAllGroups(): void;
176
+ private bindColumnStateApi;
177
+ private bindSheetTabsApi;
178
+ private setActiveSheet;
179
+ private handleSheetAdd;
180
+ private renderSheetTabs;
181
+ private emitGridStateEvents;
182
+ private emitPinnedColumnChanges;
169
183
  /** Subscribe to grid events. */
170
184
  on<K extends keyof OGridEvents<T>>(event: K, handler: (data: OGridEvents<T>[K]) => void): void;
171
185
  /** Unsubscribe from grid events. */
@@ -45,6 +45,7 @@ export interface InteractionResult<T> {
45
45
  */
46
46
  export interface EventWiringCallbacks<_T> {
47
47
  updateRendererInteractionState: () => void;
48
+ renderAll: () => void;
48
49
  updateDragAttributes: () => void;
49
50
  clearCachedDragCells: () => void;
50
51
  showContextMenu: (x: number, y: number) => void;
@@ -66,7 +66,7 @@ export interface OGridRenderingContext<T> {
66
66
  filterConfigs: Map<string, HeaderFilterConfig>;
67
67
  loadingOverlay: HTMLElement | null;
68
68
  setLoadingOverlay: (el: HTMLElement | null) => void;
69
- handleCellClick: (rowIndex: number, colIndex: number) => void;
69
+ handleCellClick: (rowIndex: number, colIndex: number, shiftKey?: boolean) => void;
70
70
  handleCellMouseDown: (rowIndex: number, colIndex: number, e: MouseEvent) => void;
71
71
  handleCellContextMenu: (rowIndex: number, colIndex: number, e: MouseEvent) => void;
72
72
  startCellEdit: (rowId: import('@alaarab/ogrid-core').RowId, columnId: string) => void;
@@ -0,0 +1,9 @@
1
+ import { type ColumnHeaderMenuHandlers, type ColumnHeaderMenuInput } from '@alaarab/ogrid-core';
2
+ export declare class ColumnHeaderMenu {
3
+ private menu;
4
+ private outsideClickHandler;
5
+ private escapeHandler;
6
+ show(anchorElement: HTMLElement, input: ColumnHeaderMenuInput, handlers: Partial<ColumnHeaderMenuHandlers>): void;
7
+ close(): void;
8
+ destroy(): void;
9
+ }
@@ -10,8 +10,13 @@ export interface ContextMenuHandlers {
10
10
  export declare class ContextMenu {
11
11
  private menu;
12
12
  private handlers;
13
+ private menuItems;
14
+ private outsideClickCleanup;
13
15
  show(x: number, y: number, handlers: ContextMenuHandlers, canUndo: boolean, canRedo: boolean, selectionRange: ISelectionRange | null): void;
14
16
  close(): void;
15
17
  private handleItemClick;
16
18
  destroy(): void;
19
+ private focusAdjacentMenuItem;
20
+ private focusFirstEnabledMenuItem;
21
+ private focusLastEnabledMenuItem;
17
22
  }
@@ -27,6 +27,8 @@ export declare class FormulaBar {
27
27
  mount(container: HTMLElement): void;
28
28
  /** Update the formula bar display with the current active cell ref and formula text. */
29
29
  update(cellRef: string | null, formulaText: string): void;
30
+ /** Update the input placeholder for the active cell's editor semantics. */
31
+ setPlaceholder(placeholder: string | null): void;
30
32
  /** Set editing state. When true, the input becomes editable and receives focus. */
31
33
  setEditing(editing: boolean): void;
32
34
  /** Remove the formula bar from the DOM and clean up event listeners. */
@@ -34,4 +36,5 @@ export declare class FormulaBar {
34
36
  private handleKeyDown;
35
37
  private handleInput;
36
38
  private handleClick;
39
+ private handleBlur;
37
40
  }
@@ -16,6 +16,7 @@ export declare class InlineCellEditor<T> {
16
16
  rowId: RowId;
17
17
  columnId: string;
18
18
  } | null;
19
+ cancelEdit(): boolean;
19
20
  closeEditor(): void;
20
21
  private createEditor;
21
22
  /**
@@ -0,0 +1,14 @@
1
+ import type { ISheetDef } from '@alaarab/ogrid-core';
2
+ export interface SheetTabsRenderProps {
3
+ sheets: ISheetDef[];
4
+ activeSheet: string;
5
+ onSheetChange: (sheetId: string) => void;
6
+ onSheetAdd?: () => void;
7
+ }
8
+ export declare class SheetTabs {
9
+ private container;
10
+ private el;
11
+ constructor(container: HTMLElement);
12
+ render(props: SheetTabsRenderProps): void;
13
+ destroy(): void;
14
+ }
@@ -1,8 +1,10 @@
1
- import type { IStatusBarProps } from '@alaarab/ogrid-core';
1
+ import type { IStatusBarProps, StatusBarPartsInput } from '@alaarab/ogrid-core';
2
+ type JSStatusBarProps = IStatusBarProps & Pick<StatusBarPartsInput, 'selectedCellCount'>;
2
3
  export declare class StatusBar {
3
4
  private container;
4
5
  private el;
5
6
  constructor(container: HTMLElement);
6
- render(props: IStatusBarProps): void;
7
+ render(props: JSStatusBarProps): void;
7
8
  destroy(): void;
8
9
  }
10
+ export {};
@@ -2,8 +2,6 @@ export type { ColumnFilterType, IDateFilterValue, IColumnFilterDef, IColumnMeta,
2
2
  export { toUserLike, isInSelectionRange, normalizeSelectionRange, escapeCsvValue, buildCsvHeader, buildCsvRows, exportToCsv, triggerCsvDownload, getCellValue, isColumnEditable, createGridDataAccessor, flattenColumns, buildHeaderRows, isFilterConfig, getFilterField, mergeFilter, deriveFilterOptionsFromData, getMultiSelectFilterFields, getStatusBarParts, getDataGridStatusBarConfig, getPaginationViewModel, PAGE_SIZE_OPTIONS, MAX_PAGE_BUTTONS, GRID_CONTEXT_MENU_ITEMS, COLUMN_HEADER_MENU_ITEMS, getContextMenuHandlers, getColumnHeaderMenuItems, formatShortcut, parseValue, numberParser, currencyParser, dateParser, emailParser, booleanParser, computeAggregations, processClientSideData, areGridRowPropsEqual, isRowInRange, getPinStateForColumn, reorderColumnArray, calculateDropTarget, computeVisibleRange, computeTotalHeight, getScrollTopForRow, computeVisibleColumnRange, partitionColumnsForVirtualization, createSortFilterWorker, terminateSortFilterWorker, extractValueMatrix, processClientSideDataAsync, getHeaderFilterConfig, getCellRenderDescriptor, CellDescriptorCache, resolveCellDisplayContent, resolveCellStyle, buildInlineEditorProps, buildPopoverEditorProps, measureRange, buildCellIndex, injectGlobalStyles, computeNextSortState, measureColumnContentWidth, AUTOSIZE_EXTRA_PX, AUTOSIZE_MAX_PX, findCtrlArrowTarget, computeTabNavigation, computeArrowNavigation, applyCellDeletion, rangesEqual, clampSelectionToBounds, computeAutoScrollSpeed, applyRangeRowSelection, computeRowSelectionState, formatCellValueForTsv, formatSelectionAsTsv, parseTsvClipboard, applyPastedValues, applyCutClear, applyFillValues, UndoRedoStack, validateColumns, validateRowIds, validateVirtualScrollConfig, indexToColumnLetter, columnLetterToIndex, formatCellReference, getResponsiveHiddenColumns, RESPONSIVE_BREAKPOINTS, resolveResponsiveConfig, applyResponsiveHiding, } from '@alaarab/ogrid-core';
3
3
  export { CHECKBOX_COLUMN_WIDTH, ROW_NUMBER_COLUMN_WIDTH, ROW_NUMBER_COLUMN_ID, ROW_NUMBER_COLUMN_MIN_WIDTH, DEFAULT_MIN_COLUMN_WIDTH, CELL_PADDING, GRID_BORDER_RADIUS, DEFAULT_DEBOUNCE_MS, PEOPLE_SEARCH_DEBOUNCE_MS, SIDEBAR_TRANSITION_MS, Z_INDEX, } from '@alaarab/ogrid-core';
4
4
  export { FormulaError, FormulaEngine, FormulaEvaluator, DependencyGraph, tokenize, parse, createBuiltInFunctions, parseCellRef, parseRange, formatAddress, toCellKey, fromCellKey, adjustFormulaReferences, toNumber, formulaToString, toBoolean, flattenArgs, isFormulaError, REF_ERROR, DIV_ZERO_ERROR, VALUE_ERROR, NAME_ERROR, CIRC_ERROR, GENERAL_ERROR, NA_ERROR, extractFormulaReferences, processFormulaBarCommit, deriveFormulaBarText, handleFormulaBarKeyDown, canInsertReference, insertReferenceAtCursor, FORMULA_REF_COLORS, FORMULA_BAR_CSS, FORMULA_BAR_STYLES, } from '@alaarab/ogrid-core/formula';
5
- export type { IRowGroup, IRowGroupingConfig, RowGroupingDisplayRow, } from '@alaarab/ogrid-core';
6
- export { isGroupHeader, buildGroupedRows } from '@alaarab/ogrid-core';
7
5
  export type { IColumnDef, IColumnGroupDef, ICellEditorContext } from './types/columnTypes';
8
6
  export type { OGridOptions, OGridEvents, IJsOGridApi, CellEvent } from './types/gridTypes';
9
7
  export { debounce } from './utils';
@@ -35,6 +35,10 @@ export interface TableRendererInteractionState {
35
35
  rightOffsets?: Record<string, number>;
36
36
  onColumnReorderStart?: (columnId: string, event: PointerEvent) => void;
37
37
  onBooleanToggle?: (rowId: RowId, columnId: string, currentValue: boolean) => void;
38
+ onPinColumn?: (columnId: string, side: 'left' | 'right' | null) => void;
39
+ onSetColumnSort?: (columnId: string, direction: 'asc' | 'desc' | null) => void;
40
+ onAutosizeColumn?: (columnId: string) => void;
41
+ onAutosizeAllColumns?: () => void;
38
42
  }
39
43
  export declare class TableRenderer<T> {
40
44
  private container;
@@ -51,11 +55,15 @@ export declare class TableRenderer<T> {
51
55
  private virtualScrollState;
52
56
  private _tbodyClickHandler;
53
57
  private _tbodyPointerdownHandler;
58
+ private _tbodyMousedownHandler;
54
59
  private _tbodyDblclickHandler;
55
60
  private _tbodyContextmenuHandler;
61
+ private _tbodySelectstartHandler;
56
62
  private _theadClickHandler;
57
63
  private _theadPointerdownHandler;
64
+ private _theadMousedownHandler;
58
65
  private _theadDblclickHandler;
66
+ private _theadSelectstartHandler;
59
67
  private lastActiveCell;
60
68
  private lastSelectionRange;
61
69
  private lastCopyRange;
@@ -71,6 +79,7 @@ export declare class TableRenderer<T> {
71
79
  private lastAllSelected;
72
80
  private lastSomeSelected;
73
81
  private formulaEngine;
82
+ private headerMenu;
74
83
  constructor(container: HTMLElement, state: GridState<T>);
75
84
  setFormulaEngine(engine: FormulaEngineState): void;
76
85
  setVirtualScrollState(vs: VirtualScrollState): void;
@@ -78,6 +87,9 @@ export declare class TableRenderer<T> {
78
87
  setOnFilterIconClick(handler: (columnId: string, headerEl: HTMLElement) => void): void;
79
88
  setInteractionState(state: TableRendererInteractionState | null): void;
80
89
  private getCellFromEvent;
90
+ private addDelegatedListeners;
91
+ private removeDelegatedListeners;
92
+ private isNonDataSelectionSurface;
81
93
  private attachBodyDelegation;
82
94
  private detachBodyDelegation;
83
95
  /** Attach delegated event listeners to <thead> for sort clicks, resize, reorder, and filter icon clicks. */
@@ -102,8 +114,11 @@ export declare class TableRenderer<T> {
102
114
  getColOffset(): number;
103
115
  private applyPinningStyles;
104
116
  private renderHeader;
117
+ private appendHeaderContent;
118
+ private createHeaderFilterButton;
119
+ private createHeaderMenuButton;
120
+ private openColumnMenu;
105
121
  private appendSelectAllCheckbox;
106
- private renderGroupHeaderRow;
107
122
  private renderBody;
108
123
  /** Get the table element (used by ColumnReorderState for header cell queries). */
109
124
  getTableElement(): HTMLTableElement | null;
@@ -1,11 +1,33 @@
1
1
  import type { IColumnDef, IColumnGroupDef } from '../types/columnTypes';
2
2
  import type { RowId, IFilters, OGridOptions, IJsOGridApi } from '../types/gridTypes';
3
3
  import type { FilterValue, IResponsiveColumnsConfig } from '@alaarab/ogrid-core';
4
- import type { RowGroupingDisplayRow } from '@alaarab/ogrid-core';
5
4
  import type { FormulaEngineState } from './FormulaEngineState';
6
- interface StateChangeEvent {
7
- type: 'data' | 'sort' | 'filter' | 'page' | 'columns' | 'loading';
8
- }
5
+ type StateChangeEvent = {
6
+ type: 'data';
7
+ } | {
8
+ type: 'loading';
9
+ } | {
10
+ type: 'sort';
11
+ sort: {
12
+ field: string;
13
+ direction: 'asc' | 'desc';
14
+ } | undefined;
15
+ } | {
16
+ type: 'filter';
17
+ filters: IFilters;
18
+ } | {
19
+ type: 'page';
20
+ page: number;
21
+ } | {
22
+ type: 'pageSize';
23
+ page: number;
24
+ pageSize: number;
25
+ } | {
26
+ type: 'columns';
27
+ reason: 'visibleColumns' | 'columnOrder' | 'responsive';
28
+ visibleColumns?: Set<string>;
29
+ columnOrder?: string[];
30
+ };
9
31
  export declare class GridState<T> {
10
32
  private emitter;
11
33
  private _data;
@@ -28,20 +50,25 @@ export declare class GridState<T> {
28
50
  private _firstDataRendered;
29
51
  private _rowHeight?;
30
52
  private _ariaLabel?;
53
+ private _ariaLabelledBy?;
31
54
  private _stickyHeader;
32
55
  private _fullScreen;
33
56
  private _workerSort;
34
57
  private _formulaEngine;
35
58
  private _filterOptions;
36
59
  private _columnOrder;
37
- private _groupByColumnIds;
38
- private _expandedGroups;
39
60
  private _responsiveColumns;
40
61
  private _containerWidth;
41
62
  private _visibleColsCache;
42
63
  private _visibleColsDirty;
43
64
  private _sortedIndices;
44
65
  private _sortDirty;
66
+ private getKnownColumnIds;
67
+ private normalizeVisibleColumns;
68
+ private normalizeColumnOrder;
69
+ private emitStateChange;
70
+ private emitDataChange;
71
+ private handleQueryStateChange;
45
72
  constructor(options: OGridOptions<T>);
46
73
  get data(): T[];
47
74
  get page(): number;
@@ -63,9 +90,8 @@ export declare class GridState<T> {
63
90
  get columnOrder(): string[];
64
91
  get rowHeight(): number | undefined;
65
92
  get ariaLabel(): string | undefined;
93
+ get ariaLabelledBy(): string | undefined;
66
94
  get responsiveColumns(): IResponsiveColumnsConfig | null;
67
- get groupByColumnIds(): string[];
68
- get expandedGroups(): Set<string>;
69
95
  /** Get the visible columns in display order (respects column reorder and responsive hiding). Memoized via dirty flag. */
70
96
  get visibleColumnDefs(): IColumnDef<T>[];
71
97
  /** Get processed (sorted, filtered, paginated) items for current page. */
@@ -73,18 +99,6 @@ export declare class GridState<T> {
73
99
  items: T[];
74
100
  totalCount: number;
75
101
  };
76
- /** Whether row grouping is currently active. */
77
- get isGrouped(): boolean;
78
- /**
79
- * Get display rows with group headers interleaved when grouping is active.
80
- * When groupBy is empty, returns the same items as getProcessedItems.
81
- * When groupBy is set, returns a flat array of RowGroupingDisplayRow<T>
82
- * (group headers + data rows) with pagination applied to the flat list.
83
- */
84
- getGroupedDisplayRows(): {
85
- displayRows: RowGroupingDisplayRow<T>[];
86
- totalCount: number;
87
- };
88
102
  /** Whether worker sort should be used for the current data set. */
89
103
  get useWorkerSort(): boolean;
90
104
  /**
@@ -98,10 +112,6 @@ export declare class GridState<T> {
98
112
  }>;
99
113
  private fetchServerData;
100
114
  setData(data: T[]): void;
101
- setGroupBy(columnIds: string[]): void;
102
- toggleGroup(groupKey: string): void;
103
- expandAllGroups(): void;
104
- collapseAllGroups(): void;
105
115
  setPage(page: number): void;
106
116
  setPageSize(pageSize: number): void;
107
117
  setSort(sort: {
@@ -113,6 +123,7 @@ export declare class GridState<T> {
113
123
  clearFilters(): void;
114
124
  setVisibleColumns(columns: Set<string>): void;
115
125
  setColumnOrder(order: string[]): void;
126
+ setFilterModel(filters: IFilters): void;
116
127
  /** Update the container width for responsive column hiding. Invalidates the visible-cols cache. */
117
128
  setContainerWidth(width: number): void;
118
129
  setLoading(loading: boolean): void;
@@ -13,6 +13,7 @@ export interface KeyboardNavParams<T> {
13
13
  onRedo?: () => void;
14
14
  onContextMenu?: (x: number, y: number) => void;
15
15
  onStartEdit?: (rowId: RowId, columnId: string) => void;
16
+ onCancelEdit?: () => boolean;
16
17
  clearClipboardRanges?: () => void;
17
18
  /** Custom keydown handler. Called before grid default. preventDefault() suppresses grid handling. */
18
19
  onKeyDown?: (event: KeyboardEvent) => void;
@@ -15,6 +15,7 @@ export declare class SelectionState {
15
15
  private _selectedRowIds;
16
16
  private _isDragging;
17
17
  private dragStartCell;
18
+ private dragStartSelectionCol;
18
19
  private rafHandle;
19
20
  private pendingRange;
20
21
  get activeCell(): IActiveCell | null;
@@ -24,11 +25,11 @@ export declare class SelectionState {
24
25
  get isDragging(): boolean;
25
26
  /** Get the current drag range (used during drag for DOM attribute updates). */
26
27
  getDragRange(): ISelectionRange | null;
27
- setActiveCell(cell: IActiveCell | null): void;
28
+ setActiveCell(cell: IActiveCell | null, selectionColumnIndex?: number): void;
28
29
  setSelectionRange(range: ISelectionRange | null): void;
29
30
  clearSelection(): void;
30
- startDrag(rowIndex: number, colIndex: number): void;
31
- updateDrag(rowIndex: number, colIndex: number, applyFn: (range: ISelectionRange) => void): void;
31
+ startDrag(rowIndex: number, colIndex: number, selectionColIndex?: number): void;
32
+ updateDrag(rowIndex: number, colIndex: number, applyFn: (range: ISelectionRange) => void, selectionColIndex?: number): void;
32
33
  endDrag(): void;
33
34
  setSelectedRowIds(ids: Set<RowId>): void;
34
35
  onSelectionChange(handler: (data: SelectionStateEvents['selectionChange']) => void): () => void;
@@ -1,6 +1,6 @@
1
1
  import type { IColumnDef, IColumnGroupDef, ICellValueChangedEvent } from './columnTypes';
2
- import type { RowId, IFilters, IDataSource, RowSelectionMode, IRowSelectionChangeEvent, IOGridApi, ISideBarDef, IStatusBarProps, IVirtualScrollConfig, IFormulaFunction, IRecalcResult, IGridDataAccessor, IResponsiveColumnsConfig } from '@alaarab/ogrid-core';
3
- export type { RowId, UserLike, UserLikeInput, FilterValue, IFilters, IFetchParams, IPageResult, IDataSource, IGridColumnState, RowSelectionMode, IRowSelectionChangeEvent, StatusBarPanel, IStatusBarProps, IActiveCell, ISelectionRange, SideBarPanelId, ISideBarDef, IVirtualScrollConfig, IOGridApi, IFormulaFunction, IRecalcResult, IGridDataAccessor, IAuditEntry, IAuditTrail, IResponsiveColumnsConfig, } from '@alaarab/ogrid-core';
2
+ import type { RowId, IFilters, IDataSource, RowSelectionMode, IRowSelectionChangeEvent, IOGridApi, ISideBarDef, ISheetDef, IStatusBarProps, IVirtualScrollConfig, IFormulaFunction, IRecalcResult, IGridDataAccessor, IResponsiveColumnsConfig } from '@alaarab/ogrid-core';
3
+ export type { RowId, UserLike, UserLikeInput, FilterValue, IFilters, IFetchParams, IPageResult, IDataSource, IGridColumnState, RowSelectionMode, IRowSelectionChangeEvent, StatusBarPanel, IStatusBarProps, IActiveCell, ISelectionRange, SideBarPanelId, ISideBarDef, ISheetDef, IVirtualScrollConfig, IOGridApi, IFormulaFunction, IRecalcResult, IGridDataAccessor, IAuditEntry, IAuditTrail, IResponsiveColumnsConfig, } from '@alaarab/ogrid-core';
4
4
  /** Standardized cell event parameter for cell interaction callbacks. */
5
5
  export interface CellEvent {
6
6
  /** Zero-based row index within the current page. */
@@ -28,6 +28,16 @@ export interface IJsOGridApi<T> extends IOGridApi<T> {
28
28
  getColumnOrder: () => string[];
29
29
  /** Set the column display order. */
30
30
  setColumnOrder: (order: string[]) => void;
31
+ /** Get the currently active sheet tab id. */
32
+ getActiveSheet: () => string | null;
33
+ /** Set the active sheet tab id. */
34
+ setActiveSheet: (sheetId: string) => void;
35
+ /** Get the current sheet tab definitions. */
36
+ getSheetDefs: () => ISheetDef[];
37
+ /** Replace the current sheet tab definitions. */
38
+ setSheetDefs: (sheetDefs: ISheetDef[], options?: {
39
+ activeSheet?: string;
40
+ }) => void;
31
41
  }
32
42
  /** Options for the vanilla JS OGrid constructor. */
33
43
  export interface OGridOptions<T> {
@@ -84,6 +94,14 @@ export interface OGridOptions<T> {
84
94
  'aria-labelledby'?: string;
85
95
  /** Side bar configuration (columns panel + filters panel). */
86
96
  sideBar?: boolean | ISideBarDef;
97
+ /** Sheet definitions for bottom tab bar. When set, renders Excel-style sheet tabs. */
98
+ sheetDefs?: ISheetDef[];
99
+ /** Initially active sheet id. Defaults to the first provided sheet. */
100
+ activeSheet?: string;
101
+ /** Called when the user switches sheets. */
102
+ onSheetChange?: (sheetId: string) => void;
103
+ /** Called when the user clicks the add-sheet button. */
104
+ onSheetAdd?: () => void;
87
105
  /** Error callback for server-side data source failures. */
88
106
  onError?: (error: unknown) => void;
89
107
  /** Called when a cell editor throws an error. JS alternative: listen to the 'cellError' event. */
@@ -119,8 +137,6 @@ export interface OGridOptions<T> {
119
137
  * - `false` (default): use synchronous sort
120
138
  */
121
139
  workerSort?: boolean | 'auto';
122
- /** Column IDs to group rows by. Groups are collapsed by default. */
123
- groupBy?: string[];
124
140
  /** Fixed row height in pixels. Overrides default row height (36px). */
125
141
  rowHeight?: number;
126
142
  /** Cell spacing/density preset. Controls cell padding throughout the grid. Default: 'normal'. */
@@ -167,8 +183,10 @@ export interface OGridEvents<T> extends Record<string, unknown> {
167
183
  cellValueChanged: ICellValueChangedEvent<T>;
168
184
  selectionChange: IRowSelectionChangeEvent<T>;
169
185
  sortChange: {
170
- field: string;
171
- direction: 'asc' | 'desc';
186
+ sort: {
187
+ field: string;
188
+ direction: 'asc' | 'desc';
189
+ } | undefined;
172
190
  };
173
191
  filterChange: {
174
192
  filters: IFilters;
@@ -176,4 +194,23 @@ export interface OGridEvents<T> extends Record<string, unknown> {
176
194
  pageChange: {
177
195
  page: number;
178
196
  };
197
+ pageSizeChange: {
198
+ page: number;
199
+ pageSize: number;
200
+ };
201
+ columnOrderChange: {
202
+ order: string[];
203
+ };
204
+ columnResized: {
205
+ columnId: string;
206
+ width: number;
207
+ };
208
+ columnPinned: {
209
+ columnId: string;
210
+ pin: 'left' | 'right' | null;
211
+ };
212
+ sheetChange: {
213
+ sheetId: string;
214
+ };
215
+ sheetAdd: Record<string, never>;
179
216
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alaarab/ogrid-js",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "description": "OGrid vanilla JS – framework-free data grid with sorting, filtering, pagination, and spreadsheet-style editing.",
5
5
  "main": "dist/esm/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -36,7 +36,7 @@
36
36
  "node": ">=18"
37
37
  },
38
38
  "dependencies": {
39
- "@alaarab/ogrid-core": "2.6.0"
39
+ "@alaarab/ogrid-core": "2.7.0"
40
40
  },
41
41
  "sideEffects": [
42
42
  "**/*.css"