@rowsncolumns/spreadsheet-state 29.1.17 → 29.1.19
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/validation.d.ts.map +1 -1
- package/dist/cjs/api/validation.js +9 -6
- package/dist/cjs/components/editors/conditional-format-editor.d.ts +7 -2
- package/dist/cjs/components/editors/conditional-format-editor.d.ts.map +1 -1
- package/dist/cjs/components/editors/conditional-format-editor.js +3 -2
- package/dist/cjs/components/editors/data-validation-editor.d.ts +7 -2
- package/dist/cjs/components/editors/data-validation-editor.d.ts.map +1 -1
- package/dist/cjs/components/editors/data-validation-editor.js +3 -2
- package/dist/cjs/components/editors/sheet-filter.d.ts +16 -4
- package/dist/cjs/components/editors/sheet-filter.d.ts.map +1 -1
- package/dist/cjs/components/editors/sheet-filter.js +22 -9
- package/dist/esm/api/validation.d.ts.map +1 -1
- package/dist/esm/api/validation.js +9 -6
- package/dist/esm/components/editors/conditional-format-editor.d.ts +7 -2
- package/dist/esm/components/editors/conditional-format-editor.d.ts.map +1 -1
- package/dist/esm/components/editors/conditional-format-editor.js +3 -2
- package/dist/esm/components/editors/data-validation-editor.d.ts +7 -2
- package/dist/esm/components/editors/data-validation-editor.d.ts.map +1 -1
- package/dist/esm/components/editors/data-validation-editor.js +3 -2
- package/dist/esm/components/editors/sheet-filter.d.ts +16 -4
- package/dist/esm/components/editors/sheet-filter.d.ts.map +1 -1
- package/dist/esm/components/editors/sheet-filter.js +22 -9
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../api/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAkBpF,KAAK,mBAAmB,GACpB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,IAAI,GACJ,SAAS,GACT;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAoBxC,eAAO,MAAM,qBAAqB,GAAI,OAAO,MAAM,SA6BlD,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,kBAAkB,GAAG,SAAS,EACrC,QAAQ,mBAAmB,EAC3B,gBAAgB,mBAAmB,EACnC,iBAAiB,CAAC,OAAO,EAAE,MAAM,KAAK,cAAc,EAAE,EACtD,UAAU,uBAAuB,
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../api/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAkBpF,KAAK,mBAAmB,GACpB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,IAAI,GACJ,SAAS,GACT;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAoBxC,eAAO,MAAM,qBAAqB,GAAI,OAAO,MAAM,SA6BlD,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,kBAAkB,GAAG,SAAS,EACrC,QAAQ,mBAAmB,EAC3B,gBAAgB,mBAAmB,EACnC,iBAAiB,CAAC,OAAO,EAAE,MAAM,KAAK,cAAc,EAAE,EACtD,UAAU,uBAAuB,wBA8WlC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { escapeCharacters, getDataValidationListReference, isNil, matchesWildcardPattern, stripDataValidationTextPrefix, toDate, toSerial, } from "@rowsncolumns/utils";
|
|
2
2
|
import { convertToNumber } from "./datatype";
|
|
3
3
|
var EMAIL_REGEX = /(?:[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/;
|
|
4
4
|
var URL_REGEX = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)$/;
|
|
@@ -267,11 +267,14 @@ export var checkBooleanRule = function (rule, value, previousValue, getRangeValu
|
|
|
267
267
|
return true;
|
|
268
268
|
}
|
|
269
269
|
var userEnteredValue = (_d = valuesArray[0]) === null || _d === void 0 ? void 0 : _d.userEnteredValue;
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
270
|
+
// A ONE_OF_LIST whose value is a source formula (`=RegionList`) or an A1
|
|
271
|
+
// reference reads its options from that source, like ONE_OF_RANGE.
|
|
272
|
+
var listReference = getDataValidationListReference({
|
|
273
|
+
type: type,
|
|
274
|
+
values: valuesArray,
|
|
275
|
+
});
|
|
276
|
+
var finalValues = listReference !== undefined
|
|
277
|
+
? getRangeValues === null || getRangeValues === void 0 ? void 0 : getRangeValues(listReference)
|
|
275
278
|
: splitDataValidationListValues(userEnteredValue);
|
|
276
279
|
// A cell storing the lone text-prefix apostrophe (`'`) is Excel's
|
|
277
280
|
// "empty text" — it satisfies the list exactly like a blank cell does,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CanvasGridProps, ConditionalFormatRule, SpreadsheetTheme } from "@rowsncolumns/spreadsheet";
|
|
1
|
+
import type { CanvasGridProps, ConditionalFormatRule, Sheet, SpreadsheetTheme } from "@rowsncolumns/spreadsheet";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import type { UseSpreadsheetProps, useSpreadsheetState } from "../../hooks/use-spreadsheet-state";
|
|
4
4
|
export type ConditionalFormatEditorProps = {
|
|
@@ -6,6 +6,11 @@ export type ConditionalFormatEditorProps = {
|
|
|
6
6
|
sheetId: number;
|
|
7
7
|
functionDescriptions?: CanvasGridProps["functionDescriptions"];
|
|
8
8
|
conditionalFormats: ConditionalFormatRule[];
|
|
9
|
+
/**
|
|
10
|
+
* The workbook's sheets in tab order. Lets the "Show rules for" filter list every sheet, as
|
|
11
|
+
* Excel's Rules Manager does; without it only sheets that already have rules are offered.
|
|
12
|
+
*/
|
|
13
|
+
sheets?: ReadonlyArray<Pick<Sheet, "sheetId">>;
|
|
9
14
|
/**
|
|
10
15
|
* Locale for number parsing (e.g., "de-DE" for German)
|
|
11
16
|
*/
|
|
@@ -36,7 +41,7 @@ export type ConditionalFormatEditorProps = {
|
|
|
36
41
|
*/
|
|
37
42
|
idCreationStrategy?: UseSpreadsheetProps["idCreationStrategy"];
|
|
38
43
|
};
|
|
39
|
-
export declare const ConditionalFormatEditor: ({ sheetId, theme, conditionalFormats, functionDescriptions, locale, idCreationStrategy, onCreateRule, onDeleteRule, onUpdateRule, onPreviewRule, }: ConditionalFormatEditorProps) => React.JSX.Element;
|
|
44
|
+
export declare const ConditionalFormatEditor: ({ sheets, sheetId, theme, conditionalFormats, functionDescriptions, locale, idCreationStrategy, onCreateRule, onDeleteRule, onUpdateRule, onPreviewRule, }: ConditionalFormatEditorProps) => React.JSX.Element;
|
|
40
45
|
export declare const ConditionalFormatDialog: ({ children, }: {
|
|
41
46
|
children: React.ReactNode;
|
|
42
47
|
}) => React.JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conditional-format-editor.d.ts","sourceRoot":"","sources":["../../../../components/editors/conditional-format-editor.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AAkBnC,OAAO,KAAyC,MAAM,OAAO,CAAC;AAG9D,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,mCAAmC,CAAC;AAW3C,MAAM,MAAM,4BAA4B,GAAG;IACzC,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,eAAe,CAAC,sBAAsB,CAAC,CAAC;IAC/D,kBAAkB,EAAE,qBAAqB,EAAE,CAAC;IAC5C;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,mCAAmC,CAAC,CAAC;IACvC;;;;OAIG;IACH,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,mCAAmC,CAAC,CAAC;IACvC;;;OAGG;IACH,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,mCAAmC,CAAC,CAAC;IACvC;;;OAGG;IACH,aAAa,EAAE,UAAU,CACvB,OAAO,mBAAmB,CAC3B,CAAC,oCAAoC,CAAC,CAAC;IACxC;;OAEG;IACH,kBAAkB,CAAC,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;CAChE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,
|
|
1
|
+
{"version":3,"file":"conditional-format-editor.d.ts","sourceRoot":"","sources":["../../../../components/editors/conditional-format-editor.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACrB,KAAK,EACL,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AAkBnC,OAAO,KAAyC,MAAM,OAAO,CAAC;AAG9D,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,mCAAmC,CAAC;AAW3C,MAAM,MAAM,4BAA4B,GAAG;IACzC,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,eAAe,CAAC,sBAAsB,CAAC,CAAC;IAC/D,kBAAkB,EAAE,qBAAqB,EAAE,CAAC;IAC5C;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAC/C;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,mCAAmC,CAAC,CAAC;IACvC;;;;OAIG;IACH,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,mCAAmC,CAAC,CAAC;IACvC;;;OAGG;IACH,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,mCAAmC,CAAC,CAAC;IACvC;;;OAGG;IACH,aAAa,EAAE,UAAU,CACvB,OAAO,mBAAmB,CAC3B,CAAC,oCAAoC,CAAC,CAAC;IACxC;;OAEG;IACH,kBAAkB,CAAC,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;CAChE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,4JAYrC,4BAA4B,sBAqR9B,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,eAErC;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,sBAyBA,CAAC"}
|
|
@@ -10,7 +10,7 @@ import { useConditionalFormatDialogState } from "../../atoms/dialog-state.atom";
|
|
|
10
10
|
import { ConditionalFormatRuleEditor, createRulePreviewStyle, } from "./conditional-format-rule-editor";
|
|
11
11
|
import { SheetFilterEmptyState, SheetFilterSelect, useSheetFilter, } from "./sheet-filter";
|
|
12
12
|
export var ConditionalFormatEditor = function (_a) {
|
|
13
|
-
var sheetId = _a.sheetId, theme = _a.theme, conditionalFormats = _a.conditionalFormats, functionDescriptions = _a.functionDescriptions, locale = _a.locale, idCreationStrategy = _a.idCreationStrategy, onCreateRule = _a.onCreateRule, onDeleteRule = _a.onDeleteRule, onUpdateRule = _a.onUpdateRule, onPreviewRule = _a.onPreviewRule;
|
|
13
|
+
var sheets = _a.sheets, sheetId = _a.sheetId, theme = _a.theme, conditionalFormats = _a.conditionalFormats, functionDescriptions = _a.functionDescriptions, locale = _a.locale, idCreationStrategy = _a.idCreationStrategy, onCreateRule = _a.onCreateRule, onDeleteRule = _a.onDeleteRule, onUpdateRule = _a.onUpdateRule, onPreviewRule = _a.onPreviewRule;
|
|
14
14
|
var _b = __read(useState(), 2), editingId = _b[0], setEditingId = _b[1];
|
|
15
15
|
// Deferred create: "Add another rule" holds the new rule as a local draft and only
|
|
16
16
|
// persists it on Save — Excel/Google Sheets create the rule on OK/Done, and an
|
|
@@ -21,7 +21,8 @@ export var ConditionalFormatEditor = function (_a) {
|
|
|
21
21
|
var rangeToFormula = useFormulaRangeHelpers({
|
|
22
22
|
sheetId: sheetId,
|
|
23
23
|
}).rangeToFormula;
|
|
24
|
-
var
|
|
24
|
+
var workbookSheetIds = useMemo(function () { return sheets === null || sheets === void 0 ? void 0 : sheets.map(function (sheet) { return sheet.sheetId; }); }, [sheets]);
|
|
25
|
+
var _d = useSheetFilter(sheetId, conditionalFormats, workbookSheetIds), sheetFilter = _d.sheetFilter, setSheetFilter = _d.setSheetFilter, filterableSheetIds = _d.filterableSheetIds, visibleRules = _d.visibleRules, showFilter = _d.showFilter;
|
|
25
26
|
var onNewRule = function () {
|
|
26
27
|
var _a, _b, _c;
|
|
27
28
|
var activeCell = (_a = api === null || api === void 0 ? void 0 : api.getActiveSheet()) === null || _a === void 0 ? void 0 : _a.getActiveCell();
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import type { CanvasGridProps, DataValidationRuleRecord } from "@rowsncolumns/spreadsheet";
|
|
1
|
+
import type { CanvasGridProps, DataValidationRuleRecord, Sheet } from "@rowsncolumns/spreadsheet";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import type { UseSpreadsheetProps, useSpreadsheetState } from "../../hooks/use-spreadsheet-state";
|
|
4
4
|
type DataValidationEditorProps = {
|
|
5
5
|
dataValidations?: DataValidationRuleRecord[];
|
|
6
6
|
sheetId: number;
|
|
7
|
+
/**
|
|
8
|
+
* The workbook's sheets in tab order. Lets the "Show rules for" filter list every sheet, as
|
|
9
|
+
* Excel's Rules Manager does; without it only sheets that already have rules are offered.
|
|
10
|
+
*/
|
|
11
|
+
sheets?: ReadonlyArray<Pick<Sheet, "sheetId">>;
|
|
7
12
|
functionDescriptions?: CanvasGridProps["functionDescriptions"];
|
|
8
13
|
onDeleteRules: ReturnType<typeof useSpreadsheetState>["onDeleteDataValidationRules"];
|
|
9
14
|
onUpdateRule: ReturnType<typeof useSpreadsheetState>["onUpdateDataValidationRule"];
|
|
@@ -19,7 +24,7 @@ type DataValidationEditorProps = {
|
|
|
19
24
|
* @param param0
|
|
20
25
|
* @returns
|
|
21
26
|
*/
|
|
22
|
-
export declare const DataValidationEditor: ({ sheetId, dataValidations, functionDescriptions, idCreationStrategy, onDeleteRules, onDeleteRule, onCreateRule, onUpdateRule, }: DataValidationEditorProps) => React.JSX.Element;
|
|
27
|
+
export declare const DataValidationEditor: ({ sheets, sheetId, dataValidations, functionDescriptions, idCreationStrategy, onDeleteRules, onDeleteRule, onCreateRule, onUpdateRule, }: DataValidationEditorProps) => React.JSX.Element;
|
|
23
28
|
export declare const DataValidationEditorDialog: ({ children, }: {
|
|
24
29
|
children: React.ReactNode;
|
|
25
30
|
}) => React.JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-validation-editor.d.ts","sourceRoot":"","sources":["../../../../components/editors/data-validation-editor.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,
|
|
1
|
+
{"version":3,"file":"data-validation-editor.d.ts","sourceRoot":"","sources":["../../../../components/editors/data-validation-editor.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,EACxB,KAAK,EACN,MAAM,2BAA2B,CAAC;AAoBnC,OAAO,KAAkD,MAAM,OAAO,CAAC;AAOvE,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,mCAAmC,CAAC;AAQ3C,KAAK,yBAAyB,GAAG;IAC/B,eAAe,CAAC,EAAE,wBAAwB,EAAE,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAC/C,oBAAoB,CAAC,EAAE,eAAe,CAAC,sBAAsB,CAAC,CAAC;IAC/D,aAAa,EAAE,UAAU,CACvB,OAAO,mBAAmB,CAC3B,CAAC,6BAA6B,CAAC,CAAC;IACjC,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,4BAA4B,CAAC,CAAC;IAChC,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,4BAA4B,CAAC,CAAC;IAChC,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,4BAA4B,CAAC,CAAC;IAChC;;OAEG;IACH,kBAAkB,CAAC,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;CAChE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,0IAUlC,yBAAyB,sBAwP3B,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,eAExC;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,sBAyBA,CAAC"}
|
|
@@ -14,7 +14,7 @@ import { SheetFilterEmptyState, SheetFilterSelect, useSheetFilter, } from "./she
|
|
|
14
14
|
* @returns
|
|
15
15
|
*/
|
|
16
16
|
export var DataValidationEditor = function (_a) {
|
|
17
|
-
var sheetId = _a.sheetId, dataValidations = _a.dataValidations, functionDescriptions = _a.functionDescriptions, idCreationStrategy = _a.idCreationStrategy, onDeleteRules = _a.onDeleteRules, onDeleteRule = _a.onDeleteRule, onCreateRule = _a.onCreateRule, onUpdateRule = _a.onUpdateRule;
|
|
17
|
+
var sheets = _a.sheets, sheetId = _a.sheetId, dataValidations = _a.dataValidations, functionDescriptions = _a.functionDescriptions, idCreationStrategy = _a.idCreationStrategy, onDeleteRules = _a.onDeleteRules, onDeleteRule = _a.onDeleteRule, onCreateRule = _a.onCreateRule, onUpdateRule = _a.onUpdateRule;
|
|
18
18
|
var _b = __read(useEditingDataValidationIdState(), 2), editingId = _b[0], setEditingId = _b[1];
|
|
19
19
|
// Deferred create: "Add rule" and the seeded openers (Insert → Dropdown, the ribbon's
|
|
20
20
|
// Data Validation button via `useOnRequestDataValidation`) hold the new rule as a draft
|
|
@@ -26,7 +26,8 @@ export var DataValidationEditor = function (_a) {
|
|
|
26
26
|
var rangeToFormula = useFormulaRangeHelpers({
|
|
27
27
|
sheetId: sheetId,
|
|
28
28
|
}).rangeToFormula;
|
|
29
|
-
var
|
|
29
|
+
var workbookSheetIds = useMemo(function () { return sheets === null || sheets === void 0 ? void 0 : sheets.map(function (sheet) { return sheet.sheetId; }); }, [sheets]);
|
|
30
|
+
var _d = useSheetFilter(sheetId, dataValidations !== null && dataValidations !== void 0 ? dataValidations : [], workbookSheetIds), sheetFilter = _d.sheetFilter, setSheetFilter = _d.setSheetFilter, filterableSheetIds = _d.filterableSheetIds, visibleRules = _d.visibleRules, showFilter = _d.showFilter;
|
|
30
31
|
var onNewRule = function () {
|
|
31
32
|
var _a, _b, _c;
|
|
32
33
|
var id = (_a = idCreationStrategy === null || idCreationStrategy === void 0 ? void 0 : idCreationStrategy("data-validation")) !== null && _a !== void 0 ? _a : uuid();
|
|
@@ -33,13 +33,25 @@ export declare function shouldShowSheetFilter({ ruleCount, sheetFilter, sheetId,
|
|
|
33
33
|
sheetFilter: SheetFilter;
|
|
34
34
|
sheetId: number;
|
|
35
35
|
}): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* The sheets the filter offers, in the order they are listed.
|
|
38
|
+
*
|
|
39
|
+
* Excel's Rules Manager lists every worksheet in tab order whether or not it carries a rule, so a
|
|
40
|
+
* user can jump to any tab from the dropdown; a sheet without rules simply shows an empty list.
|
|
41
|
+
* `workbookSheetIds` (the host's sheets, in tab order) gives that. Without it the list falls back
|
|
42
|
+
* to the sheets that have rules, which is all the rule list itself can know. The active sheet is
|
|
43
|
+
* always offered either way — it is the default selection.
|
|
44
|
+
*/
|
|
45
|
+
export declare function getFilterableSheetIds(rules: RuleWithRanges[], sheetId: number, workbookSheetIds?: readonly number[]): number[];
|
|
36
46
|
/**
|
|
37
47
|
* Rule lists (conditional formats, data validations) are scoped to the active
|
|
38
|
-
* sheet by default; the SheetFilterSelect widens the view to
|
|
39
|
-
*
|
|
40
|
-
*
|
|
48
|
+
* sheet by default; the SheetFilterSelect widens the view to another sheet, or
|
|
49
|
+
* all sheets. Follows the active sheet if the user switches sheets while the
|
|
50
|
+
* dialog is open.
|
|
51
|
+
*
|
|
52
|
+
* `workbookSheetIds` is the workbook's sheets in tab order; see getFilterableSheetIds.
|
|
41
53
|
*/
|
|
42
|
-
export declare function useSheetFilter<T extends RuleWithRanges>(sheetId: number, rules: T[]): {
|
|
54
|
+
export declare function useSheetFilter<T extends RuleWithRanges>(sheetId: number, rules: T[], workbookSheetIds?: readonly number[]): {
|
|
43
55
|
sheetFilter: SheetFilter;
|
|
44
56
|
setSheetFilter: React.Dispatch<React.SetStateAction<SheetFilter>>;
|
|
45
57
|
filterableSheetIds: number[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sheet-filter.d.ts","sourceRoot":"","sources":["../../../../components/editors/sheet-filter.tsx"],"names":[],"mappings":"AASA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC;AAEzC,KAAK,cAAc,GAAG;IACpB,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjC,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,cAAc,EACzD,KAAK,EAAE,CAAC,EAAE,EACV,MAAM,EAAE,WAAW,GAClB,CAAC,EAAE,CAML;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAUtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,WAAW,EACX,OAAO,GACR,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAEV;AAED
|
|
1
|
+
{"version":3,"file":"sheet-filter.d.ts","sourceRoot":"","sources":["../../../../components/editors/sheet-filter.tsx"],"names":[],"mappings":"AASA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC;AAEzC,KAAK,cAAc,GAAG;IACpB,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjC,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,cAAc,EACzD,KAAK,EAAE,CAAC,EAAE,EACV,MAAM,EAAE,WAAW,GAClB,CAAC,EAAE,CAML;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAUtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,WAAW,EACX,OAAO,GACR,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAEV;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE,MAAM,EACf,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,GACnC,MAAM,EAAE,CAKV;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,cAAc,EACrD,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,CAAC,EAAE,EACV,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE;;;;;;EA8BrC;AAED,eAAO,MAAM,iBAAiB,GAAI,qCAI/B;IACD,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CAC7C,sBA6BA,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,yBAGnC;IACD,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf,sBAKA,CAAC"}
|
|
@@ -62,22 +62,35 @@ export function shouldShowSheetFilter(_a) {
|
|
|
62
62
|
var ruleCount = _a.ruleCount, sheetFilter = _a.sheetFilter, sheetId = _a.sheetId;
|
|
63
63
|
return ruleCount > 0 || sheetFilter !== sheetId;
|
|
64
64
|
}
|
|
65
|
+
/**
|
|
66
|
+
* The sheets the filter offers, in the order they are listed.
|
|
67
|
+
*
|
|
68
|
+
* Excel's Rules Manager lists every worksheet in tab order whether or not it carries a rule, so a
|
|
69
|
+
* user can jump to any tab from the dropdown; a sheet without rules simply shows an empty list.
|
|
70
|
+
* `workbookSheetIds` (the host's sheets, in tab order) gives that. Without it the list falls back
|
|
71
|
+
* to the sheets that have rules, which is all the rule list itself can know. The active sheet is
|
|
72
|
+
* always offered either way — it is the default selection.
|
|
73
|
+
*/
|
|
74
|
+
export function getFilterableSheetIds(rules, sheetId, workbookSheetIds) {
|
|
75
|
+
var ids = workbookSheetIds
|
|
76
|
+
? Array.from(new Set(workbookSheetIds))
|
|
77
|
+
: getSheetIdsWithRules(rules);
|
|
78
|
+
return ids.includes(sheetId) ? ids : __spreadArray([sheetId], __read(ids), false);
|
|
79
|
+
}
|
|
65
80
|
/**
|
|
66
81
|
* Rule lists (conditional formats, data validations) are scoped to the active
|
|
67
|
-
* sheet by default; the SheetFilterSelect widens the view to
|
|
68
|
-
*
|
|
69
|
-
*
|
|
82
|
+
* sheet by default; the SheetFilterSelect widens the view to another sheet, or
|
|
83
|
+
* all sheets. Follows the active sheet if the user switches sheets while the
|
|
84
|
+
* dialog is open.
|
|
85
|
+
*
|
|
86
|
+
* `workbookSheetIds` is the workbook's sheets in tab order; see getFilterableSheetIds.
|
|
70
87
|
*/
|
|
71
|
-
export function useSheetFilter(sheetId, rules) {
|
|
88
|
+
export function useSheetFilter(sheetId, rules, workbookSheetIds) {
|
|
72
89
|
var _a = __read(useState(sheetId), 2), sheetFilter = _a[0], setSheetFilter = _a[1];
|
|
73
90
|
useEffect(function () {
|
|
74
91
|
setSheetFilter(sheetId);
|
|
75
92
|
}, [sheetId]);
|
|
76
|
-
var filterableSheetIds = useMemo(function () {
|
|
77
|
-
var ids = getSheetIdsWithRules(rules);
|
|
78
|
-
// The active sheet is always offered, even before it has rules.
|
|
79
|
-
return ids.includes(sheetId) ? ids : __spreadArray([sheetId], __read(ids), false);
|
|
80
|
-
}, [rules, sheetId]);
|
|
93
|
+
var filterableSheetIds = useMemo(function () { return getFilterableSheetIds(rules, sheetId, workbookSheetIds); }, [rules, sheetId, workbookSheetIds]);
|
|
81
94
|
var visibleRules = useMemo(function () { return filterRulesBySheet(rules, sheetFilter); }, [rules, sheetFilter]);
|
|
82
95
|
var showFilter = shouldShowSheetFilter({
|
|
83
96
|
ruleCount: rules.length,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../api/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAkBpF,KAAK,mBAAmB,GACpB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,IAAI,GACJ,SAAS,GACT;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAoBxC,eAAO,MAAM,qBAAqB,GAAI,OAAO,MAAM,SA6BlD,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,kBAAkB,GAAG,SAAS,EACrC,QAAQ,mBAAmB,EAC3B,gBAAgB,mBAAmB,EACnC,iBAAiB,CAAC,OAAO,EAAE,MAAM,KAAK,cAAc,EAAE,EACtD,UAAU,uBAAuB,
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../api/validation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAkBpF,KAAK,mBAAmB,GACpB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,IAAI,GACJ,SAAS,GACT;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAoBxC,eAAO,MAAM,qBAAqB,GAAI,OAAO,MAAM,SA6BlD,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,OAAO,kBAAkB,GAAG,SAAS,EACrC,QAAQ,mBAAmB,EAC3B,gBAAgB,mBAAmB,EACnC,iBAAiB,CAAC,OAAO,EAAE,MAAM,KAAK,cAAc,EAAE,EACtD,UAAU,uBAAuB,wBA8WlC,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { escapeCharacters, getDataValidationListReference, isNil, matchesWildcardPattern, stripDataValidationTextPrefix, toDate, toSerial, } from "@rowsncolumns/utils";
|
|
2
2
|
import { convertToNumber } from "./datatype";
|
|
3
3
|
const EMAIL_REGEX = /(?:[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/;
|
|
4
4
|
const URL_REGEX = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b(?:[-a-zA-Z0-9()@:%_\+.~#?&\/=]*)$/;
|
|
@@ -260,11 +260,14 @@ export const checkBooleanRule = (rule, value, previousValue, getRangeValues, opt
|
|
|
260
260
|
return true;
|
|
261
261
|
}
|
|
262
262
|
const userEnteredValue = valuesArray[0]?.userEnteredValue;
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
263
|
+
// A ONE_OF_LIST whose value is a source formula (`=RegionList`) or an A1
|
|
264
|
+
// reference reads its options from that source, like ONE_OF_RANGE.
|
|
265
|
+
const listReference = getDataValidationListReference({
|
|
266
|
+
type,
|
|
267
|
+
values: valuesArray,
|
|
268
|
+
});
|
|
269
|
+
const finalValues = listReference !== undefined
|
|
270
|
+
? getRangeValues?.(listReference)
|
|
268
271
|
: splitDataValidationListValues(userEnteredValue);
|
|
269
272
|
// A cell storing the lone text-prefix apostrophe (`'`) is Excel's
|
|
270
273
|
// "empty text" — it satisfies the list exactly like a blank cell does,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CanvasGridProps, ConditionalFormatRule, SpreadsheetTheme } from "@rowsncolumns/spreadsheet";
|
|
1
|
+
import type { CanvasGridProps, ConditionalFormatRule, Sheet, SpreadsheetTheme } from "@rowsncolumns/spreadsheet";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import type { UseSpreadsheetProps, useSpreadsheetState } from "../../hooks/use-spreadsheet-state";
|
|
4
4
|
export type ConditionalFormatEditorProps = {
|
|
@@ -6,6 +6,11 @@ export type ConditionalFormatEditorProps = {
|
|
|
6
6
|
sheetId: number;
|
|
7
7
|
functionDescriptions?: CanvasGridProps["functionDescriptions"];
|
|
8
8
|
conditionalFormats: ConditionalFormatRule[];
|
|
9
|
+
/**
|
|
10
|
+
* The workbook's sheets in tab order. Lets the "Show rules for" filter list every sheet, as
|
|
11
|
+
* Excel's Rules Manager does; without it only sheets that already have rules are offered.
|
|
12
|
+
*/
|
|
13
|
+
sheets?: ReadonlyArray<Pick<Sheet, "sheetId">>;
|
|
9
14
|
/**
|
|
10
15
|
* Locale for number parsing (e.g., "de-DE" for German)
|
|
11
16
|
*/
|
|
@@ -36,7 +41,7 @@ export type ConditionalFormatEditorProps = {
|
|
|
36
41
|
*/
|
|
37
42
|
idCreationStrategy?: UseSpreadsheetProps["idCreationStrategy"];
|
|
38
43
|
};
|
|
39
|
-
export declare const ConditionalFormatEditor: ({ sheetId, theme, conditionalFormats, functionDescriptions, locale, idCreationStrategy, onCreateRule, onDeleteRule, onUpdateRule, onPreviewRule, }: ConditionalFormatEditorProps) => React.JSX.Element;
|
|
44
|
+
export declare const ConditionalFormatEditor: ({ sheets, sheetId, theme, conditionalFormats, functionDescriptions, locale, idCreationStrategy, onCreateRule, onDeleteRule, onUpdateRule, onPreviewRule, }: ConditionalFormatEditorProps) => React.JSX.Element;
|
|
40
45
|
export declare const ConditionalFormatDialog: ({ children, }: {
|
|
41
46
|
children: React.ReactNode;
|
|
42
47
|
}) => React.JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"conditional-format-editor.d.ts","sourceRoot":"","sources":["../../../../components/editors/conditional-format-editor.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AAkBnC,OAAO,KAAyC,MAAM,OAAO,CAAC;AAG9D,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,mCAAmC,CAAC;AAW3C,MAAM,MAAM,4BAA4B,GAAG;IACzC,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,eAAe,CAAC,sBAAsB,CAAC,CAAC;IAC/D,kBAAkB,EAAE,qBAAqB,EAAE,CAAC;IAC5C;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,mCAAmC,CAAC,CAAC;IACvC;;;;OAIG;IACH,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,mCAAmC,CAAC,CAAC;IACvC;;;OAGG;IACH,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,mCAAmC,CAAC,CAAC;IACvC;;;OAGG;IACH,aAAa,EAAE,UAAU,CACvB,OAAO,mBAAmB,CAC3B,CAAC,oCAAoC,CAAC,CAAC;IACxC;;OAEG;IACH,kBAAkB,CAAC,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;CAChE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,
|
|
1
|
+
{"version":3,"file":"conditional-format-editor.d.ts","sourceRoot":"","sources":["../../../../components/editors/conditional-format-editor.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACrB,KAAK,EACL,gBAAgB,EACjB,MAAM,2BAA2B,CAAC;AAkBnC,OAAO,KAAyC,MAAM,OAAO,CAAC;AAG9D,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,mCAAmC,CAAC;AAW3C,MAAM,MAAM,4BAA4B,GAAG;IACzC,KAAK,EAAE,gBAAgB,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,oBAAoB,CAAC,EAAE,eAAe,CAAC,sBAAsB,CAAC,CAAC;IAC/D,kBAAkB,EAAE,qBAAqB,EAAE,CAAC;IAC5C;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAC/C;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,mCAAmC,CAAC,CAAC;IACvC;;;;OAIG;IACH,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,mCAAmC,CAAC,CAAC;IACvC;;;OAGG;IACH,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,mCAAmC,CAAC,CAAC;IACvC;;;OAGG;IACH,aAAa,EAAE,UAAU,CACvB,OAAO,mBAAmB,CAC3B,CAAC,oCAAoC,CAAC,CAAC;IACxC;;OAEG;IACH,kBAAkB,CAAC,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;CAChE,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,4JAYrC,4BAA4B,sBAqR9B,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,eAErC;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,sBAyBA,CAAC"}
|
|
@@ -8,7 +8,7 @@ import React, { useCallback, useMemo, useState } from "react";
|
|
|
8
8
|
import { useConditionalFormatDialogState } from "../../atoms/dialog-state.atom";
|
|
9
9
|
import { ConditionalFormatRuleEditor, createRulePreviewStyle, } from "./conditional-format-rule-editor";
|
|
10
10
|
import { SheetFilterEmptyState, SheetFilterSelect, useSheetFilter, } from "./sheet-filter";
|
|
11
|
-
export const ConditionalFormatEditor = ({ sheetId, theme, conditionalFormats, functionDescriptions, locale, idCreationStrategy, onCreateRule, onDeleteRule, onUpdateRule, onPreviewRule, }) => {
|
|
11
|
+
export const ConditionalFormatEditor = ({ sheets, sheetId, theme, conditionalFormats, functionDescriptions, locale, idCreationStrategy, onCreateRule, onDeleteRule, onUpdateRule, onPreviewRule, }) => {
|
|
12
12
|
const [editingId, setEditingId] = useState();
|
|
13
13
|
// Deferred create: "Add another rule" holds the new rule as a local draft and only
|
|
14
14
|
// persists it on Save — Excel/Google Sheets create the rule on OK/Done, and an
|
|
@@ -19,7 +19,8 @@ export const ConditionalFormatEditor = ({ sheetId, theme, conditionalFormats, fu
|
|
|
19
19
|
const { rangeToFormula } = useFormulaRangeHelpers({
|
|
20
20
|
sheetId,
|
|
21
21
|
});
|
|
22
|
-
const
|
|
22
|
+
const workbookSheetIds = useMemo(() => sheets?.map((sheet) => sheet.sheetId), [sheets]);
|
|
23
|
+
const { sheetFilter, setSheetFilter, filterableSheetIds, visibleRules, showFilter, } = useSheetFilter(sheetId, conditionalFormats, workbookSheetIds);
|
|
23
24
|
const onNewRule = () => {
|
|
24
25
|
const activeCell = api?.getActiveSheet()?.getActiveCell();
|
|
25
26
|
const selections = api?.getActiveSheet()?.getSelections();
|
|
@@ -1,9 +1,14 @@
|
|
|
1
|
-
import type { CanvasGridProps, DataValidationRuleRecord } from "@rowsncolumns/spreadsheet";
|
|
1
|
+
import type { CanvasGridProps, DataValidationRuleRecord, Sheet } from "@rowsncolumns/spreadsheet";
|
|
2
2
|
import React from "react";
|
|
3
3
|
import type { UseSpreadsheetProps, useSpreadsheetState } from "../../hooks/use-spreadsheet-state";
|
|
4
4
|
type DataValidationEditorProps = {
|
|
5
5
|
dataValidations?: DataValidationRuleRecord[];
|
|
6
6
|
sheetId: number;
|
|
7
|
+
/**
|
|
8
|
+
* The workbook's sheets in tab order. Lets the "Show rules for" filter list every sheet, as
|
|
9
|
+
* Excel's Rules Manager does; without it only sheets that already have rules are offered.
|
|
10
|
+
*/
|
|
11
|
+
sheets?: ReadonlyArray<Pick<Sheet, "sheetId">>;
|
|
7
12
|
functionDescriptions?: CanvasGridProps["functionDescriptions"];
|
|
8
13
|
onDeleteRules: ReturnType<typeof useSpreadsheetState>["onDeleteDataValidationRules"];
|
|
9
14
|
onUpdateRule: ReturnType<typeof useSpreadsheetState>["onUpdateDataValidationRule"];
|
|
@@ -19,7 +24,7 @@ type DataValidationEditorProps = {
|
|
|
19
24
|
* @param param0
|
|
20
25
|
* @returns
|
|
21
26
|
*/
|
|
22
|
-
export declare const DataValidationEditor: ({ sheetId, dataValidations, functionDescriptions, idCreationStrategy, onDeleteRules, onDeleteRule, onCreateRule, onUpdateRule, }: DataValidationEditorProps) => React.JSX.Element;
|
|
27
|
+
export declare const DataValidationEditor: ({ sheets, sheetId, dataValidations, functionDescriptions, idCreationStrategy, onDeleteRules, onDeleteRule, onCreateRule, onUpdateRule, }: DataValidationEditorProps) => React.JSX.Element;
|
|
23
28
|
export declare const DataValidationEditorDialog: ({ children, }: {
|
|
24
29
|
children: React.ReactNode;
|
|
25
30
|
}) => React.JSX.Element;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-validation-editor.d.ts","sourceRoot":"","sources":["../../../../components/editors/data-validation-editor.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,
|
|
1
|
+
{"version":3,"file":"data-validation-editor.d.ts","sourceRoot":"","sources":["../../../../components/editors/data-validation-editor.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,eAAe,EACf,wBAAwB,EACxB,KAAK,EACN,MAAM,2BAA2B,CAAC;AAoBnC,OAAO,KAAkD,MAAM,OAAO,CAAC;AAOvE,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,mCAAmC,CAAC;AAQ3C,KAAK,yBAAyB,GAAG;IAC/B,eAAe,CAAC,EAAE,wBAAwB,EAAE,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;IAC/C,oBAAoB,CAAC,EAAE,eAAe,CAAC,sBAAsB,CAAC,CAAC;IAC/D,aAAa,EAAE,UAAU,CACvB,OAAO,mBAAmB,CAC3B,CAAC,6BAA6B,CAAC,CAAC;IACjC,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,4BAA4B,CAAC,CAAC;IAChC,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,4BAA4B,CAAC,CAAC;IAChC,YAAY,EAAE,UAAU,CACtB,OAAO,mBAAmB,CAC3B,CAAC,4BAA4B,CAAC,CAAC;IAChC;;OAEG;IACH,kBAAkB,CAAC,EAAE,mBAAmB,CAAC,oBAAoB,CAAC,CAAC;CAChE,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,0IAUlC,yBAAyB,sBAwP3B,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,eAExC;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,sBAyBA,CAAC"}
|
|
@@ -12,7 +12,7 @@ import { SheetFilterEmptyState, SheetFilterSelect, useSheetFilter, } from "./she
|
|
|
12
12
|
* @param param0
|
|
13
13
|
* @returns
|
|
14
14
|
*/
|
|
15
|
-
export const DataValidationEditor = ({ sheetId, dataValidations, functionDescriptions, idCreationStrategy, onDeleteRules, onDeleteRule, onCreateRule, onUpdateRule, }) => {
|
|
15
|
+
export const DataValidationEditor = ({ sheets, sheetId, dataValidations, functionDescriptions, idCreationStrategy, onDeleteRules, onDeleteRule, onCreateRule, onUpdateRule, }) => {
|
|
16
16
|
const [editingId, setEditingId] = useEditingDataValidationIdState();
|
|
17
17
|
// Deferred create: "Add rule" and the seeded openers (Insert → Dropdown, the ribbon's
|
|
18
18
|
// Data Validation button via `useOnRequestDataValidation`) hold the new rule as a draft
|
|
@@ -24,7 +24,8 @@ export const DataValidationEditor = ({ sheetId, dataValidations, functionDescrip
|
|
|
24
24
|
const { rangeToFormula } = useFormulaRangeHelpers({
|
|
25
25
|
sheetId,
|
|
26
26
|
});
|
|
27
|
-
const
|
|
27
|
+
const workbookSheetIds = useMemo(() => sheets?.map((sheet) => sheet.sheetId), [sheets]);
|
|
28
|
+
const { sheetFilter, setSheetFilter, filterableSheetIds, visibleRules, showFilter, } = useSheetFilter(sheetId, dataValidations ?? [], workbookSheetIds);
|
|
28
29
|
const onNewRule = () => {
|
|
29
30
|
const id = idCreationStrategy?.("data-validation") ?? uuid();
|
|
30
31
|
const activeCell = api?.getActiveSheet()?.getActiveCell();
|
|
@@ -33,13 +33,25 @@ export declare function shouldShowSheetFilter({ ruleCount, sheetFilter, sheetId,
|
|
|
33
33
|
sheetFilter: SheetFilter;
|
|
34
34
|
sheetId: number;
|
|
35
35
|
}): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* The sheets the filter offers, in the order they are listed.
|
|
38
|
+
*
|
|
39
|
+
* Excel's Rules Manager lists every worksheet in tab order whether or not it carries a rule, so a
|
|
40
|
+
* user can jump to any tab from the dropdown; a sheet without rules simply shows an empty list.
|
|
41
|
+
* `workbookSheetIds` (the host's sheets, in tab order) gives that. Without it the list falls back
|
|
42
|
+
* to the sheets that have rules, which is all the rule list itself can know. The active sheet is
|
|
43
|
+
* always offered either way — it is the default selection.
|
|
44
|
+
*/
|
|
45
|
+
export declare function getFilterableSheetIds(rules: RuleWithRanges[], sheetId: number, workbookSheetIds?: readonly number[]): number[];
|
|
36
46
|
/**
|
|
37
47
|
* Rule lists (conditional formats, data validations) are scoped to the active
|
|
38
|
-
* sheet by default; the SheetFilterSelect widens the view to
|
|
39
|
-
*
|
|
40
|
-
*
|
|
48
|
+
* sheet by default; the SheetFilterSelect widens the view to another sheet, or
|
|
49
|
+
* all sheets. Follows the active sheet if the user switches sheets while the
|
|
50
|
+
* dialog is open.
|
|
51
|
+
*
|
|
52
|
+
* `workbookSheetIds` is the workbook's sheets in tab order; see getFilterableSheetIds.
|
|
41
53
|
*/
|
|
42
|
-
export declare function useSheetFilter<T extends RuleWithRanges>(sheetId: number, rules: T[]): {
|
|
54
|
+
export declare function useSheetFilter<T extends RuleWithRanges>(sheetId: number, rules: T[], workbookSheetIds?: readonly number[]): {
|
|
43
55
|
sheetFilter: SheetFilter;
|
|
44
56
|
setSheetFilter: React.Dispatch<React.SetStateAction<SheetFilter>>;
|
|
45
57
|
filterableSheetIds: number[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sheet-filter.d.ts","sourceRoot":"","sources":["../../../../components/editors/sheet-filter.tsx"],"names":[],"mappings":"AASA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC;AAEzC,KAAK,cAAc,GAAG;IACpB,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjC,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,cAAc,EACzD,KAAK,EAAE,CAAC,EAAE,EACV,MAAM,EAAE,WAAW,GAClB,CAAC,EAAE,CAML;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAUtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,WAAW,EACX,OAAO,GACR,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAEV;AAED
|
|
1
|
+
{"version":3,"file":"sheet-filter.d.ts","sourceRoot":"","sources":["../../../../components/editors/sheet-filter.tsx"],"names":[],"mappings":"AASA,OAAO,KAAuC,MAAM,OAAO,CAAC;AAE5D;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,KAAK,CAAC;AAEzC,KAAK,cAAc,GAAG;IACpB,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjC,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,cAAc,EACzD,KAAK,EAAE,CAAC,EAAE,EACV,MAAM,EAAE,WAAW,GAClB,CAAC,EAAE,CAML;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,MAAM,EAAE,CAUtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,WAAW,EACX,OAAO,GACR,EAAE;IACD,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAEV;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CACnC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE,MAAM,EACf,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,GACnC,MAAM,EAAE,CAKV;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,cAAc,EACrD,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,CAAC,EAAE,EACV,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE;;;;;;EA8BrC;AAED,eAAO,MAAM,iBAAiB,GAAI,qCAI/B;IACD,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,aAAa,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CAC7C,sBA6BA,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,yBAGnC;IACD,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;CACf,sBAKA,CAAC"}
|
|
@@ -38,22 +38,35 @@ export function getSheetIdsWithRules(rules) {
|
|
|
38
38
|
export function shouldShowSheetFilter({ ruleCount, sheetFilter, sheetId, }) {
|
|
39
39
|
return ruleCount > 0 || sheetFilter !== sheetId;
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* The sheets the filter offers, in the order they are listed.
|
|
43
|
+
*
|
|
44
|
+
* Excel's Rules Manager lists every worksheet in tab order whether or not it carries a rule, so a
|
|
45
|
+
* user can jump to any tab from the dropdown; a sheet without rules simply shows an empty list.
|
|
46
|
+
* `workbookSheetIds` (the host's sheets, in tab order) gives that. Without it the list falls back
|
|
47
|
+
* to the sheets that have rules, which is all the rule list itself can know. The active sheet is
|
|
48
|
+
* always offered either way — it is the default selection.
|
|
49
|
+
*/
|
|
50
|
+
export function getFilterableSheetIds(rules, sheetId, workbookSheetIds) {
|
|
51
|
+
const ids = workbookSheetIds
|
|
52
|
+
? Array.from(new Set(workbookSheetIds))
|
|
53
|
+
: getSheetIdsWithRules(rules);
|
|
54
|
+
return ids.includes(sheetId) ? ids : [sheetId, ...ids];
|
|
55
|
+
}
|
|
41
56
|
/**
|
|
42
57
|
* Rule lists (conditional formats, data validations) are scoped to the active
|
|
43
|
-
* sheet by default; the SheetFilterSelect widens the view to
|
|
44
|
-
*
|
|
45
|
-
*
|
|
58
|
+
* sheet by default; the SheetFilterSelect widens the view to another sheet, or
|
|
59
|
+
* all sheets. Follows the active sheet if the user switches sheets while the
|
|
60
|
+
* dialog is open.
|
|
61
|
+
*
|
|
62
|
+
* `workbookSheetIds` is the workbook's sheets in tab order; see getFilterableSheetIds.
|
|
46
63
|
*/
|
|
47
|
-
export function useSheetFilter(sheetId, rules) {
|
|
64
|
+
export function useSheetFilter(sheetId, rules, workbookSheetIds) {
|
|
48
65
|
const [sheetFilter, setSheetFilter] = useState(sheetId);
|
|
49
66
|
useEffect(() => {
|
|
50
67
|
setSheetFilter(sheetId);
|
|
51
68
|
}, [sheetId]);
|
|
52
|
-
const filterableSheetIds = useMemo(() =>
|
|
53
|
-
const ids = getSheetIdsWithRules(rules);
|
|
54
|
-
// The active sheet is always offered, even before it has rules.
|
|
55
|
-
return ids.includes(sheetId) ? ids : [sheetId, ...ids];
|
|
56
|
-
}, [rules, sheetId]);
|
|
69
|
+
const filterableSheetIds = useMemo(() => getFilterableSheetIds(rules, sheetId, workbookSheetIds), [rules, sheetId, workbookSheetIds]);
|
|
57
70
|
const visibleRules = useMemo(() => filterRulesBySheet(rules, sheetFilter), [rules, sheetFilter]);
|
|
58
71
|
const showFilter = shouldShowSheetFilter({
|
|
59
72
|
ruleCount: rules.length,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rowsncolumns/spreadsheet-state",
|
|
3
|
-
"version": "29.1.
|
|
3
|
+
"version": "29.1.19",
|
|
4
4
|
"main": "./dist/cjs/index.js",
|
|
5
5
|
"module": "./dist/esm/index.js",
|
|
6
6
|
"types": "./dist/esm/index.d.ts",
|
|
@@ -78,15 +78,15 @@
|
|
|
78
78
|
"@rowsncolumns/fast-formula-parser": ">=6.2.45",
|
|
79
79
|
"@rowsncolumns/grid": ">=13.2.39",
|
|
80
80
|
"@rowsncolumns/icons": ">=7.2.33",
|
|
81
|
-
"@rowsncolumns/spreadsheet": ">=10.5.
|
|
81
|
+
"@rowsncolumns/spreadsheet": ">=10.5.16",
|
|
82
82
|
"@rowsncolumns/ui": ">=16.1.0",
|
|
83
|
-
"@rowsncolumns/utils": ">=9.5.
|
|
83
|
+
"@rowsncolumns/utils": ">=9.5.7"
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
86
|
"@rowsncolumns/calculation-worker": ">=10.0.3",
|
|
87
87
|
"@rowsncolumns/date-parser": ">=13.0.4",
|
|
88
88
|
"@rowsncolumns/functions": ">=15.1.0",
|
|
89
|
-
"@rowsncolumns/toolkit": ">=24.5.
|
|
89
|
+
"@rowsncolumns/toolkit": ">=24.5.18",
|
|
90
90
|
"formik": "^2.4.6",
|
|
91
91
|
"immer": "^10.1.1",
|
|
92
92
|
"jotai": "^2.12.4",
|