@rowsncolumns/spreadsheet-state 29.1.16 → 29.1.18

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 (35) hide show
  1. package/dist/cjs/components/editors/conditional-format-editor.d.ts +7 -2
  2. package/dist/cjs/components/editors/conditional-format-editor.d.ts.map +1 -1
  3. package/dist/cjs/components/editors/conditional-format-editor.js +3 -2
  4. package/dist/cjs/components/editors/data-validation-editor.d.ts +7 -2
  5. package/dist/cjs/components/editors/data-validation-editor.d.ts.map +1 -1
  6. package/dist/cjs/components/editors/data-validation-editor.js +3 -2
  7. package/dist/cjs/components/editors/sheet-filter.d.ts +16 -4
  8. package/dist/cjs/components/editors/sheet-filter.d.ts.map +1 -1
  9. package/dist/cjs/components/editors/sheet-filter.js +22 -9
  10. package/dist/cjs/hooks/use-on-request-create-table.d.ts +3 -3
  11. package/dist/cjs/hooks/use-on-request-create-table.d.ts.map +1 -1
  12. package/dist/cjs/hooks/use-on-request-create-table.js +8 -4
  13. package/dist/cjs/interface/delete-cells.d.ts.map +1 -1
  14. package/dist/cjs/interface/delete-cells.js +64 -22
  15. package/dist/cjs/interface/remove-table.d.ts +11 -0
  16. package/dist/cjs/interface/remove-table.d.ts.map +1 -1
  17. package/dist/cjs/interface/remove-table.js +71 -40
  18. package/dist/esm/components/editors/conditional-format-editor.d.ts +7 -2
  19. package/dist/esm/components/editors/conditional-format-editor.d.ts.map +1 -1
  20. package/dist/esm/components/editors/conditional-format-editor.js +3 -2
  21. package/dist/esm/components/editors/data-validation-editor.d.ts +7 -2
  22. package/dist/esm/components/editors/data-validation-editor.d.ts.map +1 -1
  23. package/dist/esm/components/editors/data-validation-editor.js +3 -2
  24. package/dist/esm/components/editors/sheet-filter.d.ts +16 -4
  25. package/dist/esm/components/editors/sheet-filter.d.ts.map +1 -1
  26. package/dist/esm/components/editors/sheet-filter.js +22 -9
  27. package/dist/esm/hooks/use-on-request-create-table.d.ts +3 -3
  28. package/dist/esm/hooks/use-on-request-create-table.d.ts.map +1 -1
  29. package/dist/esm/hooks/use-on-request-create-table.js +8 -4
  30. package/dist/esm/interface/delete-cells.d.ts.map +1 -1
  31. package/dist/esm/interface/delete-cells.js +31 -6
  32. package/dist/esm/interface/remove-table.d.ts +11 -0
  33. package/dist/esm/interface/remove-table.d.ts.map +1 -1
  34. package/dist/esm/interface/remove-table.js +49 -33
  35. package/package.json +1 -1
@@ -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,oJAWrC,4BAA4B,sBAiR9B,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,eAErC;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,sBAyBA,CAAC"}
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 _d = useSheetFilter(sheetId, conditionalFormats), sheetFilter = _d.sheetFilter, setSheetFilter = _d.setSheetFilter, filterableSheetIds = _d.filterableSheetIds, visibleRules = _d.visibleRules, showFilter = _d.showFilter;
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,EACzB,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,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,kIASlC,yBAAyB,sBAoP3B,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,eAExC;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,sBAyBA,CAAC"}
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 _d = useSheetFilter(sheetId, dataValidations !== null && dataValidations !== void 0 ? dataValidations : []), sheetFilter = _d.sheetFilter, setSheetFilter = _d.setSheetFilter, filterableSheetIds = _d.filterableSheetIds, visibleRules = _d.visibleRules, showFilter = _d.showFilter;
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 any sheet with
39
- * rules, or all sheets. Follows the active sheet if the user switches sheets
40
- * while the dialog is open.
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;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,cAAc,EACrD,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,CAAC,EAAE;;;;;;EA+BX;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"}
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 any sheet with
68
- * rules, or all sheets. Follows the active sheet if the user switches sheets
69
- * while the dialog is open.
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,
@@ -5,9 +5,9 @@ export type UseOnRequestCreateTableProps = {
5
5
  };
6
6
  /**
7
7
  * Open Excel's "Create Table" dialog (Ctrl+T / Insert → Table / Format as Table): the range
8
- * pre-fills with the selection, else the data region around the active cell (Ctrl+A's region),
9
- * and "My table has headers" is guessed from that range's first row. The dialog submits through
10
- * `onCreateTable`.
8
+ * pre-fills with the selection, else — with none, or one collapsed on a single cell — the data
9
+ * region around the active cell (Ctrl+A's region), and "My table has headers" is guessed from
10
+ * that range's first row. The dialog submits through `onCreateTable`.
11
11
  */
12
12
  export declare const useOnRequestCreateTable: ({ getEffectiveExtendedValue, }: UseOnRequestCreateTableProps) => (sheetId: number, activeCell: CellInterface, selections: SelectionArea<SelectionAttributes>[], theme?: TableTheme, bandedRange?: BandedDefinition) => void;
13
13
  //# sourceMappingURL=use-on-request-create-table.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-on-request-create-table.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-request-create-table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACd,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,EACX,MAAM,2BAA2B,CAAC;AASnC,MAAM,MAAM,4BAA4B,GAAG;IACzC,yBAAyB,EAAE,CACzB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,KAChB,aAAa,GAAG,IAAI,GAAG,SAAS,CAAC;CACvC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,gCAErC,4BAA4B,eAMhB,MAAM,cACH,aAAa,cACb,aAAa,CAAC,mBAAmB,CAAC,EAAE,UACxC,UAAU,gBACJ,gBAAgB,SA6BnC,CAAC"}
1
+ {"version":3,"file":"use-on-request-create-table.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-request-create-table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACd,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,EACX,MAAM,2BAA2B,CAAC;AASnC,MAAM,MAAM,4BAA4B,GAAG;IACzC,yBAAyB,EAAE,CACzB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,KAChB,aAAa,GAAG,IAAI,GAAG,SAAS,CAAC;CACvC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,gCAErC,4BAA4B,eAMhB,MAAM,cACH,aAAa,cACb,aAAa,CAAC,mBAAmB,CAAC,EAAE,UACxC,UAAU,gBACJ,gBAAgB,SAkCnC,CAAC"}
@@ -6,9 +6,9 @@ import { useSetCreatingTable } from "../atoms/creating-table.atom";
6
6
  import { useSetCreateTableDialogValue } from "../atoms/dialog-state.atom";
7
7
  /**
8
8
  * Open Excel's "Create Table" dialog (Ctrl+T / Insert → Table / Format as Table): the range
9
- * pre-fills with the selection, else the data region around the active cell (Ctrl+A's region),
10
- * and "My table has headers" is guessed from that range's first row. The dialog submits through
11
- * `onCreateTable`.
9
+ * pre-fills with the selection, else — with none, or one collapsed on a single cell — the data
10
+ * region around the active cell (Ctrl+A's region), and "My table has headers" is guessed from
11
+ * that range's first row. The dialog submits through `onCreateTable`.
12
12
  */
13
13
  export var useOnRequestCreateTable = function (_a) {
14
14
  var getEffectiveExtendedValue = _a.getEffectiveExtendedValue;
@@ -18,7 +18,11 @@ export var useOnRequestCreateTable = function (_a) {
18
18
  return useCallback(function (sheetId, activeCell, selections, theme, bandedRange) {
19
19
  var _a;
20
20
  var lastSelection = selections === null || selections === void 0 ? void 0 : selections[selections.length - 1];
21
- var range = lastSelection
21
+ var collapsed = !lastSelection ||
22
+ (lastSelection.range.startRowIndex === lastSelection.range.endRowIndex &&
23
+ lastSelection.range.startColumnIndex ===
24
+ lastSelection.range.endColumnIndex);
25
+ var range = !collapsed
22
26
  ? lastSelection.range
23
27
  : (_a = getContentfulRangeAroundCell === null || getContentfulRangeAroundCell === void 0 ? void 0 : getContentfulRangeAroundCell(sheetId, activeCell)) !== null && _a !== void 0 ? _a : selectionFromActiveCell(activeCell)[0].range;
24
28
  setCreatingTable({
@@ -1 +1 @@
1
- {"version":3,"file":"delete-cells.d.ts","sourceRoot":"","sources":["../../../interface/delete-cells.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAEb,aAAa,EACd,MAAM,4BAA4B,CAAC;AAGpC,OAAO,KAAK,EACV,QAAQ,EAER,mBAAmB,EACnB,KAAK,EACN,MAAM,2BAA2B,CAAC;AAKnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAK/D,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,gUAoB9D,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,MAErB,SAAS,MAAM,EACf,MAAM,aAAa,EACnB,YAAY,aAAa,CAAC,mBAAmB,CAAC,EAAE,EAChD,YAAW,SAAsB,SAgSpC,CAAC"}
1
+ {"version":3,"file":"delete-cells.d.ts","sourceRoot":"","sources":["../../../interface/delete-cells.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAEb,aAAa,EACd,MAAM,4BAA4B,CAAC;AAGpC,OAAO,KAAK,EACV,QAAQ,EAER,mBAAmB,EACnB,KAAK,EACN,MAAM,2BAA2B,CAAC;AAKnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAM/D,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,gUAoB9D,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,MAErB,SAAS,MAAM,EACf,MAAM,aAAa,EACnB,YAAY,aAAa,CAAC,mBAAmB,CAAC,EAAE,EAChD,YAAW,SAAsB,SA+TpC,CAAC"}
@@ -5,6 +5,7 @@ import { produceWithPatches } from "immer";
5
5
  import { createSheetCellIdentifier } from "../api/formula";
6
6
  import { createSheetDraft } from "../api/immer-utils";
7
7
  import { SheetCell } from "../sheet-cell";
8
+ import { releaseTableFilterRows } from "./remove-table";
8
9
  import { getTableHeaderRefills } from "./table-utils";
9
10
  export var deleteCells = function (_a) {
10
11
  var locale = _a.locale, rowCount = _a.rowCount, cellXfsRegistry = _a.cellXfsRegistry, sharedStringRegistry = _a.sharedStringRegistry, getDataValidationById = _a.getDataValidationById, getDependents = _a.getDependents, getDataRowCount = _a.getDataRowCount, onChangeSheetData = _a.onChangeSheetData, onChangeSheets = _a.onChangeSheets, onChangeTables = _a.onChangeTables, onChangeCitations = _a.onChangeCitations, onChangeActiveCell = _a.onChangeActiveCell, enqueueCalculation = _a.enqueueCalculation, enqueueStructureChange = _a.enqueueStructureChange, createHistory = _a.createHistory, isArrayFormula = _a.isArrayFormula, getRowHeight = _a.getRowHeight, tables = _a.tables, generatedNames = _a.generatedNames;
@@ -18,13 +19,28 @@ export var deleteCells = function (_a) {
18
19
  : selectionFromActiveCell(cell);
19
20
  var saveHistory = createHistory();
20
21
  var maxRowCount = getDataRowCount();
21
- // A table survives Delete / Clear (Excel): only its cells empty out, and
22
- // cleared header cells are re-named `ColumnN` so the header row and
23
- // `columns[]` stay in step.
22
+ // Delete / Clear over a selection that covers a whole table deletes the table (Excel's
23
+ // "select the table and press Delete"): the table, its filter and its style go with the
24
+ // cells, and the structured references into it error as they do for any deleted table
25
+ // (Convert to Range is the path that rewrites them to A1).
26
+ var removedTables = shouldClearContents
27
+ ? (tables !== null && tables !== void 0 ? tables : []).filter(function (table) {
28
+ return table.sheetId === sheetId &&
29
+ finalSelections.some(function (selection) {
30
+ return areaInsideArea(table.range, selection.range);
31
+ });
32
+ })
33
+ : [];
34
+ var keptTables = removedTables.length
35
+ ? tables === null || tables === void 0 ? void 0 : tables.filter(function (table) { return !removedTables.includes(table); })
36
+ : tables;
37
+ // A table survives Delete / Clear over part of it (Excel): only its cells
38
+ // empty out, and cleared header cells are re-named `ColumnN` so the header
39
+ // row and `columns[]` stay in step.
24
40
  var headerRefills = shouldClearContents
25
41
  ? getTableHeaderRefills({
26
42
  sheetId: sheetId,
27
- tables: tables,
43
+ tables: keptTables,
28
44
  selections: finalSelections,
29
45
  generatedNames: generatedNames,
30
46
  })
@@ -170,17 +186,36 @@ export var deleteCells = function (_a) {
170
186
  });
171
187
  return nextState;
172
188
  });
173
- // Rename the columns whose header cells were cleared
174
- if (headerRefills.length) {
189
+ // Drop the tables the selection covered, and rename the columns whose header cells were cleared
190
+ if (headerRefills.length || removedTables.length) {
175
191
  onChangeTables === null || onChangeTables === void 0 ? void 0 : onChangeTables(function (prevTables) {
176
192
  var _a = __read(produceWithPatches(prevTables, function (draft) {
177
- var e_4, _a;
178
- var _b;
179
- var _loop_1 = function (tableId, dimensionIndex, name_2) {
193
+ var e_4, _a, e_5, _b;
194
+ var _c;
195
+ var _loop_1 = function (removed) {
196
+ var tableIndex = draft.findIndex(function (table) { return table.id == removed.id; });
197
+ if (tableIndex !== -1) {
198
+ draft.splice(tableIndex, 1);
199
+ }
200
+ };
201
+ try {
202
+ for (var removedTables_1 = __values(removedTables), removedTables_1_1 = removedTables_1.next(); !removedTables_1_1.done; removedTables_1_1 = removedTables_1.next()) {
203
+ var removed = removedTables_1_1.value;
204
+ _loop_1(removed);
205
+ }
206
+ }
207
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
208
+ finally {
209
+ try {
210
+ if (removedTables_1_1 && !removedTables_1_1.done && (_a = removedTables_1.return)) _a.call(removedTables_1);
211
+ }
212
+ finally { if (e_4) throw e_4.error; }
213
+ }
214
+ var _loop_2 = function (tableId, dimensionIndex, name_2) {
180
215
  var table = draft.find(function (table) { return table.sheetId === sheetId && table.id === tableId; });
181
216
  if (!table)
182
217
  return "continue";
183
- (_b = table.columns) !== null && _b !== void 0 ? _b : (table.columns = []);
218
+ (_c = table.columns) !== null && _c !== void 0 ? _c : (table.columns = []);
184
219
  var column = table.columns[dimensionIndex];
185
220
  if (column) {
186
221
  column.name = name_2;
@@ -191,16 +226,16 @@ export var deleteCells = function (_a) {
191
226
  };
192
227
  try {
193
228
  for (var headerRefills_2 = __values(headerRefills), headerRefills_2_1 = headerRefills_2.next(); !headerRefills_2_1.done; headerRefills_2_1 = headerRefills_2.next()) {
194
- var _c = headerRefills_2_1.value, tableId = _c.tableId, dimensionIndex = _c.dimensionIndex, name_2 = _c.name;
195
- _loop_1(tableId, dimensionIndex, name_2);
229
+ var _d = headerRefills_2_1.value, tableId = _d.tableId, dimensionIndex = _d.dimensionIndex, name_2 = _d.name;
230
+ _loop_2(tableId, dimensionIndex, name_2);
196
231
  }
197
232
  }
198
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
233
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
199
234
  finally {
200
235
  try {
201
- if (headerRefills_2_1 && !headerRefills_2_1.done && (_a = headerRefills_2.return)) _a.call(headerRefills_2);
236
+ if (headerRefills_2_1 && !headerRefills_2_1.done && (_b = headerRefills_2.return)) _b.call(headerRefills_2);
202
237
  }
203
- finally { if (e_4) throw e_4.error; }
238
+ finally { if (e_5) throw e_5.error; }
204
239
  }
205
240
  }), 3), nextState = _a[0], patches = _a[1], inversePatches = _a[2];
206
241
  saveHistory({
@@ -208,6 +243,13 @@ export var deleteCells = function (_a) {
208
243
  });
209
244
  return nextState;
210
245
  });
246
+ releaseTableFilterRows({
247
+ tables: removedTables,
248
+ onChangeSheets: onChangeSheets,
249
+ saveHistory: saveHistory,
250
+ getDependents: getDependents,
251
+ enqueueCalculation: enqueueCalculation,
252
+ });
211
253
  }
212
254
  // Update citations - retire citations whose cited cells lose their contents.
213
255
  // Clearing formats only leaves the cited values in place, so the citations stay.
@@ -215,7 +257,7 @@ export var deleteCells = function (_a) {
215
257
  onChangeCitations === null || onChangeCitations === void 0 ? void 0 : onChangeCitations(function (prevCitations) {
216
258
  var updatedAt = new Date().toISOString();
217
259
  var _a = __read(produceWithPatches(prevCitations, function (draft) {
218
- var _loop_2 = function (idx) {
260
+ var _loop_3 = function (idx) {
219
261
  var citation = draft[idx];
220
262
  // Check if citation is active, on the same sheet and inside a cleared selection
221
263
  if (citation.active !== false &&
@@ -229,7 +271,7 @@ export var deleteCells = function (_a) {
229
271
  }
230
272
  };
231
273
  for (var idx = draft.length - 1; idx >= 0; idx--) {
232
- _loop_2(idx);
274
+ _loop_3(idx);
233
275
  }
234
276
  }), 3), nextState = _a[0], patches = _a[1], inversePatches = _a[2];
235
277
  saveHistory({
@@ -241,11 +283,11 @@ export var deleteCells = function (_a) {
241
283
  // Update banded cells
242
284
  onChangeSheets === null || onChangeSheets === void 0 ? void 0 : onChangeSheets(function (prevSheets) {
243
285
  var _a = __read(produceWithPatches(prevSheets, function (draft) {
244
- var e_5, _a;
286
+ var e_6, _a;
245
287
  var _b, _c, _d, _e, _f;
246
288
  var sheet = draft.find(function (sheet) { return sheet.sheetId === sheetId; });
247
289
  if (sheet) {
248
- var _loop_3 = function (selection) {
290
+ var _loop_4 = function (selection) {
249
291
  for (var rowIndex = selection.range.startRowIndex; rowIndex <=
250
292
  Math.min(maxRowCount !== null && maxRowCount !== void 0 ? maxRowCount : rowCount, selection.range.endRowIndex); rowIndex++) {
251
293
  var isRowResizedByUser = !!((_c = (_b = sheet === null || sheet === void 0 ? void 0 : sheet.rowMetadata) === null || _b === void 0 ? void 0 : _b[rowIndex]) === null || _c === void 0 ? void 0 : _c.resizedByUser);
@@ -270,15 +312,15 @@ export var deleteCells = function (_a) {
270
312
  // Adjust row height
271
313
  for (var finalSelections_3 = __values(finalSelections), finalSelections_3_1 = finalSelections_3.next(); !finalSelections_3_1.done; finalSelections_3_1 = finalSelections_3.next()) {
272
314
  var selection = finalSelections_3_1.value;
273
- _loop_3(selection);
315
+ _loop_4(selection);
274
316
  }
275
317
  }
276
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
318
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
277
319
  finally {
278
320
  try {
279
321
  if (finalSelections_3_1 && !finalSelections_3_1.done && (_a = finalSelections_3.return)) _a.call(finalSelections_3);
280
322
  }
281
- finally { if (e_5) throw e_5.error; }
323
+ finally { if (e_6) throw e_6.error; }
282
324
  }
283
325
  }
284
326
  }), 3), nextState = _a[0], patches = _a[1], inversePatches = _a[2];
@@ -1,4 +1,15 @@
1
1
  import type { CellData, Sheet, TableView } from "@rowsncolumns/spreadsheet";
2
2
  import type { UseOnTableProps } from "../hooks/use-on-table";
3
3
  export declare const removeTable: <T extends CellData, S extends Sheet>({ locale, cellXfsRegistry, sharedStringRegistry, getSheetName, onChangeTables, onChangeSheets, onChangeSheetData, createHistory, getDependents, getGraphNodes, getBandedCells, enqueueCalculation, enqueueGraphOperation, }: Pick<UseOnTableProps<T, S>, "locale" | "cellXfsRegistry" | "sharedStringRegistry" | "getSheetName" | "onChangeTables" | "onChangeSheets" | "onChangeSheetData" | "getDependents" | "getGraphNodes" | "getBandedCells" | "enqueueCalculation" | "enqueueGraphOperation" | "createHistory">) => (tableView: TableView) => void;
4
+ /**
5
+ * A removed table's filter goes with it: the rows it hid become visible again, in the history step
6
+ * of the removal (`saveHistory`). Their values did not change, so only the formulas that read
7
+ * visibility — `SUBTOTAL(101…111)` / `AGGREGATE` over those rows — are stale; dirtying the
8
+ * un-hidden cells recalculates exactly those dependents. Shared by Convert to Range
9
+ * (`removeTable`) and Delete over a whole table (`deleteCells`).
10
+ */
11
+ export declare const releaseTableFilterRows: <T extends CellData, S extends Sheet>({ tables, onChangeSheets, saveHistory, getDependents, enqueueCalculation, }: Pick<UseOnTableProps<T, S>, "onChangeSheets" | "getDependents" | "enqueueCalculation"> & {
12
+ tables: TableView[];
13
+ saveHistory: ReturnType<UseOnTableProps<T, S>["createHistory"]>;
14
+ }) => void;
4
15
  //# sourceMappingURL=remove-table.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"remove-table.d.ts","sourceRoot":"","sources":["../../../interface/remove-table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAK5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAI7D,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,6NAc9D,IAAI,CACL,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACnB,QAAQ,GACR,iBAAiB,GACjB,sBAAsB,GACtB,cAAc,GACd,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,oBAAoB,GACpB,uBAAuB,GACvB,eAAe,CAClB,MACS,WAAW,SAAS,SAwH7B,CAAC"}
1
+ {"version":3,"file":"remove-table.d.ts","sourceRoot":"","sources":["../../../interface/remove-table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAK5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAI7D,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,6NAc9D,IAAI,CACL,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACnB,QAAQ,GACR,iBAAiB,GACjB,sBAAsB,GACtB,cAAc,GACd,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,oBAAoB,GACpB,uBAAuB,GACvB,eAAe,CAClB,MACS,WAAW,SAAS,SA0E7B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,6EAMzE,IAAI,CACL,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACrB,gBAAgB,GAAG,eAAe,GAAG,oBAAoB,CAC1D,GAAG;IACF,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;CACjE,SAoDA,CAAC"}
@@ -59,51 +59,82 @@ export var removeTable = function (_a) {
59
59
  });
60
60
  return nextState;
61
61
  });
62
- // The table's filter goes with it: rows it hid become visible again. Their values did not
63
- // change, so only the formulas that read visibility — `SUBTOTAL(101…111)` / `AGGREGATE` over
64
- // those rows — are stale; dirtying the un-hidden cells recalculates exactly those dependents
65
- // (the rewritten structured references were re-entered above with `force`).
66
- var unhiddenRecalcCells = new Map();
67
- onChangeSheets(function (prevSheets) {
68
- var _a = __read(produceWithPatches(prevSheets, function (draft) {
69
- var e_1, _a;
70
- var _b;
62
+ releaseTableFilterRows({
63
+ tables: [tableView],
64
+ onChangeSheets: onChangeSheets,
65
+ saveHistory: saveHistory,
66
+ getDependents: getDependents,
67
+ enqueueCalculation: enqueueCalculation,
68
+ });
69
+ };
70
+ };
71
+ /**
72
+ * A removed table's filter goes with it: the rows it hid become visible again, in the history step
73
+ * of the removal (`saveHistory`). Their values did not change, so only the formulas that read
74
+ * visibility — `SUBTOTAL(101…111)` / `AGGREGATE` over those rows — are stale; dirtying the
75
+ * un-hidden cells recalculates exactly those dependents. Shared by Convert to Range
76
+ * (`removeTable`) and Delete over a whole table (`deleteCells`).
77
+ */
78
+ export var releaseTableFilterRows = function (_a) {
79
+ var tables = _a.tables, onChangeSheets = _a.onChangeSheets, saveHistory = _a.saveHistory, getDependents = _a.getDependents, enqueueCalculation = _a.enqueueCalculation;
80
+ if (!tables.length)
81
+ return;
82
+ var unhiddenRecalcCells = new Map();
83
+ onChangeSheets(function (prevSheets) {
84
+ var _a = __read(produceWithPatches(prevSheets, function (draft) {
85
+ var e_1, _a;
86
+ var _b;
87
+ var _loop_1 = function (tableView) {
88
+ var e_2, _c;
71
89
  var sheet = draft.find(function (sheet) { return sheet.sheetId === tableView.sheetId; });
72
- if (sheet && tableView) {
73
- if (!sheet.rowMetadata) {
74
- sheet.rowMetadata = [];
75
- }
76
- var range = tableView.range;
77
- for (var rowIndex = range.startRowIndex; rowIndex <= range.endRowIndex; rowIndex++) {
78
- if ((_b = sheet.rowMetadata[rowIndex]) === null || _b === void 0 ? void 0 : _b.hiddenByFilter) {
79
- sheet.rowMetadata[rowIndex].hiddenByFilter = false;
80
- try {
81
- for (var _c = (e_1 = void 0, __values(markTableAsDirty(tableView.sheetId, __assign(__assign({}, range), { startRowIndex: rowIndex, endRowIndex: rowIndex }), getDependents, enqueueCalculation))), _d = _c.next(); !_d.done; _d = _c.next()) {
82
- var _e = __read(_d.value, 2), key = _e[0], position = _e[1];
83
- unhiddenRecalcCells.set(key, position);
84
- }
90
+ if (!sheet)
91
+ return "continue";
92
+ if (!sheet.rowMetadata) {
93
+ sheet.rowMetadata = [];
94
+ }
95
+ var range = tableView.range;
96
+ for (var rowIndex = range.startRowIndex; rowIndex <= range.endRowIndex; rowIndex++) {
97
+ if ((_b = sheet.rowMetadata[rowIndex]) === null || _b === void 0 ? void 0 : _b.hiddenByFilter) {
98
+ sheet.rowMetadata[rowIndex].hiddenByFilter = false;
99
+ try {
100
+ for (var _d = (e_2 = void 0, __values(markTableAsDirty(tableView.sheetId, __assign(__assign({}, range), { startRowIndex: rowIndex, endRowIndex: rowIndex }), getDependents, enqueueCalculation))), _e = _d.next(); !_e.done; _e = _d.next()) {
101
+ var _f = __read(_e.value, 2), key = _f[0], position = _f[1];
102
+ unhiddenRecalcCells.set(key, position);
85
103
  }
86
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
87
- finally {
88
- try {
89
- if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
90
- }
91
- finally { if (e_1) throw e_1.error; }
104
+ }
105
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
106
+ finally {
107
+ try {
108
+ if (_e && !_e.done && (_c = _d.return)) _c.call(_d);
92
109
  }
110
+ finally { if (e_2) throw e_2.error; }
93
111
  }
94
112
  }
95
113
  }
96
- }), 3), nextState = _a[0], patches = _a[1], inversePatches = _a[2];
97
- // Save to history
98
- saveHistory(__assign({ sheets: { patches: patches, inversePatches: inversePatches } }, (unhiddenRecalcCells.size
99
- ? {
100
- recalcCells: {
101
- undo: unhiddenRecalcCells,
102
- redo: unhiddenRecalcCells,
103
- },
114
+ };
115
+ try {
116
+ for (var tables_1 = __values(tables), tables_1_1 = tables_1.next(); !tables_1_1.done; tables_1_1 = tables_1.next()) {
117
+ var tableView = tables_1_1.value;
118
+ _loop_1(tableView);
104
119
  }
105
- : {})));
106
- return nextState;
107
- });
108
- };
120
+ }
121
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
122
+ finally {
123
+ try {
124
+ if (tables_1_1 && !tables_1_1.done && (_a = tables_1.return)) _a.call(tables_1);
125
+ }
126
+ finally { if (e_1) throw e_1.error; }
127
+ }
128
+ }), 3), nextState = _a[0], patches = _a[1], inversePatches = _a[2];
129
+ // Save to history
130
+ saveHistory(__assign({ sheets: { patches: patches, inversePatches: inversePatches } }, (unhiddenRecalcCells.size
131
+ ? {
132
+ recalcCells: {
133
+ undo: unhiddenRecalcCells,
134
+ redo: unhiddenRecalcCells,
135
+ },
136
+ }
137
+ : {})));
138
+ return nextState;
139
+ });
109
140
  };
@@ -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,oJAWrC,4BAA4B,sBAiR9B,CAAC;AAEF,eAAO,MAAM,uBAAuB,GAAI,eAErC;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,sBAyBA,CAAC"}
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 { sheetFilter, setSheetFilter, filterableSheetIds, visibleRules, showFilter, } = useSheetFilter(sheetId, conditionalFormats);
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,EACzB,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,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,kIASlC,yBAAyB,sBAoP3B,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,eAExC;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,sBAyBA,CAAC"}
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 { sheetFilter, setSheetFilter, filterableSheetIds, visibleRules, showFilter, } = useSheetFilter(sheetId, dataValidations ?? []);
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 any sheet with
39
- * rules, or all sheets. Follows the active sheet if the user switches sheets
40
- * while the dialog is open.
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;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,cAAc,EACrD,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,CAAC,EAAE;;;;;;EA+BX;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"}
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 any sheet with
44
- * rules, or all sheets. Follows the active sheet if the user switches sheets
45
- * while the dialog is open.
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,
@@ -5,9 +5,9 @@ export type UseOnRequestCreateTableProps = {
5
5
  };
6
6
  /**
7
7
  * Open Excel's "Create Table" dialog (Ctrl+T / Insert → Table / Format as Table): the range
8
- * pre-fills with the selection, else the data region around the active cell (Ctrl+A's region),
9
- * and "My table has headers" is guessed from that range's first row. The dialog submits through
10
- * `onCreateTable`.
8
+ * pre-fills with the selection, else — with none, or one collapsed on a single cell — the data
9
+ * region around the active cell (Ctrl+A's region), and "My table has headers" is guessed from
10
+ * that range's first row. The dialog submits through `onCreateTable`.
11
11
  */
12
12
  export declare const useOnRequestCreateTable: ({ getEffectiveExtendedValue, }: UseOnRequestCreateTableProps) => (sheetId: number, activeCell: CellInterface, selections: SelectionArea<SelectionAttributes>[], theme?: TableTheme, bandedRange?: BandedDefinition) => void;
13
13
  //# sourceMappingURL=use-on-request-create-table.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-on-request-create-table.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-request-create-table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACd,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,EACX,MAAM,2BAA2B,CAAC;AASnC,MAAM,MAAM,4BAA4B,GAAG;IACzC,yBAAyB,EAAE,CACzB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,KAChB,aAAa,GAAG,IAAI,GAAG,SAAS,CAAC;CACvC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,gCAErC,4BAA4B,eAMhB,MAAM,cACH,aAAa,cACb,aAAa,CAAC,mBAAmB,CAAC,EAAE,UACxC,UAAU,gBACJ,gBAAgB,SA6BnC,CAAC"}
1
+ {"version":3,"file":"use-on-request-create-table.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-request-create-table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,aAAa,EACb,aAAa,EACd,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EACV,gBAAgB,EAChB,mBAAmB,EACnB,UAAU,EACX,MAAM,2BAA2B,CAAC;AASnC,MAAM,MAAM,4BAA4B,GAAG;IACzC,yBAAyB,EAAE,CACzB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,KAChB,aAAa,GAAG,IAAI,GAAG,SAAS,CAAC;CACvC,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,gCAErC,4BAA4B,eAMhB,MAAM,cACH,aAAa,cACb,aAAa,CAAC,mBAAmB,CAAC,EAAE,UACxC,UAAU,gBACJ,gBAAgB,SAkCnC,CAAC"}
@@ -6,9 +6,9 @@ import { useSetCreatingTable } from "../atoms/creating-table.atom";
6
6
  import { useSetCreateTableDialogValue } from "../atoms/dialog-state.atom";
7
7
  /**
8
8
  * Open Excel's "Create Table" dialog (Ctrl+T / Insert → Table / Format as Table): the range
9
- * pre-fills with the selection, else the data region around the active cell (Ctrl+A's region),
10
- * and "My table has headers" is guessed from that range's first row. The dialog submits through
11
- * `onCreateTable`.
9
+ * pre-fills with the selection, else — with none, or one collapsed on a single cell — the data
10
+ * region around the active cell (Ctrl+A's region), and "My table has headers" is guessed from
11
+ * that range's first row. The dialog submits through `onCreateTable`.
12
12
  */
13
13
  export const useOnRequestCreateTable = ({ getEffectiveExtendedValue, }) => {
14
14
  const setCreateDialog = useSetCreateTableDialogValue();
@@ -16,7 +16,11 @@ export const useOnRequestCreateTable = ({ getEffectiveExtendedValue, }) => {
16
16
  const getContentfulRangeAroundCell = useGetContentfulRangeAroundCell();
17
17
  return useCallback((sheetId, activeCell, selections, theme, bandedRange) => {
18
18
  const lastSelection = selections?.[selections.length - 1];
19
- const range = lastSelection
19
+ const collapsed = !lastSelection ||
20
+ (lastSelection.range.startRowIndex === lastSelection.range.endRowIndex &&
21
+ lastSelection.range.startColumnIndex ===
22
+ lastSelection.range.endColumnIndex);
23
+ const range = !collapsed
20
24
  ? lastSelection.range
21
25
  : getContentfulRangeAroundCell?.(sheetId, activeCell) ??
22
26
  selectionFromActiveCell(activeCell)[0].range;
@@ -1 +1 @@
1
- {"version":3,"file":"delete-cells.d.ts","sourceRoot":"","sources":["../../../interface/delete-cells.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAEb,aAAa,EACd,MAAM,4BAA4B,CAAC;AAGpC,OAAO,KAAK,EACV,QAAQ,EAER,mBAAmB,EACnB,KAAK,EACN,MAAM,2BAA2B,CAAC;AAKnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAK/D,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,gUAoB9D,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,MAErB,SAAS,MAAM,EACf,MAAM,aAAa,EACnB,YAAY,aAAa,CAAC,mBAAmB,CAAC,EAAE,EAChD,YAAW,SAAsB,SAgSpC,CAAC"}
1
+ {"version":3,"file":"delete-cells.d.ts","sourceRoot":"","sources":["../../../interface/delete-cells.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAEb,aAAa,EACd,MAAM,4BAA4B,CAAC;AAGpC,OAAO,KAAK,EACV,QAAQ,EAER,mBAAmB,EACnB,KAAK,EACN,MAAM,2BAA2B,CAAC;AAKnC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAM/D,MAAM,MAAM,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAAC;AAEvD,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,gUAoB9D,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAC,MAErB,SAAS,MAAM,EACf,MAAM,aAAa,EACnB,YAAY,aAAa,CAAC,mBAAmB,CAAC,EAAE,EAChD,YAAW,SAAsB,SA+TpC,CAAC"}
@@ -4,6 +4,7 @@ import { produceWithPatches } from "immer";
4
4
  import { createSheetCellIdentifier } from "../api/formula";
5
5
  import { createSheetDraft } from "../api/immer-utils";
6
6
  import { SheetCell } from "../sheet-cell";
7
+ import { releaseTableFilterRows } from "./remove-table";
7
8
  import { getTableHeaderRefills } from "./table-utils";
8
9
  export const deleteCells = ({ locale, rowCount, cellXfsRegistry, sharedStringRegistry, getDataValidationById, getDependents, getDataRowCount, onChangeSheetData, onChangeSheets, onChangeTables, onChangeCitations, onChangeActiveCell, enqueueCalculation, enqueueStructureChange, createHistory, isArrayFormula, getRowHeight, tables, generatedNames, }) => {
9
10
  return (sheetId, cell, selections, clearType = "contents") => {
@@ -14,13 +15,24 @@ export const deleteCells = ({ locale, rowCount, cellXfsRegistry, sharedStringReg
14
15
  : selectionFromActiveCell(cell);
15
16
  const saveHistory = createHistory();
16
17
  const maxRowCount = getDataRowCount();
17
- // A table survives Delete / Clear (Excel): only its cells empty out, and
18
- // cleared header cells are re-named `ColumnN` so the header row and
19
- // `columns[]` stay in step.
18
+ // Delete / Clear over a selection that covers a whole table deletes the table (Excel's
19
+ // "select the table and press Delete"): the table, its filter and its style go with the
20
+ // cells, and the structured references into it error as they do for any deleted table
21
+ // (Convert to Range is the path that rewrites them to A1).
22
+ const removedTables = shouldClearContents
23
+ ? (tables ?? []).filter((table) => table.sheetId === sheetId &&
24
+ finalSelections.some((selection) => areaInsideArea(table.range, selection.range)))
25
+ : [];
26
+ const keptTables = removedTables.length
27
+ ? tables?.filter((table) => !removedTables.includes(table))
28
+ : tables;
29
+ // A table survives Delete / Clear over part of it (Excel): only its cells
30
+ // empty out, and cleared header cells are re-named `ColumnN` so the header
31
+ // row and `columns[]` stay in step.
20
32
  const headerRefills = shouldClearContents
21
33
  ? getTableHeaderRefills({
22
34
  sheetId,
23
- tables,
35
+ tables: keptTables,
24
36
  selections: finalSelections,
25
37
  generatedNames,
26
38
  })
@@ -133,10 +145,16 @@ export const deleteCells = ({ locale, rowCount, cellXfsRegistry, sharedStringReg
133
145
  });
134
146
  return nextState;
135
147
  });
136
- // Rename the columns whose header cells were cleared
137
- if (headerRefills.length) {
148
+ // Drop the tables the selection covered, and rename the columns whose header cells were cleared
149
+ if (headerRefills.length || removedTables.length) {
138
150
  onChangeTables?.((prevTables) => {
139
151
  const [nextState, patches, inversePatches] = produceWithPatches(prevTables, (draft) => {
152
+ for (const removed of removedTables) {
153
+ const tableIndex = draft.findIndex((table) => table.id == removed.id);
154
+ if (tableIndex !== -1) {
155
+ draft.splice(tableIndex, 1);
156
+ }
157
+ }
140
158
  for (const { tableId, dimensionIndex, name } of headerRefills) {
141
159
  const table = draft.find((table) => table.sheetId === sheetId && table.id === tableId);
142
160
  if (!table)
@@ -156,6 +174,13 @@ export const deleteCells = ({ locale, rowCount, cellXfsRegistry, sharedStringReg
156
174
  });
157
175
  return nextState;
158
176
  });
177
+ releaseTableFilterRows({
178
+ tables: removedTables,
179
+ onChangeSheets,
180
+ saveHistory,
181
+ getDependents,
182
+ enqueueCalculation,
183
+ });
159
184
  }
160
185
  // Update citations - retire citations whose cited cells lose their contents.
161
186
  // Clearing formats only leaves the cited values in place, so the citations stay.
@@ -1,4 +1,15 @@
1
1
  import type { CellData, Sheet, TableView } from "@rowsncolumns/spreadsheet";
2
2
  import type { UseOnTableProps } from "../hooks/use-on-table";
3
3
  export declare const removeTable: <T extends CellData, S extends Sheet>({ locale, cellXfsRegistry, sharedStringRegistry, getSheetName, onChangeTables, onChangeSheets, onChangeSheetData, createHistory, getDependents, getGraphNodes, getBandedCells, enqueueCalculation, enqueueGraphOperation, }: Pick<UseOnTableProps<T, S>, "locale" | "cellXfsRegistry" | "sharedStringRegistry" | "getSheetName" | "onChangeTables" | "onChangeSheets" | "onChangeSheetData" | "getDependents" | "getGraphNodes" | "getBandedCells" | "enqueueCalculation" | "enqueueGraphOperation" | "createHistory">) => (tableView: TableView) => void;
4
+ /**
5
+ * A removed table's filter goes with it: the rows it hid become visible again, in the history step
6
+ * of the removal (`saveHistory`). Their values did not change, so only the formulas that read
7
+ * visibility — `SUBTOTAL(101…111)` / `AGGREGATE` over those rows — are stale; dirtying the
8
+ * un-hidden cells recalculates exactly those dependents. Shared by Convert to Range
9
+ * (`removeTable`) and Delete over a whole table (`deleteCells`).
10
+ */
11
+ export declare const releaseTableFilterRows: <T extends CellData, S extends Sheet>({ tables, onChangeSheets, saveHistory, getDependents, enqueueCalculation, }: Pick<UseOnTableProps<T, S>, "onChangeSheets" | "getDependents" | "enqueueCalculation"> & {
12
+ tables: TableView[];
13
+ saveHistory: ReturnType<UseOnTableProps<T, S>["createHistory"]>;
14
+ }) => void;
4
15
  //# sourceMappingURL=remove-table.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"remove-table.d.ts","sourceRoot":"","sources":["../../../interface/remove-table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAK5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAI7D,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,6NAc9D,IAAI,CACL,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACnB,QAAQ,GACR,iBAAiB,GACjB,sBAAsB,GACtB,cAAc,GACd,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,oBAAoB,GACpB,uBAAuB,GACvB,eAAe,CAClB,MACS,WAAW,SAAS,SAwH7B,CAAC"}
1
+ {"version":3,"file":"remove-table.d.ts","sourceRoot":"","sources":["../../../interface/remove-table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAK5E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAI7D,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,6NAc9D,IAAI,CACL,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACnB,QAAQ,GACR,iBAAiB,GACjB,sBAAsB,GACtB,cAAc,GACd,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,oBAAoB,GACpB,uBAAuB,GACvB,eAAe,CAClB,MACS,WAAW,SAAS,SA0E7B,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,QAAQ,EAAE,CAAC,SAAS,KAAK,EAAE,6EAMzE,IAAI,CACL,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,EACrB,gBAAgB,GAAG,eAAe,GAAG,oBAAoB,CAC1D,GAAG;IACF,MAAM,EAAE,SAAS,EAAE,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;CACjE,SAoDA,CAAC"}
@@ -57,42 +57,58 @@ export const removeTable = ({ locale, cellXfsRegistry, sharedStringRegistry, get
57
57
  });
58
58
  return nextState;
59
59
  });
60
- // The table's filter goes with it: rows it hid become visible again. Their values did not
61
- // change, so only the formulas that read visibility — `SUBTOTAL(101…111)` / `AGGREGATE` over
62
- // those rows — are stale; dirtying the un-hidden cells recalculates exactly those dependents
63
- // (the rewritten structured references were re-entered above with `force`).
64
- const unhiddenRecalcCells = new Map();
65
- onChangeSheets((prevSheets) => {
66
- const [nextState, patches, inversePatches] = produceWithPatches(prevSheets, (draft) => {
60
+ releaseTableFilterRows({
61
+ tables: [tableView],
62
+ onChangeSheets,
63
+ saveHistory,
64
+ getDependents,
65
+ enqueueCalculation,
66
+ });
67
+ };
68
+ };
69
+ /**
70
+ * A removed table's filter goes with it: the rows it hid become visible again, in the history step
71
+ * of the removal (`saveHistory`). Their values did not change, so only the formulas that read
72
+ * visibility — `SUBTOTAL(101…111)` / `AGGREGATE` over those rows — are stale; dirtying the
73
+ * un-hidden cells recalculates exactly those dependents. Shared by Convert to Range
74
+ * (`removeTable`) and Delete over a whole table (`deleteCells`).
75
+ */
76
+ export const releaseTableFilterRows = ({ tables, onChangeSheets, saveHistory, getDependents, enqueueCalculation, }) => {
77
+ if (!tables.length)
78
+ return;
79
+ const unhiddenRecalcCells = new Map();
80
+ onChangeSheets((prevSheets) => {
81
+ const [nextState, patches, inversePatches] = produceWithPatches(prevSheets, (draft) => {
82
+ for (const tableView of tables) {
67
83
  const sheet = draft.find((sheet) => sheet.sheetId === tableView.sheetId);
68
- if (sheet && tableView) {
69
- if (!sheet.rowMetadata) {
70
- sheet.rowMetadata = [];
71
- }
72
- const { range } = tableView;
73
- for (let rowIndex = range.startRowIndex; rowIndex <= range.endRowIndex; rowIndex++) {
74
- if (sheet.rowMetadata[rowIndex]?.hiddenByFilter) {
75
- sheet.rowMetadata[rowIndex].hiddenByFilter = false;
76
- for (const [key, position] of markTableAsDirty(tableView.sheetId, { ...range, startRowIndex: rowIndex, endRowIndex: rowIndex }, getDependents, enqueueCalculation)) {
77
- unhiddenRecalcCells.set(key, position);
78
- }
84
+ if (!sheet)
85
+ continue;
86
+ if (!sheet.rowMetadata) {
87
+ sheet.rowMetadata = [];
88
+ }
89
+ const { range } = tableView;
90
+ for (let rowIndex = range.startRowIndex; rowIndex <= range.endRowIndex; rowIndex++) {
91
+ if (sheet.rowMetadata[rowIndex]?.hiddenByFilter) {
92
+ sheet.rowMetadata[rowIndex].hiddenByFilter = false;
93
+ for (const [key, position] of markTableAsDirty(tableView.sheetId, { ...range, startRowIndex: rowIndex, endRowIndex: rowIndex }, getDependents, enqueueCalculation)) {
94
+ unhiddenRecalcCells.set(key, position);
79
95
  }
80
96
  }
81
97
  }
82
- });
83
- // Save to history
84
- saveHistory({
85
- sheets: { patches, inversePatches },
86
- ...(unhiddenRecalcCells.size
87
- ? {
88
- recalcCells: {
89
- undo: unhiddenRecalcCells,
90
- redo: unhiddenRecalcCells,
91
- },
92
- }
93
- : {}),
94
- });
95
- return nextState;
98
+ }
96
99
  });
97
- };
100
+ // Save to history
101
+ saveHistory({
102
+ sheets: { patches, inversePatches },
103
+ ...(unhiddenRecalcCells.size
104
+ ? {
105
+ recalcCells: {
106
+ undo: unhiddenRecalcCells,
107
+ redo: unhiddenRecalcCells,
108
+ },
109
+ }
110
+ : {}),
111
+ });
112
+ return nextState;
113
+ });
98
114
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rowsncolumns/spreadsheet-state",
3
- "version": "29.1.16",
3
+ "version": "29.1.18",
4
4
  "main": "./dist/cjs/index.js",
5
5
  "module": "./dist/esm/index.js",
6
6
  "types": "./dist/esm/index.d.ts",