@alaarab/ogrid-vue 2.3.0 → 2.4.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.
- package/dist/esm/index.js +348 -30
- package/dist/types/components/FormulaBar.d.ts +52 -0
- package/dist/types/components/FormulaRefOverlay.d.ts +39 -0
- package/dist/types/components/SheetTabs.d.ts +45 -0
- package/dist/types/composables/index.d.ts +2 -0
- package/dist/types/composables/useFormulaBar.d.ts +44 -0
- package/dist/types/composables/useOGrid.d.ts +4 -0
- package/dist/types/index.d.ts +5 -2
- 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,4 +1,4 @@
|
|
|
1
|
-
import { injectGlobalStyles, Z_INDEX, getStatusBarParts, measureRange, flattenColumns, getMultiSelectFilterFields, deriveFilterOptionsFromData, processClientSideData, processClientSideDataAsync, validateColumns, validateRowIds, computeRowSelectionState, buildCellIndex, UndoRedoStack, CHECKBOX_COLUMN_WIDTH, DEFAULT_MIN_COLUMN_WIDTH, CELL_PADDING, computeAggregations, getDataGridStatusBarConfig, validateVirtualScrollConfig, computeVisibleRange, computeTotalHeight, computeVisibleColumnRange, partitionColumnsForVirtualization, formatCellReference, buildHeaderRows, indexToColumnLetter, ROW_NUMBER_COLUMN_WIDTH, getHeaderFilterConfig, getCellRenderDescriptor, buildInlineEditorProps, buildPopoverEditorProps, resolveCellDisplayContent, resolveCellStyle, rangesEqual, normalizeSelectionRange, formatSelectionAsTsv, parseTsvClipboard, applyPastedValues, applyCutClear, measureColumnContentWidth, getPinStateForColumn, parseValue, applyFillValues, applyCellDeletion, computeTabNavigation, computeArrowNavigation, computeNextSortState, mergeFilter, applyRangeRowSelection, getScrollTopForRow, FormulaEngine,
|
|
1
|
+
import { injectGlobalStyles, Z_INDEX, getStatusBarParts, FORMULA_BAR_STYLES, handleFormulaBarKeyDown, measureRange, FORMULA_REF_COLORS, deriveFormulaBarText, extractFormulaReferences, flattenColumns, getMultiSelectFilterFields, deriveFilterOptionsFromData, processClientSideData, processClientSideDataAsync, validateColumns, validateRowIds, computeRowSelectionState, buildCellIndex, UndoRedoStack, CHECKBOX_COLUMN_WIDTH, DEFAULT_MIN_COLUMN_WIDTH, CELL_PADDING, computeAggregations, getDataGridStatusBarConfig, validateVirtualScrollConfig, computeVisibleRange, computeTotalHeight, computeVisibleColumnRange, partitionColumnsForVirtualization, formatCellReference, buildHeaderRows, indexToColumnLetter, ROW_NUMBER_COLUMN_WIDTH, getHeaderFilterConfig, getCellRenderDescriptor, buildInlineEditorProps, buildPopoverEditorProps, resolveCellDisplayContent, resolveCellStyle, rangesEqual, normalizeSelectionRange, formatSelectionAsTsv, parseTsvClipboard, applyPastedValues, applyCutClear, measureColumnContentWidth, getPinStateForColumn, parseValue, applyFillValues, processFormulaBarCommit, applyCellDeletion, computeTabNavigation, computeArrowNavigation, computeNextSortState, mergeFilter, columnLetterToIndex, getCellValue, applyRangeRowSelection, getScrollTopForRow, FormulaEngine, calculateDropTarget, reorderColumnArray, createGridDataAccessor, computeAutoScrollSpeed } from '@alaarab/ogrid-core';
|
|
2
2
|
export * from '@alaarab/ogrid-core';
|
|
3
3
|
export { buildInlineEditorProps, buildPopoverEditorProps, getCellRenderDescriptor, getHeaderFilterConfig, isInSelectionRange, normalizeSelectionRange, resolveCellDisplayContent, resolveCellStyle, toUserLike } from '@alaarab/ogrid-core';
|
|
4
4
|
import { defineComponent, ref, computed, onMounted, watch, toValue, onUnmounted, h, shallowRef, triggerRef, nextTick, Teleport, isRef, isReadonly, unref, customRef } from 'vue';
|
|
@@ -173,6 +173,211 @@ var StatusBar = defineComponent({
|
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
175
|
});
|
|
176
|
+
var FormulaBar = defineComponent({
|
|
177
|
+
name: "FormulaBar",
|
|
178
|
+
props: {
|
|
179
|
+
cellRef: { type: [String, null], default: null },
|
|
180
|
+
formulaText: { type: String, required: true },
|
|
181
|
+
isEditing: { type: Boolean, required: true }
|
|
182
|
+
},
|
|
183
|
+
emits: ["inputChange", "commit", "cancel", "startEditing"],
|
|
184
|
+
setup(props, { emit }) {
|
|
185
|
+
const inputRef = ref(null);
|
|
186
|
+
watch(() => props.isEditing, (editing) => {
|
|
187
|
+
if (editing && inputRef.value) {
|
|
188
|
+
inputRef.value.focus();
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
return () => h("div", { style: FORMULA_BAR_STYLES.bar, role: "toolbar", "aria-label": "Formula bar" }, [
|
|
192
|
+
h(
|
|
193
|
+
"div",
|
|
194
|
+
{ style: FORMULA_BAR_STYLES.nameBox, "aria-label": "Active cell reference" },
|
|
195
|
+
props.cellRef ?? "\u2014"
|
|
196
|
+
),
|
|
197
|
+
h("div", { style: FORMULA_BAR_STYLES.fxLabel, "aria-hidden": "true" }, "fx"),
|
|
198
|
+
h("input", {
|
|
199
|
+
ref: inputRef,
|
|
200
|
+
type: "text",
|
|
201
|
+
style: FORMULA_BAR_STYLES.input,
|
|
202
|
+
value: props.formulaText,
|
|
203
|
+
readonly: !props.isEditing,
|
|
204
|
+
onInput: (e) => emit("inputChange", e.target.value),
|
|
205
|
+
onKeydown: (e) => handleFormulaBarKeyDown(e.key, () => e.preventDefault(), () => emit("commit"), () => emit("cancel")),
|
|
206
|
+
onClick: () => {
|
|
207
|
+
if (!props.isEditing) emit("startEditing");
|
|
208
|
+
},
|
|
209
|
+
onDblclick: () => {
|
|
210
|
+
if (!props.isEditing) emit("startEditing");
|
|
211
|
+
},
|
|
212
|
+
"aria-label": "Formula input",
|
|
213
|
+
spellcheck: false,
|
|
214
|
+
autocomplete: "off"
|
|
215
|
+
})
|
|
216
|
+
]);
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
var barStyle = {
|
|
220
|
+
display: "flex",
|
|
221
|
+
alignItems: "center",
|
|
222
|
+
borderTop: "1px solid var(--ogrid-border, #e0e0e0)",
|
|
223
|
+
background: "var(--ogrid-header-bg, #f5f5f5)",
|
|
224
|
+
minHeight: "30px",
|
|
225
|
+
overflowX: "auto",
|
|
226
|
+
overflowY: "hidden",
|
|
227
|
+
gap: "0",
|
|
228
|
+
fontSize: "12px"
|
|
229
|
+
};
|
|
230
|
+
var addBtnStyle = {
|
|
231
|
+
background: "none",
|
|
232
|
+
border: "none",
|
|
233
|
+
cursor: "pointer",
|
|
234
|
+
padding: "4px 10px",
|
|
235
|
+
fontSize: "16px",
|
|
236
|
+
lineHeight: "22px",
|
|
237
|
+
color: "var(--ogrid-fg-secondary, #666)",
|
|
238
|
+
flexShrink: 0
|
|
239
|
+
};
|
|
240
|
+
var tabBaseStyle = {
|
|
241
|
+
background: "none",
|
|
242
|
+
border: "none",
|
|
243
|
+
borderBottom: "2px solid transparent",
|
|
244
|
+
cursor: "pointer",
|
|
245
|
+
padding: "4px 16px",
|
|
246
|
+
fontSize: "12px",
|
|
247
|
+
lineHeight: "22px",
|
|
248
|
+
color: "var(--ogrid-fg, #242424)",
|
|
249
|
+
whiteSpace: "nowrap",
|
|
250
|
+
position: "relative"
|
|
251
|
+
};
|
|
252
|
+
var activeTabStyle = {
|
|
253
|
+
...tabBaseStyle,
|
|
254
|
+
fontWeight: 600,
|
|
255
|
+
borderBottomColor: "var(--ogrid-primary, #217346)",
|
|
256
|
+
background: "var(--ogrid-bg, #fff)"
|
|
257
|
+
};
|
|
258
|
+
var SheetTabs = defineComponent({
|
|
259
|
+
name: "SheetTabs",
|
|
260
|
+
props: {
|
|
261
|
+
sheets: { type: Array, required: true },
|
|
262
|
+
activeSheet: { type: String, required: true },
|
|
263
|
+
showAddButton: { type: Boolean, default: false }
|
|
264
|
+
},
|
|
265
|
+
emits: ["sheetChange", "sheetAdd"],
|
|
266
|
+
setup(props, { emit }) {
|
|
267
|
+
return () => h("div", { style: barStyle, role: "tablist", "aria-label": "Sheet tabs" }, [
|
|
268
|
+
props.showAddButton ? h("button", {
|
|
269
|
+
type: "button",
|
|
270
|
+
style: addBtnStyle,
|
|
271
|
+
onClick: () => emit("sheetAdd"),
|
|
272
|
+
title: "Add sheet",
|
|
273
|
+
"aria-label": "Add sheet"
|
|
274
|
+
}, "+") : null,
|
|
275
|
+
...props.sheets.map((sheet) => {
|
|
276
|
+
const isActive = sheet.id === props.activeSheet;
|
|
277
|
+
const base = isActive ? activeTabStyle : tabBaseStyle;
|
|
278
|
+
const style = isActive && sheet.color ? { ...base, borderBottomColor: sheet.color } : base;
|
|
279
|
+
return h("button", {
|
|
280
|
+
key: sheet.id,
|
|
281
|
+
type: "button",
|
|
282
|
+
role: "tab",
|
|
283
|
+
"aria-selected": isActive,
|
|
284
|
+
style,
|
|
285
|
+
onClick: () => emit("sheetChange", sheet.id)
|
|
286
|
+
}, sheet.name);
|
|
287
|
+
})
|
|
288
|
+
]);
|
|
289
|
+
}
|
|
290
|
+
});
|
|
291
|
+
function measureRef(container, r, colOffset) {
|
|
292
|
+
const startCol = r.col + colOffset;
|
|
293
|
+
const endCol = (r.endCol ?? r.col) + colOffset;
|
|
294
|
+
const endRow = r.endRow ?? r.row;
|
|
295
|
+
const tl = container.querySelector(
|
|
296
|
+
`[data-row-index="${r.row}"][data-col-index="${startCol}"]`
|
|
297
|
+
);
|
|
298
|
+
const br = container.querySelector(
|
|
299
|
+
`[data-row-index="${endRow}"][data-col-index="${endCol}"]`
|
|
300
|
+
);
|
|
301
|
+
if (!tl || !br) return null;
|
|
302
|
+
const cRect = container.getBoundingClientRect();
|
|
303
|
+
const tlRect = tl.getBoundingClientRect();
|
|
304
|
+
const brRect = br.getBoundingClientRect();
|
|
305
|
+
return {
|
|
306
|
+
top: Math.round(tlRect.top - cRect.top),
|
|
307
|
+
left: Math.round(tlRect.left - cRect.left),
|
|
308
|
+
width: Math.round(brRect.right - tlRect.left),
|
|
309
|
+
height: Math.round(brRect.bottom - tlRect.top),
|
|
310
|
+
color: FORMULA_REF_COLORS[r.colorIndex % FORMULA_REF_COLORS.length]
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
var FormulaRefOverlay = defineComponent({
|
|
314
|
+
name: "FormulaRefOverlay",
|
|
315
|
+
props: {
|
|
316
|
+
containerEl: { type: Object, default: null },
|
|
317
|
+
references: { type: Array, required: true },
|
|
318
|
+
colOffset: { type: Number, required: true }
|
|
319
|
+
},
|
|
320
|
+
setup(props) {
|
|
321
|
+
const rects = ref([]);
|
|
322
|
+
let rafId = 0;
|
|
323
|
+
function measureAll() {
|
|
324
|
+
const container = props.containerEl;
|
|
325
|
+
const refs = props.references;
|
|
326
|
+
if (!container || refs.length === 0) {
|
|
327
|
+
rects.value = [];
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
const measured = [];
|
|
331
|
+
for (const r of refs) {
|
|
332
|
+
const rect = measureRef(container, r, props.colOffset);
|
|
333
|
+
if (rect) measured.push(rect);
|
|
334
|
+
}
|
|
335
|
+
rects.value = measured;
|
|
336
|
+
}
|
|
337
|
+
watch(
|
|
338
|
+
() => [props.references, props.containerEl, props.colOffset],
|
|
339
|
+
() => {
|
|
340
|
+
cancelAnimationFrame(rafId);
|
|
341
|
+
if (!props.containerEl || props.references.length === 0) {
|
|
342
|
+
rects.value = [];
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
rafId = requestAnimationFrame(measureAll);
|
|
346
|
+
},
|
|
347
|
+
{ immediate: true }
|
|
348
|
+
);
|
|
349
|
+
return () => {
|
|
350
|
+
if (rects.value.length === 0) return null;
|
|
351
|
+
return rects.value.map(
|
|
352
|
+
(r, i) => h("svg", {
|
|
353
|
+
key: i,
|
|
354
|
+
style: {
|
|
355
|
+
position: "absolute",
|
|
356
|
+
top: `${r.top}px`,
|
|
357
|
+
left: `${r.left}px`,
|
|
358
|
+
width: `${r.width}px`,
|
|
359
|
+
height: `${r.height}px`,
|
|
360
|
+
pointerEvents: "none",
|
|
361
|
+
zIndex: 3,
|
|
362
|
+
overflow: "visible"
|
|
363
|
+
},
|
|
364
|
+
"aria-hidden": "true"
|
|
365
|
+
}, [
|
|
366
|
+
h("rect", {
|
|
367
|
+
x: "1",
|
|
368
|
+
y: "1",
|
|
369
|
+
width: Math.max(0, r.width - 2),
|
|
370
|
+
height: Math.max(0, r.height - 2),
|
|
371
|
+
fill: "none",
|
|
372
|
+
stroke: r.color,
|
|
373
|
+
"stroke-width": "2",
|
|
374
|
+
style: "shape-rendering: crispEdges"
|
|
375
|
+
})
|
|
376
|
+
])
|
|
377
|
+
);
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
});
|
|
176
381
|
function useFilterOptions(dataSource, fields) {
|
|
177
382
|
const filterOptions = ref({});
|
|
178
383
|
const loadingOptions = ref({});
|
|
@@ -245,17 +450,7 @@ function useFormulaEngine(params) {
|
|
|
245
450
|
let initialLoaded = false;
|
|
246
451
|
const enabled = computed(() => formulas?.value ?? false);
|
|
247
452
|
function createAccessor() {
|
|
248
|
-
|
|
249
|
-
const currentCols = flatColumnsRef.value;
|
|
250
|
-
return {
|
|
251
|
-
getCellValue: (col, row) => {
|
|
252
|
-
if (row < 0 || row >= currentItems.length) return null;
|
|
253
|
-
if (col < 0 || col >= currentCols.length) return null;
|
|
254
|
-
return getCellValue(currentItems[row], currentCols[col]);
|
|
255
|
-
},
|
|
256
|
-
getRowCount: () => currentItems.length,
|
|
257
|
-
getColumnCount: () => currentCols.length
|
|
258
|
-
};
|
|
453
|
+
return createGridDataAccessor(itemsRef.value, flatColumnsRef.value);
|
|
259
454
|
}
|
|
260
455
|
watch(
|
|
261
456
|
enabled,
|
|
@@ -330,6 +525,53 @@ function useFormulaEngine(params) {
|
|
|
330
525
|
getAuditTrail
|
|
331
526
|
};
|
|
332
527
|
}
|
|
528
|
+
function useFormulaBar(params) {
|
|
529
|
+
const { activeCol, activeRow, activeCellRef, getFormula, getRawValue, setFormula, onCellValueChanged } = params;
|
|
530
|
+
const isEditing = ref(false);
|
|
531
|
+
const editText = ref("");
|
|
532
|
+
const isFormulaBarEditing = ref(false);
|
|
533
|
+
const displayText = computed(
|
|
534
|
+
() => deriveFormulaBarText(activeCol.value, activeRow.value, getFormula, getRawValue)
|
|
535
|
+
);
|
|
536
|
+
watch([activeCol, activeRow], () => {
|
|
537
|
+
isEditing.value = false;
|
|
538
|
+
isFormulaBarEditing.value = false;
|
|
539
|
+
});
|
|
540
|
+
const startEditing = () => {
|
|
541
|
+
editText.value = displayText.value;
|
|
542
|
+
isEditing.value = true;
|
|
543
|
+
isFormulaBarEditing.value = true;
|
|
544
|
+
};
|
|
545
|
+
const onInputChange = (text) => {
|
|
546
|
+
editText.value = text;
|
|
547
|
+
};
|
|
548
|
+
const onCommit = () => {
|
|
549
|
+
const col = activeCol.value;
|
|
550
|
+
const row = activeRow.value;
|
|
551
|
+
if (col == null || row == null || !setFormula) return;
|
|
552
|
+
processFormulaBarCommit(editText.value, col, row, setFormula, onCellValueChanged);
|
|
553
|
+
isEditing.value = false;
|
|
554
|
+
isFormulaBarEditing.value = false;
|
|
555
|
+
};
|
|
556
|
+
const onCancel = () => {
|
|
557
|
+
isEditing.value = false;
|
|
558
|
+
isFormulaBarEditing.value = false;
|
|
559
|
+
editText.value = "";
|
|
560
|
+
};
|
|
561
|
+
const formulaText = computed(() => isEditing.value ? editText.value : displayText.value);
|
|
562
|
+
const referencedCells = computed(() => extractFormulaReferences(formulaText.value));
|
|
563
|
+
return {
|
|
564
|
+
cellRef: activeCellRef,
|
|
565
|
+
formulaText,
|
|
566
|
+
isEditing,
|
|
567
|
+
onInputChange,
|
|
568
|
+
onCommit,
|
|
569
|
+
onCancel,
|
|
570
|
+
startEditing,
|
|
571
|
+
referencedCells,
|
|
572
|
+
isFormulaBarEditing
|
|
573
|
+
};
|
|
574
|
+
}
|
|
333
575
|
var DEFAULT_PANELS = ["columns", "filters"];
|
|
334
576
|
function useSideBarState(params) {
|
|
335
577
|
const { config } = params;
|
|
@@ -615,12 +857,17 @@ function useOGrid(props) {
|
|
|
615
857
|
() => isClientSide.value && resolvedClientItems.value ? resolvedClientItems.value.totalCount : serverTotalCount.value
|
|
616
858
|
);
|
|
617
859
|
const formulasRef = computed(() => !!props.value.formulas);
|
|
860
|
+
const formulaVersionRef = ref(0);
|
|
861
|
+
const wrappedOnFormulaRecalc = (result) => {
|
|
862
|
+
formulaVersionRef.value += 1;
|
|
863
|
+
props.value.onFormulaRecalc?.(result);
|
|
864
|
+
};
|
|
618
865
|
const formulaEngine = useFormulaEngine({
|
|
619
866
|
formulas: formulasRef,
|
|
620
867
|
items: displayItems,
|
|
621
868
|
flatColumns: columns,
|
|
622
869
|
initialFormulas: props.value.initialFormulas,
|
|
623
|
-
onFormulaRecalc:
|
|
870
|
+
onFormulaRecalc: wrappedOnFormulaRecalc,
|
|
624
871
|
formulaFunctions: props.value.formulaFunctions,
|
|
625
872
|
namedRanges: props.value.namedRanges,
|
|
626
873
|
sheets: props.value.sheets
|
|
@@ -713,9 +960,36 @@ function useOGrid(props) {
|
|
|
713
960
|
const clearAllFilters = () => setFilters({});
|
|
714
961
|
const isLoadingResolved = computed(() => isServerSide.value && loading.value || displayLoading.value);
|
|
715
962
|
const activeCellRef = ref(null);
|
|
963
|
+
const activeCellCoords = ref(null);
|
|
716
964
|
const onActiveCellChange = (cellRef) => {
|
|
717
965
|
activeCellRef.value = cellRef;
|
|
966
|
+
if (cellRef) {
|
|
967
|
+
const m = cellRef.match(/^([A-Z]+)(\d+)$/);
|
|
968
|
+
if (m) {
|
|
969
|
+
activeCellCoords.value = { col: columnLetterToIndex(m[1]), row: parseInt(m[2], 10) - 1 };
|
|
970
|
+
} else {
|
|
971
|
+
activeCellCoords.value = null;
|
|
972
|
+
}
|
|
973
|
+
} else {
|
|
974
|
+
activeCellCoords.value = null;
|
|
975
|
+
}
|
|
718
976
|
};
|
|
977
|
+
const formulaBarActiveCol = computed(() => activeCellCoords.value?.col ?? null);
|
|
978
|
+
const formulaBarActiveRow = computed(() => activeCellCoords.value?.row ?? null);
|
|
979
|
+
const getRawValue = (col, row) => {
|
|
980
|
+
const items = displayItems.value;
|
|
981
|
+
const cols = columns.value;
|
|
982
|
+
if (row < 0 || row >= items.length || col < 0 || col >= cols.length) return void 0;
|
|
983
|
+
return getCellValue(items[row], cols[col]);
|
|
984
|
+
};
|
|
985
|
+
const formulaBarState = useFormulaBar({
|
|
986
|
+
activeCol: formulaBarActiveCol,
|
|
987
|
+
activeRow: formulaBarActiveRow,
|
|
988
|
+
activeCellRef,
|
|
989
|
+
getFormula: formulaEngine.enabled.value ? formulaEngine.getFormula : void 0,
|
|
990
|
+
getRawValue,
|
|
991
|
+
setFormula: formulaEngine.enabled.value ? formulaEngine.setFormula : void 0
|
|
992
|
+
});
|
|
719
993
|
const dataGridProps = computed(() => {
|
|
720
994
|
const p = props.value;
|
|
721
995
|
const ds = dataProps.value.dataSource;
|
|
@@ -743,10 +1017,11 @@ function useOGrid(props) {
|
|
|
743
1017
|
rowSelection: p.rowSelection ?? "none",
|
|
744
1018
|
selectedRows: effectiveSelectedRows.value,
|
|
745
1019
|
onSelectionChange: handleSelectionChange,
|
|
746
|
-
showRowNumbers: p.showRowNumbers || p.cellReferences,
|
|
747
|
-
showColumnLetters: !!p.cellReferences,
|
|
748
|
-
showNameBox: !!p.cellReferences,
|
|
749
|
-
|
|
1020
|
+
showRowNumbers: p.showRowNumbers || p.cellReferences || p.formulas,
|
|
1021
|
+
showColumnLetters: !!(p.cellReferences || p.formulas),
|
|
1022
|
+
showNameBox: !!(p.cellReferences && !p.formulas),
|
|
1023
|
+
// formula bar includes name box
|
|
1024
|
+
onActiveCellChange: p.cellReferences || p.formulas ? onActiveCellChange : void 0,
|
|
750
1025
|
currentPage: page.value,
|
|
751
1026
|
pageSize: pageSize.value,
|
|
752
1027
|
statusBar: statusBarConfig.value,
|
|
@@ -773,6 +1048,7 @@ function useOGrid(props) {
|
|
|
773
1048
|
render: p.emptyState?.render
|
|
774
1049
|
},
|
|
775
1050
|
formulas: p.formulas,
|
|
1051
|
+
formulaVersion: formulaVersionRef.value,
|
|
776
1052
|
...formulaEngine.enabled.value ? {
|
|
777
1053
|
getFormulaValue: formulaEngine.getFormulaValue,
|
|
778
1054
|
hasFormula: formulaEngine.hasFormula,
|
|
@@ -782,7 +1058,8 @@ function useOGrid(props) {
|
|
|
782
1058
|
getPrecedents: formulaEngine.getPrecedents,
|
|
783
1059
|
getDependents: formulaEngine.getDependents,
|
|
784
1060
|
getAuditTrail: formulaEngine.getAuditTrail
|
|
785
|
-
} : {}
|
|
1061
|
+
} : {},
|
|
1062
|
+
formulaReferences: formulaBarState.referencedCells.value.length > 0 ? formulaBarState.referencedCells.value : void 0
|
|
786
1063
|
};
|
|
787
1064
|
});
|
|
788
1065
|
const pagination = computed(() => ({
|
|
@@ -801,8 +1078,10 @@ function useOGrid(props) {
|
|
|
801
1078
|
placement: columnChooserPlacement.value
|
|
802
1079
|
}));
|
|
803
1080
|
const layout = computed(() => {
|
|
804
|
-
const
|
|
805
|
-
|
|
1081
|
+
const p = props.value;
|
|
1082
|
+
const formulas = !!p.formulas;
|
|
1083
|
+
const showNameBox = !!p.cellReferences && !formulas;
|
|
1084
|
+
let resolvedToolbar = p.toolbar;
|
|
806
1085
|
if (showNameBox) {
|
|
807
1086
|
const nameBoxEl = h("div", {
|
|
808
1087
|
style: {
|
|
@@ -823,13 +1102,32 @@ function useOGrid(props) {
|
|
|
823
1102
|
}, activeCellRef.value ?? "\u2014");
|
|
824
1103
|
resolvedToolbar = [nameBoxEl, resolvedToolbar];
|
|
825
1104
|
}
|
|
1105
|
+
const formulaBarEl = formulas ? h(FormulaBar, {
|
|
1106
|
+
cellRef: formulaBarState.cellRef.value,
|
|
1107
|
+
formulaText: formulaBarState.formulaText.value,
|
|
1108
|
+
isEditing: formulaBarState.isEditing.value,
|
|
1109
|
+
onInputChange: formulaBarState.onInputChange,
|
|
1110
|
+
onCommit: formulaBarState.onCommit,
|
|
1111
|
+
onCancel: formulaBarState.onCancel,
|
|
1112
|
+
onStartEditing: formulaBarState.startEditing
|
|
1113
|
+
}) : void 0;
|
|
1114
|
+
const sheetTabsEl = p.sheetDefs && p.sheetDefs.length > 0 && p.activeSheet && p.onSheetChange ? h(SheetTabs, {
|
|
1115
|
+
sheets: p.sheetDefs,
|
|
1116
|
+
activeSheet: p.activeSheet,
|
|
1117
|
+
showAddButton: !!p.onSheetAdd,
|
|
1118
|
+
onSheetChange: p.onSheetChange,
|
|
1119
|
+
onSheetAdd: p.onSheetAdd ?? (() => {
|
|
1120
|
+
})
|
|
1121
|
+
}) : void 0;
|
|
826
1122
|
return {
|
|
827
1123
|
toolbar: resolvedToolbar,
|
|
828
|
-
toolbarBelow:
|
|
829
|
-
className:
|
|
830
|
-
emptyState:
|
|
1124
|
+
toolbarBelow: p.toolbarBelow,
|
|
1125
|
+
className: p.className,
|
|
1126
|
+
emptyState: p.emptyState,
|
|
831
1127
|
sideBarProps: sideBarProps.value,
|
|
832
|
-
fullScreen:
|
|
1128
|
+
fullScreen: p.fullScreen,
|
|
1129
|
+
formulaBar: formulaBarEl,
|
|
1130
|
+
sheetTabs: sheetTabsEl
|
|
833
1131
|
};
|
|
834
1132
|
});
|
|
835
1133
|
const filtersResult = computed(() => ({
|
|
@@ -2449,7 +2747,10 @@ function useDataGridState(params) {
|
|
|
2449
2747
|
getRowId,
|
|
2450
2748
|
editable: editableProp.value,
|
|
2451
2749
|
onCellValueChanged: onCellValueChanged.value,
|
|
2452
|
-
isDragging: cellSelection.value ? isDragging.value : false
|
|
2750
|
+
isDragging: cellSelection.value ? isDragging.value : false,
|
|
2751
|
+
getFormulaValue: props.value.getFormulaValue,
|
|
2752
|
+
hasFormula: props.value.hasFormula,
|
|
2753
|
+
formulaVersion: props.value.formulaVersion
|
|
2453
2754
|
}));
|
|
2454
2755
|
const popoverAnchorEl = ref(null);
|
|
2455
2756
|
const setPopoverAnchorEl = (el) => {
|
|
@@ -3138,9 +3439,14 @@ function useColumnChooserState(params) {
|
|
|
3138
3439
|
}
|
|
3139
3440
|
function useInlineCellEditorState(params) {
|
|
3140
3441
|
const { value, editorType, onCommit, onCancel } = params;
|
|
3141
|
-
const localValue = ref(
|
|
3142
|
-
value
|
|
3143
|
-
|
|
3442
|
+
const localValue = ref((() => {
|
|
3443
|
+
if (value === null || value === void 0) return "";
|
|
3444
|
+
if (editorType === "date") {
|
|
3445
|
+
const str = String(value);
|
|
3446
|
+
return str.match(/^\d{4}-\d{2}-\d{2}/) ? str.substring(0, 10) : str;
|
|
3447
|
+
}
|
|
3448
|
+
return String(value);
|
|
3449
|
+
})());
|
|
3144
3450
|
const setLocalValue = (v) => {
|
|
3145
3451
|
localValue.value = v;
|
|
3146
3452
|
};
|
|
@@ -3569,7 +3875,7 @@ function createDataGridTable(ui) {
|
|
|
3569
3875
|
const cb = propsRef.value.onActiveCellChange;
|
|
3570
3876
|
if (!cb) return;
|
|
3571
3877
|
if (ac) {
|
|
3572
|
-
cb(formatCellReference(ac.columnIndex, offset + ac.rowIndex + 1));
|
|
3878
|
+
cb(formatCellReference(ac.columnIndex - state.layout.value.colOffset, offset + ac.rowIndex + 1));
|
|
3573
3879
|
} else {
|
|
3574
3880
|
cb(null);
|
|
3575
3881
|
}
|
|
@@ -4112,6 +4418,14 @@ function createDataGridTable(ui) {
|
|
|
4112
4418
|
columnSizingOverrides: layout.columnSizingOverrides,
|
|
4113
4419
|
columnOrder: p.columnOrder
|
|
4114
4420
|
}),
|
|
4421
|
+
// Formula reference overlay
|
|
4422
|
+
...p.formulaReferences && p.formulaReferences.length > 0 ? [
|
|
4423
|
+
h(FormulaRefOverlay, {
|
|
4424
|
+
containerEl: tableContainerRef.value,
|
|
4425
|
+
references: p.formulaReferences,
|
|
4426
|
+
colOffset: _colOffset
|
|
4427
|
+
})
|
|
4428
|
+
] : [],
|
|
4115
4429
|
// Column header menu
|
|
4116
4430
|
h(ui.ColumnHeaderMenu, {
|
|
4117
4431
|
isOpen: headerMenu.isOpen,
|
|
@@ -4713,8 +5027,12 @@ function createOGrid(ui) {
|
|
|
4713
5027
|
style: { padding: "8px 12px", borderBottom: "1px solid var(--ogrid-border, rgba(0,0,0,0.12))" }
|
|
4714
5028
|
}, [layout.value.toolbarBelow])
|
|
4715
5029
|
] : [],
|
|
5030
|
+
// Formula bar (between toolbar and grid)
|
|
5031
|
+
...layout.value.formulaBar ? [layout.value.formulaBar] : [],
|
|
4716
5032
|
// Main content area (sidebar + grid)
|
|
4717
5033
|
h("div", { style: { display: "flex", flex: "1", minHeight: "0" } }, mainAreaChildren),
|
|
5034
|
+
// Sheet tabs (between grid and footer)
|
|
5035
|
+
...layout.value.sheetTabs ? [layout.value.sheetTabs] : [],
|
|
4718
5036
|
// Footer strip (pagination)
|
|
4719
5037
|
h("div", {
|
|
4720
5038
|
style: {
|
|
@@ -4731,4 +5049,4 @@ function createOGrid(ui) {
|
|
|
4731
5049
|
});
|
|
4732
5050
|
}
|
|
4733
5051
|
|
|
4734
|
-
export { MarchingAntsOverlay, StatusBar, createDataGridTable, createInlineCellEditor, createOGrid, getCellInteractionProps, useActiveCell, useCellEditing, useCellSelection, useClipboard, useColumnChooserState, useColumnHeaderFilterState, useColumnHeaderMenuState, useColumnPinning, useColumnReorder, useColumnResize, useContextMenu, useDataGridState, useDataGridTableSetup, useDateFilterState, useDebounce, useDebouncedCallback, useFillHandle, useFilterOptions, useInlineCellEditorState, useKeyboardNavigation, useMultiSelectFilterState, useOGrid, usePeopleFilterState, useRichSelectState, useRowSelection, useSideBarState, useTableLayout, useTextFilterState, useUndoRedo, useVirtualScroll };
|
|
5052
|
+
export { FormulaBar, FormulaRefOverlay, MarchingAntsOverlay, SheetTabs, StatusBar, createDataGridTable, createInlineCellEditor, createOGrid, getCellInteractionProps, useActiveCell, useCellEditing, useCellSelection, useClipboard, useColumnChooserState, useColumnHeaderFilterState, useColumnHeaderMenuState, useColumnPinning, useColumnReorder, useColumnResize, useContextMenu, useDataGridState, useDataGridTableSetup, useDateFilterState, useDebounce, useDebouncedCallback, useFillHandle, useFilterOptions, useFormulaBar, useInlineCellEditorState, useKeyboardNavigation, useMultiSelectFilterState, useOGrid, usePeopleFilterState, useRichSelectState, useRowSelection, useSideBarState, useTableLayout, useTextFilterState, useUndoRedo, useVirtualScroll };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FormulaBar — Headless Excel-style formula bar component.
|
|
3
|
+
*
|
|
4
|
+
* Layout: [Name Box] [fx] [Formula Input]
|
|
5
|
+
*
|
|
6
|
+
* Uses --ogrid-* CSS variables for theming.
|
|
7
|
+
*/
|
|
8
|
+
import { type PropType } from 'vue';
|
|
9
|
+
export interface FormulaBarProps {
|
|
10
|
+
/** Active cell reference (e.g. "A1"). */
|
|
11
|
+
cellRef: string | null;
|
|
12
|
+
/** Text displayed/edited in the formula input. */
|
|
13
|
+
formulaText: string;
|
|
14
|
+
/** Whether the input is in editing mode. */
|
|
15
|
+
isEditing: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare const FormulaBar: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
18
|
+
cellRef: {
|
|
19
|
+
type: PropType<string | null>;
|
|
20
|
+
default: null;
|
|
21
|
+
};
|
|
22
|
+
formulaText: {
|
|
23
|
+
type: StringConstructor;
|
|
24
|
+
required: true;
|
|
25
|
+
};
|
|
26
|
+
isEditing: {
|
|
27
|
+
type: BooleanConstructor;
|
|
28
|
+
required: true;
|
|
29
|
+
};
|
|
30
|
+
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
31
|
+
[key: string]: any;
|
|
32
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("cancel" | "inputChange" | "commit" | "startEditing")[], "cancel" | "inputChange" | "commit" | "startEditing", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
33
|
+
cellRef: {
|
|
34
|
+
type: PropType<string | null>;
|
|
35
|
+
default: null;
|
|
36
|
+
};
|
|
37
|
+
formulaText: {
|
|
38
|
+
type: StringConstructor;
|
|
39
|
+
required: true;
|
|
40
|
+
};
|
|
41
|
+
isEditing: {
|
|
42
|
+
type: BooleanConstructor;
|
|
43
|
+
required: true;
|
|
44
|
+
};
|
|
45
|
+
}>> & Readonly<{
|
|
46
|
+
onCancel?: ((...args: any[]) => any) | undefined;
|
|
47
|
+
onInputChange?: ((...args: any[]) => any) | undefined;
|
|
48
|
+
onCommit?: ((...args: any[]) => any) | undefined;
|
|
49
|
+
onStartEditing?: ((...args: any[]) => any) | undefined;
|
|
50
|
+
}>, {
|
|
51
|
+
cellRef: string | null;
|
|
52
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FormulaRefOverlay — Renders colored border overlays on cells referenced by
|
|
3
|
+
* the active formula, like Excel's reference highlighting.
|
|
4
|
+
*
|
|
5
|
+
* Port of React's FormulaRefOverlay component.
|
|
6
|
+
*/
|
|
7
|
+
import { type PropType } from 'vue';
|
|
8
|
+
import { type FormulaReference } from '@alaarab/ogrid-core';
|
|
9
|
+
export declare const FormulaRefOverlay: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
10
|
+
containerEl: {
|
|
11
|
+
type: PropType<HTMLElement | null>;
|
|
12
|
+
default: null;
|
|
13
|
+
};
|
|
14
|
+
references: {
|
|
15
|
+
type: PropType<FormulaReference[]>;
|
|
16
|
+
required: true;
|
|
17
|
+
};
|
|
18
|
+
colOffset: {
|
|
19
|
+
type: NumberConstructor;
|
|
20
|
+
required: true;
|
|
21
|
+
};
|
|
22
|
+
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
23
|
+
[key: string]: any;
|
|
24
|
+
}>[] | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
25
|
+
containerEl: {
|
|
26
|
+
type: PropType<HTMLElement | null>;
|
|
27
|
+
default: null;
|
|
28
|
+
};
|
|
29
|
+
references: {
|
|
30
|
+
type: PropType<FormulaReference[]>;
|
|
31
|
+
required: true;
|
|
32
|
+
};
|
|
33
|
+
colOffset: {
|
|
34
|
+
type: NumberConstructor;
|
|
35
|
+
required: true;
|
|
36
|
+
};
|
|
37
|
+
}>> & Readonly<{}>, {
|
|
38
|
+
containerEl: HTMLElement | null;
|
|
39
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SheetTabs — Excel-style sheet tab bar at the bottom of the grid.
|
|
3
|
+
*
|
|
4
|
+
* Layout: [+] [Sheet1] [Sheet2] [Sheet3]
|
|
5
|
+
*/
|
|
6
|
+
import { type PropType } from 'vue';
|
|
7
|
+
import type { ISheetDef } from '@alaarab/ogrid-core';
|
|
8
|
+
export interface SheetTabsProps {
|
|
9
|
+
sheets: ISheetDef[];
|
|
10
|
+
activeSheet: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const SheetTabs: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
13
|
+
sheets: {
|
|
14
|
+
type: PropType<ISheetDef[]>;
|
|
15
|
+
required: true;
|
|
16
|
+
};
|
|
17
|
+
activeSheet: {
|
|
18
|
+
type: StringConstructor;
|
|
19
|
+
required: true;
|
|
20
|
+
};
|
|
21
|
+
showAddButton: {
|
|
22
|
+
type: BooleanConstructor;
|
|
23
|
+
default: boolean;
|
|
24
|
+
};
|
|
25
|
+
}>, () => import("vue").VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
26
|
+
[key: string]: any;
|
|
27
|
+
}>, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, ("sheetChange" | "sheetAdd")[], "sheetChange" | "sheetAdd", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
28
|
+
sheets: {
|
|
29
|
+
type: PropType<ISheetDef[]>;
|
|
30
|
+
required: true;
|
|
31
|
+
};
|
|
32
|
+
activeSheet: {
|
|
33
|
+
type: StringConstructor;
|
|
34
|
+
required: true;
|
|
35
|
+
};
|
|
36
|
+
showAddButton: {
|
|
37
|
+
type: BooleanConstructor;
|
|
38
|
+
default: boolean;
|
|
39
|
+
};
|
|
40
|
+
}>> & Readonly<{
|
|
41
|
+
onSheetChange?: ((...args: any[]) => any) | undefined;
|
|
42
|
+
onSheetAdd?: ((...args: any[]) => any) | undefined;
|
|
43
|
+
}>, {
|
|
44
|
+
showAddButton: boolean;
|
|
45
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
@@ -32,6 +32,8 @@ export { useTableLayout } from './useTableLayout';
|
|
|
32
32
|
export type { UseTableLayoutParams, UseTableLayoutResult } from './useTableLayout';
|
|
33
33
|
export { useFormulaEngine } from './useFormulaEngine';
|
|
34
34
|
export type { UseFormulaEngineParams, UseFormulaEngineResult } from './useFormulaEngine';
|
|
35
|
+
export { useFormulaBar } from './useFormulaBar';
|
|
36
|
+
export type { UseFormulaBarParams, UseFormulaBarResult } from './useFormulaBar';
|
|
35
37
|
export { useColumnHeaderFilterState } from './useColumnHeaderFilterState';
|
|
36
38
|
export type { UseColumnHeaderFilterStateParams, UseColumnHeaderFilterStateResult, } from './useColumnHeaderFilterState';
|
|
37
39
|
export { useTextFilterState } from './useTextFilterState';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useFormulaBar — Vue composable for formula bar state.
|
|
3
|
+
*
|
|
4
|
+
* Manages the formula bar text, editing mode, and reference extraction.
|
|
5
|
+
*/
|
|
6
|
+
import { type Ref } from 'vue';
|
|
7
|
+
import { type FormulaReference } from '@alaarab/ogrid-core';
|
|
8
|
+
export interface UseFormulaBarParams {
|
|
9
|
+
/** Active cell column index (0-based). */
|
|
10
|
+
activeCol: Ref<number | null>;
|
|
11
|
+
/** Active cell row index (0-based). */
|
|
12
|
+
activeRow: Ref<number | null>;
|
|
13
|
+
/** Active cell reference string (e.g. "A1"). */
|
|
14
|
+
activeCellRef: Ref<string | null>;
|
|
15
|
+
/** Get formula string for a cell. */
|
|
16
|
+
getFormula?: (col: number, row: number) => string | undefined;
|
|
17
|
+
/** Get raw display value for a cell. */
|
|
18
|
+
getRawValue?: (col: number, row: number) => unknown;
|
|
19
|
+
/** Set formula for a cell. */
|
|
20
|
+
setFormula?: (col: number, row: number, formula: string | null) => void;
|
|
21
|
+
/** Commit a non-formula value change. */
|
|
22
|
+
onCellValueChanged?: (col: number, row: number, value: unknown) => void;
|
|
23
|
+
}
|
|
24
|
+
export interface UseFormulaBarResult {
|
|
25
|
+
/** Cell reference string (e.g. "A1"). */
|
|
26
|
+
cellRef: Ref<string | null>;
|
|
27
|
+
/** Text shown in the formula bar input. */
|
|
28
|
+
formulaText: Ref<string>;
|
|
29
|
+
/** Whether the formula bar input is being edited. */
|
|
30
|
+
isEditing: Ref<boolean>;
|
|
31
|
+
/** Update the formula bar input text. */
|
|
32
|
+
onInputChange: (text: string) => void;
|
|
33
|
+
/** Commit the current edit. */
|
|
34
|
+
onCommit: () => void;
|
|
35
|
+
/** Cancel the current edit. */
|
|
36
|
+
onCancel: () => void;
|
|
37
|
+
/** Start editing the formula bar. */
|
|
38
|
+
startEditing: () => void;
|
|
39
|
+
/** References extracted from the current formula text (for highlighting). */
|
|
40
|
+
referencedCells: Ref<FormulaReference[]>;
|
|
41
|
+
/** Whether the formula bar is actively being edited (for click-to-insert-ref guards). */
|
|
42
|
+
isFormulaBarEditing: Ref<boolean>;
|
|
43
|
+
}
|
|
44
|
+
export declare function useFormulaBar(params: UseFormulaBarParams): UseFormulaBarResult;
|
|
@@ -31,6 +31,10 @@ export interface UseOGridLayout {
|
|
|
31
31
|
};
|
|
32
32
|
sideBarProps: SideBarProps | null;
|
|
33
33
|
fullScreen?: boolean;
|
|
34
|
+
/** Formula bar element (rendered between toolbar and grid). */
|
|
35
|
+
formulaBar?: unknown;
|
|
36
|
+
/** Sheet tabs element (rendered between grid and footer). */
|
|
37
|
+
sheetTabs?: unknown;
|
|
34
38
|
}
|
|
35
39
|
/** Filter state. */
|
|
36
40
|
export interface UseOGridFilters {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -4,8 +4,11 @@ export type { ColumnFilterType, IColumnFilterDef, IColumnMeta, IColumnGroupDef,
|
|
|
4
4
|
export { toUserLike, isInSelectionRange, normalizeSelectionRange } from './types';
|
|
5
5
|
export { MarchingAntsOverlay } from './components/MarchingAntsOverlay';
|
|
6
6
|
export { StatusBar, type StatusBarProps } from './components/StatusBar';
|
|
7
|
-
export {
|
|
8
|
-
export
|
|
7
|
+
export { FormulaBar, type FormulaBarProps } from './components/FormulaBar';
|
|
8
|
+
export { SheetTabs, type SheetTabsProps } from './components/SheetTabs';
|
|
9
|
+
export { FormulaRefOverlay } from './components/FormulaRefOverlay';
|
|
10
|
+
export { useOGrid, useDataGridState, useActiveCell, useCellEditing, useCellSelection, useClipboard, useRowSelection, useKeyboardNavigation, useFillHandle, useUndoRedo, useContextMenu, useColumnResize, useColumnReorder, useVirtualScroll, useFilterOptions, useDebounce, useDebouncedCallback, useTableLayout, useColumnHeaderFilterState, useTextFilterState, useMultiSelectFilterState, usePeopleFilterState, useDateFilterState, useColumnChooserState, useInlineCellEditorState, useRichSelectState, useSideBarState, useColumnPinning, useColumnHeaderMenuState, useDataGridTableSetup, useFormulaBar, } from './composables';
|
|
11
|
+
export type { UseOGridResult, UseOGridPagination, UseOGridColumnChooser, UseOGridLayout, UseOGridFilters, ColumnChooserPlacement, UseDataGridStateParams, UseDataGridStateResult, DataGridLayoutState, DataGridRowSelectionState, DataGridEditingState, DataGridCellInteractionState, DataGridContextMenuState, DataGridViewModelState, DataGridPinningState, UseActiveCellResult, EditingCell, UseCellEditingParams, UseCellEditingResult, UseCellSelectionParams, UseCellSelectionResult, UseClipboardParams, UseClipboardResult, UseRowSelectionParams, UseRowSelectionResult, UseKeyboardNavigationParams, UseKeyboardNavigationResult, UseFillHandleParams, UseFillHandleResult, UseUndoRedoParams, UseUndoRedoResult, ContextMenuPosition, UseContextMenuResult, UseColumnResizeParams, UseColumnResizeResult, UseColumnReorderParams, UseColumnReorderResult, UseVirtualScrollParams, UseVirtualScrollResult, UseFilterOptionsResult, UseTableLayoutParams, UseTableLayoutResult, UseColumnHeaderFilterStateParams, UseColumnHeaderFilterStateResult, UseTextFilterStateParams, UseTextFilterStateResult, UseMultiSelectFilterStateParams, UseMultiSelectFilterStateResult, UsePeopleFilterStateParams, UsePeopleFilterStateResult, UseDateFilterStateParams, UseDateFilterStateResult, UseColumnChooserStateParams, UseColumnChooserStateResult, InlineCellEditorType, UseInlineCellEditorStateParams, UseInlineCellEditorStateResult, UseRichSelectStateParams, UseRichSelectStateResult, UseSideBarStateParams, UseSideBarStateResult, DebouncedFn, UseColumnPinningParams, UseColumnPinningResult, UseColumnHeaderMenuStateParams, UseColumnHeaderMenuStateResult, UseDataGridTableSetupParams, UseDataGridTableSetupResult, MaybeShallowRef, UseFormulaBarParams, UseFormulaBarResult, } from './composables';
|
|
9
12
|
export { getHeaderFilterConfig, getCellRenderDescriptor, resolveCellDisplayContent, resolveCellStyle, buildInlineEditorProps, buildPopoverEditorProps, getCellInteractionProps, } from './utils';
|
|
10
13
|
export type { HeaderFilterConfigInput, HeaderFilterConfig, CellRenderDescriptorInput, CellRenderDescriptor, CellRenderMode, CellInteractionHandlers, CellInteractionProps, } from './utils';
|
|
11
14
|
export { createDataGridTable, type IDataGridTableUIBindings } from './components/createDataGridTable';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { IColumnDef, IColumnGroupDef, ICellValueChangedEvent } from './columnTypes';
|
|
2
|
-
export type { RowId, UserLike, UserLikeInput, FilterValue, IFilters, IFetchParams, IPageResult, IDataSource, IGridColumnState, RowSelectionMode, IRowSelectionChangeEvent, StatusBarPanel, IStatusBarProps, IActiveCell, ISelectionRange, SideBarPanelId, ISideBarDef, IOGridApi, IVirtualScrollConfig, IFormulaFunction, IRecalcResult, IGridDataAccessor, IAuditEntry, IAuditTrail, } from '@alaarab/ogrid-core';
|
|
2
|
+
export type { RowId, UserLike, UserLikeInput, FilterValue, IFilters, IFetchParams, IPageResult, IDataSource, IGridColumnState, RowSelectionMode, IRowSelectionChangeEvent, StatusBarPanel, IStatusBarProps, IActiveCell, ISelectionRange, SideBarPanelId, ISideBarDef, IOGridApi, IVirtualScrollConfig, IFormulaFunction, IRecalcResult, IGridDataAccessor, IAuditEntry, IAuditTrail, ISheetDef, FormulaReference, } from '@alaarab/ogrid-core';
|
|
3
3
|
export { toUserLike, isInSelectionRange, normalizeSelectionRange } from '@alaarab/ogrid-core';
|
|
4
|
-
import type { RowId, UserLike, IFilters, FilterValue, RowSelectionMode, IRowSelectionChangeEvent, IStatusBarProps, IDataSource, ISideBarDef, IVirtualScrollConfig, IFormulaFunction, IRecalcResult, IGridDataAccessor, IAuditEntry, IAuditTrail } from '@alaarab/ogrid-core';
|
|
4
|
+
import type { RowId, UserLike, IFilters, FilterValue, RowSelectionMode, IRowSelectionChangeEvent, IStatusBarProps, IDataSource, ISideBarDef, IVirtualScrollConfig, IFormulaFunction, IRecalcResult, IGridDataAccessor, IAuditEntry, IAuditTrail, ISheetDef, FormulaReference } from '@alaarab/ogrid-core';
|
|
5
5
|
/** Base props shared by both client-side and server-side OGrid modes. */
|
|
6
6
|
interface IOGridBaseProps<T> {
|
|
7
7
|
columns: (IColumnDef<T> | IColumnGroupDef<T>)[];
|
|
@@ -105,6 +105,14 @@ interface IOGridBaseProps<T> {
|
|
|
105
105
|
namedRanges?: Record<string, string>;
|
|
106
106
|
/** Sheet accessors for cross-sheet formula references (e.g. { Sheet2: accessor }). */
|
|
107
107
|
sheets?: Record<string, IGridDataAccessor>;
|
|
108
|
+
/** Sheet definitions for the tab bar at grid bottom. */
|
|
109
|
+
sheetDefs?: ISheetDef[];
|
|
110
|
+
/** Active sheet ID (controlled). */
|
|
111
|
+
activeSheet?: string;
|
|
112
|
+
/** Called when user clicks a sheet tab. */
|
|
113
|
+
onSheetChange?: (sheetId: string) => void;
|
|
114
|
+
/** Called when user clicks the "+" add sheet button. */
|
|
115
|
+
onSheetAdd?: () => void;
|
|
108
116
|
'aria-label'?: string;
|
|
109
117
|
'aria-labelledby'?: string;
|
|
110
118
|
}
|
|
@@ -215,4 +223,8 @@ export interface IOGridDataGridProps<T> {
|
|
|
215
223
|
getDependents?: (col: number, row: number) => IAuditEntry[];
|
|
216
224
|
/** Get full audit trail for a cell. */
|
|
217
225
|
getAuditTrail?: (col: number, row: number) => IAuditTrail | null;
|
|
226
|
+
/** Monotonic counter incremented on each formula recalculation — used for cache invalidation. */
|
|
227
|
+
formulaVersion?: number;
|
|
228
|
+
/** Cell references to highlight (from active formula in formula bar). */
|
|
229
|
+
formulaReferences?: FormulaReference[];
|
|
218
230
|
}
|
|
@@ -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, } 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, 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-vue",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "OGrid Vue – Vue 3 composables, headless components, and utilities for OGrid data grids.",
|
|
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.
|
|
39
|
+
"@alaarab/ogrid-core": "2.4.0"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
42
|
"vue": "^3.3.0"
|