@rowsncolumns/spreadsheet-state 29.1.1 → 29.1.2

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.
@@ -1,7 +1,22 @@
1
+ import type { DataValidationRuleRecord } from "@rowsncolumns/spreadsheet";
1
2
  export declare const editingDataValidationId: import("jotai").PrimitiveAtom<string | number | undefined> & {
2
3
  init: string | number | undefined;
3
4
  };
4
5
  export declare const useEditingDataValidationIdValue: () => string | number | undefined;
5
6
  export declare const useSetEditingDataValidationId: () => (args_0: string | number | ((prev: string | number | undefined) => string | number | undefined) | undefined) => void;
6
7
  export declare const useEditingDataValidationIdState: () => [string | number | undefined, (args_0: string | number | ((prev: string | number | undefined) => string | number | undefined) | undefined) => void];
8
+ /**
9
+ * A data-validation rule the editor is composing that does NOT exist in the
10
+ * document yet — Excel's Data Validation dialog is transactional (nothing is
11
+ * written until OK). Insert → Dropdown / the ribbon's Data Validation button
12
+ * seed this atom instead of creating the rule; the `DataValidationEditor`
13
+ * resolves the editing id against it when no persisted rule matches, creates
14
+ * it on Save and discards it on Cancel / close.
15
+ */
16
+ export declare const draftDataValidationRule: import("jotai").PrimitiveAtom<DataValidationRuleRecord | undefined> & {
17
+ init: DataValidationRuleRecord | undefined;
18
+ };
19
+ export declare const useDraftDataValidationRuleValue: () => DataValidationRuleRecord | undefined;
20
+ export declare const useSetDraftDataValidationRule: () => (args_0: DataValidationRuleRecord | ((prev: DataValidationRuleRecord | undefined) => DataValidationRuleRecord | undefined) | undefined) => void;
21
+ export declare const useDraftDataValidationRuleState: () => [DataValidationRuleRecord | undefined, (args_0: DataValidationRuleRecord | ((prev: DataValidationRuleRecord | undefined) => DataValidationRuleRecord | undefined) | undefined) => void];
7
22
  //# sourceMappingURL=editing-data-validation-id.atom.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"editing-data-validation-id.atom.d.ts","sourceRoot":"","sources":["../../../atoms/editing-data-validation-id.atom.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,uBAAuB;;CAExB,CAAC;AAEb,eAAO,MAAM,+BAA+B,mCACL,CAAC;AAExC,eAAO,MAAM,6BAA6B,4HACL,CAAC;AAEtC,eAAO,MAAM,+BAA+B,2JACV,CAAC"}
1
+ {"version":3,"file":"editing-data-validation-id.atom.d.ts","sourceRoot":"","sources":["../../../atoms/editing-data-validation-id.atom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAI1E,eAAO,MAAM,uBAAuB;;CAExB,CAAC;AAEb,eAAO,MAAM,+BAA+B,mCACL,CAAC;AAExC,eAAO,MAAM,6BAA6B,4HACL,CAAC;AAEtC,eAAO,MAAM,+BAA+B,2JACV,CAAC;AAEnC;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB;;CAExB,CAAC;AAEb,eAAO,MAAM,+BAA+B,4CACL,CAAC;AAExC,eAAO,MAAM,6BAA6B,uJACL,CAAC;AAEtC,eAAO,MAAM,+BAA+B,+LACV,CAAC"}
@@ -10,3 +10,21 @@ export var useSetEditingDataValidationId = function () {
10
10
  export var useEditingDataValidationIdState = function () {
11
11
  return useAtom(editingDataValidationId);
12
12
  };
13
+ /**
14
+ * A data-validation rule the editor is composing that does NOT exist in the
15
+ * document yet — Excel's Data Validation dialog is transactional (nothing is
16
+ * written until OK). Insert → Dropdown / the ribbon's Data Validation button
17
+ * seed this atom instead of creating the rule; the `DataValidationEditor`
18
+ * resolves the editing id against it when no persisted rule matches, creates
19
+ * it on Save and discards it on Cancel / close.
20
+ */
21
+ export var draftDataValidationRule = atom(undefined);
22
+ export var useDraftDataValidationRuleValue = function () {
23
+ return useAtomValue(draftDataValidationRule);
24
+ };
25
+ export var useSetDraftDataValidationRule = function () {
26
+ return useSetAtom(draftDataValidationRule);
27
+ };
28
+ export var useDraftDataValidationRuleState = function () {
29
+ return useAtom(draftDataValidationRule);
30
+ };
@@ -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,KAA4D,MAAM,OAAO,CAAC;AAIjF,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,sBA+O3B,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,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"}
@@ -3,9 +3,9 @@ import { CopyIcon, Cross2Icon, Pencil2Icon, PlusIcon, TrashIcon, } from "@rowsnc
3
3
  import { CONDITION_LABELS, getUserSelections, useFocusSheet, useFormulaRangeHelpers, useSpreadsheetApi, } from "@rowsncolumns/spreadsheet";
4
4
  import { Button, Dialog, DialogBody, DialogCloseButton, DialogContent, DialogTitle, IconButton, Separator, Stack, } from "@rowsncolumns/ui";
5
5
  import { uuid } from "@rowsncolumns/utils";
6
- import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
6
+ import React, { useCallback, useEffect, useMemo, useRef } from "react";
7
7
  import { useDataValidationDialogState } from "../../atoms/dialog-state.atom";
8
- import { useEditingDataValidationIdState } from "../../atoms/editing-data-validation-id.atom";
8
+ import { useDraftDataValidationRuleState, useEditingDataValidationIdState, } from "../../atoms/editing-data-validation-id.atom";
9
9
  import { DataValidationRuleEditor } from "./data-validation-rule-editor";
10
10
  import { SheetFilterEmptyState, SheetFilterSelect, useSheetFilter, } from "./sheet-filter";
11
11
  /**
@@ -16,10 +16,12 @@ import { SheetFilterEmptyState, SheetFilterSelect, useSheetFilter, } from "./she
16
16
  export var DataValidationEditor = function (_a) {
17
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;
18
18
  var _b = __read(useEditingDataValidationIdState(), 2), editingId = _b[0], setEditingId = _b[1];
19
- // Deferred create: "Add rule" holds the new rule as a local draft and only persists
20
- // it on Save — Excel's dialog is transactional (no rule exists until OK), and an
21
- // eagerly-created stub would survive Cancel/close as a blank, conditionless rule.
22
- var _c = __read(useState(), 2), draftRule = _c[0], setDraftRule = _c[1];
19
+ // Deferred create: "Add rule" and the seeded openers (Insert → Dropdown, the ribbon's
20
+ // Data Validation button via `useOnRequestDataValidation`) hold the new rule as a draft
21
+ // and only persist it on Save — Excel's dialog is transactional (no rule exists until
22
+ // OK), and an eagerly-created stub would survive Cancel/close as a real rule (a blank
23
+ // conditionless one, or a placeholder list that rejects every existing cell value).
24
+ var _c = __read(useDraftDataValidationRuleState(), 2), draftRule = _c[0], setDraftRule = _c[1];
23
25
  var api = useSpreadsheetApi();
24
26
  var rangeToFormula = useFormulaRangeHelpers({
25
27
  sheetId: sheetId,
@@ -74,19 +76,22 @@ export var DataValidationEditor = function (_a) {
74
76
  ? draftRule
75
77
  : dataValidations === null || dataValidations === void 0 ? void 0 : dataValidations.find(function (rule) { return rule.id === editingId; });
76
78
  }, [dataValidations, editingId, draftRule]);
77
- // The editing id lives in a shared atom that outlives this editor. If the dialog
78
- // closes while a draft is being edited, clear it on unmount — otherwise reopening
79
- // the dialog resolves an id with no rule, hiding the Add rule / Remove all footer.
79
+ // The editing id and the draft live in shared atoms that outlive this editor. If the
80
+ // dialog closes while a draft is being edited, clear both on unmount — otherwise
81
+ // reopening the dialog resumes the abandoned draft instead of showing the rule list.
80
82
  var unmountCleanupRef = useRef({ editingId: undefined, draftId: undefined });
81
83
  useEffect(function () {
82
84
  unmountCleanupRef.current = { editingId: editingId, draftId: draftRule === null || draftRule === void 0 ? void 0 : draftRule.id };
83
85
  }, [editingId, draftRule]);
84
86
  useEffect(function () { return function () {
85
87
  var _a = unmountCleanupRef.current, editingId = _a.editingId, draftId = _a.draftId;
86
- if (draftId !== undefined && editingId === draftId) {
87
- setEditingId(undefined);
88
+ if (draftId !== undefined) {
89
+ setDraftRule(undefined);
90
+ if (editingId === draftId) {
91
+ setEditingId(undefined);
92
+ }
88
93
  }
89
- }; }, [setEditingId]);
94
+ }; }, [setEditingId, setDraftRule]);
90
95
  var unMark = function () {
91
96
  api === null || api === void 0 ? void 0 : api.unmark();
92
97
  };
@@ -2,6 +2,13 @@ import type { useDataValidationRules } from "./use-data-validation-rules";
2
2
  type UseOnRequestDataValidationProps = {
3
3
  onCreateDataValidationRule?: ReturnType<typeof useDataValidationRules>["onCreateDataValidationRule"];
4
4
  };
5
+ /**
6
+ * Opens the Data Validation dialog. A seeded rule is NOT written to the document
7
+ * while the dialog is showing it: Excel's dialog is transactional (nothing exists
8
+ * until OK), so the rule is handed to the editor as a draft that Save creates and
9
+ * Cancel / close discards. Only a seeded rule with the edit UI suppressed
10
+ * (Insert → Checkbox) is created immediately — there is no dialog to confirm it.
11
+ */
5
12
  export declare const useOnRequestDataValidation: ({ onCreateDataValidationRule, }: UseOnRequestDataValidationProps) => (sheetId: number, activeCell: import("@rowsncolumns/grid").CellInterface, selections: import("@rowsncolumns/grid").SelectionArea<import("@rowsncolumns/spreadsheet").SelectionAttributes>[], initialDataValidationRule?: import("@rowsncolumns/common-types").DataValidationRuleRecord, showEditUI?: boolean) => void;
6
13
  export {};
7
14
  //# sourceMappingURL=use-on-request-data-validation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-on-request-data-validation.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-request-data-validation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE1E,KAAK,+BAA+B,GAAG;IACrC,0BAA0B,CAAC,EAAE,UAAU,CACrC,OAAO,sBAAsB,CAC9B,CAAC,4BAA4B,CAAC,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,iCAExC,+BAA+B,0TA4BjC,CAAC"}
1
+ {"version":3,"file":"use-on-request-data-validation.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-request-data-validation.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE1E,KAAK,+BAA+B,GAAG;IACrC,0BAA0B,CAAC,EAAE,UAAU,CACrC,OAAO,sBAAsB,CAC9B,CAAC,4BAA4B,CAAC,CAAC;CACjC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,GAAI,iCAExC,+BAA+B,0TAgCjC,CAAC"}
@@ -1,23 +1,35 @@
1
1
  import { useCallback } from "react";
2
2
  import { useSetDataValidationDialogAState } from "../atoms/dialog-state.atom";
3
- import { useSetEditingDataValidationId } from "../atoms/editing-data-validation-id.atom";
3
+ import { useSetDraftDataValidationRule, useSetEditingDataValidationId, } from "../atoms/editing-data-validation-id.atom";
4
+ /**
5
+ * Opens the Data Validation dialog. A seeded rule is NOT written to the document
6
+ * while the dialog is showing it: Excel's dialog is transactional (nothing exists
7
+ * until OK), so the rule is handed to the editor as a draft that Save creates and
8
+ * Cancel / close discards. Only a seeded rule with the edit UI suppressed
9
+ * (Insert → Checkbox) is created immediately — there is no dialog to confirm it.
10
+ */
4
11
  export var useOnRequestDataValidation = function (_a) {
5
12
  var onCreateDataValidationRule = _a.onCreateDataValidationRule;
6
13
  var onOpenChange = useSetDataValidationDialogAState();
7
14
  var setEditingDataValidationId = useSetEditingDataValidationId();
15
+ var setDraftDataValidationRule = useSetDraftDataValidationRule();
8
16
  return useCallback(function (sheetId, activeCell, selections, initialDataValidationRule, showEditUI) {
9
17
  if (showEditUI === void 0) { showEditUI = true; }
10
- if (initialDataValidationRule) {
11
- // Create a new rule
12
- onCreateDataValidationRule === null || onCreateDataValidationRule === void 0 ? void 0 : onCreateDataValidationRule(initialDataValidationRule);
13
- }
14
- if (showEditUI) {
15
- // Open dialog
16
- onOpenChange(true);
18
+ if (!showEditUI) {
17
19
  if (initialDataValidationRule) {
18
- // Set editing id
19
- setEditingDataValidationId(initialDataValidationRule.id);
20
+ onCreateDataValidationRule === null || onCreateDataValidationRule === void 0 ? void 0 : onCreateDataValidationRule(initialDataValidationRule);
20
21
  }
22
+ return;
23
+ }
24
+ if (initialDataValidationRule) {
25
+ setDraftDataValidationRule(initialDataValidationRule);
26
+ setEditingDataValidationId(initialDataValidationRule.id);
21
27
  }
22
- }, [onOpenChange, setEditingDataValidationId, onCreateDataValidationRule]);
28
+ onOpenChange(true);
29
+ }, [
30
+ onOpenChange,
31
+ setEditingDataValidationId,
32
+ setDraftDataValidationRule,
33
+ onCreateDataValidationRule,
34
+ ]);
23
35
  };
@@ -1,7 +1,22 @@
1
+ import type { DataValidationRuleRecord } from "@rowsncolumns/spreadsheet";
1
2
  export declare const editingDataValidationId: import("jotai").PrimitiveAtom<string | number | undefined> & {
2
3
  init: string | number | undefined;
3
4
  };
4
5
  export declare const useEditingDataValidationIdValue: () => string | number | undefined;
5
6
  export declare const useSetEditingDataValidationId: () => (args_0: string | number | ((prev: string | number | undefined) => string | number | undefined) | undefined) => void;
6
7
  export declare const useEditingDataValidationIdState: () => [string | number | undefined, (args_0: string | number | ((prev: string | number | undefined) => string | number | undefined) | undefined) => void];
8
+ /**
9
+ * A data-validation rule the editor is composing that does NOT exist in the
10
+ * document yet — Excel's Data Validation dialog is transactional (nothing is
11
+ * written until OK). Insert → Dropdown / the ribbon's Data Validation button
12
+ * seed this atom instead of creating the rule; the `DataValidationEditor`
13
+ * resolves the editing id against it when no persisted rule matches, creates
14
+ * it on Save and discards it on Cancel / close.
15
+ */
16
+ export declare const draftDataValidationRule: import("jotai").PrimitiveAtom<DataValidationRuleRecord | undefined> & {
17
+ init: DataValidationRuleRecord | undefined;
18
+ };
19
+ export declare const useDraftDataValidationRuleValue: () => DataValidationRuleRecord | undefined;
20
+ export declare const useSetDraftDataValidationRule: () => (args_0: DataValidationRuleRecord | ((prev: DataValidationRuleRecord | undefined) => DataValidationRuleRecord | undefined) | undefined) => void;
21
+ export declare const useDraftDataValidationRuleState: () => [DataValidationRuleRecord | undefined, (args_0: DataValidationRuleRecord | ((prev: DataValidationRuleRecord | undefined) => DataValidationRuleRecord | undefined) | undefined) => void];
7
22
  //# sourceMappingURL=editing-data-validation-id.atom.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"editing-data-validation-id.atom.d.ts","sourceRoot":"","sources":["../../../atoms/editing-data-validation-id.atom.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,uBAAuB;;CAExB,CAAC;AAEb,eAAO,MAAM,+BAA+B,mCACL,CAAC;AAExC,eAAO,MAAM,6BAA6B,4HACL,CAAC;AAEtC,eAAO,MAAM,+BAA+B,2JACV,CAAC"}
1
+ {"version":3,"file":"editing-data-validation-id.atom.d.ts","sourceRoot":"","sources":["../../../atoms/editing-data-validation-id.atom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AAI1E,eAAO,MAAM,uBAAuB;;CAExB,CAAC;AAEb,eAAO,MAAM,+BAA+B,mCACL,CAAC;AAExC,eAAO,MAAM,6BAA6B,4HACL,CAAC;AAEtC,eAAO,MAAM,+BAA+B,2JACV,CAAC;AAEnC;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB;;CAExB,CAAC;AAEb,eAAO,MAAM,+BAA+B,4CACL,CAAC;AAExC,eAAO,MAAM,6BAA6B,uJACL,CAAC;AAEtC,eAAO,MAAM,+BAA+B,+LACV,CAAC"}
@@ -4,3 +4,15 @@ export const editingDataValidationId = atom(undefined);
4
4
  export const useEditingDataValidationIdValue = () => useAtomValue(editingDataValidationId);
5
5
  export const useSetEditingDataValidationId = () => useSetAtom(editingDataValidationId);
6
6
  export const useEditingDataValidationIdState = () => useAtom(editingDataValidationId);
7
+ /**
8
+ * A data-validation rule the editor is composing that does NOT exist in the
9
+ * document yet — Excel's Data Validation dialog is transactional (nothing is
10
+ * written until OK). Insert → Dropdown / the ribbon's Data Validation button
11
+ * seed this atom instead of creating the rule; the `DataValidationEditor`
12
+ * resolves the editing id against it when no persisted rule matches, creates
13
+ * it on Save and discards it on Cancel / close.
14
+ */
15
+ export const draftDataValidationRule = atom(undefined);
16
+ export const useDraftDataValidationRuleValue = () => useAtomValue(draftDataValidationRule);
17
+ export const useSetDraftDataValidationRule = () => useSetAtom(draftDataValidationRule);
18
+ export const useDraftDataValidationRuleState = () => useAtom(draftDataValidationRule);
@@ -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,KAA4D,MAAM,OAAO,CAAC;AAIjF,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,sBA+O3B,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,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"}
@@ -2,9 +2,9 @@ import { CopyIcon, Cross2Icon, Pencil2Icon, PlusIcon, TrashIcon, } from "@rowsnc
2
2
  import { CONDITION_LABELS, getUserSelections, useFocusSheet, useFormulaRangeHelpers, useSpreadsheetApi, } from "@rowsncolumns/spreadsheet";
3
3
  import { Button, Dialog, DialogBody, DialogCloseButton, DialogContent, DialogTitle, IconButton, Separator, Stack, } from "@rowsncolumns/ui";
4
4
  import { uuid } from "@rowsncolumns/utils";
5
- import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
5
+ import React, { useCallback, useEffect, useMemo, useRef } from "react";
6
6
  import { useDataValidationDialogState } from "../../atoms/dialog-state.atom";
7
- import { useEditingDataValidationIdState } from "../../atoms/editing-data-validation-id.atom";
7
+ import { useDraftDataValidationRuleState, useEditingDataValidationIdState, } from "../../atoms/editing-data-validation-id.atom";
8
8
  import { DataValidationRuleEditor } from "./data-validation-rule-editor";
9
9
  import { SheetFilterEmptyState, SheetFilterSelect, useSheetFilter, } from "./sheet-filter";
10
10
  /**
@@ -14,10 +14,12 @@ import { SheetFilterEmptyState, SheetFilterSelect, useSheetFilter, } from "./she
14
14
  */
15
15
  export const DataValidationEditor = ({ sheetId, dataValidations, functionDescriptions, idCreationStrategy, onDeleteRules, onDeleteRule, onCreateRule, onUpdateRule, }) => {
16
16
  const [editingId, setEditingId] = useEditingDataValidationIdState();
17
- // Deferred create: "Add rule" holds the new rule as a local draft and only persists
18
- // it on Save — Excel's dialog is transactional (no rule exists until OK), and an
19
- // eagerly-created stub would survive Cancel/close as a blank, conditionless rule.
20
- const [draftRule, setDraftRule] = useState();
17
+ // Deferred create: "Add rule" and the seeded openers (Insert → Dropdown, the ribbon's
18
+ // Data Validation button via `useOnRequestDataValidation`) hold the new rule as a draft
19
+ // and only persist it on Save — Excel's dialog is transactional (no rule exists until
20
+ // OK), and an eagerly-created stub would survive Cancel/close as a real rule (a blank
21
+ // conditionless one, or a placeholder list that rejects every existing cell value).
22
+ const [draftRule, setDraftRule] = useDraftDataValidationRuleState();
21
23
  const api = useSpreadsheetApi();
22
24
  const { rangeToFormula } = useFormulaRangeHelpers({
23
25
  sheetId,
@@ -73,19 +75,22 @@ export const DataValidationEditor = ({ sheetId, dataValidations, functionDescrip
73
75
  const activeRule = useMemo(() => draftRule && draftRule.id === editingId
74
76
  ? draftRule
75
77
  : dataValidations?.find((rule) => rule.id === editingId), [dataValidations, editingId, draftRule]);
76
- // The editing id lives in a shared atom that outlives this editor. If the dialog
77
- // closes while a draft is being edited, clear it on unmount — otherwise reopening
78
- // the dialog resolves an id with no rule, hiding the Add rule / Remove all footer.
78
+ // The editing id and the draft live in shared atoms that outlive this editor. If the
79
+ // dialog closes while a draft is being edited, clear both on unmount — otherwise
80
+ // reopening the dialog resumes the abandoned draft instead of showing the rule list.
79
81
  const unmountCleanupRef = useRef({ editingId: undefined, draftId: undefined });
80
82
  useEffect(() => {
81
83
  unmountCleanupRef.current = { editingId, draftId: draftRule?.id };
82
84
  }, [editingId, draftRule]);
83
85
  useEffect(() => () => {
84
86
  const { editingId, draftId } = unmountCleanupRef.current;
85
- if (draftId !== undefined && editingId === draftId) {
86
- setEditingId(undefined);
87
+ if (draftId !== undefined) {
88
+ setDraftRule(undefined);
89
+ if (editingId === draftId) {
90
+ setEditingId(undefined);
91
+ }
87
92
  }
88
- }, [setEditingId]);
93
+ }, [setEditingId, setDraftRule]);
89
94
  const unMark = () => {
90
95
  api?.unmark();
91
96
  };
@@ -2,6 +2,13 @@ import type { useDataValidationRules } from "./use-data-validation-rules";
2
2
  type UseOnRequestDataValidationProps = {
3
3
  onCreateDataValidationRule?: ReturnType<typeof useDataValidationRules>["onCreateDataValidationRule"];
4
4
  };
5
+ /**
6
+ * Opens the Data Validation dialog. A seeded rule is NOT written to the document
7
+ * while the dialog is showing it: Excel's dialog is transactional (nothing exists
8
+ * until OK), so the rule is handed to the editor as a draft that Save creates and
9
+ * Cancel / close discards. Only a seeded rule with the edit UI suppressed
10
+ * (Insert → Checkbox) is created immediately — there is no dialog to confirm it.
11
+ */
5
12
  export declare const useOnRequestDataValidation: ({ onCreateDataValidationRule, }: UseOnRequestDataValidationProps) => (sheetId: number, activeCell: import("@rowsncolumns/grid").CellInterface, selections: import("@rowsncolumns/grid").SelectionArea<import("@rowsncolumns/spreadsheet").SelectionAttributes>[], initialDataValidationRule?: import("@rowsncolumns/common-types").DataValidationRuleRecord, showEditUI?: boolean) => void;
6
13
  export {};
7
14
  //# sourceMappingURL=use-on-request-data-validation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-on-request-data-validation.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-request-data-validation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE1E,KAAK,+BAA+B,GAAG;IACrC,0BAA0B,CAAC,EAAE,UAAU,CACrC,OAAO,sBAAsB,CAC9B,CAAC,4BAA4B,CAAC,CAAC;CACjC,CAAC;AAEF,eAAO,MAAM,0BAA0B,GAAI,iCAExC,+BAA+B,0TA4BjC,CAAC"}
1
+ {"version":3,"file":"use-on-request-data-validation.d.ts","sourceRoot":"","sources":["../../../hooks/use-on-request-data-validation.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAE1E,KAAK,+BAA+B,GAAG;IACrC,0BAA0B,CAAC,EAAE,UAAU,CACrC,OAAO,sBAAsB,CAC9B,CAAC,4BAA4B,CAAC,CAAC;CACjC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B,GAAI,iCAExC,+BAA+B,0TAgCjC,CAAC"}
@@ -1,21 +1,33 @@
1
1
  import { useCallback } from "react";
2
2
  import { useSetDataValidationDialogAState } from "../atoms/dialog-state.atom";
3
- import { useSetEditingDataValidationId } from "../atoms/editing-data-validation-id.atom";
3
+ import { useSetDraftDataValidationRule, useSetEditingDataValidationId, } from "../atoms/editing-data-validation-id.atom";
4
+ /**
5
+ * Opens the Data Validation dialog. A seeded rule is NOT written to the document
6
+ * while the dialog is showing it: Excel's dialog is transactional (nothing exists
7
+ * until OK), so the rule is handed to the editor as a draft that Save creates and
8
+ * Cancel / close discards. Only a seeded rule with the edit UI suppressed
9
+ * (Insert → Checkbox) is created immediately — there is no dialog to confirm it.
10
+ */
4
11
  export const useOnRequestDataValidation = ({ onCreateDataValidationRule, }) => {
5
12
  const onOpenChange = useSetDataValidationDialogAState();
6
13
  const setEditingDataValidationId = useSetEditingDataValidationId();
14
+ const setDraftDataValidationRule = useSetDraftDataValidationRule();
7
15
  return useCallback((sheetId, activeCell, selections, initialDataValidationRule, showEditUI = true) => {
8
- if (initialDataValidationRule) {
9
- // Create a new rule
10
- onCreateDataValidationRule?.(initialDataValidationRule);
11
- }
12
- if (showEditUI) {
13
- // Open dialog
14
- onOpenChange(true);
16
+ if (!showEditUI) {
15
17
  if (initialDataValidationRule) {
16
- // Set editing id
17
- setEditingDataValidationId(initialDataValidationRule.id);
18
+ onCreateDataValidationRule?.(initialDataValidationRule);
18
19
  }
20
+ return;
21
+ }
22
+ if (initialDataValidationRule) {
23
+ setDraftDataValidationRule(initialDataValidationRule);
24
+ setEditingDataValidationId(initialDataValidationRule.id);
19
25
  }
20
- }, [onOpenChange, setEditingDataValidationId, onCreateDataValidationRule]);
26
+ onOpenChange(true);
27
+ }, [
28
+ onOpenChange,
29
+ setEditingDataValidationId,
30
+ setDraftDataValidationRule,
31
+ onCreateDataValidationRule,
32
+ ]);
21
33
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rowsncolumns/spreadsheet-state",
3
- "version": "29.1.1",
3
+ "version": "29.1.2",
4
4
  "main": "./dist/cjs/index.js",
5
5
  "module": "./dist/esm/index.js",
6
6
  "types": "./dist/esm/index.d.ts",