@rowsncolumns/spreadsheet-state 28.0.72 → 28.0.74
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/cjs/api/advanced-filter.d.ts +72 -0
- package/dist/cjs/api/advanced-filter.d.ts.map +1 -0
- package/dist/cjs/api/advanced-filter.js +0 -0
- package/dist/cjs/api/goal-seek.d.ts +29 -0
- package/dist/cjs/api/goal-seek.d.ts.map +1 -0
- package/dist/cjs/api/goal-seek.js +131 -0
- package/dist/cjs/api/immer-utils.d.ts.map +1 -1
- package/dist/cjs/api/immer-utils.js +2 -0
- package/dist/cjs/api/paint-format.d.ts +41 -0
- package/dist/cjs/api/paint-format.d.ts.map +1 -0
- package/dist/cjs/api/paint-format.js +115 -0
- package/dist/cjs/api/paste-special.d.ts +48 -0
- package/dist/cjs/api/paste-special.d.ts.map +1 -0
- package/dist/cjs/api/paste-special.js +229 -0
- package/dist/cjs/api/split-text.d.ts +12 -0
- package/dist/cjs/api/split-text.d.ts.map +1 -1
- package/dist/cjs/api/split-text.js +41 -0
- package/dist/cjs/api/subtotal.d.ts +85 -0
- package/dist/cjs/api/subtotal.d.ts.map +1 -0
- package/dist/cjs/api/subtotal.js +250 -0
- package/dist/cjs/commands.d.ts +13 -0
- package/dist/cjs/commands.d.ts.map +1 -1
- package/dist/cjs/components/editors/data-validation-rule-editor.d.ts.map +1 -1
- package/dist/cjs/components/editors/data-validation-rule-editor.js +83 -16
- package/dist/cjs/components/editors/table-editor.js +7 -2
- package/dist/cjs/hooks/use-calculation-worker.d.ts.map +1 -1
- package/dist/cjs/hooks/use-calculation-worker.js +39 -8
- package/dist/cjs/hooks/use-calculation.d.ts +12 -2
- package/dist/cjs/hooks/use-calculation.d.ts.map +1 -1
- package/dist/cjs/hooks/use-calculation.js +71 -35
- package/dist/cjs/hooks/use-on-advanced-filter.d.ts +21 -0
- package/dist/cjs/hooks/use-on-advanced-filter.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-advanced-filter.js +42 -0
- package/dist/cjs/hooks/use-on-goal-seek.d.ts +30 -0
- package/dist/cjs/hooks/use-on-goal-seek.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-goal-seek.js +140 -0
- package/dist/cjs/hooks/use-on-import-excel.d.ts +10 -1
- package/dist/cjs/hooks/use-on-import-excel.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-import-excel.js +8 -4
- package/dist/cjs/hooks/use-on-merge-unmerge-cells.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-merge-unmerge-cells.js +53 -34
- package/dist/cjs/hooks/use-on-paste.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-paste.js +82 -52
- package/dist/cjs/hooks/use-on-remove-duplicates.d.ts +2 -1
- package/dist/cjs/hooks/use-on-remove-duplicates.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-remove-duplicates.js +5 -3
- package/dist/cjs/hooks/use-on-show-column.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-show-column.js +2 -0
- package/dist/cjs/hooks/use-on-show-row.d.ts.map +1 -1
- package/dist/cjs/hooks/use-on-show-row.js +2 -0
- package/dist/cjs/hooks/use-on-subtotal.d.ts +26 -0
- package/dist/cjs/hooks/use-on-subtotal.d.ts.map +1 -0
- package/dist/cjs/hooks/use-on-subtotal.js +53 -0
- package/dist/cjs/hooks/use-paint-format.d.ts +19 -3
- package/dist/cjs/hooks/use-paint-format.d.ts.map +1 -1
- package/dist/cjs/hooks/use-paint-format.js +85 -31
- package/dist/cjs/hooks/use-sheet-properties.d.ts +3 -0
- package/dist/cjs/hooks/use-sheet-properties.d.ts.map +1 -1
- package/dist/cjs/hooks/use-sheet-properties.js +8 -0
- package/dist/cjs/hooks/use-split-text-to-columns.d.ts +2 -1
- package/dist/cjs/hooks/use-split-text-to-columns.d.ts.map +1 -1
- package/dist/cjs/hooks/use-split-text-to-columns.js +3 -2
- package/dist/cjs/hooks/use-spreadsheet-state.d.ts +50 -36
- package/dist/cjs/hooks/use-spreadsheet-state.d.ts.map +1 -1
- package/dist/cjs/hooks/use-spreadsheet-state.js +98 -18
- package/dist/cjs/index.d.ts +9 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +9 -0
- package/dist/cjs/interface/calculation-interface.d.ts.map +1 -1
- package/dist/cjs/interface/calculation-interface.js +5 -0
- package/dist/cjs/interface/change-batch-stream.d.ts.map +1 -1
- package/dist/cjs/interface/change-batch-stream.js +12 -6
- package/dist/cjs/interface/change-batch.d.ts.map +1 -1
- package/dist/cjs/interface/change-batch.js +17 -9
- package/dist/cjs/interface/change-formatting.d.ts.map +1 -1
- package/dist/cjs/interface/change-formatting.js +30 -11
- package/dist/cjs/interface/hide-column.d.ts.map +1 -1
- package/dist/cjs/interface/hide-column.js +4 -0
- package/dist/cjs/interface/hide-row.d.ts.map +1 -1
- package/dist/cjs/interface/hide-row.js +4 -0
- package/dist/cjs/interface/remove-duplicates.d.ts +3 -2
- package/dist/cjs/interface/remove-duplicates.d.ts.map +1 -1
- package/dist/cjs/interface/remove-duplicates.js +41 -7
- package/dist/cjs/interface/split-text.d.ts +2 -1
- package/dist/cjs/interface/split-text.d.ts.map +1 -1
- package/dist/cjs/interface/split-text.js +7 -3
- package/dist/cjs/interface/spreadsheet-interface.d.ts +2 -1
- package/dist/cjs/interface/spreadsheet-interface.d.ts.map +1 -1
- package/dist/cjs/interface/spreadsheet-interface.js +5 -5
- package/dist/cjs/sheet-cell.d.ts.map +1 -1
- package/dist/cjs/sheet-cell.js +7 -0
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/api/advanced-filter.d.ts +72 -0
- package/dist/esm/api/advanced-filter.d.ts.map +1 -0
- package/dist/esm/api/advanced-filter.js +0 -0
- package/dist/esm/api/goal-seek.d.ts +29 -0
- package/dist/esm/api/goal-seek.d.ts.map +1 -0
- package/dist/esm/api/goal-seek.js +108 -0
- package/dist/esm/api/immer-utils.d.ts.map +1 -1
- package/dist/esm/api/immer-utils.js +2 -0
- package/dist/esm/api/paint-format.d.ts +41 -0
- package/dist/esm/api/paint-format.d.ts.map +1 -0
- package/dist/esm/api/paint-format.js +77 -0
- package/dist/esm/api/paste-special.d.ts +48 -0
- package/dist/esm/api/paste-special.d.ts.map +1 -0
- package/dist/esm/api/paste-special.js +220 -0
- package/dist/esm/api/split-text.d.ts +12 -0
- package/dist/esm/api/split-text.d.ts.map +1 -1
- package/dist/esm/api/split-text.js +28 -0
- package/dist/esm/api/subtotal.d.ts +85 -0
- package/dist/esm/api/subtotal.d.ts.map +1 -0
- package/dist/esm/api/subtotal.js +181 -0
- package/dist/esm/commands.d.ts +13 -0
- package/dist/esm/commands.d.ts.map +1 -1
- package/dist/esm/components/editors/data-validation-rule-editor.d.ts.map +1 -1
- package/dist/esm/components/editors/data-validation-rule-editor.js +52 -4
- package/dist/esm/components/editors/table-editor.js +7 -4
- package/dist/esm/hooks/use-calculation-worker.d.ts.map +1 -1
- package/dist/esm/hooks/use-calculation-worker.js +20 -2
- package/dist/esm/hooks/use-calculation.d.ts +12 -2
- package/dist/esm/hooks/use-calculation.d.ts.map +1 -1
- package/dist/esm/hooks/use-calculation.js +38 -7
- package/dist/esm/hooks/use-on-advanced-filter.d.ts +21 -0
- package/dist/esm/hooks/use-on-advanced-filter.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-advanced-filter.js +41 -0
- package/dist/esm/hooks/use-on-goal-seek.d.ts +30 -0
- package/dist/esm/hooks/use-on-goal-seek.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-goal-seek.js +82 -0
- package/dist/esm/hooks/use-on-import-excel.d.ts +10 -1
- package/dist/esm/hooks/use-on-import-excel.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-import-excel.js +8 -4
- package/dist/esm/hooks/use-on-merge-unmerge-cells.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-merge-unmerge-cells.js +13 -13
- package/dist/esm/hooks/use-on-paste.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-paste.js +49 -14
- package/dist/esm/hooks/use-on-remove-duplicates.d.ts +2 -1
- package/dist/esm/hooks/use-on-remove-duplicates.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-remove-duplicates.js +5 -3
- package/dist/esm/hooks/use-on-show-column.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-show-column.js +2 -0
- package/dist/esm/hooks/use-on-show-row.d.ts.map +1 -1
- package/dist/esm/hooks/use-on-show-row.js +2 -0
- package/dist/esm/hooks/use-on-subtotal.d.ts +26 -0
- package/dist/esm/hooks/use-on-subtotal.d.ts.map +1 -0
- package/dist/esm/hooks/use-on-subtotal.js +48 -0
- package/dist/esm/hooks/use-paint-format.d.ts +19 -3
- package/dist/esm/hooks/use-paint-format.d.ts.map +1 -1
- package/dist/esm/hooks/use-paint-format.js +71 -29
- package/dist/esm/hooks/use-sheet-properties.d.ts +3 -0
- package/dist/esm/hooks/use-sheet-properties.d.ts.map +1 -1
- package/dist/esm/hooks/use-sheet-properties.js +8 -0
- package/dist/esm/hooks/use-split-text-to-columns.d.ts +2 -1
- package/dist/esm/hooks/use-split-text-to-columns.d.ts.map +1 -1
- package/dist/esm/hooks/use-split-text-to-columns.js +3 -2
- package/dist/esm/hooks/use-spreadsheet-state.d.ts +50 -36
- package/dist/esm/hooks/use-spreadsheet-state.d.ts.map +1 -1
- package/dist/esm/hooks/use-spreadsheet-state.js +89 -16
- package/dist/esm/index.d.ts +9 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +9 -0
- package/dist/esm/interface/calculation-interface.d.ts.map +1 -1
- package/dist/esm/interface/calculation-interface.js +3 -0
- package/dist/esm/interface/change-batch-stream.d.ts.map +1 -1
- package/dist/esm/interface/change-batch-stream.js +12 -6
- package/dist/esm/interface/change-batch.d.ts.map +1 -1
- package/dist/esm/interface/change-batch.js +15 -9
- package/dist/esm/interface/change-formatting.d.ts.map +1 -1
- package/dist/esm/interface/change-formatting.js +28 -11
- package/dist/esm/interface/hide-column.d.ts.map +1 -1
- package/dist/esm/interface/hide-column.js +4 -0
- package/dist/esm/interface/hide-row.d.ts.map +1 -1
- package/dist/esm/interface/hide-row.js +4 -0
- package/dist/esm/interface/remove-duplicates.d.ts +3 -2
- package/dist/esm/interface/remove-duplicates.d.ts.map +1 -1
- package/dist/esm/interface/remove-duplicates.js +37 -6
- package/dist/esm/interface/split-text.d.ts +2 -1
- package/dist/esm/interface/split-text.d.ts.map +1 -1
- package/dist/esm/interface/split-text.js +6 -3
- package/dist/esm/interface/spreadsheet-interface.d.ts +2 -1
- package/dist/esm/interface/spreadsheet-interface.d.ts.map +1 -1
- package/dist/esm/interface/spreadsheet-interface.js +5 -5
- package/dist/esm/sheet-cell.d.ts.map +1 -1
- package/dist/esm/sheet-cell.js +7 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/package.json +18 -18
|
@@ -284,7 +284,7 @@ const isHeavyArrayFormula = (formula) => {
|
|
|
284
284
|
hasLargeExplicitRange(formula));
|
|
285
285
|
};
|
|
286
286
|
const cellPromises = new Map();
|
|
287
|
-
export const useCalculation = ({ locale, functions, iterativeCalculation, onDemandFormulaPattern, activeSheetId, onSuccess, onChangeDependencyGraph, getSheetId, getSheetName, getSheetIndex, getSheetCount, getActiveSheetId, getEffectiveValue, getUserEnteredValue, getConditionalFormatFormula, getDataValidationFormula, getSheetProperties, getCellData, onStructuredReference, onNamedRange, namedRanges, onChangeStaticReference, onBeginCalculation, getEffectiveStructuredValue, isRowHidden, isRowHiddenByFilter, enableLazyCalculation = true, enabled = true, }) => {
|
|
287
|
+
export const useCalculation = ({ locale, functions, iterativeCalculation, onDemandFormulaPattern, activeSheetId, onSuccess, onChangeDependencyGraph, getSheetId, getSheetName, getSheetIndex, getSheetNames, getSheetCount, getActiveSheetId, getEffectiveValue, getUserEnteredValue, getConditionalFormatFormula, getDataValidationFormula, getSheetProperties, getCellData, onStructuredReference, onNamedRange, namedRanges, onChangeStaticReference, onBeginCalculation, getEffectiveStructuredValue, isRowHidden, isRowHiddenByFilter, enableLazyCalculation = true, enabled = true, }) => {
|
|
288
288
|
// Convert string pattern to RegExp if provided
|
|
289
289
|
const onDemandPattern = useMemo(() => {
|
|
290
290
|
if (!onDemandFormulaPattern)
|
|
@@ -299,6 +299,9 @@ export const useCalculation = ({ locale, functions, iterativeCalculation, onDema
|
|
|
299
299
|
const graphOperationQueue = useRef([]);
|
|
300
300
|
// Results queue
|
|
301
301
|
const resultsQueueRef = useRef(new Map());
|
|
302
|
+
// Circular-reference members awaiting the next `onSuccess` flush (see
|
|
303
|
+
// `CalculationSuccessContext.circularReferences`).
|
|
304
|
+
const circularReferencesQueueRef = useRef(new Map());
|
|
302
305
|
const resultsFlushPendingRef = useRef(false);
|
|
303
306
|
const isFullRecalcRef = useRef(false);
|
|
304
307
|
const staticNodeArrayRef = useRef([]);
|
|
@@ -306,6 +309,7 @@ export const useCalculation = ({ locale, functions, iterativeCalculation, onDema
|
|
|
306
309
|
const getSheetNameStable = useCallbackRef(getSheetName);
|
|
307
310
|
const getSheetIdStable = useCallbackRef(getSheetId);
|
|
308
311
|
const getSheetIndexStable = useCallbackRef(getSheetIndex);
|
|
312
|
+
const getSheetNamesStable = useCallbackRef(getSheetNames);
|
|
309
313
|
const getSheetCountStable = useCallbackRef(getSheetCount);
|
|
310
314
|
const getCellDataStable = useCallbackRef(getCellData);
|
|
311
315
|
const onStructuredReferenceStable = useCallbackRef(onStructuredReference);
|
|
@@ -595,6 +599,7 @@ export const useCalculation = ({ locale, functions, iterativeCalculation, onDema
|
|
|
595
599
|
locale,
|
|
596
600
|
getSheetId: getSheetIdStable,
|
|
597
601
|
getSheetIndex: getSheetIndexStable,
|
|
602
|
+
getSheetNames: getSheetNames ? getSheetNamesStable : undefined,
|
|
598
603
|
getSheetCount: getSheetCountStable,
|
|
599
604
|
getSheetProperties: (sheetId = getActiveSheetId()) => getSheetProperties(sheetId),
|
|
600
605
|
getSheetName: getSheetNameStable,
|
|
@@ -602,6 +607,17 @@ export const useCalculation = ({ locale, functions, iterativeCalculation, onDema
|
|
|
602
607
|
isRowHiddenByFilter: isRowHiddenByFilter
|
|
603
608
|
? isRowHiddenByFilterStable
|
|
604
609
|
: undefined,
|
|
610
|
+
getCellFormula(sheetId, rowIndex, columnIndex) {
|
|
611
|
+
const userEnteredValue = getFinalUserEnteredValue({
|
|
612
|
+
sheetId,
|
|
613
|
+
rowIndex,
|
|
614
|
+
columnIndex,
|
|
615
|
+
});
|
|
616
|
+
return typeof userEnteredValue === "string" &&
|
|
617
|
+
isAFormula(userEnteredValue)
|
|
618
|
+
? userEnteredValue
|
|
619
|
+
: undefined;
|
|
620
|
+
},
|
|
605
621
|
getCellValue(sheetId, rowIndex, columnIndex, property) {
|
|
606
622
|
const key = makeKey({
|
|
607
623
|
sheetId,
|
|
@@ -884,16 +900,22 @@ export const useCalculation = ({ locale, functions, iterativeCalculation, onDema
|
|
|
884
900
|
if (!iterativeCalculationRef.current?.enabled) {
|
|
885
901
|
const circularKeys = findCircularKeys(cellNodes);
|
|
886
902
|
if (circularKeys.size) {
|
|
903
|
+
// Excel with iterative calculation off: a circular cell displays
|
|
904
|
+
// 0 — never an error value — so its dependents compute with 0
|
|
905
|
+
// (`=A1+1` → 1, `ISERROR(A1)` → FALSE) and nothing Excel doesn't
|
|
906
|
+
// recognise reaches an export. The warning Excel raises travels
|
|
907
|
+
// on `CalculationSuccessContext.circularReferences`.
|
|
887
908
|
const results = new Map();
|
|
909
|
+
const circularPositions = [];
|
|
888
910
|
for (const node of cellNodes) {
|
|
889
911
|
if (!circularKeys.has(node.key)) {
|
|
890
912
|
continue;
|
|
891
913
|
}
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
914
|
+
getComputationCache().set(node.key, 0);
|
|
915
|
+
results.set(node.key, [node.position, 0]);
|
|
916
|
+
circularPositions.push(node.position);
|
|
895
917
|
}
|
|
896
|
-
publishResults(results.values());
|
|
918
|
+
publishResults(results.values(), circularPositions);
|
|
897
919
|
cellNodes = cellNodes.filter((node) => !circularKeys.has(node.key));
|
|
898
920
|
}
|
|
899
921
|
}
|
|
@@ -1501,11 +1523,14 @@ export const useCalculation = ({ locale, functions, iterativeCalculation, onDema
|
|
|
1501
1523
|
/**
|
|
1502
1524
|
* Publish results back to the
|
|
1503
1525
|
*/
|
|
1504
|
-
const publishResults = useCallback((item) => {
|
|
1526
|
+
const publishResults = useCallback((item, circularReferences) => {
|
|
1505
1527
|
for (const entry of item) {
|
|
1506
1528
|
const [key] = entry;
|
|
1507
1529
|
resultsQueueRef.current.set(makeKey(key), entry);
|
|
1508
1530
|
}
|
|
1531
|
+
for (const position of circularReferences ?? []) {
|
|
1532
|
+
circularReferencesQueueRef.current.set(makeKey(position), position);
|
|
1533
|
+
}
|
|
1509
1534
|
if (resultsQueueRef.current.size === 0) {
|
|
1510
1535
|
return;
|
|
1511
1536
|
}
|
|
@@ -1523,14 +1548,20 @@ export const useCalculation = ({ locale, functions, iterativeCalculation, onDema
|
|
|
1523
1548
|
if (!resultsQueueRef.current.size) {
|
|
1524
1549
|
return;
|
|
1525
1550
|
}
|
|
1551
|
+
const context = circularReferencesQueueRef.current.size > 0
|
|
1552
|
+
? {
|
|
1553
|
+
circularReferences: Array.from(circularReferencesQueueRef.current.values()),
|
|
1554
|
+
}
|
|
1555
|
+
: {};
|
|
1526
1556
|
try {
|
|
1527
|
-
onSuccess?.(resultsQueueRef.current.values(), isFullRecalc,
|
|
1557
|
+
onSuccess?.(resultsQueueRef.current.values(), isFullRecalc, context);
|
|
1528
1558
|
}
|
|
1529
1559
|
catch (err) {
|
|
1530
1560
|
console.error("[spreadsheet-state] recalculation pass aborted:", err);
|
|
1531
1561
|
}
|
|
1532
1562
|
finally {
|
|
1533
1563
|
resultsQueueRef.current.clear();
|
|
1564
|
+
circularReferencesQueueRef.current.clear();
|
|
1534
1565
|
isFullRecalcRef.current = false;
|
|
1535
1566
|
}
|
|
1536
1567
|
});
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { GridRange } from "@rowsncolumns/common-types";
|
|
2
|
+
import { type AdvancedFilterOptions, type AdvancedFilterPlan, type AdvancedFilterPlanExecutor } from "../api/advanced-filter";
|
|
3
|
+
import type { useSheetProperties } from "./use-sheet-properties";
|
|
4
|
+
export type { AdvancedFilterOptions, AdvancedFilterPlan };
|
|
5
|
+
export type UseOnAdvancedFilterProps = {
|
|
6
|
+
getEffectiveValue: ReturnType<typeof useSheetProperties>["getEffectiveValue"];
|
|
7
|
+
getFormattedValue: ReturnType<typeof useSheetProperties>["getFormattedValue"];
|
|
8
|
+
onHideRow: AdvancedFilterPlanExecutor["onHideRow"];
|
|
9
|
+
onShowRow: AdvancedFilterPlanExecutor["onShowRow"];
|
|
10
|
+
onChangeBatch: (sheetId: number, ranges: GridRange, values: (string | number | boolean | null)[][]) => void;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Excel's Data → Sort & Filter → Advanced, composed over the existing
|
|
14
|
+
* hide/show-row and batch-write callbacks so both engines execute it through
|
|
15
|
+
* the same streamed commands. Records are compared by their effective value
|
|
16
|
+
* (numbers stay numeric) and fall back to the displayed text. Returns the
|
|
17
|
+
* applied plan, or `undefined` when the list has no records, the copy
|
|
18
|
+
* destination is missing / protected, or the sheet cannot be edited.
|
|
19
|
+
*/
|
|
20
|
+
export declare const useOnAdvancedFilter: ({ getEffectiveValue, getFormattedValue, onHideRow, onShowRow, onChangeBatch, }: UseOnAdvancedFilterProps) => (sheetId: number, options: AdvancedFilterOptions) => AdvancedFilterPlan | undefined;
|
|
21
|
+
//# sourceMappingURL=use-on-advanced-filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-on-advanced-filter.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-advanced-filter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAG5D,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACvB,KAAK,0BAA0B,EAGhC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,YAAY,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,CAAC;AAE1D,MAAM,MAAM,wBAAwB,GAAG;IACrC,iBAAiB,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAC9E,iBAAiB,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAC9E,SAAS,EAAE,0BAA0B,CAAC,WAAW,CAAC,CAAC;IACnD,SAAS,EAAE,0BAA0B,CAAC,WAAW,CAAC,CAAC;IACnD,aAAa,EAAE,CACb,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,EAAE,EAAE,KAC3C,IAAI,CAAC;CACX,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,mBAAmB,GAAI,gFAMjC,wBAAwB,eAKb,MAAM,WAAW,qBAAqB,KAAG,kBAAkB,GAAG,SA2B3E,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { useCallback } from "react";
|
|
2
|
+
import { applyAdvancedFilterPlan, planAdvancedFilter, } from "../api/advanced-filter";
|
|
3
|
+
import { useCanEditCellRange, useCanEditSheet } from "./use-can-edit-cellrange";
|
|
4
|
+
/**
|
|
5
|
+
* Excel's Data → Sort & Filter → Advanced, composed over the existing
|
|
6
|
+
* hide/show-row and batch-write callbacks so both engines execute it through
|
|
7
|
+
* the same streamed commands. Records are compared by their effective value
|
|
8
|
+
* (numbers stay numeric) and fall back to the displayed text. Returns the
|
|
9
|
+
* applied plan, or `undefined` when the list has no records, the copy
|
|
10
|
+
* destination is missing / protected, or the sheet cannot be edited.
|
|
11
|
+
*/
|
|
12
|
+
export const useOnAdvancedFilter = ({ getEffectiveValue, getFormattedValue, onHideRow, onShowRow, onChangeBatch, }) => {
|
|
13
|
+
const canEditCellRange = useCanEditCellRange();
|
|
14
|
+
const canEditSheet = useCanEditSheet();
|
|
15
|
+
return useCallback((sheetId, options) => {
|
|
16
|
+
if (!canEditSheet(sheetId)) {
|
|
17
|
+
console.debug("This sheet is protected, users cannot filter it.");
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
const plan = planAdvancedFilter(options, (rowIndex, columnIndex) => {
|
|
21
|
+
const value = getEffectiveValue(sheetId, rowIndex, columnIndex);
|
|
22
|
+
return value ?? getFormattedValue(sheetId, rowIndex, columnIndex);
|
|
23
|
+
});
|
|
24
|
+
if (!plan)
|
|
25
|
+
return undefined;
|
|
26
|
+
if (plan.copy && !canEditCellRange(sheetId, plan.copy.range)) {
|
|
27
|
+
console.debug("This range is protected, users cannot edit this cell range.");
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
applyAdvancedFilterPlan(sheetId, plan, { onHideRow, onShowRow, onChangeBatch });
|
|
31
|
+
return plan;
|
|
32
|
+
}, [
|
|
33
|
+
canEditSheet,
|
|
34
|
+
canEditCellRange,
|
|
35
|
+
getEffectiveValue,
|
|
36
|
+
getFormattedValue,
|
|
37
|
+
onHideRow,
|
|
38
|
+
onShowRow,
|
|
39
|
+
onChangeBatch,
|
|
40
|
+
]);
|
|
41
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { CellInterface } from "@rowsncolumns/common-types";
|
|
2
|
+
import { type GoalSeekResult } from "../api/goal-seek";
|
|
3
|
+
import type { useCalculation } from "./use-calculation";
|
|
4
|
+
import type { useOnChange } from "./use-on-change";
|
|
5
|
+
import type { useSheetProperties } from "./use-sheet-properties";
|
|
6
|
+
export type { GoalSeekResult };
|
|
7
|
+
export type UseOnGoalSeekProps = {
|
|
8
|
+
getFormulaValue: ReturnType<typeof useSheetProperties>["getFormulaValue"];
|
|
9
|
+
getEffectiveValue: ReturnType<typeof useSheetProperties>["getEffectiveValue"];
|
|
10
|
+
/** The calculator's scratch evaluation (UNFORMATTED results). */
|
|
11
|
+
onRequestCalculate: ReturnType<typeof useCalculation>["onRequestCalculate"];
|
|
12
|
+
getDependents: ReturnType<typeof useCalculation>["getDependents"];
|
|
13
|
+
onChange: ReturnType<typeof useOnChange>;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Excel's Goal Seek (Data → What-If Analysis): find the value of
|
|
17
|
+
* `changingCell` that makes the formula in `setCell` evaluate to
|
|
18
|
+
* `targetValue`. Every trial is a scratch evaluation — the changing cell is
|
|
19
|
+
* pinned through the calculator's override map and the formula cells between
|
|
20
|
+
* it and the set cell (its transitive dependents, in dependency order) are
|
|
21
|
+
* re-evaluated into the same map, so nothing is written until the search
|
|
22
|
+
* ends. The final value is committed through `onChange` (one undo step,
|
|
23
|
+
* streamed to any engine consumer like a typed edit).
|
|
24
|
+
*
|
|
25
|
+
* Resolves to `undefined` when the set cell holds no formula or the changing
|
|
26
|
+
* cell is protected; otherwise the {@link GoalSeekResult} — Excel reports
|
|
27
|
+
* "found a solution" / "may not have found a solution" from `status`.
|
|
28
|
+
*/
|
|
29
|
+
export declare const useOnGoalSeek: ({ getFormulaValue, getEffectiveValue, onRequestCalculate, getDependents, onChange, }: UseOnGoalSeekProps) => (sheetId: number, setCell: CellInterface, targetValue: number, changingCell: CellInterface) => Promise<GoalSeekResult | undefined>;
|
|
30
|
+
//# sourceMappingURL=use-on-goal-seek.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-on-goal-seek.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-goal-seek.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAIhE,OAAO,EAAY,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,KAAK,EAGV,cAAc,EACf,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,YAAY,EAAE,cAAc,EAAE,CAAC;AAE/B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,eAAe,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAC1E,iBAAiB,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAC9E,iEAAiE;IACjE,kBAAkB,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAC5E,aAAa,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,eAAe,CAAC,CAAC;IAClE,QAAQ,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;CAC1C,CAAC;AAUF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,aAAa,GAAI,sFAM3B,kBAAkB,eAKN,MAAM,WACN,aAAa,eACT,MAAM,gBACL,aAAa,KAC1B,OAAO,CAAC,cAAc,GAAG,SAAS,CA+DxC,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { isCellNode, makeKey } from "@rowsncolumns/dag";
|
|
2
|
+
import { useCallback } from "react";
|
|
3
|
+
import { goalSeek } from "../api/goal-seek";
|
|
4
|
+
import { useCanEditCellRange } from "./use-can-edit-cellrange";
|
|
5
|
+
/** Cap on the formula chain re-evaluated per trial (a runaway dependency fan-out). */
|
|
6
|
+
const MAX_AFFECTED_CELLS = 2000;
|
|
7
|
+
const sameCell = (a, sheetId, b) => (a.sheetId ?? sheetId) === sheetId &&
|
|
8
|
+
a.rowIndex === b.rowIndex &&
|
|
9
|
+
a.columnIndex === b.columnIndex;
|
|
10
|
+
/**
|
|
11
|
+
* Excel's Goal Seek (Data → What-If Analysis): find the value of
|
|
12
|
+
* `changingCell` that makes the formula in `setCell` evaluate to
|
|
13
|
+
* `targetValue`. Every trial is a scratch evaluation — the changing cell is
|
|
14
|
+
* pinned through the calculator's override map and the formula cells between
|
|
15
|
+
* it and the set cell (its transitive dependents, in dependency order) are
|
|
16
|
+
* re-evaluated into the same map, so nothing is written until the search
|
|
17
|
+
* ends. The final value is committed through `onChange` (one undo step,
|
|
18
|
+
* streamed to any engine consumer like a typed edit).
|
|
19
|
+
*
|
|
20
|
+
* Resolves to `undefined` when the set cell holds no formula or the changing
|
|
21
|
+
* cell is protected; otherwise the {@link GoalSeekResult} — Excel reports
|
|
22
|
+
* "found a solution" / "may not have found a solution" from `status`.
|
|
23
|
+
*/
|
|
24
|
+
export const useOnGoalSeek = ({ getFormulaValue, getEffectiveValue, onRequestCalculate, getDependents, onChange, }) => {
|
|
25
|
+
const canEditCellRange = useCanEditCellRange();
|
|
26
|
+
return useCallback(async (sheetId, setCell, targetValue, changingCell) => {
|
|
27
|
+
if (!Number.isFinite(targetValue))
|
|
28
|
+
return undefined;
|
|
29
|
+
if (!canEditCellRange(sheetId, changingCell)) {
|
|
30
|
+
console.debug("This range is protected, users cannot edit this cell range.");
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
const formula = getFormulaValue(sheetId, setCell.rowIndex, setCell.columnIndex);
|
|
34
|
+
if (!formula)
|
|
35
|
+
return undefined;
|
|
36
|
+
if (sameCell(setCell, sheetId, changingCell))
|
|
37
|
+
return undefined;
|
|
38
|
+
const changingPosition = { sheetId, ...changingCell };
|
|
39
|
+
// Formula cells downstream of the changing cell, in dependency order,
|
|
40
|
+
// minus the set cell itself (evaluated last, from the trial map).
|
|
41
|
+
const affected = [];
|
|
42
|
+
for (const node of getDependents(changingPosition)) {
|
|
43
|
+
if (!isCellNode(node))
|
|
44
|
+
continue;
|
|
45
|
+
const { position } = node;
|
|
46
|
+
if (sameCell(position, sheetId, setCell) && position.sheetId === sheetId)
|
|
47
|
+
continue;
|
|
48
|
+
if (position.conditionalFormatId != null || position.dataValidationId != null)
|
|
49
|
+
continue;
|
|
50
|
+
affected.push(position);
|
|
51
|
+
if (affected.length >= MAX_AFFECTED_CELLS)
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
const evaluate = async (trial) => {
|
|
55
|
+
const overrides = new Map([[makeKey(changingPosition), trial]]);
|
|
56
|
+
const scratch = async (text, position) => onRequestCalculate(text, position.sheetId, position.rowIndex, position.columnIndex, {
|
|
57
|
+
overrides,
|
|
58
|
+
disablePreview: true,
|
|
59
|
+
});
|
|
60
|
+
for (const position of affected) {
|
|
61
|
+
const cellFormula = getFormulaValue(position.sheetId, position.rowIndex, position.columnIndex);
|
|
62
|
+
if (!cellFormula)
|
|
63
|
+
continue;
|
|
64
|
+
const value = await scratch(cellFormula, position);
|
|
65
|
+
// An errored intermediate reads as an error in the set cell too,
|
|
66
|
+
// which the solver treats as an unusable trial.
|
|
67
|
+
overrides.set(makeKey(position), value instanceof Error ? undefined : value);
|
|
68
|
+
}
|
|
69
|
+
const result = await scratch(formula, { sheetId, ...setCell });
|
|
70
|
+
return typeof result === "number" && Number.isFinite(result) ? result : undefined;
|
|
71
|
+
};
|
|
72
|
+
const current = getEffectiveValue(sheetId, changingCell.rowIndex, changingCell.columnIndex);
|
|
73
|
+
const initialValue = typeof current === "number"
|
|
74
|
+
? current
|
|
75
|
+
: typeof current === "string" && current.trim() !== "" && Number.isFinite(Number(current))
|
|
76
|
+
? Number(current)
|
|
77
|
+
: 0;
|
|
78
|
+
const result = await goalSeek({ evaluate, targetValue, initialValue });
|
|
79
|
+
onChange(sheetId, changingCell, String(result.value), undefined);
|
|
80
|
+
return result;
|
|
81
|
+
}, [canEditCellRange, getFormulaValue, getEffectiveValue, onRequestCalculate, getDependents, onChange]);
|
|
82
|
+
};
|
|
@@ -19,6 +19,7 @@ export type UseOnImportExcelFileProps<T extends CellData, S extends Sheet> = {
|
|
|
19
19
|
onChangeCellXfs?: UseSpreadsheetProps<T, S>["onChangeCellXfs"];
|
|
20
20
|
onRequestFonts: UseSpreadsheetProps<T, S>["onRequestFonts"];
|
|
21
21
|
onChangeTheme: UseSpreadsheetProps<T, S>["onChangeTheme"];
|
|
22
|
+
onChangeNamedCellStyles?: UseSpreadsheetProps<T, S>["onChangeNamedCellStyles"];
|
|
22
23
|
onChangeSlicers: UseSpreadsheetProps<T, S>["onChangeSlicers"];
|
|
23
24
|
/**
|
|
24
25
|
* Phase D1 — pivot table import. Worker emits
|
|
@@ -39,7 +40,15 @@ export type UseOnImportExcelFileProps<T extends CellData, S extends Sheet> = {
|
|
|
39
40
|
export type ExcelImportResponse = {
|
|
40
41
|
requiresRecalc?: boolean;
|
|
41
42
|
iterativeCalculationOptions?: IterativeCalculationOptions;
|
|
43
|
+
/**
|
|
44
|
+
* Date system of the imported cell data — always the 1900 system: a
|
|
45
|
+
* `date1904` workbook is converted on import (date-formatted serials
|
|
46
|
+
* shifted by 1462 days), so this can be wired straight to
|
|
47
|
+
* `SheetCell.setUse1904` / `createExcelFile({ use1904 })`.
|
|
48
|
+
*/
|
|
42
49
|
use1904?: boolean;
|
|
50
|
+
/** The source workbook declared the 1904 date system (informational). */
|
|
51
|
+
sourceUse1904?: boolean;
|
|
43
52
|
success: boolean;
|
|
44
53
|
isPasswordProtected?: boolean;
|
|
45
54
|
};
|
|
@@ -59,7 +68,7 @@ export type ExcelImportOptions = {
|
|
|
59
68
|
*/
|
|
60
69
|
prompt?: UseSpreadsheetProps["onPrompt"];
|
|
61
70
|
};
|
|
62
|
-
export declare const useOnImportExcelFile: <T extends CellData, S extends Sheet>({ enableExcelImportHistory, onChangeSheetData, onChangeSheets, onChangeTables, onChangeEmbeds, onChangeNamedRanges, onChangeSharedStrings, onChangeConditionalFormats, onChangeDataValidations, onChangeCellXfs, onChangeCharts, onRequestFonts, onChangeTheme, onCreateDataValidationRule, onClearHistory, onChangeHistory, onChangeSlicers, onChangePivotTables, evaluateConditionalFormatting, evaluateDataValidations, clearRangeCache, onConfirm, onPrompt, }: UseOnImportExcelFileProps<T, S>) => {
|
|
71
|
+
export declare const useOnImportExcelFile: <T extends CellData, S extends Sheet>({ enableExcelImportHistory, onChangeSheetData, onChangeSheets, onChangeTables, onChangeEmbeds, onChangeNamedRanges, onChangeSharedStrings, onChangeConditionalFormats, onChangeDataValidations, onChangeCellXfs, onChangeCharts, onRequestFonts, onChangeTheme, onChangeNamedCellStyles, onCreateDataValidationRule, onClearHistory, onChangeHistory, onChangeSlicers, onChangePivotTables, evaluateConditionalFormatting, evaluateDataValidations, clearRangeCache, onConfirm, onPrompt, }: UseOnImportExcelFileProps<T, S>) => {
|
|
63
72
|
importExcelFile: (file: File | ArrayBuffer, options?: ExcelImportOptions) => Promise<ExcelImportResponse>;
|
|
64
73
|
isImportingExcelfile: boolean;
|
|
65
74
|
generateStatePatches: () => Promise<SpreadsheetPatch>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-on-import-excel.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-import-excel.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"use-on-import-excel.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-import-excel.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,7 @@ import { produce, produceWithPatches } from "immer";
|
|
|
5
5
|
import { useCallback, useState } from "react";
|
|
6
6
|
import { SheetCell } from "../sheet-cell";
|
|
7
7
|
const TIMEOUT_FONT_LOAD = 5000;
|
|
8
|
-
export const useOnImportExcelFile = ({ enableExcelImportHistory = false, onChangeSheetData, onChangeSheets, onChangeTables, onChangeEmbeds, onChangeNamedRanges, onChangeSharedStrings, onChangeConditionalFormats, onChangeDataValidations, onChangeCellXfs, onChangeCharts, onRequestFonts, onChangeTheme, onCreateDataValidationRule, onClearHistory, onChangeHistory, onChangeSlicers, onChangePivotTables, evaluateConditionalFormatting, evaluateDataValidations, clearRangeCache, onConfirm, onPrompt, }) => {
|
|
8
|
+
export const useOnImportExcelFile = ({ enableExcelImportHistory = false, onChangeSheetData, onChangeSheets, onChangeTables, onChangeEmbeds, onChangeNamedRanges, onChangeSharedStrings, onChangeConditionalFormats, onChangeDataValidations, onChangeCellXfs, onChangeCharts, onRequestFonts, onChangeTheme, onChangeNamedCellStyles, onCreateDataValidationRule, onClearHistory, onChangeHistory, onChangeSlicers, onChangePivotTables, evaluateConditionalFormatting, evaluateDataValidations, clearRangeCache, onConfirm, onPrompt, }) => {
|
|
9
9
|
const [isImportingExcelfile, setIsImporting] = useState(false);
|
|
10
10
|
const [showLoader, hideLoader] = useLoadingIndicator();
|
|
11
11
|
const getViewPort = useGetViewPort();
|
|
@@ -229,7 +229,7 @@ export const useOnImportExcelFile = ({ enableExcelImportHistory = false, onChang
|
|
|
229
229
|
const { observable, sendMessage } = createExcelImportWorker(file, minRowCount, minColumnCount);
|
|
230
230
|
let requiresRecalc = false;
|
|
231
231
|
let iterativeCalculationOptions;
|
|
232
|
-
let
|
|
232
|
+
let sourceUse1904 = false;
|
|
233
233
|
let isPromptingForPassword = false;
|
|
234
234
|
let isPasswordProtected = false;
|
|
235
235
|
// Set import
|
|
@@ -345,7 +345,7 @@ export const useOnImportExcelFile = ({ enableExcelImportHistory = false, onChang
|
|
|
345
345
|
requiresRecalc = response.requiresRecalc ?? false;
|
|
346
346
|
iterativeCalculationOptions =
|
|
347
347
|
response.iterativeCalculationOptions ?? undefined;
|
|
348
|
-
|
|
348
|
+
sourceUse1904 = response.use1904 ?? false;
|
|
349
349
|
}
|
|
350
350
|
if (response.responseType === ResponseType.GET_SHEETS_SUCCESS) {
|
|
351
351
|
onChangeSheets(response.sheets);
|
|
@@ -357,6 +357,9 @@ export const useOnImportExcelFile = ({ enableExcelImportHistory = false, onChang
|
|
|
357
357
|
if (response.theme) {
|
|
358
358
|
onChangeTheme?.(response.theme);
|
|
359
359
|
}
|
|
360
|
+
if (response.namedCellStyles) {
|
|
361
|
+
onChangeNamedCellStyles?.(response.namedCellStyles);
|
|
362
|
+
}
|
|
360
363
|
}
|
|
361
364
|
if (response.responseType === ResponseType.GET_CONDITIONAL_FORMATTING) {
|
|
362
365
|
showLoader("Loading conditional formatting");
|
|
@@ -555,7 +558,8 @@ export const useOnImportExcelFile = ({ enableExcelImportHistory = false, onChang
|
|
|
555
558
|
resolve({
|
|
556
559
|
requiresRecalc,
|
|
557
560
|
iterativeCalculationOptions,
|
|
558
|
-
use1904,
|
|
561
|
+
use1904: false,
|
|
562
|
+
sourceUse1904,
|
|
559
563
|
success: true,
|
|
560
564
|
isPasswordProtected,
|
|
561
565
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-on-merge-unmerge-cells.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-merge-unmerge-cells.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAGL,SAAS,EAGV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,QAAQ,EACR,mBAAmB,EACnB,KAAK,EACN,MAAM,2BAA2B,CAAC;AAOnC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAO9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,KAAK,2BAA2B,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,IAAI;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAC5B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACzD,iBAAiB,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAC/D,cAAc,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAC5D,kBAAkB,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAC3E,kBAAkB,EAAE,CAAC,SAAS,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC9D,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,iKAWzE,2BAA2B,CAAC,CAAC,EAAE,CAAC,CAAC;4BASrB,MAAM,cACH,aAAa,cACb,aAAa,CAAC,mBAAmB,CAAC,EAAE,cACpC,SAAS;
|
|
1
|
+
{"version":3,"file":"use-on-merge-unmerge-cells.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-merge-unmerge-cells.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAGL,SAAS,EAGV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EACV,QAAQ,EACR,mBAAmB,EACnB,KAAK,EACN,MAAM,2BAA2B,CAAC;AAOnC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAO9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,KAAK,2BAA2B,CAAC,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,IAAI;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IAC5B,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACzD,iBAAiB,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAC/D,cAAc,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAC5D,kBAAkB,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAC3E,kBAAkB,EAAE,CAAC,SAAS,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAC9D,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,iKAWzE,2BAA2B,CAAC,CAAC,EAAE,CAAC,CAAC;4BASrB,MAAM,cACH,aAAa,cACb,aAAa,CAAC,mBAAmB,CAAC,EAAE,cACpC,SAAS;8BAqRZ,MAAM,cACH,aAAa,qBACN,aAAa,CAAC,mBAAmB,CAAC,EAAE;CA4I5D,CAAC"}
|
|
@@ -51,6 +51,13 @@ export const useOnMergeUnMergeCells = ({ locale, merges, cellXfsRegistry, shared
|
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
|
+
else if (selections.length > 1) {
|
|
55
|
+
// A multi-area selection merges each area on its own (Excel's Merge & Center on a
|
|
56
|
+
// Ctrl-selection). The format painter tiles a source block's merges through this path.
|
|
57
|
+
for (const sel of selections) {
|
|
58
|
+
newMerges.push(sel.range);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
54
61
|
else {
|
|
55
62
|
newMerges.push(range);
|
|
56
63
|
}
|
|
@@ -136,22 +143,15 @@ export const useOnMergeUnMergeCells = ({ locale, merges, cellXfsRegistry, shared
|
|
|
136
143
|
// Keep track of master cells
|
|
137
144
|
// Merging cells only keeps the upper-left value and discards other values.
|
|
138
145
|
const masterCells = new Set();
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
masterCells.add(cellIdentifier(rowIndex, range.startColumnIndex));
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
else if (direction === Direction.Down) {
|
|
145
|
-
for (let columnIndex = range.startColumnIndex; columnIndex <= range.endColumnIndex; columnIndex++) {
|
|
146
|
-
masterCells.add(cellIdentifier(range.startRowIndex, columnIndex));
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
masterCells.add(cellIdentifier(range.startRowIndex, range.startColumnIndex));
|
|
146
|
+
for (const merge of newMerges) {
|
|
147
|
+
masterCells.add(cellIdentifier(merge.startRowIndex, merge.startColumnIndex));
|
|
151
148
|
}
|
|
152
149
|
// Create a cell
|
|
153
150
|
const sheetCell = new SheetCell();
|
|
154
|
-
|
|
151
|
+
const mergedCells = newMerges.flatMap((merge) => [
|
|
152
|
+
...iterateCellsInRange(merge),
|
|
153
|
+
]);
|
|
154
|
+
for (const [rowIndex, columnIndex] of mergedCells) {
|
|
155
155
|
const cellId = cellIdentifier(rowIndex, columnIndex);
|
|
156
156
|
if (masterCells.has(cellId)) {
|
|
157
157
|
continue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-on-paste.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-paste.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EACV,aAAa,EAEb,aAAa,EACd,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EACV,QAAQ,EACR,wBAAwB,
|
|
1
|
+
{"version":3,"file":"use-on-paste.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-paste.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,7 @@ import { useCallback } from "react";
|
|
|
9
9
|
import { processSideEffectDependentCells } from "../api/dependency";
|
|
10
10
|
import { createSheetCellIdentifier } from "../api/formula";
|
|
11
11
|
import { createSheetDraft } from "../api/immer-utils";
|
|
12
|
+
import { applyPasteOperation, isBlankClipboardCell, resolvePasteSpecialOptions, } from "../api/paste-special";
|
|
12
13
|
import { findAdjacentTable, findTableColumnIndex } from "../api/table";
|
|
13
14
|
import { addCalculatedColumnsForRowExpansion } from "../interface/change-table-column";
|
|
14
15
|
import { collectDataValidationTarget, extendDataValidationRanges, } from "../interface/data-validation-utils";
|
|
@@ -62,7 +63,11 @@ export const useOnPaste = ({ rowCount, columnCount, locale, sheetData, tables: c
|
|
|
62
63
|
const getFinalRowHeight = useGetFinalRowHeight();
|
|
63
64
|
const { enqueue, processQueue } = useCalculationQueue({ enqueueCalculation });
|
|
64
65
|
return useCallback(async (e, sourceSheetId, destinationSheetId, copiedSelections, activeCell, selections, finalSelections, isCutOperation) => {
|
|
65
|
-
|
|
66
|
+
// Paste Special request (values / formats / formulas, operation, skip
|
|
67
|
+
// blanks, transpose) stashed on the event by the grid's `paste()`.
|
|
68
|
+
const pasteSpecial = resolvePasteSpecialOptions(e?.clipboardData);
|
|
69
|
+
const pasteMode = pasteSpecial.paste;
|
|
70
|
+
const pasteOperation = pasteSpecial.operation;
|
|
66
71
|
const pasteEvent = e;
|
|
67
72
|
const forcePlainText = Boolean(pasteEvent?.__forcePlainText ||
|
|
68
73
|
(pasteEvent?.shiftKey &&
|
|
@@ -104,16 +109,16 @@ export const useOnPaste = ({ rowCount, columnCount, locale, sheetData, tables: c
|
|
|
104
109
|
if (isNil(selectedRowValues)) {
|
|
105
110
|
return;
|
|
106
111
|
}
|
|
107
|
-
if (
|
|
112
|
+
if (pasteSpecial.transpose && selectedRowValues.length) {
|
|
108
113
|
selectedRowValues = transpose(selectedRowValues);
|
|
109
114
|
}
|
|
110
|
-
|
|
115
|
+
if (pasteMode === "formats") {
|
|
111
116
|
selectedRowValues = pickFormatting(selectedRowValues);
|
|
112
117
|
}
|
|
113
|
-
else if (
|
|
118
|
+
else if (pasteMode === "formulas") {
|
|
114
119
|
selectedRowValues = pickFormula(selectedRowValues, destinationSheetId, locale);
|
|
115
120
|
}
|
|
116
|
-
else if (
|
|
121
|
+
else if (pasteMode === "values") {
|
|
117
122
|
selectedRowValues = pickValue(selectedRowValues, destinationSheetId, locale);
|
|
118
123
|
}
|
|
119
124
|
const saveHistory = createHistory();
|
|
@@ -362,19 +367,50 @@ export const useOnPaste = ({ rowCount, columnCount, locale, sheetData, tables: c
|
|
|
362
367
|
for (let columnIndex = to.range.startColumnIndex; columnIndex <= to.range.endColumnIndex; columnIndex++, columnCursor++) {
|
|
363
368
|
const dataColumnIndex = colSpan > 0 ? columnCursor % colSpan : 0;
|
|
364
369
|
let cellValue = selectedRowValues[dataRowIndex]?.[dataColumnIndex];
|
|
365
|
-
|
|
370
|
+
// Skip blanks: an empty clipboard cell leaves the
|
|
371
|
+
// destination (value and format) untouched.
|
|
372
|
+
if (pasteSpecial.skipBlanks &&
|
|
373
|
+
isBlankClipboardCell(cellValue)) {
|
|
374
|
+
continue;
|
|
375
|
+
}
|
|
376
|
+
// Operation: combine the pasted cell with the cell it
|
|
377
|
+
// lands on. The clipboard is anchored at the FIRST tile,
|
|
378
|
+
// so a source formula is relocated to the tile it lands
|
|
379
|
+
// on first (the same `moveFormula` shift the plain paste
|
|
380
|
+
// applies below); the composed `=(dest)op(source)` is
|
|
381
|
+
// then anchored at the destination and must not be moved
|
|
382
|
+
// again (that would shift the destination fragment too).
|
|
383
|
+
if (pasteOperation) {
|
|
384
|
+
const sourceFormula = getExtendedValueFormula(getCellUserEnteredValue(cellValue));
|
|
385
|
+
if (!isNil(sourceFormula) &&
|
|
386
|
+
dataRowIndex === 0 &&
|
|
387
|
+
dataColumnIndex === 0 &&
|
|
388
|
+
(rowIndex !== sourceCell.rowIndex ||
|
|
389
|
+
columnIndex !== sourceCell.columnIndex)) {
|
|
390
|
+
const tileCell = new SheetCell();
|
|
391
|
+
tileCell.setLocale(locale);
|
|
392
|
+
tileCell.assign(destinationSheetId, sourceCell, cellValue);
|
|
393
|
+
tileCell.moveFormula(sourceCell, { rowIndex, columnIndex }, activeSheetName, { preserveAbsolutes: true });
|
|
394
|
+
cellValue = {
|
|
395
|
+
...cellValue,
|
|
396
|
+
ue: { ...cellValue?.ue, fv: tileCell.formula },
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
cellValue = applyPasteOperation(cellValue, prevSheetData[destinationSheetId]?.[rowIndex]?.values?.[columnIndex], pasteOperation, destinationSheetId, locale);
|
|
400
|
+
}
|
|
401
|
+
if (pasteMode === "formats") {
|
|
366
402
|
const existingCellData = prevSheetData[destinationSheetId]?.[rowIndex]?.values?.[columnIndex];
|
|
367
403
|
cellValue = { ...existingCellData, ...cellValue };
|
|
368
404
|
sheetCell.extendCellData(cellValue);
|
|
369
405
|
}
|
|
370
|
-
if (
|
|
406
|
+
if (pasteMode === "values" || forcePlainText) {
|
|
371
407
|
const existingCellData = prevSheetData[destinationSheetId]?.[rowIndex]?.values?.[columnIndex];
|
|
372
408
|
// Remove ss from existingCellData since we're replacing the value
|
|
373
409
|
const { ss: _ss, ...existingWithoutSs } = existingCellData ?? {};
|
|
374
410
|
cellValue = { ...existingWithoutSs, ...cellValue };
|
|
375
411
|
sheetCell.extendCellData(cellValue);
|
|
376
412
|
}
|
|
377
|
-
if (
|
|
413
|
+
if (pasteSpecial.transpose && pasteMode === "all") {
|
|
378
414
|
sheetCell.assign(destinationSheetId, { rowIndex, columnIndex }, prevSheetData[destinationSheetId]?.[rowIndex]?.values?.[columnIndex], {
|
|
379
415
|
locale,
|
|
380
416
|
cellXfsRegistry,
|
|
@@ -396,11 +432,13 @@ export const useOnPaste = ({ rowCount, columnCount, locale, sheetData, tables: c
|
|
|
396
432
|
sharedStringRegistry,
|
|
397
433
|
});
|
|
398
434
|
}
|
|
399
|
-
if (
|
|
435
|
+
if (pasteMode === "formats") {
|
|
400
436
|
sheetCell.refreshFormattedValue();
|
|
401
437
|
}
|
|
402
438
|
if (sheetCell.isFormula()) {
|
|
403
|
-
if (dataRowIndex === 0 &&
|
|
439
|
+
if (dataRowIndex === 0 &&
|
|
440
|
+
dataColumnIndex === 0 &&
|
|
441
|
+
!pasteOperation) {
|
|
404
442
|
sheetCell.moveFormula(sourceCell, {
|
|
405
443
|
rowIndex,
|
|
406
444
|
columnIndex,
|
|
@@ -544,10 +582,7 @@ export const useOnPaste = ({ rowCount, columnCount, locale, sheetData, tables: c
|
|
|
544
582
|
// Skipped for paste-special variants since the destination
|
|
545
583
|
// cell ends up as a merge of existing + pasted data, not
|
|
546
584
|
// the raw pasted value we can read from selectedRowValues.
|
|
547
|
-
const skipAutoResize =
|
|
548
|
-
pasteSpecialType === "Value" ||
|
|
549
|
-
pasteSpecialType === "Formula" ||
|
|
550
|
-
pasteSpecialType === "Transposed";
|
|
585
|
+
const skipAutoResize = pasteSpecial.isSpecial;
|
|
551
586
|
if (!skipAutoResize &&
|
|
552
587
|
getFinalRowHeight &&
|
|
553
588
|
selectedRowValues.length &&
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CellInterface, SelectionArea } from "@rowsncolumns/common-types";
|
|
2
2
|
import type { CellData, SelectionAttributes, Sheet } from "@rowsncolumns/spreadsheet";
|
|
3
|
+
import { type RemoveDuplicatesOptions } from "../interface/remove-duplicates";
|
|
3
4
|
import type { useCalculation } from "./use-calculation";
|
|
4
5
|
import type { useSheetProperties } from "./use-sheet-properties";
|
|
5
6
|
import type { UseSpreadsheetProps } from "./use-spreadsheet-state";
|
|
@@ -17,5 +18,5 @@ export type UseOnRemoveDuplicatesProps<T extends CellData> = {
|
|
|
17
18
|
onChangeSheetData: UseSpreadsheetProps<T, Sheet>["onChangeSheetData"];
|
|
18
19
|
onCommand?: OnCommand;
|
|
19
20
|
};
|
|
20
|
-
export declare const useOnRemoveDuplicates: <T extends CellData>({ locale, cellXfsRegistry, sharedStringRegistry, getFormattedValue, onChangeSheetData, enqueueCalculation, createHistory, onCommand, }: UseOnRemoveDuplicatesProps<T>) => (sheetId: number, activeCell: CellInterface, selections?: SelectionArea<SelectionAttributes>[]) => import("../interface/remove-duplicates").RemoveDuplicatesResult | undefined;
|
|
21
|
+
export declare const useOnRemoveDuplicates: <T extends CellData>({ locale, cellXfsRegistry, sharedStringRegistry, getFormattedValue, onChangeSheetData, enqueueCalculation, createHistory, onCommand, }: UseOnRemoveDuplicatesProps<T>) => (sheetId: number, activeCell: CellInterface, selections?: SelectionArea<SelectionAttributes>[], options?: RemoveDuplicatesOptions) => import("../interface/remove-duplicates").RemoveDuplicatesResult | undefined;
|
|
21
22
|
//# sourceMappingURL=use-on-remove-duplicates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-on-remove-duplicates.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-remove-duplicates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,KAAK,EACV,QAAQ,EACR,mBAAmB,EACnB,KAAK,EACN,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"use-on-remove-duplicates.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-remove-duplicates.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,KAAK,EACV,QAAQ,EACR,mBAAmB,EACnB,KAAK,EACN,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,gCAAgC,CAAC;AAExC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,MAAM,MAAM,0BAA0B,CAAC,CAAC,SAAS,QAAQ,IAAI;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,iBAAiB,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAC9E,kBAAkB,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,oBAAoB,CAAC,CAAC;IAC5E,aAAa,EAAE,MAAM,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACzD,iBAAiB,EAAE,mBAAmB,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,mBAAmB,CAAC,CAAC;IACtE,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,QAAQ,EAAE,wIASvD,0BAA0B,CAAC,CAAC,CAAC,eAKjB,MAAM,cACH,aAAa,eACZ,aAAa,CAAC,mBAAmB,CAAC,EAAE,YACvC,uBAAuB,gFA2CtC,CAAC"}
|