@alaarab/ogrid-angular 2.3.0 → 2.4.1
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/dist/esm/index.js +553 -30
- package/dist/types/components/base-column-header-menu.component.d.ts +30 -0
- package/dist/types/components/base-datagrid-table.component.d.ts +5 -0
- package/dist/types/components/formula-bar.component.d.ts +29 -0
- package/dist/types/components/formula-ref-overlay.component.d.ts +27 -0
- package/dist/types/components/ogrid-layout.component.d.ts +7 -0
- package/dist/types/components/sheet-tabs.component.d.ts +16 -0
- package/dist/types/index.d.ts +6 -2
- package/dist/types/services/datagrid-state.service.d.ts +3 -0
- package/dist/types/services/formula-engine.service.d.ts +1 -3
- package/dist/types/services/ogrid.service.d.ts +41 -1
- package/dist/types/types/dataGridTypes.d.ts +14 -2
- package/dist/types/types/index.d.ts +1 -1
- package/package.json +2 -2
package/dist/esm/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { FormulaEngine,
|
|
1
|
+
import { handleFormulaBarKeyDown, FormulaEngine, createGridDataAccessor, columnLetterToIndex, flattenColumns, getMultiSelectFilterFields, deriveFilterOptionsFromData, processClientSideData, deriveFormulaBarText, extractFormulaReferences, validateColumns, processClientSideDataAsync, validateRowIds, computeNextSortState, mergeFilter, CHECKBOX_COLUMN_WIDTH, DEFAULT_MIN_COLUMN_WIDTH, CELL_PADDING, parseValue, UndoRedoStack, rangesEqual, normalizeSelectionRange, formatSelectionAsTsv, parseTsvClipboard, getCellValue, applyCellDeletion, getScrollTopForRow, computeTabNavigation, applyFillValues, computeAggregations, getDataGridStatusBarConfig, computeVisibleRange, computeTotalHeight, computeVisibleColumnRange, validateVirtualScrollConfig, GRID_BORDER_RADIUS, getStatusBarParts, GRID_CONTEXT_MENU_ITEMS, formatShortcut, injectGlobalStyles, partitionColumnsForVirtualization, buildHeaderRows, ROW_NUMBER_COLUMN_ID, ROW_NUMBER_COLUMN_WIDTH, getHeaderFilterConfig, getCellRenderDescriptor, resolveCellDisplayContent, resolveCellStyle, buildPopoverEditorProps, ROW_NUMBER_COLUMN_MIN_WIDTH, measureColumnContentWidth, getPaginationViewModel, getColumnHeaderMenuItems, reorderColumnArray, findCtrlArrowTarget, measureRange, FORMULA_REF_COLORS } from '@alaarab/ogrid-core';
|
|
2
2
|
export * from '@alaarab/ogrid-core';
|
|
3
|
-
export { CELL_PADDING, CHECKBOX_COLUMN_WIDTH, DEFAULT_DEBOUNCE_MS, DEFAULT_MIN_COLUMN_WIDTH, GRID_BORDER_RADIUS, PEOPLE_SEARCH_DEBOUNCE_MS, ROW_NUMBER_COLUMN_WIDTH, SIDEBAR_TRANSITION_MS, Z_INDEX, debounce, getCellRenderDescriptor, getHeaderFilterConfig, isInSelectionRange, normalizeSelectionRange, resolveCellDisplayContent, resolveCellStyle, toUserLike } from '@alaarab/ogrid-core';
|
|
4
|
-
import { Injectable, Input, Component, ChangeDetectionStrategy, ViewEncapsulation, Output, ViewChild, inject, DestroyRef, signal, computed,
|
|
3
|
+
export { CELL_PADDING, CHECKBOX_COLUMN_WIDTH, DEFAULT_DEBOUNCE_MS, DEFAULT_MIN_COLUMN_WIDTH, GRID_BORDER_RADIUS, PEOPLE_SEARCH_DEBOUNCE_MS, ROW_NUMBER_COLUMN_ID, ROW_NUMBER_COLUMN_MIN_WIDTH, ROW_NUMBER_COLUMN_WIDTH, SIDEBAR_TRANSITION_MS, Z_INDEX, debounce, getCellRenderDescriptor, getHeaderFilterConfig, isInSelectionRange, normalizeSelectionRange, resolveCellDisplayContent, resolveCellStyle, toUserLike } from '@alaarab/ogrid-core';
|
|
4
|
+
import { Injectable, Input, Component, ChangeDetectionStrategy, ViewEncapsulation, Output, ViewChild, input, output, viewChild, effect, inject, DestroyRef, signal, computed, NgZone, EventEmitter, Injector, EnvironmentInjector, createComponent } from '@angular/core';
|
|
5
5
|
import { NgTemplateOutlet } from '@angular/common';
|
|
6
6
|
|
|
7
7
|
var __defProp = Object.defineProperty;
|
|
@@ -199,21 +199,9 @@ var FormulaEngineService = class {
|
|
|
199
199
|
return this.engine?.getAuditTrail(col, row) ?? null;
|
|
200
200
|
}
|
|
201
201
|
// --- Private helpers ---
|
|
202
|
-
/**
|
|
203
|
-
* Create a data accessor that bridges grid data to formula coordinates.
|
|
204
|
-
*/
|
|
202
|
+
/** Create a data accessor that bridges grid data to formula coordinates. */
|
|
205
203
|
createAccessor() {
|
|
206
|
-
|
|
207
|
-
const cols = this.flatColumns;
|
|
208
|
-
return {
|
|
209
|
-
getCellValue: (col, row) => {
|
|
210
|
-
if (row < 0 || row >= items.length) return null;
|
|
211
|
-
if (col < 0 || col >= cols.length) return null;
|
|
212
|
-
return getCellValue(items[row], cols[col]);
|
|
213
|
-
},
|
|
214
|
-
getRowCount: () => items.length,
|
|
215
|
-
getColumnCount: () => cols.length
|
|
216
|
-
};
|
|
204
|
+
return createGridDataAccessor(this.items, this.flatColumns);
|
|
217
205
|
}
|
|
218
206
|
};
|
|
219
207
|
FormulaEngineService = __decorateClass([
|
|
@@ -291,14 +279,35 @@ var OGridService = class {
|
|
|
291
279
|
this.formulaFunctions = signal(void 0);
|
|
292
280
|
this.namedRanges = signal(void 0);
|
|
293
281
|
this.sheets = signal(void 0);
|
|
282
|
+
this.sheetDefs = signal(void 0);
|
|
283
|
+
this.activeSheet = signal(void 0);
|
|
284
|
+
this.onSheetChange = signal(void 0);
|
|
285
|
+
this.onSheetAdd = signal(void 0);
|
|
294
286
|
/** Active cell reference string (e.g. 'A1') updated by DataGridTable when cellReferences is enabled. */
|
|
295
287
|
this.activeCellRef = signal(null);
|
|
296
|
-
/**
|
|
288
|
+
/** Active cell coordinates (0-based col/row). */
|
|
289
|
+
this.activeCellCoords = signal(null);
|
|
290
|
+
/** Stable callback passed to DataGridTable to update activeCellRef + coords. */
|
|
297
291
|
this.handleActiveCellChange = (ref) => {
|
|
298
292
|
this.activeCellRef.set(ref);
|
|
293
|
+
if (ref) {
|
|
294
|
+
const m = ref.match(/^([A-Z]+)(\d+)$/);
|
|
295
|
+
if (m) {
|
|
296
|
+
this.activeCellCoords.set({ col: columnLetterToIndex(m[1]), row: parseInt(m[2], 10) - 1 });
|
|
297
|
+
} else {
|
|
298
|
+
this.activeCellCoords.set(null);
|
|
299
|
+
}
|
|
300
|
+
} else {
|
|
301
|
+
this.activeCellCoords.set(null);
|
|
302
|
+
}
|
|
299
303
|
};
|
|
304
|
+
// --- Formula bar state ---
|
|
305
|
+
this.formulaBarEditing = signal(false);
|
|
306
|
+
this.formulaBarEditText = signal("");
|
|
300
307
|
// --- Formula engine ---
|
|
301
308
|
this.formulaService = new FormulaEngineService();
|
|
309
|
+
/** Monotonic counter incremented on formula recalculation — drives cache invalidation. */
|
|
310
|
+
this.formulaVersion = signal(0);
|
|
302
311
|
// Stable formula method references for dataGridProps (avoid per-recompute arrow functions)
|
|
303
312
|
this.getFormulaValueFn = (col, row) => this.formulaService.getValue(col, row);
|
|
304
313
|
this.hasFormulaFn = (col, row) => this.formulaService.hasFormula(col, row);
|
|
@@ -460,6 +469,52 @@ var OGridService = class {
|
|
|
460
469
|
toggle: (panel) => this.sideBarActivePanel.update((p) => p === panel ? null : panel),
|
|
461
470
|
close: () => this.sideBarActivePanel.set(null)
|
|
462
471
|
}));
|
|
472
|
+
// --- Formula bar derived state ---
|
|
473
|
+
/** Display text derived from active cell (formula string or raw value). */
|
|
474
|
+
this.formulaBarDisplayText = computed(() => {
|
|
475
|
+
const coords = this.activeCellCoords();
|
|
476
|
+
if (!coords) return "";
|
|
477
|
+
const getFormula = this.formulaService.enabled() ? (c, r) => this.formulaService.getFormula(c, r) : void 0;
|
|
478
|
+
const items = this.displayItems();
|
|
479
|
+
const cols = this.columns();
|
|
480
|
+
const getRawValue = (c, r) => {
|
|
481
|
+
if (r < 0 || r >= items.length || c < 0 || c >= cols.length) return void 0;
|
|
482
|
+
return getCellValue(items[r], cols[c]);
|
|
483
|
+
};
|
|
484
|
+
return deriveFormulaBarText(coords.col, coords.row, getFormula, getRawValue);
|
|
485
|
+
});
|
|
486
|
+
/** Formula text shown in the bar: edit text when editing, display text otherwise. */
|
|
487
|
+
this.formulaBarText = computed(
|
|
488
|
+
() => this.formulaBarEditing() ? this.formulaBarEditText() : this.formulaBarDisplayText()
|
|
489
|
+
);
|
|
490
|
+
/** References extracted from the current formula text (for highlighting). */
|
|
491
|
+
this.formulaBarReferences = computed(
|
|
492
|
+
() => extractFormulaReferences(this.formulaBarText())
|
|
493
|
+
);
|
|
494
|
+
// Stable formula bar callbacks (avoid new closures per computed)
|
|
495
|
+
this.formulaBarOnInputChangeFn = (text) => {
|
|
496
|
+
this.formulaBarEditText.set(text);
|
|
497
|
+
};
|
|
498
|
+
this.formulaBarOnCommitFn = () => {
|
|
499
|
+
this.commitFormulaBar();
|
|
500
|
+
};
|
|
501
|
+
this.formulaBarOnCancelFn = () => {
|
|
502
|
+
this.cancelFormulaBar();
|
|
503
|
+
};
|
|
504
|
+
this.formulaBarStartEditingFn = () => {
|
|
505
|
+
this.startFormulaBarEditing();
|
|
506
|
+
};
|
|
507
|
+
/** Aggregate formula bar state for template consumption. */
|
|
508
|
+
this.formulaBarState = computed(() => ({
|
|
509
|
+
cellRef: this.activeCellRef(),
|
|
510
|
+
formulaText: this.formulaBarText(),
|
|
511
|
+
isEditing: this.formulaBarEditing(),
|
|
512
|
+
onInputChange: this.formulaBarOnInputChangeFn,
|
|
513
|
+
onCommit: this.formulaBarOnCommitFn,
|
|
514
|
+
onCancel: this.formulaBarOnCancelFn,
|
|
515
|
+
startEditing: this.formulaBarStartEditingFn,
|
|
516
|
+
referencedCells: this.formulaBarReferences()
|
|
517
|
+
}));
|
|
463
518
|
// --- Pre-computed stable callback references for dataGridProps ---
|
|
464
519
|
// These avoid recreating arrow functions on every dataGridProps recomputation.
|
|
465
520
|
this.handleSortFn = (columnKey, direction) => this.handleSort(columnKey, direction);
|
|
@@ -499,10 +554,10 @@ var OGridService = class {
|
|
|
499
554
|
rowSelection: this.rowSelection(),
|
|
500
555
|
selectedRows: this.effectiveSelectedRows(),
|
|
501
556
|
onSelectionChange: this.handleSelectionChangeFn,
|
|
502
|
-
showRowNumbers: this.showRowNumbers() || this.cellReferences(),
|
|
503
|
-
showColumnLetters: !!this.cellReferences(),
|
|
504
|
-
showNameBox: !!this.cellReferences(),
|
|
505
|
-
onActiveCellChange: this.cellReferences() ? this.handleActiveCellChange : void 0,
|
|
557
|
+
showRowNumbers: this.showRowNumbers() || this.cellReferences() || this.formulasEnabled(),
|
|
558
|
+
showColumnLetters: !!(this.cellReferences() || this.formulasEnabled()),
|
|
559
|
+
showNameBox: !!(this.cellReferences() && !this.formulasEnabled()),
|
|
560
|
+
onActiveCellChange: this.cellReferences() || this.formulasEnabled() ? this.handleActiveCellChange : void 0,
|
|
506
561
|
currentPage: this.page(),
|
|
507
562
|
pageSize: this.pageSize(),
|
|
508
563
|
statusBar: this.statusBarConfig(),
|
|
@@ -527,6 +582,8 @@ var OGridService = class {
|
|
|
527
582
|
render: this.emptyState()?.render
|
|
528
583
|
},
|
|
529
584
|
formulas: this.formulasEnabled(),
|
|
585
|
+
formulaVersion: this.formulaVersion(),
|
|
586
|
+
formulaReferences: this.formulaBarReferences().length > 0 ? this.formulaBarReferences() : void 0,
|
|
530
587
|
...this.formulaService.enabled() ? {
|
|
531
588
|
getFormulaValue: this.getFormulaValueFn,
|
|
532
589
|
hasFormula: this.hasFormulaFn,
|
|
@@ -694,11 +751,19 @@ var OGridService = class {
|
|
|
694
751
|
}
|
|
695
752
|
});
|
|
696
753
|
effect(() => {
|
|
754
|
+
this.activeCellCoords();
|
|
755
|
+
this.formulaBarEditing.set(false);
|
|
756
|
+
});
|
|
757
|
+
effect(() => {
|
|
758
|
+
const userRecalcCb = this.onFormulaRecalc();
|
|
697
759
|
this.formulaService.configure({
|
|
698
760
|
formulas: this.formulasEnabled(),
|
|
699
761
|
initialFormulas: this.initialFormulas(),
|
|
700
762
|
formulaFunctions: this.formulaFunctions(),
|
|
701
|
-
onFormulaRecalc:
|
|
763
|
+
onFormulaRecalc: (result) => {
|
|
764
|
+
this.formulaVersion.update((v) => v + 1);
|
|
765
|
+
userRecalcCb?.(result);
|
|
766
|
+
},
|
|
702
767
|
namedRanges: this.namedRanges(),
|
|
703
768
|
sheets: this.sheets()
|
|
704
769
|
});
|
|
@@ -786,6 +851,33 @@ var OGridService = class {
|
|
|
786
851
|
});
|
|
787
852
|
this.onColumnPinned()?.(columnId, pinned);
|
|
788
853
|
}
|
|
854
|
+
// --- Formula bar methods ---
|
|
855
|
+
startFormulaBarEditing() {
|
|
856
|
+
this.formulaBarEditText.set(this.formulaBarDisplayText());
|
|
857
|
+
this.formulaBarEditing.set(true);
|
|
858
|
+
}
|
|
859
|
+
commitFormulaBar() {
|
|
860
|
+
const coords = this.activeCellCoords();
|
|
861
|
+
if (!coords) return;
|
|
862
|
+
const text = this.formulaBarEditText().trim();
|
|
863
|
+
if (text.startsWith("=")) {
|
|
864
|
+
this.formulaService.setFormula(coords.col, coords.row, text);
|
|
865
|
+
this.formulaVersion.update((v) => v + 1);
|
|
866
|
+
} else {
|
|
867
|
+
this.formulaService.setFormula(coords.col, coords.row, null);
|
|
868
|
+
this.onCellValueChanged()?.({
|
|
869
|
+
rowIndex: coords.row,
|
|
870
|
+
columnId: this.columns()[coords.col]?.columnId ?? "",
|
|
871
|
+
oldValue: void 0,
|
|
872
|
+
newValue: text
|
|
873
|
+
});
|
|
874
|
+
}
|
|
875
|
+
this.formulaBarEditing.set(false);
|
|
876
|
+
}
|
|
877
|
+
cancelFormulaBar() {
|
|
878
|
+
this.formulaBarEditing.set(false);
|
|
879
|
+
this.formulaBarEditText.set("");
|
|
880
|
+
}
|
|
789
881
|
// --- Configure from props ---
|
|
790
882
|
configure(props) {
|
|
791
883
|
this.columnsProp.set(props.columns);
|
|
@@ -847,6 +939,10 @@ var OGridService = class {
|
|
|
847
939
|
if (props.formulaFunctions !== void 0) this.formulaFunctions.set(props.formulaFunctions);
|
|
848
940
|
if (props.namedRanges !== void 0) this.namedRanges.set(props.namedRanges);
|
|
849
941
|
if (props.sheets !== void 0) this.sheets.set(props.sheets);
|
|
942
|
+
if (props.sheetDefs !== void 0) this.sheetDefs.set(props.sheetDefs);
|
|
943
|
+
if (props.activeSheet !== void 0) this.activeSheet.set(props.activeSheet);
|
|
944
|
+
if (props.onSheetChange) this.onSheetChange.set(props.onSheetChange);
|
|
945
|
+
if (props.onSheetAdd) this.onSheetAdd.set(props.onSheetAdd);
|
|
850
946
|
if (props.entityLabelPlural !== void 0) this.entityLabelPlural.set(props.entityLabelPlural);
|
|
851
947
|
if (props.className !== void 0) this.className.set(props.className);
|
|
852
948
|
if (props.layoutMode !== void 0) this.layoutMode.set(props.layoutMode);
|
|
@@ -1443,6 +1539,7 @@ var DataGridInteractionHelper = class {
|
|
|
1443
1539
|
}
|
|
1444
1540
|
break;
|
|
1445
1541
|
case "ArrowDown": {
|
|
1542
|
+
if (editingCell != null) break;
|
|
1446
1543
|
e.preventDefault();
|
|
1447
1544
|
const newRow = ctrl ? findCtrlTarget(rowIndex, maxRowIndex, 1, (r) => isEmptyAt(r, Math.max(0, dataColIndex))) : Math.min(rowIndex + 1, maxRowIndex);
|
|
1448
1545
|
if (shift) {
|
|
@@ -1459,6 +1556,7 @@ var DataGridInteractionHelper = class {
|
|
|
1459
1556
|
break;
|
|
1460
1557
|
}
|
|
1461
1558
|
case "ArrowUp": {
|
|
1559
|
+
if (editingCell != null) break;
|
|
1462
1560
|
e.preventDefault();
|
|
1463
1561
|
const newRowUp = ctrl ? findCtrlTarget(rowIndex, 0, -1, (r) => isEmptyAt(r, Math.max(0, dataColIndex))) : Math.max(rowIndex - 1, 0);
|
|
1464
1562
|
if (shift) {
|
|
@@ -1475,6 +1573,7 @@ var DataGridInteractionHelper = class {
|
|
|
1475
1573
|
break;
|
|
1476
1574
|
}
|
|
1477
1575
|
case "ArrowRight": {
|
|
1576
|
+
if (editingCell != null) break;
|
|
1478
1577
|
e.preventDefault();
|
|
1479
1578
|
let newCol;
|
|
1480
1579
|
if (ctrl && dataColIndex >= 0) {
|
|
@@ -1497,6 +1596,7 @@ var DataGridInteractionHelper = class {
|
|
|
1497
1596
|
break;
|
|
1498
1597
|
}
|
|
1499
1598
|
case "ArrowLeft": {
|
|
1599
|
+
if (editingCell != null) break;
|
|
1500
1600
|
e.preventDefault();
|
|
1501
1601
|
let newColLeft;
|
|
1502
1602
|
if (ctrl && dataColIndex >= 0) {
|
|
@@ -2277,7 +2377,10 @@ var DataGridStateService = class {
|
|
|
2277
2377
|
getRowId: p?.getRowId ?? ((item) => item["id"]),
|
|
2278
2378
|
editable: p?.editable,
|
|
2279
2379
|
onCellValueChanged: this.wrappedOnCellValueChanged(),
|
|
2280
|
-
isDragging: cellSel ? this.interactionHelper.isDraggingSig() : false
|
|
2380
|
+
isDragging: cellSel ? this.interactionHelper.isDraggingSig() : false,
|
|
2381
|
+
getFormulaValue: p?.getFormulaValue,
|
|
2382
|
+
hasFormula: p?.hasFormula,
|
|
2383
|
+
formulaVersion: p?.formulaVersion
|
|
2281
2384
|
},
|
|
2282
2385
|
statusBarConfig: this.statusBarConfig(),
|
|
2283
2386
|
showEmptyInGrid: this.showEmptyInGrid(),
|
|
@@ -2924,6 +3027,205 @@ SideBarComponent = __decorateClass([
|
|
|
2924
3027
|
`
|
|
2925
3028
|
})
|
|
2926
3029
|
], SideBarComponent);
|
|
3030
|
+
var FormulaBarComponent = class {
|
|
3031
|
+
constructor() {
|
|
3032
|
+
/** Active cell reference (e.g. "A1"). */
|
|
3033
|
+
this.cellRef = input(null);
|
|
3034
|
+
/** Text displayed/edited in the formula input. */
|
|
3035
|
+
this.formulaText = input("");
|
|
3036
|
+
/** Whether the input is in editing mode. */
|
|
3037
|
+
this.isEditing = input(false);
|
|
3038
|
+
/** Called when the user changes the input text. */
|
|
3039
|
+
this.inputChange = output();
|
|
3040
|
+
/** Commit the formula bar value. */
|
|
3041
|
+
this.commit = output();
|
|
3042
|
+
/** Cancel editing. */
|
|
3043
|
+
this.cancel = output();
|
|
3044
|
+
/** Start editing the formula bar. */
|
|
3045
|
+
this.startEditing = output();
|
|
3046
|
+
this.inputEl = viewChild("formulaInput");
|
|
3047
|
+
effect(() => {
|
|
3048
|
+
if (this.isEditing()) {
|
|
3049
|
+
const el = this.inputEl()?.nativeElement;
|
|
3050
|
+
if (el) el.focus();
|
|
3051
|
+
}
|
|
3052
|
+
});
|
|
3053
|
+
}
|
|
3054
|
+
onInput(event) {
|
|
3055
|
+
this.inputChange.emit(event.target.value);
|
|
3056
|
+
}
|
|
3057
|
+
onKeyDown(event) {
|
|
3058
|
+
handleFormulaBarKeyDown(
|
|
3059
|
+
event.key,
|
|
3060
|
+
() => event.preventDefault(),
|
|
3061
|
+
() => this.commit.emit(),
|
|
3062
|
+
() => this.cancel.emit()
|
|
3063
|
+
);
|
|
3064
|
+
}
|
|
3065
|
+
onClick() {
|
|
3066
|
+
if (!this.isEditing()) {
|
|
3067
|
+
this.startEditing.emit();
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3070
|
+
};
|
|
3071
|
+
FormulaBarComponent = __decorateClass([
|
|
3072
|
+
Component({
|
|
3073
|
+
selector: "ogrid-formula-bar",
|
|
3074
|
+
standalone: true,
|
|
3075
|
+
encapsulation: ViewEncapsulation.None,
|
|
3076
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3077
|
+
styles: [`
|
|
3078
|
+
.ogrid-formula-bar {
|
|
3079
|
+
display: flex;
|
|
3080
|
+
align-items: center;
|
|
3081
|
+
border-bottom: 1px solid var(--ogrid-border, #e0e0e0);
|
|
3082
|
+
background: var(--ogrid-bg, #fff);
|
|
3083
|
+
min-height: 28px;
|
|
3084
|
+
font-size: 13px;
|
|
3085
|
+
}
|
|
3086
|
+
.ogrid-formula-bar__name-box {
|
|
3087
|
+
font-family: monospace;
|
|
3088
|
+
font-size: 12px;
|
|
3089
|
+
font-weight: 500;
|
|
3090
|
+
padding: 2px 8px;
|
|
3091
|
+
border-right: 1px solid var(--ogrid-border, #e0e0e0);
|
|
3092
|
+
background: var(--ogrid-bg, #fff);
|
|
3093
|
+
color: var(--ogrid-fg, #242424);
|
|
3094
|
+
min-width: 52px;
|
|
3095
|
+
text-align: center;
|
|
3096
|
+
line-height: 24px;
|
|
3097
|
+
user-select: none;
|
|
3098
|
+
white-space: nowrap;
|
|
3099
|
+
}
|
|
3100
|
+
.ogrid-formula-bar__fx {
|
|
3101
|
+
padding: 2px 8px;
|
|
3102
|
+
font-style: italic;
|
|
3103
|
+
font-weight: 600;
|
|
3104
|
+
color: var(--ogrid-muted-fg, #888);
|
|
3105
|
+
user-select: none;
|
|
3106
|
+
border-right: 1px solid var(--ogrid-border, #e0e0e0);
|
|
3107
|
+
line-height: 24px;
|
|
3108
|
+
font-size: 12px;
|
|
3109
|
+
}
|
|
3110
|
+
.ogrid-formula-bar__input {
|
|
3111
|
+
flex: 1;
|
|
3112
|
+
border: none;
|
|
3113
|
+
outline: none;
|
|
3114
|
+
padding: 2px 8px;
|
|
3115
|
+
font-family: monospace;
|
|
3116
|
+
font-size: 12px;
|
|
3117
|
+
line-height: 24px;
|
|
3118
|
+
background: transparent;
|
|
3119
|
+
color: var(--ogrid-fg, #242424);
|
|
3120
|
+
min-width: 0;
|
|
3121
|
+
}
|
|
3122
|
+
`],
|
|
3123
|
+
template: `
|
|
3124
|
+
<div class="ogrid-formula-bar" role="toolbar" aria-label="Formula bar">
|
|
3125
|
+
<div class="ogrid-formula-bar__name-box" aria-label="Active cell reference">
|
|
3126
|
+
{{ cellRef() ?? '\u2014' }}
|
|
3127
|
+
</div>
|
|
3128
|
+
<div class="ogrid-formula-bar__fx" aria-hidden="true">fx</div>
|
|
3129
|
+
<input
|
|
3130
|
+
#formulaInput
|
|
3131
|
+
type="text"
|
|
3132
|
+
class="ogrid-formula-bar__input"
|
|
3133
|
+
[value]="formulaText()"
|
|
3134
|
+
[readOnly]="!isEditing()"
|
|
3135
|
+
(input)="onInput($event)"
|
|
3136
|
+
(keydown)="onKeyDown($event)"
|
|
3137
|
+
(click)="onClick()"
|
|
3138
|
+
(dblclick)="onClick()"
|
|
3139
|
+
aria-label="Formula input"
|
|
3140
|
+
[attr.spellcheck]="false"
|
|
3141
|
+
autocomplete="off"
|
|
3142
|
+
/>
|
|
3143
|
+
</div>
|
|
3144
|
+
`
|
|
3145
|
+
})
|
|
3146
|
+
], FormulaBarComponent);
|
|
3147
|
+
var SheetTabsComponent = class {
|
|
3148
|
+
constructor() {
|
|
3149
|
+
this.sheets = input.required();
|
|
3150
|
+
this.activeSheet = input.required();
|
|
3151
|
+
this.showAddButton = input(false);
|
|
3152
|
+
this.sheetChange = output();
|
|
3153
|
+
this.sheetAdd = output();
|
|
3154
|
+
}
|
|
3155
|
+
};
|
|
3156
|
+
SheetTabsComponent = __decorateClass([
|
|
3157
|
+
Component({
|
|
3158
|
+
selector: "ogrid-sheet-tabs",
|
|
3159
|
+
standalone: true,
|
|
3160
|
+
encapsulation: ViewEncapsulation.None,
|
|
3161
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3162
|
+
styles: [`
|
|
3163
|
+
.ogrid-sheet-tabs {
|
|
3164
|
+
display: flex;
|
|
3165
|
+
align-items: center;
|
|
3166
|
+
border-top: 1px solid var(--ogrid-border, #e0e0e0);
|
|
3167
|
+
background: var(--ogrid-header-bg, #f5f5f5);
|
|
3168
|
+
min-height: 30px;
|
|
3169
|
+
overflow-x: auto;
|
|
3170
|
+
overflow-y: hidden;
|
|
3171
|
+
gap: 0;
|
|
3172
|
+
font-size: 12px;
|
|
3173
|
+
}
|
|
3174
|
+
.ogrid-sheet-tabs__add-btn {
|
|
3175
|
+
background: none;
|
|
3176
|
+
border: none;
|
|
3177
|
+
cursor: pointer;
|
|
3178
|
+
padding: 4px 10px;
|
|
3179
|
+
font-size: 16px;
|
|
3180
|
+
line-height: 22px;
|
|
3181
|
+
color: var(--ogrid-fg-secondary, #666);
|
|
3182
|
+
flex-shrink: 0;
|
|
3183
|
+
}
|
|
3184
|
+
.ogrid-sheet-tabs__tab {
|
|
3185
|
+
background: none;
|
|
3186
|
+
border: none;
|
|
3187
|
+
border-bottom: 2px solid transparent;
|
|
3188
|
+
cursor: pointer;
|
|
3189
|
+
padding: 4px 16px;
|
|
3190
|
+
font-size: 12px;
|
|
3191
|
+
line-height: 22px;
|
|
3192
|
+
color: var(--ogrid-fg, #242424);
|
|
3193
|
+
white-space: nowrap;
|
|
3194
|
+
position: relative;
|
|
3195
|
+
}
|
|
3196
|
+
.ogrid-sheet-tabs__tab--active {
|
|
3197
|
+
font-weight: 600;
|
|
3198
|
+
border-bottom-color: var(--ogrid-primary, #217346);
|
|
3199
|
+
background: var(--ogrid-bg, #fff);
|
|
3200
|
+
}
|
|
3201
|
+
`],
|
|
3202
|
+
template: `
|
|
3203
|
+
<div class="ogrid-sheet-tabs" role="tablist" aria-label="Sheet tabs">
|
|
3204
|
+
@if (showAddButton()) {
|
|
3205
|
+
<button
|
|
3206
|
+
type="button"
|
|
3207
|
+
class="ogrid-sheet-tabs__add-btn"
|
|
3208
|
+
(click)="sheetAdd.emit()"
|
|
3209
|
+
title="Add sheet"
|
|
3210
|
+
aria-label="Add sheet"
|
|
3211
|
+
>+</button>
|
|
3212
|
+
}
|
|
3213
|
+
@for (sheet of sheets(); track sheet.id) {
|
|
3214
|
+
@let isActive = sheet.id === activeSheet();
|
|
3215
|
+
<button
|
|
3216
|
+
type="button"
|
|
3217
|
+
role="tab"
|
|
3218
|
+
class="ogrid-sheet-tabs__tab"
|
|
3219
|
+
[class.ogrid-sheet-tabs__tab--active]="isActive"
|
|
3220
|
+
[attr.aria-selected]="isActive"
|
|
3221
|
+
[style.border-bottom-color]="isActive && sheet.color ? sheet.color : null"
|
|
3222
|
+
(click)="sheetChange.emit(sheet.id)"
|
|
3223
|
+
>{{ sheet.name }}</button>
|
|
3224
|
+
}
|
|
3225
|
+
</div>
|
|
3226
|
+
`
|
|
3227
|
+
})
|
|
3228
|
+
], SheetTabsComponent);
|
|
2927
3229
|
|
|
2928
3230
|
// src/styles/ogrid-theme-vars.ts
|
|
2929
3231
|
var OGRID_THEME_VARS_CSS = `
|
|
@@ -3042,6 +3344,7 @@ var OGridLayoutComponent = class {
|
|
|
3042
3344
|
this.fullScreen = false;
|
|
3043
3345
|
this.showNameBox = false;
|
|
3044
3346
|
this.activeCellRef = null;
|
|
3347
|
+
this.formulaBar = null;
|
|
3045
3348
|
this.isFullScreen = false;
|
|
3046
3349
|
this.borderRadius = GRID_BORDER_RADIUS;
|
|
3047
3350
|
this.escListener = null;
|
|
@@ -3095,13 +3398,28 @@ __decorateClass([
|
|
|
3095
3398
|
__decorateClass([
|
|
3096
3399
|
Input()
|
|
3097
3400
|
], OGridLayoutComponent.prototype, "activeCellRef", 2);
|
|
3401
|
+
__decorateClass([
|
|
3402
|
+
Input()
|
|
3403
|
+
], OGridLayoutComponent.prototype, "formulaBar", 2);
|
|
3404
|
+
__decorateClass([
|
|
3405
|
+
Input()
|
|
3406
|
+
], OGridLayoutComponent.prototype, "sheetDefs", 2);
|
|
3407
|
+
__decorateClass([
|
|
3408
|
+
Input()
|
|
3409
|
+
], OGridLayoutComponent.prototype, "activeSheet", 2);
|
|
3410
|
+
__decorateClass([
|
|
3411
|
+
Input()
|
|
3412
|
+
], OGridLayoutComponent.prototype, "onSheetChange", 2);
|
|
3413
|
+
__decorateClass([
|
|
3414
|
+
Input()
|
|
3415
|
+
], OGridLayoutComponent.prototype, "onSheetAdd", 2);
|
|
3098
3416
|
OGridLayoutComponent = __decorateClass([
|
|
3099
3417
|
Component({
|
|
3100
3418
|
selector: "ogrid-layout",
|
|
3101
3419
|
standalone: true,
|
|
3102
3420
|
encapsulation: ViewEncapsulation.None,
|
|
3103
3421
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3104
|
-
imports: [SideBarComponent],
|
|
3422
|
+
imports: [SideBarComponent, FormulaBarComponent, SheetTabsComponent],
|
|
3105
3423
|
styles: [OGRID_THEME_VARS_CSS, `
|
|
3106
3424
|
:host { display: block; height: 100%; }
|
|
3107
3425
|
.ogrid-layout-root { display: flex; flex-direction: column; height: 100%; }
|
|
@@ -3203,6 +3521,19 @@ OGridLayoutComponent = __decorateClass([
|
|
|
3203
3521
|
</div>
|
|
3204
3522
|
}
|
|
3205
3523
|
|
|
3524
|
+
<!-- Formula bar (between toolbar and grid) -->
|
|
3525
|
+
@if (formulaBar) {
|
|
3526
|
+
<ogrid-formula-bar
|
|
3527
|
+
[cellRef]="formulaBar.cellRef"
|
|
3528
|
+
[formulaText]="formulaBar.formulaText"
|
|
3529
|
+
[isEditing]="formulaBar.isEditing"
|
|
3530
|
+
(inputChange)="formulaBar.onInputChange($event)"
|
|
3531
|
+
(commit)="formulaBar.onCommit()"
|
|
3532
|
+
(cancel)="formulaBar.onCancel()"
|
|
3533
|
+
(startEditing)="formulaBar.startEditing()"
|
|
3534
|
+
/>
|
|
3535
|
+
}
|
|
3536
|
+
|
|
3206
3537
|
<!-- Grid area -->
|
|
3207
3538
|
<div class="ogrid-layout-grid-area">
|
|
3208
3539
|
@if (sideBar && sideBar.position === 'left') {
|
|
@@ -3216,6 +3547,17 @@ OGridLayoutComponent = __decorateClass([
|
|
|
3216
3547
|
}
|
|
3217
3548
|
</div>
|
|
3218
3549
|
|
|
3550
|
+
<!-- Sheet tabs (between grid and footer) -->
|
|
3551
|
+
@if (sheetDefs && sheetDefs.length > 0 && activeSheet) {
|
|
3552
|
+
<ogrid-sheet-tabs
|
|
3553
|
+
[sheets]="sheetDefs"
|
|
3554
|
+
[activeSheet]="activeSheet"
|
|
3555
|
+
[showAddButton]="!!onSheetAdd"
|
|
3556
|
+
(sheetChange)="onSheetChange?.($event)"
|
|
3557
|
+
(sheetAdd)="onSheetAdd?.()"
|
|
3558
|
+
/>
|
|
3559
|
+
}
|
|
3560
|
+
|
|
3219
3561
|
<!-- Footer strip (pagination) -->
|
|
3220
3562
|
@if (hasPagination) {
|
|
3221
3563
|
<div class="ogrid-layout-footer">
|
|
@@ -3579,6 +3921,94 @@ MarchingAntsOverlayComponent = __decorateClass([
|
|
|
3579
3921
|
`
|
|
3580
3922
|
})
|
|
3581
3923
|
], MarchingAntsOverlayComponent);
|
|
3924
|
+
function measureRef(container, ref, colOffset) {
|
|
3925
|
+
const startCol = ref.col + colOffset;
|
|
3926
|
+
const endCol = (ref.endCol ?? ref.col) + colOffset;
|
|
3927
|
+
const endRow = ref.endRow ?? ref.row;
|
|
3928
|
+
const tl = container.querySelector(
|
|
3929
|
+
`[data-row-index="${ref.row}"][data-col-index="${startCol}"]`
|
|
3930
|
+
);
|
|
3931
|
+
const br = container.querySelector(
|
|
3932
|
+
`[data-row-index="${endRow}"][data-col-index="${endCol}"]`
|
|
3933
|
+
);
|
|
3934
|
+
if (!tl || !br) return null;
|
|
3935
|
+
const cRect = container.getBoundingClientRect();
|
|
3936
|
+
const tlRect = tl.getBoundingClientRect();
|
|
3937
|
+
const brRect = br.getBoundingClientRect();
|
|
3938
|
+
return {
|
|
3939
|
+
top: Math.round(tlRect.top - cRect.top),
|
|
3940
|
+
left: Math.round(tlRect.left - cRect.left),
|
|
3941
|
+
width: Math.round(brRect.right - tlRect.left),
|
|
3942
|
+
height: Math.round(brRect.bottom - tlRect.top),
|
|
3943
|
+
color: FORMULA_REF_COLORS[ref.colorIndex % FORMULA_REF_COLORS.length]
|
|
3944
|
+
};
|
|
3945
|
+
}
|
|
3946
|
+
var FormulaRefOverlayComponent = class {
|
|
3947
|
+
constructor() {
|
|
3948
|
+
/** The positioned container that wraps the table. */
|
|
3949
|
+
this.containerEl = input(null);
|
|
3950
|
+
/** References to highlight. */
|
|
3951
|
+
this.references = input([]);
|
|
3952
|
+
/** Column offset (1 when checkbox/row-number columns are present). */
|
|
3953
|
+
this.colOffset = input(0);
|
|
3954
|
+
this.rects = signal([]);
|
|
3955
|
+
this.rafId = 0;
|
|
3956
|
+
effect(() => {
|
|
3957
|
+
const refs = this.references();
|
|
3958
|
+
const container = this.containerEl();
|
|
3959
|
+
const colOff = this.colOffset();
|
|
3960
|
+
cancelAnimationFrame(this.rafId);
|
|
3961
|
+
if (!container || refs.length === 0) {
|
|
3962
|
+
this.rects.set([]);
|
|
3963
|
+
return;
|
|
3964
|
+
}
|
|
3965
|
+
this.rafId = requestAnimationFrame(() => {
|
|
3966
|
+
const measured = [];
|
|
3967
|
+
for (const ref of refs) {
|
|
3968
|
+
const r = measureRef(container, ref, colOff);
|
|
3969
|
+
if (r) measured.push(r);
|
|
3970
|
+
}
|
|
3971
|
+
this.rects.set(measured);
|
|
3972
|
+
});
|
|
3973
|
+
});
|
|
3974
|
+
}
|
|
3975
|
+
max0(v) {
|
|
3976
|
+
return Math.max(0, v);
|
|
3977
|
+
}
|
|
3978
|
+
};
|
|
3979
|
+
FormulaRefOverlayComponent = __decorateClass([
|
|
3980
|
+
Component({
|
|
3981
|
+
selector: "ogrid-formula-ref-overlay",
|
|
3982
|
+
standalone: true,
|
|
3983
|
+
encapsulation: ViewEncapsulation.None,
|
|
3984
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
3985
|
+
template: `
|
|
3986
|
+
@for (r of rects(); track $index) {
|
|
3987
|
+
<svg
|
|
3988
|
+
[style.position]="'absolute'"
|
|
3989
|
+
[style.top.px]="r.top"
|
|
3990
|
+
[style.left.px]="r.left"
|
|
3991
|
+
[style.width.px]="r.width"
|
|
3992
|
+
[style.height.px]="r.height"
|
|
3993
|
+
[style.pointerEvents]="'none'"
|
|
3994
|
+
[style.zIndex]="3"
|
|
3995
|
+
[style.overflow]="'visible'"
|
|
3996
|
+
aria-hidden="true"
|
|
3997
|
+
>
|
|
3998
|
+
<rect
|
|
3999
|
+
x="1" y="1"
|
|
4000
|
+
[attr.width]="max0(r.width - 2)"
|
|
4001
|
+
[attr.height]="max0(r.height - 2)"
|
|
4002
|
+
fill="none"
|
|
4003
|
+
[attr.stroke]="r.color"
|
|
4004
|
+
stroke-width="2"
|
|
4005
|
+
style="shape-rendering: crispEdges"
|
|
4006
|
+
/>
|
|
4007
|
+
</svg>
|
|
4008
|
+
}
|
|
4009
|
+
`
|
|
4010
|
+
})
|
|
4011
|
+
], FormulaRefOverlayComponent);
|
|
3582
4012
|
var EmptyStateComponent = class {
|
|
3583
4013
|
constructor() {
|
|
3584
4014
|
this.message = void 0;
|
|
@@ -3881,7 +4311,7 @@ var BaseDataGridTableComponent = class {
|
|
|
3881
4311
|
const rightOffsets = {};
|
|
3882
4312
|
let leftAcc = 0;
|
|
3883
4313
|
if (this.hasCheckboxCol()) leftAcc += CHECKBOX_COLUMN_WIDTH;
|
|
3884
|
-
if (this.hasRowNumbersCol()) leftAcc +=
|
|
4314
|
+
if (this.hasRowNumbersCol()) leftAcc += this.getRowNumberWidth();
|
|
3885
4315
|
let rightAcc = 0;
|
|
3886
4316
|
const len = layouts.length;
|
|
3887
4317
|
for (let i = 0; i < len; i++) {
|
|
@@ -3954,6 +4384,12 @@ var BaseDataGridTableComponent = class {
|
|
|
3954
4384
|
getGlobalColIndex(col) {
|
|
3955
4385
|
return this.globalColIndexMap().get(col.columnId) ?? 0;
|
|
3956
4386
|
}
|
|
4387
|
+
/** Returns the effective row number column width (from overrides or default). */
|
|
4388
|
+
getRowNumberWidth() {
|
|
4389
|
+
const overrides = this.columnSizingOverrides();
|
|
4390
|
+
const override = overrides[ROW_NUMBER_COLUMN_ID];
|
|
4391
|
+
return override ? override.widthPx : ROW_NUMBER_COLUMN_WIDTH;
|
|
4392
|
+
}
|
|
3957
4393
|
/**
|
|
3958
4394
|
* Initialize base wiring effects. Must be called from subclass constructor.
|
|
3959
4395
|
*
|
|
@@ -4207,8 +4643,9 @@ var BaseDataGridTableComponent = class {
|
|
|
4207
4643
|
this.state().interaction.setSelectionRange?.(null);
|
|
4208
4644
|
this.getWrapperRef()?.nativeElement.focus({ preventScroll: true });
|
|
4209
4645
|
const startX = event.clientX;
|
|
4210
|
-
const
|
|
4211
|
-
const
|
|
4646
|
+
const columnId = col.columnId;
|
|
4647
|
+
const startWidth = columnId === ROW_NUMBER_COLUMN_ID ? this.getRowNumberWidth() : this.getColumnWidth(col);
|
|
4648
|
+
const minWidth = columnId === ROW_NUMBER_COLUMN_ID ? ROW_NUMBER_COLUMN_MIN_WIDTH : col.minWidth ?? DEFAULT_MIN_COLUMN_WIDTH;
|
|
4212
4649
|
const onMove = (e) => {
|
|
4213
4650
|
const delta = e.clientX - startX;
|
|
4214
4651
|
const newWidth = Math.max(minWidth, startWidth + delta);
|
|
@@ -4803,7 +5240,11 @@ var BaseInlineCellEditorComponent = class {
|
|
|
4803
5240
|
}
|
|
4804
5241
|
syncFromInputs() {
|
|
4805
5242
|
const v = this.value;
|
|
4806
|
-
|
|
5243
|
+
let strVal = v != null ? String(v) : "";
|
|
5244
|
+
if (this.editorType === "date" && strVal.match(/^\d{4}-\d{2}-\d{2}/)) {
|
|
5245
|
+
strVal = strVal.substring(0, 10);
|
|
5246
|
+
}
|
|
5247
|
+
this.localValue.set(strVal);
|
|
4807
5248
|
const col = this.column;
|
|
4808
5249
|
if (col?.cellEditorParams?.values) {
|
|
4809
5250
|
const vals = col.cellEditorParams.values;
|
|
@@ -5014,6 +5455,88 @@ __decorateClass([
|
|
|
5014
5455
|
__decorateClass([
|
|
5015
5456
|
ViewChild("richSelectDropdown")
|
|
5016
5457
|
], BaseInlineCellEditorComponent.prototype, "richSelectDropdown", 2);
|
|
5458
|
+
var BaseColumnHeaderMenuComponent = class {
|
|
5459
|
+
constructor() {
|
|
5460
|
+
// Signal-backed inputs so computed() tracks changes reactively
|
|
5461
|
+
this._canPinLeft = signal(true);
|
|
5462
|
+
this._canPinRight = signal(true);
|
|
5463
|
+
this._canUnpin = signal(false);
|
|
5464
|
+
this._currentSort = signal(null);
|
|
5465
|
+
this._isSortable = signal(true);
|
|
5466
|
+
this._isResizable = signal(true);
|
|
5467
|
+
this.handlers = {};
|
|
5468
|
+
this.menuItems = computed(
|
|
5469
|
+
() => getColumnHeaderMenuItems({
|
|
5470
|
+
canPinLeft: this._canPinLeft(),
|
|
5471
|
+
canPinRight: this._canPinRight(),
|
|
5472
|
+
canUnpin: this._canUnpin(),
|
|
5473
|
+
currentSort: this._currentSort(),
|
|
5474
|
+
isSortable: this._isSortable(),
|
|
5475
|
+
isResizable: this._isResizable()
|
|
5476
|
+
})
|
|
5477
|
+
);
|
|
5478
|
+
}
|
|
5479
|
+
set canPinLeft(v) {
|
|
5480
|
+
this._canPinLeft.set(v);
|
|
5481
|
+
}
|
|
5482
|
+
set canPinRight(v) {
|
|
5483
|
+
this._canPinRight.set(v);
|
|
5484
|
+
}
|
|
5485
|
+
set canUnpin(v) {
|
|
5486
|
+
this._canUnpin.set(v);
|
|
5487
|
+
}
|
|
5488
|
+
set currentSort(v) {
|
|
5489
|
+
this._currentSort.set(v);
|
|
5490
|
+
}
|
|
5491
|
+
set isSortable(v) {
|
|
5492
|
+
this._isSortable.set(v);
|
|
5493
|
+
}
|
|
5494
|
+
set isResizable(v) {
|
|
5495
|
+
this._isResizable.set(v);
|
|
5496
|
+
}
|
|
5497
|
+
handleMenuItemClick(itemId) {
|
|
5498
|
+
const h = this.handlers;
|
|
5499
|
+
const actionMap = {
|
|
5500
|
+
pinLeft: h.onPinLeft,
|
|
5501
|
+
pinRight: h.onPinRight,
|
|
5502
|
+
unpin: h.onUnpin,
|
|
5503
|
+
sortAsc: h.onSortAsc,
|
|
5504
|
+
sortDesc: h.onSortDesc,
|
|
5505
|
+
clearSort: h.onClearSort,
|
|
5506
|
+
autosizeThis: h.onAutosizeThis,
|
|
5507
|
+
autosizeAll: h.onAutosizeAll
|
|
5508
|
+
};
|
|
5509
|
+
const action = actionMap[itemId];
|
|
5510
|
+
if (action) {
|
|
5511
|
+
action();
|
|
5512
|
+
h.onClose?.();
|
|
5513
|
+
}
|
|
5514
|
+
}
|
|
5515
|
+
};
|
|
5516
|
+
__decorateClass([
|
|
5517
|
+
Input({ required: true })
|
|
5518
|
+
], BaseColumnHeaderMenuComponent.prototype, "columnId", 2);
|
|
5519
|
+
__decorateClass([
|
|
5520
|
+
Input()
|
|
5521
|
+
], BaseColumnHeaderMenuComponent.prototype, "canPinLeft", 1);
|
|
5522
|
+
__decorateClass([
|
|
5523
|
+
Input()
|
|
5524
|
+
], BaseColumnHeaderMenuComponent.prototype, "canPinRight", 1);
|
|
5525
|
+
__decorateClass([
|
|
5526
|
+
Input()
|
|
5527
|
+
], BaseColumnHeaderMenuComponent.prototype, "canUnpin", 1);
|
|
5528
|
+
__decorateClass([
|
|
5529
|
+
Input()
|
|
5530
|
+
], BaseColumnHeaderMenuComponent.prototype, "currentSort", 1);
|
|
5531
|
+
__decorateClass([
|
|
5532
|
+
Input()
|
|
5533
|
+
], BaseColumnHeaderMenuComponent.prototype, "isSortable", 1);
|
|
5534
|
+
__decorateClass([
|
|
5535
|
+
Input()
|
|
5536
|
+
], BaseColumnHeaderMenuComponent.prototype, "isResizable", 1);
|
|
5537
|
+
__decorateClass([
|
|
5538
|
+
Input()
|
|
5539
|
+
], BaseColumnHeaderMenuComponent.prototype, "handlers", 2);
|
|
5017
5540
|
|
|
5018
5541
|
// src/components/inline-cell-editor-template.ts
|
|
5019
5542
|
var INLINE_CELL_EDITOR_TEMPLATE = `
|
|
@@ -5206,4 +5729,4 @@ __decorateClass([
|
|
|
5206
5729
|
ViewChild("editorContainer")
|
|
5207
5730
|
], BasePopoverCellEditorComponent.prototype, "editorContainerRef", 2);
|
|
5208
5731
|
|
|
5209
|
-
export { BaseColumnChooserComponent, BaseColumnHeaderFilterComponent, BaseDataGridTableComponent, BaseInlineCellEditorComponent, BaseOGridComponent, BasePaginationControlsComponent, BasePopoverCellEditorComponent, ColumnReorderService, DataGridEditingHelper, DataGridInteractionHelper, DataGridLayoutHelper, DataGridStateService, EmptyStateComponent, FormulaEngineService, GridContextMenuComponent, INLINE_CELL_EDITOR_STYLES, INLINE_CELL_EDITOR_TEMPLATE, MarchingAntsOverlayComponent, OGRID_THEME_VARS_CSS, OGridLayoutComponent, OGridService, POPOVER_CELL_EDITOR_OVERLAY_STYLES, POPOVER_CELL_EDITOR_TEMPLATE, SideBarComponent, StatusBarComponent, VirtualScrollService, createDebouncedCallback, createDebouncedSignal, createLatestCallback };
|
|
5732
|
+
export { BaseColumnChooserComponent, BaseColumnHeaderFilterComponent, BaseColumnHeaderMenuComponent, BaseDataGridTableComponent, BaseInlineCellEditorComponent, BaseOGridComponent, BasePaginationControlsComponent, BasePopoverCellEditorComponent, ColumnReorderService, DataGridEditingHelper, DataGridInteractionHelper, DataGridLayoutHelper, DataGridStateService, EmptyStateComponent, FormulaBarComponent, FormulaEngineService, FormulaRefOverlayComponent, GridContextMenuComponent, INLINE_CELL_EDITOR_STYLES, INLINE_CELL_EDITOR_TEMPLATE, MarchingAntsOverlayComponent, OGRID_THEME_VARS_CSS, OGridLayoutComponent, OGridService, POPOVER_CELL_EDITOR_OVERLAY_STYLES, POPOVER_CELL_EDITOR_TEMPLATE, SheetTabsComponent, SideBarComponent, StatusBarComponent, VirtualScrollService, createDebouncedCallback, createDebouncedSignal, createLatestCallback };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { type IColumnHeaderMenuItem, type ColumnHeaderMenuHandlers } from '@alaarab/ogrid-core';
|
|
2
|
+
/**
|
|
3
|
+
* Abstract base class containing all shared TypeScript logic for ColumnHeaderMenu components.
|
|
4
|
+
* Framework-specific UI packages extend this with their templates and style overrides.
|
|
5
|
+
*
|
|
6
|
+
* Uses signal-backed @Input setters so that computed() tracks input changes reactively
|
|
7
|
+
* (plain @Input properties are not reactive in Angular signals).
|
|
8
|
+
*
|
|
9
|
+
* Subclasses must:
|
|
10
|
+
* 1. Provide a @Component decorator with template and styles
|
|
11
|
+
* 2. Implement their own menu open/close mechanism (mat-menu, p-menu, or native dropdown)
|
|
12
|
+
*/
|
|
13
|
+
export declare abstract class BaseColumnHeaderMenuComponent {
|
|
14
|
+
columnId: string;
|
|
15
|
+
private readonly _canPinLeft;
|
|
16
|
+
private readonly _canPinRight;
|
|
17
|
+
private readonly _canUnpin;
|
|
18
|
+
private readonly _currentSort;
|
|
19
|
+
private readonly _isSortable;
|
|
20
|
+
private readonly _isResizable;
|
|
21
|
+
set canPinLeft(v: boolean);
|
|
22
|
+
set canPinRight(v: boolean);
|
|
23
|
+
set canUnpin(v: boolean);
|
|
24
|
+
set currentSort(v: 'asc' | 'desc' | null);
|
|
25
|
+
set isSortable(v: boolean);
|
|
26
|
+
set isResizable(v: boolean);
|
|
27
|
+
handlers: Partial<ColumnHeaderMenuHandlers>;
|
|
28
|
+
readonly menuItems: import("@angular/core").Signal<IColumnHeaderMenuItem[]>;
|
|
29
|
+
handleMenuItemClick(itemId: string): void;
|
|
30
|
+
}
|
|
@@ -126,6 +126,9 @@ export declare abstract class BaseDataGridTableComponent<T = unknown> {
|
|
|
126
126
|
editable?: boolean;
|
|
127
127
|
onCellValueChanged?: ((event: import("@alaarab/ogrid-core").ICellValueChangedEvent<T>) => void) | undefined;
|
|
128
128
|
isDragging: boolean;
|
|
129
|
+
getFormulaValue?: (col: number, row: number) => unknown;
|
|
130
|
+
hasFormula?: (col: number, row: number) => boolean;
|
|
131
|
+
formulaVersion?: number;
|
|
129
132
|
}>;
|
|
130
133
|
readonly pinnedColumnsMap: import("@angular/core").Signal<Record<string, "left" | "right">>;
|
|
131
134
|
readonly vsEnabled: import("@angular/core").Signal<boolean>;
|
|
@@ -174,6 +177,8 @@ export declare abstract class BaseDataGridTableComponent<T = unknown> {
|
|
|
174
177
|
minWidth: number;
|
|
175
178
|
width: number;
|
|
176
179
|
}[]>;
|
|
180
|
+
/** Returns the effective row number column width (from overrides or default). */
|
|
181
|
+
getRowNumberWidth(): number;
|
|
177
182
|
readonly pinningOffsets: import("@angular/core").Signal<{
|
|
178
183
|
leftOffsets: Record<string, number>;
|
|
179
184
|
rightOffsets: Record<string, number>;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FormulaBarComponent -- Standalone Angular formula bar component.
|
|
3
|
+
*
|
|
4
|
+
* Layout: [Name Box] [fx] [Formula Input]
|
|
5
|
+
*
|
|
6
|
+
* Uses --ogrid-* CSS variables for theming.
|
|
7
|
+
* Port of React's FormulaBar component.
|
|
8
|
+
*/
|
|
9
|
+
export declare class FormulaBarComponent {
|
|
10
|
+
/** Active cell reference (e.g. "A1"). */
|
|
11
|
+
readonly cellRef: import("@angular/core").InputSignal<string | null>;
|
|
12
|
+
/** Text displayed/edited in the formula input. */
|
|
13
|
+
readonly formulaText: import("@angular/core").InputSignal<string>;
|
|
14
|
+
/** Whether the input is in editing mode. */
|
|
15
|
+
readonly isEditing: import("@angular/core").InputSignal<boolean>;
|
|
16
|
+
/** Called when the user changes the input text. */
|
|
17
|
+
readonly inputChange: import("@angular/core").OutputEmitterRef<string>;
|
|
18
|
+
/** Commit the formula bar value. */
|
|
19
|
+
readonly commit: import("@angular/core").OutputEmitterRef<void>;
|
|
20
|
+
/** Cancel editing. */
|
|
21
|
+
readonly cancel: import("@angular/core").OutputEmitterRef<void>;
|
|
22
|
+
/** Start editing the formula bar. */
|
|
23
|
+
readonly startEditing: import("@angular/core").OutputEmitterRef<void>;
|
|
24
|
+
private readonly inputEl;
|
|
25
|
+
constructor();
|
|
26
|
+
onInput(event: Event): void;
|
|
27
|
+
onKeyDown(event: KeyboardEvent): void;
|
|
28
|
+
onClick(): void;
|
|
29
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FormulaRefOverlayComponent -- Renders colored border overlays on cells
|
|
3
|
+
* referenced by the active formula, like Excel's reference highlighting.
|
|
4
|
+
*
|
|
5
|
+
* Port of React's FormulaRefOverlay component.
|
|
6
|
+
*/
|
|
7
|
+
import { type FormulaReference } from '@alaarab/ogrid-core';
|
|
8
|
+
interface RefRect {
|
|
9
|
+
top: number;
|
|
10
|
+
left: number;
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
color: string;
|
|
14
|
+
}
|
|
15
|
+
export declare class FormulaRefOverlayComponent {
|
|
16
|
+
/** The positioned container that wraps the table. */
|
|
17
|
+
readonly containerEl: import("@angular/core").InputSignal<HTMLElement | null>;
|
|
18
|
+
/** References to highlight. */
|
|
19
|
+
readonly references: import("@angular/core").InputSignal<FormulaReference[]>;
|
|
20
|
+
/** Column offset (1 when checkbox/row-number columns are present). */
|
|
21
|
+
readonly colOffset: import("@angular/core").InputSignal<number>;
|
|
22
|
+
readonly rects: import("@angular/core").WritableSignal<RefRect[]>;
|
|
23
|
+
private rafId;
|
|
24
|
+
constructor();
|
|
25
|
+
max0(v: number): number;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { SideBarProps } from './sidebar.component';
|
|
2
|
+
import type { OGridFormulaBarState } from '../services/ogrid.service';
|
|
3
|
+
import type { ISheetDef } from '@alaarab/ogrid-core';
|
|
2
4
|
export declare class OGridLayoutComponent {
|
|
3
5
|
className?: string;
|
|
4
6
|
hasToolbar: boolean;
|
|
@@ -8,6 +10,11 @@ export declare class OGridLayoutComponent {
|
|
|
8
10
|
fullScreen: boolean;
|
|
9
11
|
showNameBox: boolean;
|
|
10
12
|
activeCellRef: string | null;
|
|
13
|
+
formulaBar: OGridFormulaBarState | null;
|
|
14
|
+
sheetDefs: ISheetDef[] | undefined;
|
|
15
|
+
activeSheet: string | undefined;
|
|
16
|
+
onSheetChange: ((sheetId: string) => void) | undefined;
|
|
17
|
+
onSheetAdd: (() => void) | undefined;
|
|
11
18
|
isFullScreen: boolean;
|
|
12
19
|
readonly borderRadius = 6;
|
|
13
20
|
private escListener;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SheetTabsComponent -- Excel-style sheet tab bar at the bottom of the grid.
|
|
3
|
+
*
|
|
4
|
+
* Layout: [+] [Sheet1] [Sheet2] [Sheet3]
|
|
5
|
+
*
|
|
6
|
+
* Uses --ogrid-* CSS variables for theming.
|
|
7
|
+
* Port of React's SheetTabs component.
|
|
8
|
+
*/
|
|
9
|
+
import type { ISheetDef } from '@alaarab/ogrid-core';
|
|
10
|
+
export declare class SheetTabsComponent {
|
|
11
|
+
readonly sheets: import("@angular/core").InputSignal<ISheetDef[]>;
|
|
12
|
+
readonly activeSheet: import("@angular/core").InputSignal<string>;
|
|
13
|
+
readonly showAddButton: import("@angular/core").InputSignal<boolean>;
|
|
14
|
+
readonly sheetChange: import("@angular/core").OutputEmitterRef<string>;
|
|
15
|
+
readonly sheetAdd: import("@angular/core").OutputEmitterRef<void>;
|
|
16
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
export * from '@alaarab/ogrid-core';
|
|
2
|
-
export { CHECKBOX_COLUMN_WIDTH, ROW_NUMBER_COLUMN_WIDTH, DEFAULT_MIN_COLUMN_WIDTH, CELL_PADDING, GRID_BORDER_RADIUS, PEOPLE_SEARCH_DEBOUNCE_MS, DEFAULT_DEBOUNCE_MS, SIDEBAR_TRANSITION_MS, Z_INDEX, } from '@alaarab/ogrid-core';
|
|
2
|
+
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, PEOPLE_SEARCH_DEBOUNCE_MS, DEFAULT_DEBOUNCE_MS, SIDEBAR_TRANSITION_MS, Z_INDEX, } from '@alaarab/ogrid-core';
|
|
3
3
|
export type { IColumnDef, IColumnGroupDef, IColumnDefinition, ICellEditorProps, } from './types';
|
|
4
4
|
export type { IOGridProps, IOGridClientProps, IOGridServerProps, IOGridDataGridProps, } from './types';
|
|
5
5
|
export type { ColumnFilterType, IColumnFilterDef, IColumnMeta, ICellValueChangedEvent, CellEditorParams, IValueParserParams, IDateFilterValue, HeaderCell, HeaderRow, RowId, UserLike, UserLikeInput, FilterValue, IFilters, IFetchParams, IPageResult, IDataSource, IGridColumnState, IOGridApi, RowSelectionMode, IRowSelectionChangeEvent, StatusBarPanel, IStatusBarProps, IActiveCell, ISelectionRange, SideBarPanelId, ISideBarDef, } from './types';
|
|
6
6
|
export { toUserLike, isInSelectionRange, normalizeSelectionRange } from './types';
|
|
7
7
|
export { OGridService } from './services/ogrid.service';
|
|
8
|
-
export type { ColumnChooserPlacement, OGridPagination, OGridColumnChooser, OGridFilters, OGridSideBarState, } from './services/ogrid.service';
|
|
8
|
+
export type { ColumnChooserPlacement, OGridPagination, OGridColumnChooser, OGridFilters, OGridSideBarState, OGridFormulaBarState, } from './services/ogrid.service';
|
|
9
9
|
export { DataGridStateService } from './services/datagrid-state.service';
|
|
10
10
|
export type { DataGridLayoutState, DataGridRowSelectionState, DataGridEditingState, DataGridCellInteractionState, DataGridContextMenuState, DataGridViewModelState, DataGridPinningState, DataGridStateResult, } from './services/datagrid-state.service';
|
|
11
11
|
export { DataGridLayoutHelper } from './services/datagrid-layout.service';
|
|
@@ -21,6 +21,9 @@ export { GridContextMenuComponent } from './components/grid-context-menu.compone
|
|
|
21
21
|
export { SideBarComponent } from './components/sidebar.component';
|
|
22
22
|
export type { SideBarProps, SideBarFilterColumn } from './components/sidebar.component';
|
|
23
23
|
export { MarchingAntsOverlayComponent } from './components/marching-ants-overlay.component';
|
|
24
|
+
export { FormulaBarComponent } from './components/formula-bar.component';
|
|
25
|
+
export { SheetTabsComponent } from './components/sheet-tabs.component';
|
|
26
|
+
export { FormulaRefOverlayComponent } from './components/formula-ref-overlay.component';
|
|
24
27
|
export { EmptyStateComponent } from './components/empty-state.component';
|
|
25
28
|
export { BaseOGridComponent } from './components/base-ogrid.component';
|
|
26
29
|
export { BaseDataGridTableComponent } from './components/base-datagrid-table.component';
|
|
@@ -30,6 +33,7 @@ export { BaseColumnChooserComponent } from './components/base-column-chooser.com
|
|
|
30
33
|
export type { IColumnChooserProps } from './components/base-column-chooser.component';
|
|
31
34
|
export { BasePaginationControlsComponent } from './components/base-pagination-controls.component';
|
|
32
35
|
export { BaseInlineCellEditorComponent } from './components/base-inline-cell-editor.component';
|
|
36
|
+
export { BaseColumnHeaderMenuComponent } from './components/base-column-header-menu.component';
|
|
33
37
|
export { INLINE_CELL_EDITOR_TEMPLATE, INLINE_CELL_EDITOR_STYLES } from './components/inline-cell-editor-template';
|
|
34
38
|
export { BasePopoverCellEditorComponent, POPOVER_CELL_EDITOR_TEMPLATE, POPOVER_CELL_EDITOR_OVERLAY_STYLES } from './components/base-popover-cell-editor.component';
|
|
35
39
|
export { OGRID_THEME_VARS_CSS } from './styles/ogrid-theme-vars';
|
|
@@ -119,6 +119,9 @@ export interface DataGridViewModelState<T> {
|
|
|
119
119
|
editable?: boolean;
|
|
120
120
|
onCellValueChanged?: (event: ICellValueChangedEvent<T>) => void;
|
|
121
121
|
isDragging: boolean;
|
|
122
|
+
getFormulaValue?: (col: number, row: number) => unknown;
|
|
123
|
+
hasFormula?: (col: number, row: number) => boolean;
|
|
124
|
+
formulaVersion?: number;
|
|
122
125
|
};
|
|
123
126
|
statusBarConfig: IStatusBarProps | null;
|
|
124
127
|
showEmptyInGrid: boolean;
|
|
@@ -126,8 +126,6 @@ export declare class FormulaEngineService<T = unknown> {
|
|
|
126
126
|
* Get full audit trail for a cell.
|
|
127
127
|
*/
|
|
128
128
|
getAuditTrail(col: number, row: number): IAuditTrail | null;
|
|
129
|
-
/**
|
|
130
|
-
* Create a data accessor that bridges grid data to formula coordinates.
|
|
131
|
-
*/
|
|
129
|
+
/** Create a data accessor that bridges grid data to formula coordinates. */
|
|
132
130
|
private createAccessor;
|
|
133
131
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { FormulaReference } from '@alaarab/ogrid-core';
|
|
1
2
|
import type { RowId, IOGridApi, IFilters, FilterValue, IRowSelectionChangeEvent, IStatusBarProps, IColumnDefinition, IDataSource, ISideBarDef, IVirtualScrollConfig, SideBarPanelId, IFormulaFunction, IRecalcResult, IGridDataAccessor } from '../types';
|
|
2
3
|
import type { IOGridProps, IOGridDataGridProps } from '../types';
|
|
3
4
|
import type { IColumnDef, IColumnGroupDef, ICellValueChangedEvent } from '../types';
|
|
@@ -26,6 +27,17 @@ export interface OGridFilters {
|
|
|
26
27
|
hasActiveFilters: boolean;
|
|
27
28
|
setFilters: (f: IFilters) => void;
|
|
28
29
|
}
|
|
30
|
+
/** Formula bar state and handlers. */
|
|
31
|
+
export interface OGridFormulaBarState {
|
|
32
|
+
cellRef: string | null;
|
|
33
|
+
formulaText: string;
|
|
34
|
+
isEditing: boolean;
|
|
35
|
+
onInputChange: (text: string) => void;
|
|
36
|
+
onCommit: () => void;
|
|
37
|
+
onCancel: () => void;
|
|
38
|
+
startEditing: () => void;
|
|
39
|
+
referencedCells: FormulaReference[];
|
|
40
|
+
}
|
|
29
41
|
/** Side bar state. */
|
|
30
42
|
export interface OGridSideBarState {
|
|
31
43
|
isEnabled: boolean;
|
|
@@ -121,11 +133,24 @@ export declare class OGridService<T> {
|
|
|
121
133
|
readonly formulaFunctions: import("@angular/core").WritableSignal<Record<string, IFormulaFunction> | undefined>;
|
|
122
134
|
readonly namedRanges: import("@angular/core").WritableSignal<Record<string, string> | undefined>;
|
|
123
135
|
readonly sheets: import("@angular/core").WritableSignal<Record<string, IGridDataAccessor> | undefined>;
|
|
136
|
+
readonly sheetDefs: import("@angular/core").WritableSignal<import("@alaarab/ogrid-core").ISheetDef[] | undefined>;
|
|
137
|
+
readonly activeSheet: import("@angular/core").WritableSignal<string | undefined>;
|
|
138
|
+
readonly onSheetChange: import("@angular/core").WritableSignal<((sheetId: string) => void) | undefined>;
|
|
139
|
+
readonly onSheetAdd: import("@angular/core").WritableSignal<(() => void) | undefined>;
|
|
124
140
|
/** Active cell reference string (e.g. 'A1') updated by DataGridTable when cellReferences is enabled. */
|
|
125
141
|
readonly activeCellRef: import("@angular/core").WritableSignal<string | null>;
|
|
126
|
-
/**
|
|
142
|
+
/** Active cell coordinates (0-based col/row). */
|
|
143
|
+
readonly activeCellCoords: import("@angular/core").WritableSignal<{
|
|
144
|
+
col: number;
|
|
145
|
+
row: number;
|
|
146
|
+
} | null>;
|
|
147
|
+
/** Stable callback passed to DataGridTable to update activeCellRef + coords. */
|
|
127
148
|
private readonly handleActiveCellChange;
|
|
149
|
+
private readonly formulaBarEditing;
|
|
150
|
+
private readonly formulaBarEditText;
|
|
128
151
|
private readonly formulaService;
|
|
152
|
+
/** Monotonic counter incremented on formula recalculation — drives cache invalidation. */
|
|
153
|
+
readonly formulaVersion: import("@angular/core").WritableSignal<number>;
|
|
129
154
|
private readonly getFormulaValueFn;
|
|
130
155
|
private readonly hasFormulaFn;
|
|
131
156
|
private readonly getFormulaFn;
|
|
@@ -204,6 +229,18 @@ export declare class OGridService<T> {
|
|
|
204
229
|
filterType: "text" | "multiSelect" | "people" | "date";
|
|
205
230
|
}[]>;
|
|
206
231
|
readonly sideBarState: import("@angular/core").Signal<OGridSideBarState>;
|
|
232
|
+
/** Display text derived from active cell (formula string or raw value). */
|
|
233
|
+
private readonly formulaBarDisplayText;
|
|
234
|
+
/** Formula text shown in the bar: edit text when editing, display text otherwise. */
|
|
235
|
+
readonly formulaBarText: import("@angular/core").Signal<string>;
|
|
236
|
+
/** References extracted from the current formula text (for highlighting). */
|
|
237
|
+
readonly formulaBarReferences: import("@angular/core").Signal<FormulaReference[]>;
|
|
238
|
+
private readonly formulaBarOnInputChangeFn;
|
|
239
|
+
private readonly formulaBarOnCommitFn;
|
|
240
|
+
private readonly formulaBarOnCancelFn;
|
|
241
|
+
private readonly formulaBarStartEditingFn;
|
|
242
|
+
/** Aggregate formula bar state for template consumption. */
|
|
243
|
+
readonly formulaBarState: import("@angular/core").Signal<OGridFormulaBarState>;
|
|
207
244
|
private readonly handleSortFn;
|
|
208
245
|
private readonly handleColumnResizedFn;
|
|
209
246
|
private readonly handleColumnPinnedFn;
|
|
@@ -233,6 +270,9 @@ export declare class OGridService<T> {
|
|
|
233
270
|
handleSelectionChange(event: IRowSelectionChangeEvent<T>): void;
|
|
234
271
|
handleColumnResized(columnId: string, width: number): void;
|
|
235
272
|
handleColumnPinned(columnId: string, pinned: 'left' | 'right' | null): void;
|
|
273
|
+
private startFormulaBarEditing;
|
|
274
|
+
private commitFormulaBar;
|
|
275
|
+
private cancelFormulaBar;
|
|
236
276
|
configure(props: IOGridProps<T>): void;
|
|
237
277
|
/**
|
|
238
278
|
* Pin a column to the left or right edge.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { TemplateRef } from '@angular/core';
|
|
2
2
|
import type { IColumnDef, IColumnGroupDef, ICellValueChangedEvent } from './columnTypes';
|
|
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, } 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, ISheetDef, FormulaReference, } from '@alaarab/ogrid-core';
|
|
4
4
|
export { toUserLike, isInSelectionRange, normalizeSelectionRange } from '@alaarab/ogrid-core';
|
|
5
|
-
import type { RowId, UserLike, IFilters, FilterValue, RowSelectionMode, IRowSelectionChangeEvent, IStatusBarProps, IDataSource, ISideBarDef, IVirtualScrollConfig, IFormulaFunction, IRecalcResult, IGridDataAccessor, IAuditEntry, IAuditTrail } from '@alaarab/ogrid-core';
|
|
5
|
+
import type { RowId, UserLike, IFilters, FilterValue, RowSelectionMode, IRowSelectionChangeEvent, IStatusBarProps, IDataSource, ISideBarDef, IVirtualScrollConfig, IFormulaFunction, IRecalcResult, IGridDataAccessor, IAuditEntry, IAuditTrail, ISheetDef, FormulaReference } from '@alaarab/ogrid-core';
|
|
6
6
|
/** Base props shared by both client-side and server-side OGrid modes. */
|
|
7
7
|
interface IOGridBaseProps<T> {
|
|
8
8
|
columns: (IColumnDef<T> | IColumnGroupDef<T>)[];
|
|
@@ -90,6 +90,14 @@ interface IOGridBaseProps<T> {
|
|
|
90
90
|
namedRanges?: Record<string, string>;
|
|
91
91
|
/** Sheet accessors for cross-sheet formula references (e.g. { Sheet2: accessor }). */
|
|
92
92
|
sheets?: Record<string, IGridDataAccessor>;
|
|
93
|
+
/** Sheet definitions for the tab bar at grid bottom. */
|
|
94
|
+
sheetDefs?: ISheetDef[];
|
|
95
|
+
/** Active sheet ID (controlled). */
|
|
96
|
+
activeSheet?: string;
|
|
97
|
+
/** Called when user clicks a sheet tab. */
|
|
98
|
+
onSheetChange?: (sheetId: string) => void;
|
|
99
|
+
/** Called when user clicks the "+" add sheet button. */
|
|
100
|
+
onSheetAdd?: () => void;
|
|
93
101
|
'aria-label'?: string;
|
|
94
102
|
'aria-labelledby'?: string;
|
|
95
103
|
}
|
|
@@ -186,4 +194,8 @@ export interface IOGridDataGridProps<T> {
|
|
|
186
194
|
getDependents?: (col: number, row: number) => IAuditEntry[];
|
|
187
195
|
/** Get full audit trail for a cell. */
|
|
188
196
|
getAuditTrail?: (col: number, row: number) => IAuditTrail | null;
|
|
197
|
+
/** Monotonic counter incremented on each formula recalculation — used for cache invalidation. */
|
|
198
|
+
formulaVersion?: number;
|
|
199
|
+
/** Cell references to highlight (from active formula in formula bar). */
|
|
200
|
+
formulaReferences?: FormulaReference[];
|
|
189
201
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export type { ColumnFilterType, IColumnFilterDef, IColumnMeta, IColumnDef, IColumnGroupDef, IColumnDefinition, ICellValueChangedEvent, ICellEditorProps, CellEditorParams, IValueParserParams, IDateFilterValue, HeaderCell, HeaderRow, } from './columnTypes';
|
|
2
|
-
export type { RowId, UserLike, UserLikeInput, FilterValue, IFilters, IFetchParams, IPageResult, IDataSource, IGridColumnState, IOGridApi, IOGridProps, IOGridClientProps, IOGridServerProps, IOGridDataGridProps, RowSelectionMode, IRowSelectionChangeEvent, StatusBarPanel, IStatusBarProps, IActiveCell, ISelectionRange, SideBarPanelId, ISideBarDef, IVirtualScrollConfig, IFormulaFunction, IRecalcResult, IGridDataAccessor, IAuditEntry, IAuditTrail, } from './dataGridTypes';
|
|
2
|
+
export type { RowId, UserLike, UserLikeInput, FilterValue, IFilters, IFetchParams, IPageResult, IDataSource, IGridColumnState, IOGridApi, IOGridProps, IOGridClientProps, IOGridServerProps, IOGridDataGridProps, RowSelectionMode, IRowSelectionChangeEvent, StatusBarPanel, IStatusBarProps, IActiveCell, ISelectionRange, SideBarPanelId, ISideBarDef, IVirtualScrollConfig, IFormulaFunction, IRecalcResult, IGridDataAccessor, IAuditEntry, IAuditTrail, ISheetDef, FormulaReference, } from './dataGridTypes';
|
|
3
3
|
export { toUserLike, isInSelectionRange, normalizeSelectionRange } from './dataGridTypes';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alaarab/ogrid-angular",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"description": "OGrid Angular – Angular services, signals, and headless components for OGrid data grids.",
|
|
5
5
|
"main": "dist/esm/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"node": ">=18"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@alaarab/ogrid-core": "2.
|
|
38
|
+
"@alaarab/ogrid-core": "2.4.1"
|
|
39
39
|
},
|
|
40
40
|
"peerDependencies": {
|
|
41
41
|
"@angular/core": "^21.0.0",
|