@rowsncolumns/spreadsheet 10.5.14 → 10.5.16

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.
Files changed (37) hide show
  1. package/dist/cjs/api/validation.d.ts.map +1 -1
  2. package/dist/cjs/api/validation.js +8 -3
  3. package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
  4. package/dist/cjs/components/canvas-grid/index.js +46 -8
  5. package/dist/cjs/components/canvas-grid/typings.d.ts +11 -0
  6. package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
  7. package/dist/cjs/components/cell-editor/index.d.ts.map +1 -1
  8. package/dist/cjs/components/cell-editor/index.js +7 -5
  9. package/dist/cjs/helpers.d.ts +9 -0
  10. package/dist/cjs/helpers.d.ts.map +1 -1
  11. package/dist/cjs/helpers.js +15 -1
  12. package/dist/cjs/hooks/use-editor-submit.d.ts +3 -2
  13. package/dist/cjs/hooks/use-editor-submit.d.ts.map +1 -1
  14. package/dist/cjs/hooks/use-editor-submit.js +30 -20
  15. package/dist/cjs/hooks/use-get-values-from-range.d.ts +6 -1
  16. package/dist/cjs/hooks/use-get-values-from-range.d.ts.map +1 -1
  17. package/dist/cjs/hooks/use-get-values-from-range.js +89 -77
  18. package/dist/cjs/release-date.js +1 -1
  19. package/dist/esm/api/validation.d.ts.map +1 -1
  20. package/dist/esm/api/validation.js +10 -5
  21. package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
  22. package/dist/esm/components/canvas-grid/index.js +45 -7
  23. package/dist/esm/components/canvas-grid/typings.d.ts +11 -0
  24. package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
  25. package/dist/esm/components/cell-editor/index.d.ts.map +1 -1
  26. package/dist/esm/components/cell-editor/index.js +9 -7
  27. package/dist/esm/helpers.d.ts +9 -0
  28. package/dist/esm/helpers.d.ts.map +1 -1
  29. package/dist/esm/helpers.js +9 -0
  30. package/dist/esm/hooks/use-editor-submit.d.ts +3 -2
  31. package/dist/esm/hooks/use-editor-submit.d.ts.map +1 -1
  32. package/dist/esm/hooks/use-editor-submit.js +5 -1
  33. package/dist/esm/hooks/use-get-values-from-range.d.ts +6 -1
  34. package/dist/esm/hooks/use-get-values-from-range.d.ts.map +1 -1
  35. package/dist/esm/hooks/use-get-values-from-range.js +70 -41
  36. package/dist/esm/release-date.js +1 -1
  37. package/package.json +2 -2
@@ -101,10 +101,10 @@ var useEditorSubmit = function (_a) {
101
101
  var selectionsRef = (0, react_1.useRef)(selections);
102
102
  selectionsRef.current = selections;
103
103
  return (0, react_1.useCallback)(function (value, textFormatRuns, previousValue, editingSheetId, activeCell, nextActiveCell, isDirty, options) { return tslib_1.__awaiter(void 0, void 0, void 0, function () {
104
- var resetEditorState, commit, enforcement, decision, alert_1, request, proceed, _a;
105
- var _b, _c;
106
- return tslib_1.__generator(this, function (_d) {
107
- switch (_d.label) {
104
+ var resetEditorState, commit, pending_1, enforcement, _a, decision, alert_1, request, proceed, _b;
105
+ var _c, _d;
106
+ return tslib_1.__generator(this, function (_e) {
107
+ switch (_e.label) {
108
108
  case 0:
109
109
  /* Balance parentheses */
110
110
  if (formulaMode && typeof value !== "boolean") {
@@ -178,14 +178,24 @@ var useEditorSubmit = function (_a) {
178
178
  }
179
179
  resetEditorState();
180
180
  };
181
- if (!(value !== previousValue && getCommitValidation)) return [3 /*break*/, 4];
182
- enforcement = getCommitValidation(editingSheetId, activeCell.rowIndex, activeCell.columnIndex, value, previousValue);
183
- if (!enforcement) return [3 /*break*/, 4];
181
+ if (!(value !== previousValue && getCommitValidation)) return [3 /*break*/, 7];
182
+ pending_1 = getCommitValidation(editingSheetId, activeCell.rowIndex, activeCell.columnIndex, value, previousValue);
183
+ if (!(pending_1 instanceof Promise)) return [3 /*break*/, 2];
184
+ return [4 /*yield*/, pending_1];
185
+ case 1:
186
+ _a = _e.sent();
187
+ return [3 /*break*/, 3];
188
+ case 2:
189
+ _a = pending_1;
190
+ _e.label = 3;
191
+ case 3:
192
+ enforcement = _a;
193
+ if (!enforcement) return [3 /*break*/, 7];
184
194
  decision = enforcement.decision, alert_1 = enforcement.alert;
185
195
  request = {
186
196
  style: alert_1.style,
187
- title: (_b = alert_1.message) === null || _b === void 0 ? void 0 : _b.title,
188
- message: (_c = alert_1.message) === null || _c === void 0 ? void 0 : _c.message,
197
+ title: (_c = alert_1.message) === null || _c === void 0 ? void 0 : _c.title,
198
+ message: (_d = alert_1.message) === null || _d === void 0 ? void 0 : _d.message,
189
199
  confirm: decision === "confirm",
190
200
  };
191
201
  if (decision === "block") {
@@ -194,22 +204,22 @@ var useEditorSubmit = function (_a) {
194
204
  void (showValidationAlert === null || showValidationAlert === void 0 ? void 0 : showValidationAlert(request));
195
205
  return [2 /*return*/];
196
206
  }
197
- if (!showValidationAlert) return [3 /*break*/, 2];
207
+ if (!showValidationAlert) return [3 /*break*/, 5];
198
208
  return [4 /*yield*/, showValidationAlert(request)];
199
- case 1:
200
- _a = _d.sent();
201
- return [3 /*break*/, 3];
202
- case 2:
203
- _a = true;
204
- _d.label = 3;
205
- case 3:
206
- proceed = _a;
209
+ case 4:
210
+ _b = _e.sent();
211
+ return [3 /*break*/, 6];
212
+ case 5:
213
+ _b = true;
214
+ _e.label = 6;
215
+ case 6:
216
+ proceed = _b;
207
217
  if (!proceed) {
208
218
  resetEditorState();
209
219
  return [2 /*return*/];
210
220
  }
211
- _d.label = 4;
212
- case 4:
221
+ _e.label = 7;
222
+ case 7:
213
223
  commit();
214
224
  return [2 /*return*/];
215
225
  }
@@ -32,6 +32,11 @@ type UseGetValuesFromRangeProps<T extends CellData> = {
32
32
  * `CanvasGridProps["getValidationSourceValue"]`. Defaults to `getFormattedValue`.
33
33
  */
34
34
  getValidationSourceValue?: CanvasGridProps["getValidationSourceValue"];
35
+ /**
36
+ * Optional engine-side resolver for the list sources the tokenizer cannot resolve — see
37
+ * `CanvasGridProps["resolveValidationSourceValues"]`.
38
+ */
39
+ resolveValidationSourceValues?: CanvasGridProps["resolveValidationSourceValues"];
35
40
  };
36
41
  /**
37
42
  * Get all user entered values from a range
@@ -39,6 +44,6 @@ type UseGetValuesFromRangeProps<T extends CellData> = {
39
44
  * @param param0
40
45
  * @returns
41
46
  */
42
- export declare const useGetValuesFromRange: <T extends CellData>({ sheetId, getFormattedValue, getValidationValue, getSheetId, getSelectionsFromFormula, onRequestCalculate, getValidationSourceValue, }: UseGetValuesFromRangeProps<T>) => readonly [(address: string) => ConditionValue[], (address: string) => ConditionValue[], (address: string, rowIndex: number, columnIndex: number, targetSheetId?: number) => Promise<ConditionValue[]>];
47
+ export declare const useGetValuesFromRange: <T extends CellData>({ sheetId, getFormattedValue, getValidationValue, getSheetId, getSelectionsFromFormula, onRequestCalculate, getValidationSourceValue, resolveValidationSourceValues, }: UseGetValuesFromRangeProps<T>) => readonly [(address: string) => ConditionValue[], (address: string) => ConditionValue[], (address: string, rowIndex: number, columnIndex: number, targetSheetId?: number) => Promise<ConditionValue[]>];
43
48
  export {};
44
49
  //# sourceMappingURL=use-get-values-from-range.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-get-values-from-range.d.ts","sourceRoot":"","sources":["../../../hooks/use-get-values-from-range.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAIxD,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACpB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EACV,QAAQ,EACR,qBAAqB,EACrB,cAAc,EACd,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAGlB,KAAK,0BAA0B,CAAC,CAAC,SAAS,QAAQ,IAAI;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,iBAAiB,CACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,SAAS,CAAC;IACtB;;;;;;OAMG;IACH,kBAAkB,EAAE,CAClB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,qBAAqB,KACzB,mBAAmB,CAAC;IACzB;;;OAGG;IACH,wBAAwB,CACtB,OAAO,EAAE,MAAM,GACd,aAAa,CAAC,mBAAmB,CAAC,EAAE,CAAC;IACxC;;OAEG;IACH,UAAU,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAC1C,kBAAkB,CAAC,EAAE,eAAe,CAAC,oBAAoB,CAAC,CAAC;IAC3D;;;OAGG;IACH,wBAAwB,CAAC,EAAE,eAAe,CAAC,0BAA0B,CAAC,CAAC;CACxE,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,QAAQ,EAAE,yIAQvD,0BAA0B,CAAC,CAAC,CAAC,yBAqDhB,MAAM,KAAG,cAAc,EAAE,YASzB,MAAM,KAAG,cAAc,EAAE,YAUxB,MAAM,YACL,MAAM,eACH,MAAM,kBACJ,MAAM,KACpB,OAAO,CAAC,cAAc,EAAE,CAAC,CA4EjC,CAAC"}
1
+ {"version":3,"file":"use-get-values-from-range.d.ts","sourceRoot":"","sources":["../../../hooks/use-get-values-from-range.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAIxD,OAAO,KAAK,EACV,eAAe,EACf,mBAAmB,EACpB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EACV,QAAQ,EACR,qBAAqB,EACrB,cAAc,EACd,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAGlB,KAAK,0BAA0B,CAAC,CAAC,SAAS,QAAQ,IAAI;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,iBAAiB,CACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,SAAS,CAAC;IACtB;;;;;;OAMG;IACH,kBAAkB,EAAE,CAClB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,qBAAqB,KACzB,mBAAmB,CAAC;IACzB;;;OAGG;IACH,wBAAwB,CACtB,OAAO,EAAE,MAAM,GACd,aAAa,CAAC,mBAAmB,CAAC,EAAE,CAAC;IACxC;;OAEG;IACH,UAAU,EAAE,eAAe,CAAC,YAAY,CAAC,CAAC;IAC1C,kBAAkB,CAAC,EAAE,eAAe,CAAC,oBAAoB,CAAC,CAAC;IAC3D;;;OAGG;IACH,wBAAwB,CAAC,EAAE,eAAe,CAAC,0BAA0B,CAAC,CAAC;IACvE;;;OAGG;IACH,6BAA6B,CAAC,EAAE,eAAe,CAAC,+BAA+B,CAAC,CAAC;CAClF,CAAC;AA0BF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,QAAQ,EAAE,wKASvD,0BAA0B,CAAC,CAAC,CAAC,yBAqDhB,MAAM,KAAG,cAAc,EAAE,YASzB,MAAM,KAAG,cAAc,EAAE,YAoBxB,MAAM,YACL,MAAM,eACH,MAAM,kBACJ,MAAM,KACpB,OAAO,CAAC,cAAc,EAAE,CAAC,CAkFjC,CAAC"}
@@ -5,6 +5,38 @@ var tslib_1 = require("tslib");
5
5
  var utils_1 = require("@rowsncolumns/utils");
6
6
  var react_1 = require("react");
7
7
  var use_callback_ref_1 = require("./use-callback-ref");
8
+ /**
9
+ * The reference / array functions the LEGACY calculator previews as an array through
10
+ * `onRequestCalculate(…, { isArray: true })` — the only sources it can resolve beyond plain
11
+ * ranges. The engine resolver (`resolveValidationSourceValues`) takes any function call.
12
+ */
13
+ var LEGACY_CALC_SOURCE = /(OFFSET|INDIRECT|FILTER|UNIQUE|SORT|SEQUENCE)\s*\(/i;
14
+ /** Any function call — `OFFSET(`, `INDEX(`, `_xlfn.XLOOKUP(`, `CHOOSE(` — in a list source. */
15
+ var FUNCTION_CALL = /[A-Z_\\][A-Z0-9_.]*\s*\(/i;
16
+ /**
17
+ * Dropdown options from a resolver's display texts: blanks dropped, duplicates collapsed,
18
+ * first-seen order kept — the same shape `getValuesFromRange` builds from cells.
19
+ */
20
+ var conditionValuesFromTexts = function (texts) {
21
+ var e_1, _a;
22
+ var userEnteredValues = new Map();
23
+ try {
24
+ for (var texts_1 = tslib_1.__values(texts), texts_1_1 = texts_1.next(); !texts_1_1.done; texts_1_1 = texts_1.next()) {
25
+ var userEnteredValue = texts_1_1.value;
26
+ if (userEnteredValue) {
27
+ userEnteredValues.set(userEnteredValue, { userEnteredValue: userEnteredValue });
28
+ }
29
+ }
30
+ }
31
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
32
+ finally {
33
+ try {
34
+ if (texts_1_1 && !texts_1_1.done && (_a = texts_1.return)) _a.call(texts_1);
35
+ }
36
+ finally { if (e_1) throw e_1.error; }
37
+ }
38
+ return tslib_1.__spreadArray([], tslib_1.__read(userEnteredValues.values()), false);
39
+ };
8
40
  /**
9
41
  * Get all user entered values from a range
10
42
  * used in data validation
@@ -12,13 +44,13 @@ var use_callback_ref_1 = require("./use-callback-ref");
12
44
  * @returns
13
45
  */
14
46
  var useGetValuesFromRange = function (_a) {
15
- var sheetId = _a.sheetId, getFormattedValue = _a.getFormattedValue, getValidationValue = _a.getValidationValue, getSheetId = _a.getSheetId, getSelectionsFromFormula = _a.getSelectionsFromFormula, onRequestCalculate = _a.onRequestCalculate, getValidationSourceValue = _a.getValidationSourceValue;
47
+ var sheetId = _a.sheetId, getFormattedValue = _a.getFormattedValue, getValidationValue = _a.getValidationValue, getSheetId = _a.getSheetId, getSelectionsFromFormula = _a.getSelectionsFromFormula, onRequestCalculate = _a.onRequestCalculate, getValidationSourceValue = _a.getValidationSourceValue, resolveValidationSourceValues = _a.resolveValidationSourceValues;
16
48
  // Windowed hosts supply an off-window-safe reader for validation source ranges
17
49
  // (dropdown options + commit checks) — the plain `getFormattedValue` only sees the
18
50
  // loaded viewport there. Defaults to `getFormattedValue`.
19
51
  var readSourceValue = getValidationSourceValue !== null && getValidationSourceValue !== void 0 ? getValidationSourceValue : getFormattedValue;
20
52
  var getValuesFromRange = (0, react_1.useCallback)(function (address, callback) {
21
- var e_1, _a, e_2, _b;
53
+ var e_2, _a, e_3, _b;
22
54
  var _c;
23
55
  var selections = getSelectionsFromFormula(address);
24
56
  var userEnteredValues = new Map();
@@ -30,7 +62,7 @@ var useGetValuesFromRange = function (_a) {
30
62
  ? (_c = getSheetId === null || getSheetId === void 0 ? void 0 : getSheetId(sheetName)) !== null && _c !== void 0 ? _c : sheetId
31
63
  : sheetId;
32
64
  try {
33
- for (var _e = (e_2 = void 0, tslib_1.__values((0, utils_1.iterateCells)(startRowIndex, endColumnIndex, endRowIndex, startColumnIndex))), _f = _e.next(); !_f.done; _f = _e.next()) {
65
+ for (var _e = (e_3 = void 0, tslib_1.__values((0, utils_1.iterateCells)(startRowIndex, endColumnIndex, endRowIndex, startColumnIndex))), _f = _e.next(); !_f.done; _f = _e.next()) {
34
66
  var _g = tslib_1.__read(_f.value, 2), rowIndex = _g[0], columnIndex = _g[1];
35
67
  var userEnteredValue = callback(selectedSheetId, rowIndex, columnIndex);
36
68
  if (userEnteredValue) {
@@ -40,21 +72,21 @@ var useGetValuesFromRange = function (_a) {
40
72
  }
41
73
  }
42
74
  }
43
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
75
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
44
76
  finally {
45
77
  try {
46
78
  if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
47
79
  }
48
- finally { if (e_2) throw e_2.error; }
80
+ finally { if (e_3) throw e_3.error; }
49
81
  }
50
82
  }
51
83
  }
52
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
84
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
53
85
  finally {
54
86
  try {
55
87
  if (selections_1_1 && !selections_1_1.done && (_a = selections_1.return)) _a.call(selections_1);
56
88
  }
57
- finally { if (e_1) throw e_1.error; }
89
+ finally { if (e_2) throw e_2.error; }
58
90
  }
59
91
  return userEnteredValues;
60
92
  }, [getSelectionsFromFormula, getSheetId, sheetId]);
@@ -67,38 +99,58 @@ var useGetValuesFromRange = function (_a) {
67
99
  var getEffectiveValuesFromRange = (0, use_callback_ref_1.useCallbackRef)((0, react_1.useCallback)(function (address) {
68
100
  return tslib_1.__spreadArray([], tslib_1.__read(getValuesFromRange(address, getValidationValue).values()), false);
69
101
  }, [getValidationValue, getValuesFromRange]));
102
+ /**
103
+ * The options a list (`ONE_OF_RANGE`) source denotes at a cell — the dropdown's items and
104
+ * the commit gate's accept list. A plain or sheet-qualified range, a range-type name and a
105
+ * structured reference resolve locally from the tokenizer's selections (off-window-safe
106
+ * through `readSourceValue`). Anything else — a formula-valued name (`=RegionList` defined
107
+ * as `=Table1[Region]` / `=OFFSET(…,COUNTA(…),1)`), any function call, a source the
108
+ * tokenizer found nothing in — goes through the engine resolver when the host supplies
109
+ * one; the legacy calculator previews its reference/array functions as an array; the
110
+ * tokenizer's selections are the last resort. An empty list means "nothing resolvable".
111
+ */
70
112
  var getFormattedValuesFromRangeAsync = (0, use_callback_ref_1.useCallbackRef)((0, react_1.useCallback)(function (address_1, rowIndex_1, columnIndex_1) {
71
113
  var args_1 = [];
72
114
  for (var _i = 3; _i < arguments.length; _i++) {
73
115
  args_1[_i - 3] = arguments[_i];
74
116
  }
75
117
  return tslib_1.__awaiter(void 0, tslib_1.__spreadArray([address_1, rowIndex_1, columnIndex_1], tslib_1.__read(args_1), false), void 0, function (address, rowIndex, columnIndex, targetSheetId) {
76
- var trimmedAddress, isFormula, formulaBody, hasDirectReference, shouldCalc, selections, result, userEnteredValues, pushValue, result_1, result_1_1, row, row_1, row_1_1, entry, result_2, result_2_1, entry;
77
- var e_3, _a, e_4, _b, e_5, _c;
78
- var _d;
118
+ var trimmedAddress, isFormula, formulaBody, hasDirectReference, isFunctionCall, selections, texts, result, userEnteredValues_1, pushValue_1;
119
+ var _a;
79
120
  if (targetSheetId === void 0) { targetSheetId = sheetId; }
80
- return tslib_1.__generator(this, function (_e) {
81
- switch (_e.label) {
121
+ return tslib_1.__generator(this, function (_b) {
122
+ switch (_b.label) {
82
123
  case 0:
83
- trimmedAddress = (_d = address === null || address === void 0 ? void 0 : address.trim()) !== null && _d !== void 0 ? _d : "";
124
+ trimmedAddress = (_a = address === null || address === void 0 ? void 0 : address.trim()) !== null && _a !== void 0 ? _a : "";
125
+ if (!trimmedAddress) {
126
+ return [2 /*return*/, []];
127
+ }
84
128
  isFormula = trimmedAddress.startsWith("=");
85
129
  formulaBody = isFormula ? trimmedAddress.slice(1) : trimmedAddress;
86
130
  hasDirectReference = (0, utils_1.checkIfStringIsReference)(formulaBody);
87
- shouldCalc = isFormula &&
88
- /(OFFSET|INDIRECT|FILTER|UNIQUE|SORT|SEQUENCE)\s*\(/i.test(formulaBody);
89
- if (!onRequestCalculate || !shouldCalc) {
90
- selections = getSelectionsFromFormula(address);
91
- if (hasDirectReference || selections.length) {
92
- return [2 /*return*/, tslib_1.__spreadArray([], tslib_1.__read(getValuesFromRange(address, readSourceValue).values()), false)];
93
- }
94
- return [2 /*return*/, []];
131
+ isFunctionCall = FUNCTION_CALL.test(formulaBody);
132
+ selections = hasDirectReference
133
+ ? []
134
+ : getSelectionsFromFormula(address);
135
+ if (hasDirectReference || (selections.length && !isFunctionCall)) {
136
+ return [2 /*return*/, tslib_1.__spreadArray([], tslib_1.__read(getValuesFromRange(address, readSourceValue).values()), false)];
95
137
  }
96
- return [4 /*yield*/, onRequestCalculate(trimmedAddress, targetSheetId, rowIndex, columnIndex, { isArray: true, disablePreview: true })];
138
+ if (!resolveValidationSourceValues) return [3 /*break*/, 2];
139
+ return [4 /*yield*/, resolveValidationSourceValues(trimmedAddress, targetSheetId, rowIndex, columnIndex)];
97
140
  case 1:
98
- result = _e.sent();
99
- userEnteredValues = new Map();
100
- pushValue = function (value) {
101
- var e_6, _a;
141
+ texts = _b.sent();
142
+ if (texts) {
143
+ return [2 /*return*/, conditionValuesFromTexts(texts)];
144
+ }
145
+ _b.label = 2;
146
+ case 2:
147
+ if (!(onRequestCalculate && isFormula && LEGACY_CALC_SOURCE.test(formulaBody))) return [3 /*break*/, 4];
148
+ return [4 /*yield*/, onRequestCalculate(trimmedAddress, targetSheetId, rowIndex, columnIndex, { isArray: true, disablePreview: true })];
149
+ case 3:
150
+ result = _b.sent();
151
+ userEnteredValues_1 = new Map();
152
+ pushValue_1 = function (value) {
153
+ var e_4, _a;
102
154
  if (value === null || value === undefined) {
103
155
  return;
104
156
  }
@@ -106,15 +158,15 @@ var useGetValuesFromRange = function (_a) {
106
158
  try {
107
159
  for (var value_1 = tslib_1.__values(value), value_1_1 = value_1.next(); !value_1_1.done; value_1_1 = value_1.next()) {
108
160
  var entry = value_1_1.value;
109
- pushValue(entry);
161
+ pushValue_1(entry);
110
162
  }
111
163
  }
112
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
164
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
113
165
  finally {
114
166
  try {
115
167
  if (value_1_1 && !value_1_1.done && (_a = value_1.return)) _a.call(value_1);
116
168
  }
117
- finally { if (e_6) throw e_6.error; }
169
+ finally { if (e_4) throw e_4.error; }
118
170
  }
119
171
  return;
120
172
  }
@@ -125,56 +177,15 @@ var useGetValuesFromRange = function (_a) {
125
177
  ? "TRUE"
126
178
  : "FALSE"
127
179
  : String(value);
128
- userEnteredValues.set(userEnteredValue, { userEnteredValue: userEnteredValue });
180
+ userEnteredValues_1.set(userEnteredValue, { userEnteredValue: userEnteredValue });
129
181
  };
130
- if (Array.isArray(result)) {
131
- if (Array.isArray(result[0])) {
132
- try {
133
- for (result_1 = tslib_1.__values(result), result_1_1 = result_1.next(); !result_1_1.done; result_1_1 = result_1.next()) {
134
- row = result_1_1.value;
135
- try {
136
- for (row_1 = (e_4 = void 0, tslib_1.__values(row)), row_1_1 = row_1.next(); !row_1_1.done; row_1_1 = row_1.next()) {
137
- entry = row_1_1.value;
138
- pushValue(entry);
139
- }
140
- }
141
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
142
- finally {
143
- try {
144
- if (row_1_1 && !row_1_1.done && (_b = row_1.return)) _b.call(row_1);
145
- }
146
- finally { if (e_4) throw e_4.error; }
147
- }
148
- }
149
- }
150
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
151
- finally {
152
- try {
153
- if (result_1_1 && !result_1_1.done && (_a = result_1.return)) _a.call(result_1);
154
- }
155
- finally { if (e_3) throw e_3.error; }
156
- }
157
- }
158
- else {
159
- try {
160
- for (result_2 = tslib_1.__values(result), result_2_1 = result_2.next(); !result_2_1.done; result_2_1 = result_2.next()) {
161
- entry = result_2_1.value;
162
- pushValue(entry);
163
- }
164
- }
165
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
166
- finally {
167
- try {
168
- if (result_2_1 && !result_2_1.done && (_c = result_2.return)) _c.call(result_2);
169
- }
170
- finally { if (e_5) throw e_5.error; }
171
- }
172
- }
173
- }
174
- else {
175
- pushValue(result);
182
+ pushValue_1(result);
183
+ return [2 /*return*/, tslib_1.__spreadArray([], tslib_1.__read(userEnteredValues_1.values()), false)];
184
+ case 4:
185
+ if (selections.length) {
186
+ return [2 /*return*/, tslib_1.__spreadArray([], tslib_1.__read(getValuesFromRange(address, readSourceValue).values()), false)];
176
187
  }
177
- return [2 /*return*/, tslib_1.__spreadArray([], tslib_1.__read(userEnteredValues.values()), false)];
188
+ return [2 /*return*/, []];
178
189
  }
179
190
  });
180
191
  });
@@ -183,6 +194,7 @@ var useGetValuesFromRange = function (_a) {
183
194
  getSelectionsFromFormula,
184
195
  getValuesFromRange,
185
196
  onRequestCalculate,
197
+ resolveValidationSourceValues,
186
198
  sheetId,
187
199
  ]));
188
200
  return [
@@ -4,4 +4,4 @@ Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.releaseDate = void 0;
5
5
  exports.releaseDate =
6
6
  // @ts-ignore
7
- (_a = new Date("2026-10-28")) !== null && _a !== void 0 ? _a : new Date("2025-06-18");
7
+ (_a = new Date("2026-10-29")) !== null && _a !== void 0 ? _a : new Date("2025-06-18");
@@ -1 +1 @@
1
- {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../api/validation.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../api/validation.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { isCellWithinBounds } from "@rowsncolumns/grid";
2
- import { escapeCharacters, isNil, matchesWildcardPattern, toDate, toSerial, } from "@rowsncolumns/utils";
2
+ import { escapeCharacters, getDataValidationListReference, isNil, matchesWildcardPattern, toDate, toSerial, } from "@rowsncolumns/utils";
3
3
  import { EMAIL_REGEX, URL_REGEX } from "../config";
4
- import { checkIfStringIsReference, splitDataValidationListValues, } from "../helpers";
4
+ import { splitDataValidationListValues } from "../helpers";
5
5
  /**
6
6
  * Parse a number value with locale awareness
7
7
  * Handles common decimal separators like comma (e.g., "6,5" in German)
@@ -265,9 +265,14 @@ export const checkBooleanRule = (rule, value, previousValue, getRangeValues, opt
265
265
  return true;
266
266
  }
267
267
  const firstValue = valuesArray[0].userEnteredValue;
268
- const isAddress = type === "ONE_OF_RANGE" ? true : checkIfStringIsReference(firstValue);
269
- const finalValues = isAddress
270
- ? getRangeValues?.(firstValue)
268
+ // A ONE_OF_LIST whose value is a source formula (`=RegionList`) or an A1
269
+ // reference reads its options from that source, like ONE_OF_RANGE.
270
+ const listReference = getDataValidationListReference({
271
+ type,
272
+ values: valuesArray,
273
+ });
274
+ const finalValues = listReference !== undefined
275
+ ? getRangeValues?.(listReference)
271
276
  : splitDataValidationListValues(firstValue);
272
277
  // A cell storing the lone text-prefix apostrophe (`'`) is Excel's
273
278
  // "empty text" — it satisfies the list exactly like a blank cell does,
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/canvas-grid/index.tsx"],"names":[],"mappings":"AAoDA,OAAO,KASN,MAAM,OAAO,CAAC;AAqNf,OAAO,KAAK,EAGV,QAAQ,EAWT,MAAM,aAAa,CAAC;AAoBrB,OAAO,KAAK,EACV,wBAAwB,EACxB,iBAAiB,EACjB,eAAe,EAEhB,MAAM,WAAW,CAAC;AAy/LnB,eAAO,MAAM,UAAU,EAA4C,CACjE,CAAC,SAAS,QAAQ,CAAC,GAAG,CAAC,EAEvB,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,GACvB,wBAAwB,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;CAAE,KAChE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/canvas-grid/index.tsx"],"names":[],"mappings":"AAqDA,OAAO,KASN,MAAM,OAAO,CAAC;AAyNf,OAAO,KAAK,EAGV,QAAQ,EAWT,MAAM,aAAa,CAAC;AAoBrB,OAAO,KAAK,EACV,wBAAwB,EACxB,iBAAiB,EACjB,eAAe,EAEhB,MAAM,WAAW,CAAC;AAgjMnB,eAAO,MAAM,UAAU,EAA4C,CACjE,CAAC,SAAS,QAAQ,CAAC,GAAG,CAAC,EAEvB,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,GACvB,wBAAwB,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;CAAE,KAChE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC"}
@@ -5,7 +5,7 @@ import { getBoundedCells, MouseButtonCodes } from "@rowsncolumns/grid";
5
5
  import { isCellWithinBounds } from "@rowsncolumns/grid";
6
6
  import { cellIdentifier, Grid as BaseGrid, isEqualCells, } from "@rowsncolumns/grid";
7
7
  import { cn, DropdownMenuContent, DropdownMenuPortal, Skeleton, tryParseRichText, } from "@rowsncolumns/ui";
8
- import { cellToAddress, getCellEffectiveFormat, getContrastColor, getFormulaLocale, isConditionalFormatFormulaRule, isDataValidationFormulaRule, isNil, isNilOrBlank, iterateCellsInRange, localizeCellInput, localizeFormula, localizeFunctionDescriptions, log, resolveDefaultHorizontalAlignment, ssfFormatColor, uuid, } from "@rowsncolumns/utils";
8
+ import { cellToAddress, getCellEffectiveFormat, getContrastColor, getFormulaLocale, getEffectiveDataValidationConditionType, isConditionalFormatFormulaRule, isDataValidationFormulaRule, isNil, isNilOrBlank, iterateCellsInRange, localizeCellInput, localizeFormula, localizeFunctionDescriptions, log, resolveDefaultHorizontalAlignment, ssfFormatColor, uuid, } from "@rowsncolumns/utils";
9
9
  import { useStore } from "jotai";
10
10
  import merge from "lodash/merge";
11
11
  import throttle from "lodash/throttle";
@@ -33,7 +33,7 @@ import { useQuickEditState } from "../../atoms/magic-fill-state.atom";
33
33
  import { useOnHideFormulaHelp, useOnShowFormulaHelp, useShowFormulaHelpValue, } from "../../atoms/show-formula-help.atom";
34
34
  import { useSetSpreadsheetApi } from "../../atoms/spreadsheet-api.atom";
35
35
  import { ARROW_DOWN_WIDTH, CALCULATED_ICON_WIDTH, CELL_HORIZONTAL_ALIGNMENT, CF_ICON_SPACING, CF_ICON_WIDTH, CHIP_COLOR, CHIP_SPACING, COLUMN_HEADER_HEIGHT, DEFAULT_ACTIVE_CELL, DEFAULT_ARRAY, DEFAULT_CELL_BACKGROUND_COLOR, DEFAULT_CELL_COLOR, DEFAULT_CELL_SPACING, DEFAULT_COLUMN_COUNT, DEFAULT_COLUMN_WIDTH, DEFAULT_FONT_SIZE_PT, DEFAULT_HEADER_ACTIVE_BG, DEFAULT_HEADER_ACTIVE_TABLE_BG, DEFAULT_HEADER_BG, DEFAULT_HEADER_BORDER_COLOR, DEFAULT_HEADER_COLOR, DEFAULT_HEADER_SELECTED_BG, DEFAULT_HEADER_SELECTED_TABLE_BG, DEFAULT_HEADER_TABLE_BG, DEFAULT_ROW_COUNT, DEFAULT_ROW_HEIGHT, DEFAULT_SCROLL_POSITION, defaultSpreadsheetTheme, EXPAND_COLLAPSE_ICON_WIDTH, FILTER_ICON_WIDTH, GRIDLINE_COLOR, HEADER_TEXT_FORMAT, INDENT_SPACING, MAX_COLUMN_COUNT, MAX_ROW_COUNT, MIN_COLUMN_WIDTH, ROW_HEADER_WIDTH, SCROLLBAR_SIZE, SELECTION_BG, SELECTION_BORDER, } from "../../config";
36
- import { definedProps, getCellEffectiveValue, getCellFormattedValue, getCellUserEnteredValue, getDefaultColumnHeader, getDefaultRowHeader, getExtendedValueBool, getExtendedValueError, getExtendedValueFormula, getExtendedValueNumber, getExtendedValueString, getTableHeaderCells, isFirefox, isStyleReference, isTouchDevice, } from "../../helpers";
36
+ import { definedProps, getCellEffectiveValue, getCellFormattedValue, getCellUserEnteredValue, getDefaultColumnHeader, getDefaultRowHeader, getExtendedValueBool, getExtendedValueError, getExtendedValueFormula, getExtendedValueNumber, getExtendedValueString, getTableHeaderCells, isFirefox, isStyleReference, isTouchDevice, toEditorRangeValuesAsync, } from "../../helpers";
37
37
  import { useBorderStyles } from "../../hooks/use-border-styles";
38
38
  import { useCallbackRef } from "../../hooks/use-callback-ref";
39
39
  import { useCellPopover } from "../../hooks/use-cell-popover";
@@ -51,7 +51,7 @@ import { useEditable } from "../../hooks/use-editable";
51
51
  import { useEditorCancel } from "../../hooks/use-editor-cancel";
52
52
  import { useEditorChange } from "../../hooks/use-editor-change";
53
53
  import { useEditorKeydown } from "../../hooks/use-editor-keydown";
54
- import { useEditorSubmit } from "../../hooks/use-editor-submit";
54
+ import { useEditorSubmit, } from "../../hooks/use-editor-submit";
55
55
  import { useEmbedsCharts } from "../../hooks/use-embeds-charts";
56
56
  import { ChartSheetView } from "../chart-sheet-view";
57
57
  import { useExpandCell } from "../../hooks/use-expand-cell";
@@ -138,6 +138,9 @@ function CanvasGridComponent(props, forwardedRef) {
138
138
  // options + commit-time checks). Windowed hosts supply an off-window-safe reader;
139
139
  // defaults to `getFormattedValue` inside `useGetValuesFromRange`.
140
140
  getValidationSourceValue,
141
+ // Optional engine-side resolver for the list sources the tokenizer cannot resolve
142
+ // (formula-valued names, structured references, OFFSET/INDIRECT/FILTER/UNIQUE).
143
+ resolveValidationSourceValues,
141
144
  // Unused props only for api
142
145
  getDataColumnCount, onDeleteNamedRange, onChangeBorder, onDuplicateSheet, onCreateConditionalFormattingRule, onDeleteConditionalFormattingRule, onUpdateConditionalFormattingRule, onCreateDataValidationRule, onUpdateDataValidationRule, onDeleteDataValidationRule, onCreateChart, onDeleteSheet, onCreateEmbed, onDecreaseIndent, onIncreaseIndent, onChangeTheme, onChangeDecimals, onUpdateSheet, onChangeBatchStream, onBlur, ...rest } = props;
143
146
  // Enter on a cell opens the editor in Google Sheets and moves down in
@@ -1411,7 +1414,12 @@ function CanvasGridComponent(props, forwardedRef) {
1411
1414
  getSheetId,
1412
1415
  onRequestCalculate,
1413
1416
  getValidationSourceValue,
1417
+ resolveValidationSourceValues,
1414
1418
  });
1419
+ /**
1420
+ * The cell editor's dropdown options: same resolver, editor argument order.
1421
+ */
1422
+ const getEditorRangeValuesAsync = useMemo(() => toEditorRangeValuesAsync(getFormattedValuesFromAddressAsync), [getFormattedValuesFromAddressAsync]);
1415
1423
  /**
1416
1424
  * Get all formatted values from range as a single 1d array
1417
1425
  */
@@ -1432,7 +1440,8 @@ function CanvasGridComponent(props, forwardedRef) {
1432
1440
  * Returns the alert + decision when the value is invalid and the rule has an
1433
1441
  * error alert; otherwise `undefined` (no enforcement — the cell still gets the
1434
1442
  * flag-only red marker via `SheetCell.validate`). Formula-backed rules resolve
1435
- * asynchronously through the calculator, so they fall back to flag-only here.
1443
+ * asynchronously through the calculator, so they fall back to flag-only here;
1444
+ * a list (`ONE_OF_RANGE`) rule resolves its source asynchronously and decides.
1436
1445
  */
1437
1446
  const getCommitValidation = useCallback((validationSheetId, rowIndex, columnIndex, value, previousValue) => {
1438
1447
  const rule = getDataValidationRule(validationSheetId, rowIndex, columnIndex);
@@ -1463,6 +1472,29 @@ function CanvasGridComponent(props, forwardedRef) {
1463
1472
  ? undefined
1464
1473
  : { decision: excelDecision, alert };
1465
1474
  }
1475
+ // A list source resolves through the same path as the dropdown
1476
+ // (`getFormattedValuesFromAddressAsync`): a plain range locally, a
1477
+ // formula-valued name / structured reference / OFFSET source through the
1478
+ // engine resolver. A source the UI cannot resolve yields NO list — fail
1479
+ // OPEN rather than block valid input behind a Stop alert: the engine's
1480
+ // compiled `COUNTIF(source, cell)>0` rule still paints the red marker.
1481
+ // A ONE_OF_LIST whose value is a source formula (`=RegionList`, Excel's
1482
+ // List source typed into "Dropdown") is the same list.
1483
+ if (getEffectiveDataValidationConditionType(rule.condition) ===
1484
+ "ONE_OF_RANGE") {
1485
+ const source = rule.condition?.values?.[0]?.userEnteredValue;
1486
+ if (typeof source !== "string" || !source.trim()) {
1487
+ return undefined;
1488
+ }
1489
+ return getFormattedValuesFromAddressAsync(source, rowIndex, columnIndex, validationSheetId).then((listValues) => {
1490
+ if (!listValues.length) {
1491
+ return undefined;
1492
+ }
1493
+ const isValid = checkBooleanRule(rule, value, previousValue ?? undefined, () => listValues, { locale });
1494
+ const decision = decideValidationCommit(alert, Boolean(isValid));
1495
+ return decision === "proceed" ? undefined : { decision, alert };
1496
+ });
1497
+ }
1466
1498
  if (isDataValidationFormulaRule(rule)) {
1467
1499
  // Enforce synchronously only where `checkBooleanRule` can decide the typed
1468
1500
  // value without the calculator: CUSTOM_FORMULA's sync branch is a stub, the
@@ -1477,7 +1509,7 @@ function CanvasGridComponent(props, forwardedRef) {
1477
1509
  entry.userEnteredValue.trim().startsWith("="));
1478
1510
  const syncEnforceable = conditionType !== "CUSTOM_FORMULA" &&
1479
1511
  !conditionType?.startsWith("DATE_") &&
1480
- (conditionType === "ONE_OF_RANGE" || !hasFormulaBound);
1512
+ !hasFormulaBound;
1481
1513
  if (!syncEnforceable) {
1482
1514
  return undefined;
1483
1515
  }
@@ -1488,7 +1520,12 @@ function CanvasGridComponent(props, forwardedRef) {
1488
1520
  return undefined;
1489
1521
  }
1490
1522
  return { decision, alert };
1491
- }, [getDataValidationRule, getFormattedValuesFromAddress, locale]);
1523
+ }, [
1524
+ getDataValidationRule,
1525
+ getFormattedValuesFromAddress,
1526
+ getFormattedValuesFromAddressAsync,
1527
+ locale,
1528
+ ]);
1492
1529
  /**
1493
1530
  * Opens the blocking data-validation alert dialog (Excel error alert).
1494
1531
  */
@@ -1955,12 +1992,13 @@ function CanvasGridComponent(props, forwardedRef) {
1955
1992
  const editingSheetName = getSheetName?.(editingSheetId);
1956
1993
  const effectiveValue = getEffectiveValue(editingSheetId, rowIndex, columnIndex);
1957
1994
  const horizontalAlignment = getEditorHorizontalAlignment(editingSheetId, rowIndex, columnIndex);
1958
- return (React.createElement(CellEditor, { ...props, locale: locale, effectiveValue: effectiveValue, format: cellFormat, dataValidation: dataValidation, getRangeValues: getFormattedValuesFromAddress, getRangeValuesAsync: getFormattedValuesFromAddressAsync, scale: scale, sheetName: sheetName, editingSheetId: editingSheetId, sheetId: sheetId, editingSheetName: editingSheetName, address: address, theme: theme, tokenizer: localeTokenizer, formulaLocale: formulaLocale, horizontalAlignment: horizontalAlignment, defaultBackgroundColor: cellBackgroundColor, defaultTextColor: getStringifiedColor(cellColor, theme), functionDescriptions: localizedFunctionDescriptions, getNamedRanges: getNamedRanges, getTableNames: getTableNames, getStructuredProperties: getStructuredProperties, getTableColumnNames: getTableColumnNames, showFormulaHelp: showFormulaHelp, onHideFormulaHelp: onHideFormulaHelp, onShowFormulaHelp: onShowFormulaHelp, onRequestCalculate: onRequestCalculate, SuggestionsDropdown: SuggestionsDropdown, stickyEditor: stickyEditor, defaultFontSizePoint: defaultFontSize, getMentions: getMentions, getFunctionParameterSuggestions: getFunctionParameterSuggestions, shouldFetchFunctionParameters: shouldFetchFunctionParameters, MentionTagComponent: MentionTagComponent, MentionDropdownItemComponent: MentionDropdownItemComponent }));
1995
+ return (React.createElement(CellEditor, { ...props, locale: locale, effectiveValue: effectiveValue, format: cellFormat, dataValidation: dataValidation, getRangeValues: getFormattedValuesFromAddress, getRangeValuesAsync: getEditorRangeValuesAsync, scale: scale, sheetName: sheetName, editingSheetId: editingSheetId, sheetId: sheetId, editingSheetName: editingSheetName, address: address, theme: theme, tokenizer: localeTokenizer, formulaLocale: formulaLocale, horizontalAlignment: horizontalAlignment, defaultBackgroundColor: cellBackgroundColor, defaultTextColor: getStringifiedColor(cellColor, theme), functionDescriptions: localizedFunctionDescriptions, getNamedRanges: getNamedRanges, getTableNames: getTableNames, getStructuredProperties: getStructuredProperties, getTableColumnNames: getTableColumnNames, showFormulaHelp: showFormulaHelp, onHideFormulaHelp: onHideFormulaHelp, onShowFormulaHelp: onShowFormulaHelp, onRequestCalculate: onRequestCalculate, SuggestionsDropdown: SuggestionsDropdown, stickyEditor: stickyEditor, defaultFontSizePoint: defaultFontSize, getMentions: getMentions, getFunctionParameterSuggestions: getFunctionParameterSuggestions, shouldFetchFunctionParameters: shouldFetchFunctionParameters, MentionTagComponent: MentionTagComponent, MentionDropdownItemComponent: MentionDropdownItemComponent }));
1959
1996
  }, [
1960
1997
  scale,
1961
1998
  getEffectiveCellFormat,
1962
1999
  getDataValidationRule,
1963
2000
  getFormattedValuesFromAddress,
2001
+ getEditorRangeValuesAsync,
1964
2002
  CellEditor,
1965
2003
  getSheetName,
1966
2004
  showFormulaHelp,
@@ -1808,6 +1808,17 @@ export type CanvasGridProps<T extends CellData = CellData<any, any>> = {
1808
1808
  * off-window-safe reader here; defaults to `getFormattedValue`.
1809
1809
  */
1810
1810
  getValidationSourceValue?(sheetId: number, rowIndex: number, columnIndex: number): Maybe<string>;
1811
+ /**
1812
+ * Optional engine-side resolver for a data-validation LIST source (`ONE_OF_RANGE`) the
1813
+ * grid cannot resolve from its own tokenizer: a formula-valued defined name
1814
+ * (`=RegionList` defined as `=Table1[Region]` or `=OFFSET(…,COUNTA(…),1)`), a
1815
+ * structured reference, `INDIRECT` / `FILTER` / `UNIQUE`. Called with the rule's source
1816
+ * text and the validated cell (for relative references and `[@Col]`); returns the display
1817
+ * texts of the source's cells (row-major) or `undefined` when it cannot be resolved — the
1818
+ * dropdown then lists nothing and the commit gate fails OPEN (the engine's own validity
1819
+ * rule keeps the red marker). Plain ranges and range-type names never reach it.
1820
+ */
1821
+ resolveValidationSourceValues?(source: string, sheetId: number, rowIndex: number, columnIndex: number): Maybe<string[]> | Promise<Maybe<string[]>>;
1811
1822
  /**
1812
1823
  * Callback to get custom tooltip content for a cell
1813
1824
  * @param sheetId