@rowsncolumns/spreadsheet 10.2.75 → 10.2.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/api/fill-series.d.ts +38 -0
- package/dist/cjs/api/fill-series.d.ts.map +1 -0
- package/dist/cjs/api/fill-series.js +89 -0
- package/dist/cjs/api/spreadsheet-api.d.ts +6 -2
- package/dist/cjs/api/spreadsheet-api.d.ts.map +1 -1
- package/dist/cjs/api/spreadsheet-api.js +9 -3
- package/dist/cjs/atoms/fill-options.atom.d.ts +36 -0
- package/dist/cjs/atoms/fill-options.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/fill-options.atom.js +11 -0
- package/dist/cjs/atoms/fill-series-dialog.atom.d.ts +26 -0
- package/dist/cjs/atoms/fill-series-dialog.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/fill-series-dialog.atom.js +14 -0
- package/dist/cjs/atoms/index.d.ts +2 -0
- package/dist/cjs/atoms/index.d.ts.map +1 -1
- package/dist/cjs/atoms/index.js +2 -0
- package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
- package/dist/cjs/components/canvas-grid/index.js +224 -50
- package/dist/cjs/components/canvas-grid/typings.d.ts +13 -4
- package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/helpers.d.ts +9 -0
- package/dist/cjs/components/cell-editor/helpers.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/helpers.js +8 -1
- package/dist/cjs/components/cell-editor/helpers.spec.js +14 -0
- package/dist/cjs/components/cell-editor/index.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/index.js +6 -3
- package/dist/cjs/components/fill-series-dialog/index.d.ts +29 -0
- package/dist/cjs/components/fill-series-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/fill-series-dialog/index.js +156 -0
- package/dist/cjs/components/selection/fill-options-menu.d.ts +32 -0
- package/dist/cjs/components/selection/fill-options-menu.d.ts.map +1 -0
- package/dist/cjs/components/selection/fill-options-menu.js +65 -0
- package/dist/cjs/components/selection/index.d.ts +1 -1
- package/dist/cjs/components/selection/index.d.ts.map +1 -1
- package/dist/cjs/components/selection/index.js +4 -2
- package/dist/cjs/components/selection/types.d.ts +11 -1
- package/dist/cjs/components/selection/types.d.ts.map +1 -1
- package/dist/cjs/components/toolbar/text-format-selector.d.ts +9 -0
- package/dist/cjs/components/toolbar/text-format-selector.d.ts.map +1 -1
- package/dist/cjs/components/toolbar/text-format-selector.js +15 -3
- package/dist/cjs/hooks/use-editable.d.ts +11 -2
- package/dist/cjs/hooks/use-editable.d.ts.map +1 -1
- package/dist/cjs/hooks/use-editable.js +8 -0
- package/dist/cjs/hooks/use-editor-submit.d.ts +32 -3
- package/dist/cjs/hooks/use-editor-submit.d.ts.map +1 -1
- package/dist/cjs/hooks/use-editor-submit.js +111 -2
- package/dist/cjs/hooks/use-keyboard-handler.d.ts.map +1 -1
- package/dist/cjs/hooks/use-keyboard-handler.js +3 -2
- package/dist/cjs/hooks/use-selection-renderer.d.ts +13 -2
- package/dist/cjs/hooks/use-selection-renderer.d.ts.map +1 -1
- package/dist/cjs/hooks/use-selection-renderer.js +21 -4
- package/dist/cjs/hooks/use-selection.d.ts +54 -4
- package/dist/cjs/hooks/use-selection.d.ts.map +1 -1
- package/dist/cjs/hooks/use-selection.js +232 -37
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +3 -0
- package/dist/cjs/release-date.js +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/types.d.ts +39 -1
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/api/fill-series.d.ts +38 -0
- package/dist/esm/api/fill-series.d.ts.map +1 -0
- package/dist/esm/api/fill-series.js +78 -0
- package/dist/esm/api/spreadsheet-api.d.ts +6 -2
- package/dist/esm/api/spreadsheet-api.d.ts.map +1 -1
- package/dist/esm/api/spreadsheet-api.js +8 -3
- package/dist/esm/atoms/fill-options.atom.d.ts +36 -0
- package/dist/esm/atoms/fill-options.atom.d.ts.map +1 -0
- package/dist/esm/atoms/fill-options.atom.js +5 -0
- package/dist/esm/atoms/fill-series-dialog.atom.d.ts +26 -0
- package/dist/esm/atoms/fill-series-dialog.atom.d.ts.map +1 -0
- package/dist/esm/atoms/fill-series-dialog.atom.js +9 -0
- package/dist/esm/atoms/index.d.ts +2 -0
- package/dist/esm/atoms/index.d.ts.map +1 -1
- package/dist/esm/atoms/index.js +2 -0
- package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
- package/dist/esm/components/canvas-grid/index.js +167 -6
- package/dist/esm/components/canvas-grid/typings.d.ts +13 -4
- package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/helpers.d.ts +9 -0
- package/dist/esm/components/cell-editor/helpers.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/helpers.js +6 -0
- package/dist/esm/components/cell-editor/helpers.spec.js +15 -1
- package/dist/esm/components/cell-editor/index.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/index.js +7 -4
- package/dist/esm/components/fill-series-dialog/index.d.ts +29 -0
- package/dist/esm/components/fill-series-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/fill-series-dialog/index.js +151 -0
- package/dist/esm/components/selection/fill-options-menu.d.ts +32 -0
- package/dist/esm/components/selection/fill-options-menu.d.ts.map +1 -0
- package/dist/esm/components/selection/fill-options-menu.js +63 -0
- package/dist/esm/components/selection/index.d.ts +1 -1
- package/dist/esm/components/selection/index.d.ts.map +1 -1
- package/dist/esm/components/selection/index.js +4 -2
- package/dist/esm/components/selection/types.d.ts +11 -1
- package/dist/esm/components/selection/types.d.ts.map +1 -1
- package/dist/esm/components/toolbar/text-format-selector.d.ts +9 -0
- package/dist/esm/components/toolbar/text-format-selector.d.ts.map +1 -1
- package/dist/esm/components/toolbar/text-format-selector.js +14 -2
- package/dist/esm/hooks/use-editable.d.ts +11 -2
- package/dist/esm/hooks/use-editable.d.ts.map +1 -1
- package/dist/esm/hooks/use-editable.js +8 -0
- package/dist/esm/hooks/use-editor-submit.d.ts +32 -3
- package/dist/esm/hooks/use-editor-submit.d.ts.map +1 -1
- package/dist/esm/hooks/use-editor-submit.js +82 -3
- package/dist/esm/hooks/use-keyboard-handler.d.ts.map +1 -1
- package/dist/esm/hooks/use-keyboard-handler.js +3 -2
- package/dist/esm/hooks/use-selection-renderer.d.ts +13 -2
- package/dist/esm/hooks/use-selection-renderer.d.ts.map +1 -1
- package/dist/esm/hooks/use-selection-renderer.js +22 -5
- package/dist/esm/hooks/use-selection.d.ts +54 -4
- package/dist/esm/hooks/use-selection.d.ts.map +1 -1
- package/dist/esm/hooks/use-selection.js +220 -36
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +3 -0
- package/dist/esm/release-date.js +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/types.d.ts +39 -1
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/spreadsheet.min.css +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cell-editor/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,KAAK,EACV,UAAU,EACV,sBAAsB,EAEtB,aAAa,EACd,MAAM,kBAAkB,CAAC;AAU1B,OAAO,KAAyD,MAAM,OAAO,CAAC;AAoB9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAMlE,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,cAAc,EACd,kBAAkB,EAClB,eAAe,EACf,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/cell-editor/index.tsx"],"names":[],"mappings":"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"}
|
|
@@ -11,10 +11,10 @@ import { useIsomorphicLayoutEffect } from "../../hooks/use-isomorphic-layout-eff
|
|
|
11
11
|
import { useMergeRefs } from "../../hooks/use-merge.refs";
|
|
12
12
|
import { useTextDimension } from "../../hooks/use-text-dimensions";
|
|
13
13
|
import { getStringifiedColor } from "../../themes";
|
|
14
|
+
import { resolveCanvasTextAlign } from "../cell/alignment";
|
|
14
15
|
import { CalendarPopup } from "./calendar-popup";
|
|
15
16
|
import { FormulaResultPreview } from "./formula-result-preview";
|
|
16
|
-
import {
|
|
17
|
-
import { getDirectionFromKey, shouldShowCalendarPopup } from "./helpers";
|
|
17
|
+
import { getDirectionFromKey, isFillSelectionCommit, shouldShowCalendarPopup, } from "./helpers";
|
|
18
18
|
import { dropdownStyles, StyledAddress, StyledAddressContainer, StyledEditor, } from "./style";
|
|
19
19
|
export const CellEditor = memo(({ value = "", effectiveValue, isNewValue, onChange, sheetId, editingSheetId, cell, position, format, locale, scale = 1, autoFocus, maxWidth, maxHeight, containerWidth, onSubmit, onCancel, getNextFocusableCell, dataValidation, getRangeValues, getRangeValuesAsync, horizontalAlignment, editingSheetName, address, isScrolling, showFormulaHelp, onHideFormulaHelp, onShowFormulaHelp, onKeyDown, tokenizer, defaultBackgroundColor, defaultTextColor, theme, functionDescriptions, getNamedRanges, getTableNames, getTableColumnNames, getStructuredProperties, onRequestCalculate, editorBorderColor, isPointerDevice, SuggestionsDropdown, stickyEditor, defaultFontSizePoint, textFormatRuns, getMentions, getFunctionParameterSuggestions, shouldFetchFunctionParameters, MentionTagComponent, MentionDropdownItemComponent, navigationMode, onCopy, onPaste, onCut, onBlur, }) => {
|
|
20
20
|
const editorBorderOutlineColor = editorBorderColor
|
|
@@ -108,12 +108,15 @@ export const CellEditor = memo(({ value = "", effectiveValue, isNewValue, onChan
|
|
|
108
108
|
if (!cell || isNil(editingSheetId)) {
|
|
109
109
|
return;
|
|
110
110
|
}
|
|
111
|
-
|
|
111
|
+
// Ctrl+Enter commits into the whole selection and stays put (Excel); every other
|
|
112
|
+
// commit key moves the active cell in its direction.
|
|
113
|
+
const fillSelection = isFillSelectionCommit(e);
|
|
114
|
+
const direction = e && !fillSelection ? getDirectionFromKey(e.key, e.shiftKey) : undefined;
|
|
112
115
|
const nextActiveCell = direction
|
|
113
116
|
? getNextFocusableCell?.(editingSheetId, cell, direction)
|
|
114
117
|
: undefined;
|
|
115
118
|
// Submit value
|
|
116
|
-
onSubmit?.(newValue, textFormatRuns, editingSheetId, cell, nextActiveCell);
|
|
119
|
+
onSubmit?.(newValue, textFormatRuns, editingSheetId, cell, nextActiveCell, undefined, fillSelection ? { fillSelection: true } : undefined);
|
|
117
120
|
// Reset active editor
|
|
118
121
|
setActiveEditor(undefined);
|
|
119
122
|
}, [onSubmit, editingSheetId, cell, getNextFocusableCell, setActiveEditor]);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { FillSeriesSpec } from "../../types";
|
|
3
|
+
export type FillSeriesDialogProps = {
|
|
4
|
+
/** Controls visibility. */
|
|
5
|
+
open: boolean;
|
|
6
|
+
onOpenChange(open: boolean): void;
|
|
7
|
+
/** Pre-selected axis (a right-drag seeds it from its direction). */
|
|
8
|
+
initialIn?: FillSeriesSpec["in"];
|
|
9
|
+
onApply(spec: FillSeriesSpec): void;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Excel's Series dialog (Home > Fill > Series…). Series in Rows/Columns, Type
|
|
13
|
+
* Linear/Growth/Date/AutoFill, Date unit (Type = Date only), Trend
|
|
14
|
+
* (Linear/Growth only — disables Step/Stop), Step value (default 1, may be
|
|
15
|
+
* negative or fractional) and Stop value. UI-only: the opener turns the spec
|
|
16
|
+
* into a fill.
|
|
17
|
+
*/
|
|
18
|
+
export declare const FillSeriesDialog: React.MemoExoticComponent<({ open, onOpenChange, initialIn, onApply }: FillSeriesDialogProps) => React.JSX.Element>;
|
|
19
|
+
/**
|
|
20
|
+
* Host-mounted, atom-driven wrapper around {@link FillSeriesDialog}. Mount it
|
|
21
|
+
* once alongside the other editor dialogs; the grid opens it via
|
|
22
|
+
* `useOpenFillSeriesDialog` (right-drag menu "Series…", or
|
|
23
|
+
* `SpreadsheetApi.openFillSeriesDialog()` from a Fill toolbar/menu).
|
|
24
|
+
*/
|
|
25
|
+
export declare const FillSeriesDialogHost: {
|
|
26
|
+
(): React.JSX.Element;
|
|
27
|
+
displayName: string;
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/fill-series-dialog/index.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAGtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,qBAAqB,GAAG;IAClC,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,oEAAoE;IACpE,SAAS,CAAC,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;CACrC,CAAC;AA0BF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,yEACkB,qBAAqB,uBA4MnE,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;CAahC,CAAC"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { Button, Dialog, DialogBody, DialogCloseButton, DialogContent, DialogTitle, Input, Separator, } from "@rowsncolumns/ui";
|
|
2
|
+
import React, { memo, useCallback, useEffect, useState } from "react";
|
|
3
|
+
import { useFillSeriesDialogState } from "../../atoms/fill-series-dialog.atom";
|
|
4
|
+
const SERIES_TYPES = [
|
|
5
|
+
{ value: "linear", label: "Linear" },
|
|
6
|
+
{ value: "growth", label: "Growth" },
|
|
7
|
+
{ value: "date", label: "Date" },
|
|
8
|
+
{ value: "autofill", label: "AutoFill" },
|
|
9
|
+
];
|
|
10
|
+
const DATE_UNITS = [
|
|
11
|
+
{ value: "day", label: "Day" },
|
|
12
|
+
{ value: "weekday", label: "Weekday" },
|
|
13
|
+
{ value: "month", label: "Month" },
|
|
14
|
+
{ value: "year", label: "Year" },
|
|
15
|
+
];
|
|
16
|
+
const parseNumber = (text) => {
|
|
17
|
+
const trimmed = text.trim();
|
|
18
|
+
if (!trimmed)
|
|
19
|
+
return undefined;
|
|
20
|
+
const n = Number(trimmed);
|
|
21
|
+
return Number.isFinite(n) ? n : undefined;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Excel's Series dialog (Home > Fill > Series…). Series in Rows/Columns, Type
|
|
25
|
+
* Linear/Growth/Date/AutoFill, Date unit (Type = Date only), Trend
|
|
26
|
+
* (Linear/Growth only — disables Step/Stop), Step value (default 1, may be
|
|
27
|
+
* negative or fractional) and Stop value. UI-only: the opener turns the spec
|
|
28
|
+
* into a fill.
|
|
29
|
+
*/
|
|
30
|
+
export const FillSeriesDialog = memo(({ open, onOpenChange, initialIn, onApply }) => {
|
|
31
|
+
const [axis, setAxis] = useState(initialIn ?? "columns");
|
|
32
|
+
const [type, setType] = useState("linear");
|
|
33
|
+
const [dateUnit, setDateUnit] = useState("day");
|
|
34
|
+
const [trend, setTrend] = useState(false);
|
|
35
|
+
const [step, setStep] = useState("1");
|
|
36
|
+
const [stop, setStop] = useState("");
|
|
37
|
+
const [error, setError] = useState(undefined);
|
|
38
|
+
// Re-seed on every open (the request decides the default axis).
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (open) {
|
|
41
|
+
setAxis(initialIn ?? "columns");
|
|
42
|
+
setType("linear");
|
|
43
|
+
setDateUnit("day");
|
|
44
|
+
setTrend(false);
|
|
45
|
+
setStep("1");
|
|
46
|
+
setStop("");
|
|
47
|
+
setError(undefined);
|
|
48
|
+
}
|
|
49
|
+
}, [open, initialIn]);
|
|
50
|
+
const trendAllowed = type === "linear" || type === "growth";
|
|
51
|
+
const stepStopDisabled = trendAllowed && trend;
|
|
52
|
+
const apply = useCallback(() => {
|
|
53
|
+
const stepValue = parseNumber(step);
|
|
54
|
+
if (!stepStopDisabled && step.trim() && stepValue === undefined) {
|
|
55
|
+
setError("Step value must be a number.");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const stopValue = parseNumber(stop);
|
|
59
|
+
if (!stepStopDisabled && stop.trim() && stopValue === undefined) {
|
|
60
|
+
setError("Stop value must be a number.");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const spec = {
|
|
64
|
+
in: axis,
|
|
65
|
+
type,
|
|
66
|
+
...(type === "date" ? { dateUnit } : {}),
|
|
67
|
+
...(trendAllowed && trend ? { trend: true } : {}),
|
|
68
|
+
...(!stepStopDisabled && stepValue !== undefined
|
|
69
|
+
? { step: stepValue }
|
|
70
|
+
: {}),
|
|
71
|
+
...(!stepStopDisabled && stopValue !== undefined
|
|
72
|
+
? { stop: stopValue }
|
|
73
|
+
: {}),
|
|
74
|
+
};
|
|
75
|
+
onApply(spec);
|
|
76
|
+
onOpenChange(false);
|
|
77
|
+
}, [
|
|
78
|
+
axis,
|
|
79
|
+
type,
|
|
80
|
+
dateUnit,
|
|
81
|
+
trend,
|
|
82
|
+
trendAllowed,
|
|
83
|
+
step,
|
|
84
|
+
stop,
|
|
85
|
+
stepStopDisabled,
|
|
86
|
+
onApply,
|
|
87
|
+
onOpenChange,
|
|
88
|
+
]);
|
|
89
|
+
return (React.createElement(Dialog, { open: open, onOpenChange: onOpenChange, modal: true },
|
|
90
|
+
React.createElement(DialogContent, { className: "w-[420px] max-w-[92vw] pointer-events-auto" },
|
|
91
|
+
React.createElement(DialogTitle, null, "Series"),
|
|
92
|
+
React.createElement(DialogCloseButton, null),
|
|
93
|
+
React.createElement(DialogBody, { className: "flex flex-col gap-3" },
|
|
94
|
+
React.createElement("form", { className: "flex flex-col gap-3", onSubmit: (e) => {
|
|
95
|
+
e.preventDefault();
|
|
96
|
+
apply();
|
|
97
|
+
} },
|
|
98
|
+
React.createElement("div", { className: "grid grid-cols-3 gap-3" },
|
|
99
|
+
React.createElement("fieldset", { className: "flex flex-col gap-1 border-0 p-0 m-0" },
|
|
100
|
+
React.createElement("legend", { className: "text-xs font-medium pb-1" }, "Series in"),
|
|
101
|
+
["rows", "columns"].map((value) => (React.createElement("label", { key: value, className: "flex items-center gap-2 text-xs cursor-pointer" },
|
|
102
|
+
React.createElement("input", { type: "radio", name: "fillSeriesIn", value: value, checked: axis === value, onChange: () => setAxis(value) }),
|
|
103
|
+
value === "rows" ? "Rows" : "Columns")))),
|
|
104
|
+
React.createElement("fieldset", { className: "flex flex-col gap-1 border-0 p-0 m-0" },
|
|
105
|
+
React.createElement("legend", { className: "text-xs font-medium pb-1" }, "Type"),
|
|
106
|
+
SERIES_TYPES.map(({ value, label }) => (React.createElement("label", { key: value, className: "flex items-center gap-2 text-xs cursor-pointer" },
|
|
107
|
+
React.createElement("input", { type: "radio", name: "fillSeriesType", value: value, checked: type === value, onChange: () => setType(value) }),
|
|
108
|
+
label)))),
|
|
109
|
+
React.createElement("fieldset", { className: "flex flex-col gap-1 border-0 p-0 m-0", disabled: type !== "date" },
|
|
110
|
+
React.createElement("legend", { className: "text-xs font-medium pb-1" }, "Date unit"),
|
|
111
|
+
DATE_UNITS.map(({ value, label }) => (React.createElement("label", { key: value, className: "flex items-center gap-2 text-xs cursor-pointer disabled:opacity-50" },
|
|
112
|
+
React.createElement("input", { type: "radio", name: "fillSeriesDateUnit", value: value, checked: dateUnit === value, onChange: () => setDateUnit(value), disabled: type !== "date" }),
|
|
113
|
+
React.createElement("span", { className: type !== "date" ? "opacity-50" : "" }, label)))))),
|
|
114
|
+
React.createElement("label", { className: "flex items-center gap-2 text-xs cursor-pointer" },
|
|
115
|
+
React.createElement("input", { type: "checkbox", name: "fillSeriesTrend", checked: trendAllowed && trend, disabled: !trendAllowed, onChange: (e) => setTrend(e.target.checked) }),
|
|
116
|
+
React.createElement("span", { className: !trendAllowed ? "opacity-50" : "" }, "Trend")),
|
|
117
|
+
React.createElement("div", { className: "grid grid-cols-2 gap-3" },
|
|
118
|
+
React.createElement("label", { className: "flex flex-col gap-1 text-xs" },
|
|
119
|
+
"Step value",
|
|
120
|
+
React.createElement(Input, { name: "fillSeriesStep", value: step, disabled: stepStopDisabled, onChange: (e) => {
|
|
121
|
+
setStep(e.target.value);
|
|
122
|
+
setError(undefined);
|
|
123
|
+
}, inputMode: "decimal" })),
|
|
124
|
+
React.createElement("label", { className: "flex flex-col gap-1 text-xs" },
|
|
125
|
+
"Stop value",
|
|
126
|
+
React.createElement(Input, { name: "fillSeriesStop", value: stop, disabled: stepStopDisabled, onChange: (e) => {
|
|
127
|
+
setStop(e.target.value);
|
|
128
|
+
setError(undefined);
|
|
129
|
+
}, inputMode: "decimal" }))),
|
|
130
|
+
error ? (React.createElement("div", { role: "alert", className: "text-xs text-rnc-destructive" }, error)) : null,
|
|
131
|
+
React.createElement(Separator, null),
|
|
132
|
+
React.createElement("div", { className: "flex justify-end gap-2" },
|
|
133
|
+
React.createElement(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => onOpenChange(false) }, "Cancel"),
|
|
134
|
+
React.createElement(Button, { type: "submit", size: "sm" }, "OK")))))));
|
|
135
|
+
});
|
|
136
|
+
FillSeriesDialog.displayName = "FillSeriesDialog";
|
|
137
|
+
/**
|
|
138
|
+
* Host-mounted, atom-driven wrapper around {@link FillSeriesDialog}. Mount it
|
|
139
|
+
* once alongside the other editor dialogs; the grid opens it via
|
|
140
|
+
* `useOpenFillSeriesDialog` (right-drag menu "Series…", or
|
|
141
|
+
* `SpreadsheetApi.openFillSeriesDialog()` from a Fill toolbar/menu).
|
|
142
|
+
*/
|
|
143
|
+
export const FillSeriesDialogHost = () => {
|
|
144
|
+
const [request, setRequest] = useFillSeriesDialogState();
|
|
145
|
+
const close = useCallback(() => setRequest(null), [setRequest]);
|
|
146
|
+
return (React.createElement(FillSeriesDialog, { open: request != null, onOpenChange: (open) => {
|
|
147
|
+
if (!open)
|
|
148
|
+
close();
|
|
149
|
+
}, initialIn: request?.initialIn, onApply: (spec) => request?.onApply(spec) }));
|
|
150
|
+
};
|
|
151
|
+
FillSeriesDialogHost.displayName = "FillSeriesDialogHost";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { AutoFillType } from "../../types";
|
|
3
|
+
export type FillOptionsMenuProps = {
|
|
4
|
+
/** Position/size of the selection the menu is anchored to (bottom-right). */
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
/**
|
|
10
|
+
* `"smart-tag"` — Excel's Auto Fill Options button after a left drag (the
|
|
11
|
+
* fill already ran). `"menu"` — the menu a right-button drag opens on
|
|
12
|
+
* release (nothing filled yet).
|
|
13
|
+
*/
|
|
14
|
+
mode: "smart-tag" | "menu";
|
|
15
|
+
/** The fill type currently applied (`undefined` = auto-detected). */
|
|
16
|
+
fillType?: AutoFillType;
|
|
17
|
+
/** Source has date-formatted cells → Fill Days / Weekdays / Months / Years. */
|
|
18
|
+
hasDates: boolean;
|
|
19
|
+
onChooseFillType(fillType: AutoFillType): void;
|
|
20
|
+
/** "Series…" (right-drag menu only). Hidden when omitted. */
|
|
21
|
+
onOpenSeriesDialog?(): void;
|
|
22
|
+
/** Menu dismissed without a choice. */
|
|
23
|
+
onClose?(): void;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Excel's fill-type chooser. Two skins over one list: the Auto Fill Options
|
|
27
|
+
* smart tag (a small button at the bottom-right of the filled range that
|
|
28
|
+
* opens the list on click) and the right-drag menu (opens immediately on
|
|
29
|
+
* release, adds Linear/Growth Trend and Series…). Flash Fill is out of scope.
|
|
30
|
+
*/
|
|
31
|
+
export declare const FillOptionsMenu: ({ x, y, width, height, mode, fillType, hasDates, onChooseFillType, onOpenSeriesDialog, onClose, }: FillOptionsMenuProps) => React.JSX.Element;
|
|
32
|
+
//# sourceMappingURL=fill-options-menu.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fill-options-menu.d.ts","sourceRoot":"","sources":["../../../../components/selection/fill-options-menu.tsx"],"names":[],"mappings":"AAYA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAEhD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,MAAM,MAAM,oBAAoB,GAAG;IACjC,6EAA6E;IAC7E,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;IAC3B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,+EAA+E;IAC/E,QAAQ,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAC;IAC/C,6DAA6D;IAC7D,kBAAkB,CAAC,IAAI,IAAI,CAAC;IAC5B,uCAAuC;IACvC,OAAO,CAAC,IAAI,IAAI,CAAC;CAClB,CAAC;AAuBF;;;;;GAKG;AACH,eAAO,MAAM,eAAe,GAAI,mGAW7B,oBAAoB,sBA+EtB,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { CheckIcon, MdOutlineArrowDropDown } from "@rowsncolumns/icons";
|
|
2
|
+
import { DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuItemIndicator, DropdownMenuPortal, DropdownMenuSeparator, DropdownMenuTrigger, IconButton, } from "@rowsncolumns/ui";
|
|
3
|
+
import React, { useRef, useState } from "react";
|
|
4
|
+
import { StyledFakeTriggerButton } from "../context-menu/style";
|
|
5
|
+
const BASE_ENTRIES = [
|
|
6
|
+
{ fillType: "FillCopy", label: "Copy Cells" },
|
|
7
|
+
{ fillType: "FillSeries", label: "Fill Series" },
|
|
8
|
+
{ fillType: "FillFormats", label: "Fill Formatting Only" },
|
|
9
|
+
{ fillType: "FillWithoutFormatting", label: "Fill Without Formatting" },
|
|
10
|
+
];
|
|
11
|
+
const DATE_ENTRIES = [
|
|
12
|
+
{ fillType: "FillDays", label: "Fill Days" },
|
|
13
|
+
{ fillType: "FillWeekdays", label: "Fill Weekdays" },
|
|
14
|
+
{ fillType: "FillMonths", label: "Fill Months" },
|
|
15
|
+
{ fillType: "FillYears", label: "Fill Years" },
|
|
16
|
+
];
|
|
17
|
+
const TREND_ENTRIES = [
|
|
18
|
+
{ fillType: "LinearTrend", label: "Linear Trend" },
|
|
19
|
+
{ fillType: "GrowthTrend", label: "Growth Trend" },
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* Excel's fill-type chooser. Two skins over one list: the Auto Fill Options
|
|
23
|
+
* smart tag (a small button at the bottom-right of the filled range that
|
|
24
|
+
* opens the list on click) and the right-drag menu (opens immediately on
|
|
25
|
+
* release, adds Linear/Growth Trend and Series…). Flash Fill is out of scope.
|
|
26
|
+
*/
|
|
27
|
+
export const FillOptionsMenu = ({ x, y, width, height, mode, fillType, hasDates, onChooseFillType, onOpenSeriesDialog, onClose, }) => {
|
|
28
|
+
const [open, setOpen] = useState(mode === "menu");
|
|
29
|
+
const isMenu = mode === "menu";
|
|
30
|
+
// Radix fires `onSelect` and then closes; a close that follows a choice is
|
|
31
|
+
// not a cancel.
|
|
32
|
+
const choseRef = useRef(false);
|
|
33
|
+
const entries = [
|
|
34
|
+
...BASE_ENTRIES,
|
|
35
|
+
...(hasDates ? DATE_ENTRIES : []),
|
|
36
|
+
...(isMenu ? TREND_ENTRIES : []),
|
|
37
|
+
];
|
|
38
|
+
return (React.createElement("div", { className: "absolute pointer-events-auto flex items-start justify-start", style: { left: x + width, top: y + height }, onMouseDown: (e) => e.stopPropagation(), "data-testid": "fill-options" },
|
|
39
|
+
React.createElement(DropdownMenu, { modal: false, open: open, onOpenChange: (next) => {
|
|
40
|
+
setOpen(next);
|
|
41
|
+
if (!next && isMenu && !choseRef.current)
|
|
42
|
+
onClose?.();
|
|
43
|
+
if (!next)
|
|
44
|
+
choseRef.current = false;
|
|
45
|
+
} },
|
|
46
|
+
React.createElement(DropdownMenuTrigger, { asChild: true }, isMenu ? (React.createElement(StyledFakeTriggerButton, { "aria-label": "Fill options" })) : (React.createElement(IconButton, { tooltip: "Auto Fill Options", "aria-label": "Auto Fill Options", className: "shadow-sm bg-rnc-background border-rnc-border border border-solid rounded-md" },
|
|
47
|
+
React.createElement(MdOutlineArrowDropDown, null)))),
|
|
48
|
+
React.createElement(DropdownMenuPortal, null,
|
|
49
|
+
React.createElement(DropdownMenuContent, { align: "start", onCloseAutoFocus: (event) => event.preventDefault() },
|
|
50
|
+
entries.map((entry) => (React.createElement(DropdownMenuCheckboxItem, { key: entry.fillType, checked: fillType === entry.fillType, onSelect: () => {
|
|
51
|
+
choseRef.current = true;
|
|
52
|
+
onChooseFillType(entry.fillType);
|
|
53
|
+
} },
|
|
54
|
+
React.createElement(DropdownMenuItemIndicator, null,
|
|
55
|
+
React.createElement(CheckIcon, null)),
|
|
56
|
+
entry.label))),
|
|
57
|
+
isMenu && onOpenSeriesDialog ? (React.createElement(React.Fragment, null,
|
|
58
|
+
React.createElement(DropdownMenuSeparator, null),
|
|
59
|
+
React.createElement(DropdownMenuItem, { onSelect: () => {
|
|
60
|
+
choseRef.current = true;
|
|
61
|
+
onOpenSeriesDialog();
|
|
62
|
+
} }, "Series\u2026"))) : null)))));
|
|
63
|
+
};
|
|
@@ -5,5 +5,5 @@ import type { SelectionNewProps } from "./types";
|
|
|
5
5
|
* @param param0
|
|
6
6
|
* @returns
|
|
7
7
|
*/
|
|
8
|
-
export declare const Selection: React.MemoExoticComponent<({ x, y, width, height, fillHandleSize, showFillHandle, offset, stroke, strokeLeftColor, strokeTopColor, strokeRightColor, strokeBottomColor, strokeWidth, strokeTopWidth, strokeRightWidth, strokeBottomWidth, strokeLeftWidth, strokeStyle, fillOpacity, draggable, isDragging, borderCoverWidth, type, range, title, keepTitleWithinBounds, keepTitleWithinVerticalBounds, flipTitleToBottom, table, pivotTable, onMouseDownTitle, onMouseDownResizeHandle, onMouseDownMoveHandle, TitleComponent, onMouseDown, onRequestEditTable, onRequestEditPivotTable, onFlashEnd, zIndex, index, id, showResizeHandles, resizeHandleBorderColor, resizeHandleSize, fill, duration, selectionCount, enableMagicFill, sheetId, activeCell, selection, MagicFillComponent, metadata, readonly, showPasteMenu, onSplitTextToColumns, agentSuggestion, isHovered, MagicFillContent, QuickEdit, PasteMenu, SuggestionAction, onRemoveQuickEdit, onAddQuickEdit, }: SelectionNewProps) => React.JSX.Element>;
|
|
8
|
+
export declare const Selection: React.MemoExoticComponent<({ x, y, width, height, fillHandleSize, showFillHandle, offset, stroke, strokeLeftColor, strokeTopColor, strokeRightColor, strokeBottomColor, strokeWidth, strokeTopWidth, strokeRightWidth, strokeBottomWidth, strokeLeftWidth, strokeStyle, fillOpacity, draggable, isDragging, borderCoverWidth, type, range, title, keepTitleWithinBounds, keepTitleWithinVerticalBounds, flipTitleToBottom, table, pivotTable, onMouseDownTitle, onMouseDownResizeHandle, onMouseDownMoveHandle, TitleComponent, onMouseDown, onRequestEditTable, onRequestEditPivotTable, onFlashEnd, zIndex, index, id, showResizeHandles, resizeHandleBorderColor, resizeHandleSize, fill, duration, selectionCount, enableMagicFill, sheetId, activeCell, selection, MagicFillComponent, metadata, readonly, showPasteMenu, onSplitTextToColumns, agentSuggestion, isHovered, MagicFillContent, QuickEdit, PasteMenu, FillOptionsMenu, fillOptions, onChooseFillType, onOpenFillSeriesDialog, onCloseFillOptions, SuggestionAction, onRemoveQuickEdit, onAddQuickEdit, }: SelectionNewProps) => React.JSX.Element>;
|
|
9
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/selection/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAe,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/selection/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAe,MAAM,OAAO,CAAC;AAcpC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAEjD;;;;GAIG;AACH,eAAO,MAAM,SAAS,+gCAuEjB,iBAAiB,uBA0TrB,CAAC"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { memo } from "react";
|
|
2
|
+
import { FillOptionsMenu as DefaultFillOptionsMenu } from "./fill-options-menu";
|
|
2
3
|
import { MagicFill } from "./magic-fill";
|
|
3
4
|
import { PasteMenu as DefaultPasteMenu } from "./paste-menu";
|
|
4
5
|
import { QuickEdit as DefaultQuickEdit } from "./quick-edit";
|
|
@@ -10,7 +11,7 @@ import { SelectionTitle } from "./title";
|
|
|
10
11
|
* @param param0
|
|
11
12
|
* @returns
|
|
12
13
|
*/
|
|
13
|
-
export const Selection = memo(({ x = 0, y = 0, width = 0, height = 0, fillHandleSize = 8, showFillHandle, offset = 0, stroke, strokeLeftColor = stroke, strokeTopColor = stroke, strokeRightColor = stroke, strokeBottomColor = stroke, strokeWidth = 0, strokeTopWidth = strokeWidth, strokeRightWidth = strokeWidth, strokeBottomWidth = strokeWidth, strokeLeftWidth = strokeWidth, strokeStyle = "solid", fillOpacity = 1, draggable, isDragging, borderCoverWidth = 5, type, range, title, keepTitleWithinBounds, keepTitleWithinVerticalBounds, flipTitleToBottom, table, pivotTable, onMouseDownTitle, onMouseDownResizeHandle, onMouseDownMoveHandle, TitleComponent = SelectionTitle, onMouseDown, onRequestEditTable, onRequestEditPivotTable, onFlashEnd, zIndex, index, id, showResizeHandles, resizeHandleBorderColor, resizeHandleSize = 6, fill, duration, selectionCount, enableMagicFill, sheetId, activeCell, selection, MagicFillComponent = MagicFill, metadata, readonly, showPasteMenu, onSplitTextToColumns, agentSuggestion, isHovered, MagicFillContent, QuickEdit = DefaultQuickEdit, PasteMenu = DefaultPasteMenu, SuggestionAction = DefaultSuggestionAction, onRemoveQuickEdit, onAddQuickEdit, }) => {
|
|
14
|
+
export const Selection = memo(({ x = 0, y = 0, width = 0, height = 0, fillHandleSize = 8, showFillHandle, offset = 0, stroke, strokeLeftColor = stroke, strokeTopColor = stroke, strokeRightColor = stroke, strokeBottomColor = stroke, strokeWidth = 0, strokeTopWidth = strokeWidth, strokeRightWidth = strokeWidth, strokeBottomWidth = strokeWidth, strokeLeftWidth = strokeWidth, strokeStyle = "solid", fillOpacity = 1, draggable, isDragging, borderCoverWidth = 5, type, range, title, keepTitleWithinBounds, keepTitleWithinVerticalBounds, flipTitleToBottom, table, pivotTable, onMouseDownTitle, onMouseDownResizeHandle, onMouseDownMoveHandle, TitleComponent = SelectionTitle, onMouseDown, onRequestEditTable, onRequestEditPivotTable, onFlashEnd, zIndex, index, id, showResizeHandles, resizeHandleBorderColor, resizeHandleSize = 6, fill, duration, selectionCount, enableMagicFill, sheetId, activeCell, selection, MagicFillComponent = MagicFill, metadata, readonly, showPasteMenu, onSplitTextToColumns, agentSuggestion, isHovered, MagicFillContent, QuickEdit = DefaultQuickEdit, PasteMenu = DefaultPasteMenu, FillOptionsMenu = DefaultFillOptionsMenu, fillOptions, onChooseFillType, onOpenFillSeriesDialog, onCloseFillOptions, SuggestionAction = DefaultSuggestionAction, onRemoveQuickEdit, onAddQuickEdit, }) => {
|
|
14
15
|
// Show paste menu
|
|
15
16
|
const finalShowPasteMenu = !showPasteMenu
|
|
16
17
|
? false
|
|
@@ -187,6 +188,7 @@ export const Selection = memo(({ x = 0, y = 0, width = 0, height = 0, fillHandle
|
|
|
187
188
|
(type === "selection" ||
|
|
188
189
|
(type === "activeCell" && selectionCount === 0)) ? (React.createElement(MagicFillComponent, { sheetId: sheetId, x: x, y: y, height: height, width: width, type: type, activeCell: activeCell, selection: selection, isHovered: isHovered, MagicFillContent: MagicFillContent, onAddQuickEdit: onAddQuickEdit, backgroundColor: stroke })) : null,
|
|
189
190
|
type === "quickedit" ? (React.createElement(QuickEdit, { x: x, y: y, width: width, height: height, range: range, sheetId: sheetId, onRemoveQuickEdit: onRemoveQuickEdit })) : null,
|
|
190
|
-
finalShowPasteMenu && (React.createElement(PasteMenu, { x: x + fillHandleSize / 2, y: y + fillHandleSize / 2, width: width, height: height, onSplitTextToColumns: onSplitTextToColumns }))
|
|
191
|
+
finalShowPasteMenu && (React.createElement(PasteMenu, { x: x + fillHandleSize / 2, y: y + fillHandleSize / 2, width: width, height: height, onSplitTextToColumns: onSplitTextToColumns })),
|
|
192
|
+
fillOptions && type === "selection" && onChooseFillType ? (React.createElement(FillOptionsMenu, { x: x + fillHandleSize / 2, y: y + fillHandleSize / 2, width: width, height: height, mode: fillOptions.mode, fillType: fillOptions.fillType, hasDates: fillOptions.hasDates, onChooseFillType: onChooseFillType, onOpenSeriesDialog: onOpenFillSeriesDialog, onClose: onCloseFillOptions })) : null));
|
|
191
193
|
});
|
|
192
194
|
Selection.displayName = "Selection";
|
|
@@ -2,8 +2,9 @@ import type { CellInterface } from "@rowsncolumns/common-types";
|
|
|
2
2
|
import type { SelectionProps } from "@rowsncolumns/grid";
|
|
3
3
|
import type { ElementType } from "react";
|
|
4
4
|
import type { Maybe, PivotTable, SheetRange } from "../../types";
|
|
5
|
-
import type { TableView } from "../../types";
|
|
5
|
+
import type { AutoFillType, TableView } from "../../types";
|
|
6
6
|
import type { SelectionAttributes } from "../canvas-grid/typings";
|
|
7
|
+
import type { FillOptionsMenuProps } from "./fill-options-menu";
|
|
7
8
|
import type { MagicFillContentProps, MagicFillProps } from "./magic-fill";
|
|
8
9
|
import type { PasteMenuProps } from "./paste-menu";
|
|
9
10
|
import type { QuickEditProps } from "./quick-edit";
|
|
@@ -31,6 +32,15 @@ export type SelectionNewProps = SelectionProps<SelectionAttributes> & {
|
|
|
31
32
|
MagicFillContent?: React.ComponentType<MagicFillContentProps>;
|
|
32
33
|
QuickEdit?: React.ComponentType<QuickEditProps>;
|
|
33
34
|
PasteMenu?: React.ComponentType<PasteMenuProps>;
|
|
35
|
+
FillOptionsMenu?: React.ComponentType<FillOptionsMenuProps>;
|
|
36
|
+
/**
|
|
37
|
+
* Pending Auto Fill Options / right-drag fill menu for THIS selection
|
|
38
|
+
* (present only on the selection whose range is the fill target).
|
|
39
|
+
*/
|
|
40
|
+
fillOptions?: Pick<FillOptionsMenuProps, "mode" | "fillType" | "hasDates">;
|
|
41
|
+
onChooseFillType?(fillType: AutoFillType): void;
|
|
42
|
+
onOpenFillSeriesDialog?(): void;
|
|
43
|
+
onCloseFillOptions?(): void;
|
|
34
44
|
SuggestionAction?: React.ComponentType<SuggestionActionProps>;
|
|
35
45
|
readonly?: boolean;
|
|
36
46
|
showPasteMenu?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../components/selection/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEzC,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../components/selection/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { CellFormat } from "../../types";
|
|
3
|
+
/**
|
|
4
|
+
* What the toolbar's "General" item writes to the cell. "General" must be an
|
|
5
|
+
* EXPLICIT format, not the absence of one: a `=DATE()` cell with no
|
|
6
|
+
* `numberFormat` derives a date format at paint time in both engines, so
|
|
7
|
+
* emitting `undefined` here left the cell showing `2/29/1900` after the user
|
|
8
|
+
* chose General (rowsncolumns/spreadsheet#642 B-05). Excel stamps numFmtId 0
|
|
9
|
+
* and shows the serial.
|
|
10
|
+
*/
|
|
11
|
+
export declare const GENERAL_NUMBER_FORMAT: NonNullable<CellFormat["numberFormat"]>;
|
|
3
12
|
export type TextFormatSelectorProps = {
|
|
4
13
|
/**
|
|
5
14
|
* Current cell format
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-format-selector.d.ts","sourceRoot":"","sources":["../../../../components/toolbar/text-format-selector.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAe,MAAM,OAAO,CAAC;AAIpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,MAAM,uBAAuB,GAAG;IACpC;;OAEG;IACH,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,CAAC,CAAC,SAAS,MAAM,UAAU,EAC7C,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KACjB,IAAI,CAAC;IACV,oBAAoB,CAAC,IAAI,IAAI,CAAC;CAC/B,CAAC;AAEF,eAAO,MAAM,kBAAkB,0GAO1B,uBAAuB,uBAqY3B,CAAC"}
|
|
1
|
+
{"version":3,"file":"text-format-selector.d.ts","sourceRoot":"","sources":["../../../../components/toolbar/text-format-selector.tsx"],"names":[],"mappings":"AAyBA,OAAO,KAAe,MAAM,OAAO,CAAC;AAIpC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,UAAU,CAAC,cAAc,CAAC,CAIvE,CAAC;AAEJ,MAAM,MAAM,uBAAuB,GAAG;IACpC;;OAEG;IACH,UAAU,CAAC,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,CAAC,CAAC,SAAS,MAAM,UAAU,EAC7C,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KACjB,IAAI,CAAC;IACV,oBAAoB,CAAC,IAAI,IAAI,CAAC;CAC/B,CAAC;AAEF,eAAO,MAAM,kBAAkB,0GAO1B,uBAAuB,uBAqY3B,CAAC"}
|
|
@@ -4,6 +4,18 @@ import { getDefaultDateFormat, getLongDateFormat, ssfFormat, } from "@rowsncolum
|
|
|
4
4
|
import React, { memo } from "react";
|
|
5
5
|
import { useFocusSheet } from "../../atoms";
|
|
6
6
|
import { getCurrencySymbol } from "../../helpers";
|
|
7
|
+
/**
|
|
8
|
+
* What the toolbar's "General" item writes to the cell. "General" must be an
|
|
9
|
+
* EXPLICIT format, not the absence of one: a `=DATE()` cell with no
|
|
10
|
+
* `numberFormat` derives a date format at paint time in both engines, so
|
|
11
|
+
* emitting `undefined` here left the cell showing `2/29/1900` after the user
|
|
12
|
+
* chose General (rowsncolumns/spreadsheet#642 B-05). Excel stamps numFmtId 0
|
|
13
|
+
* and shows the serial.
|
|
14
|
+
*/
|
|
15
|
+
export const GENERAL_NUMBER_FORMAT = {
|
|
16
|
+
type: "GENERAL",
|
|
17
|
+
pattern: "General",
|
|
18
|
+
};
|
|
7
19
|
export const TextFormatSelector = memo(({ locale = "en-US", currency = "USD", cellFormat, onChangeFormatting, onRequestFormatCells, }) => {
|
|
8
20
|
const localeDateFormat = getDefaultDateFormat(locale);
|
|
9
21
|
const longDateFormat = getLongDateFormat(locale);
|
|
@@ -36,14 +48,14 @@ export const TextFormatSelector = memo(({ locale = "en-US", currency = "USD", ce
|
|
|
36
48
|
const isCurrencyRounded = cellFormat?.numberFormat?.pattern === currencyRoundedPattern;
|
|
37
49
|
return (React.createElement(DropdownMenu, { modal: false },
|
|
38
50
|
React.createElement(DropdownMenuTrigger, { asChild: true },
|
|
39
|
-
React.createElement(IconButton, { tooltip: "More formats" },
|
|
51
|
+
React.createElement(IconButton, { tooltip: "More formats", "aria-label": "More formats" },
|
|
40
52
|
React.createElement("div", { className: "text-xs" }, "123"),
|
|
41
53
|
React.createElement(MdOutlineArrowDropDown, null))),
|
|
42
54
|
React.createElement(DropdownMenuPortal, null,
|
|
43
55
|
React.createElement(DropdownMenuContent, { align: "start" },
|
|
44
56
|
React.createElement(DropdownMenuCheckboxItem, { checked: !cellFormat?.numberFormat?.type ||
|
|
45
57
|
cellFormat?.numberFormat?.type === "GENERAL", onCheckedChange: () => {
|
|
46
|
-
onChangeFormatting("numberFormat",
|
|
58
|
+
onChangeFormatting("numberFormat", GENERAL_NUMBER_FORMAT);
|
|
47
59
|
focusSheet?.();
|
|
48
60
|
} },
|
|
49
61
|
React.createElement(DropdownMenuItemIndicator, null,
|
|
@@ -33,6 +33,13 @@ export type EditorSubmitOptions = {
|
|
|
33
33
|
* there would undo the switch they just made.
|
|
34
34
|
*/
|
|
35
35
|
preserveActiveSheet?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Ctrl+Enter (Excel): commit the entry into EVERY cell of the current
|
|
38
|
+
* selection — relative references shift per cell, as a copy-fill would —
|
|
39
|
+
* and keep both the active cell and the selection where they are. On a
|
|
40
|
+
* single cell this is a plain in-place commit (no move down).
|
|
41
|
+
*/
|
|
42
|
+
fillSelection?: boolean;
|
|
36
43
|
};
|
|
37
44
|
export type UseEditableOptions<T extends CellData> = {
|
|
38
45
|
/**
|
|
@@ -260,9 +267,11 @@ export type SharedEditorProps = {
|
|
|
260
267
|
*/
|
|
261
268
|
onChange?: (value: string, textFormatRuns: TextFormatRun[] | undefined, editingSheetId: number, activeCell: CellInterface) => void;
|
|
262
269
|
/**
|
|
263
|
-
* Callback to submit the value back to data store
|
|
270
|
+
* Callback to submit the value back to data store. `shouldFocusGrid`
|
|
271
|
+
* defaults to true; `options` carries commit intent the editor derived from
|
|
272
|
+
* the keystroke (e.g. Ctrl+Enter → `fillSelection`).
|
|
264
273
|
*/
|
|
265
|
-
onSubmit?: (value: string, textFormatRuns: TextFormatRun[] | undefined, editingSheetId: number, activeCell: CellInterface, nextActiveCell?: CellInterface | null) => void;
|
|
274
|
+
onSubmit?: (value: string, textFormatRuns: TextFormatRun[] | undefined, editingSheetId: number, activeCell: CellInterface, nextActiveCell?: CellInterface | null, shouldFocusGrid?: boolean, options?: EditorSubmitOptions) => void;
|
|
266
275
|
/**
|
|
267
276
|
* On Cancel callbacks. Hides the editor
|
|
268
277
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-editable.d.ts","sourceRoot":"","sources":["../../../hooks/use-editable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,KAAK,EACL,aAAa,EACb,YAAY,EACZ,SAAS,EACT,UAAU,EACV,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAEL,SAAS,EAIV,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAa/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAGzE,OAAO,KAAK,EAAE,QAAQ,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE9E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7D;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC;;;;;OAKG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"use-editable.d.ts","sourceRoot":"","sources":["../../../hooks/use-editable.tsx"],"names":[],"mappings":"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"}
|
|
@@ -397,6 +397,14 @@ export const useEditable = ({ getEditor = getDefaultEditor, getValue, getTextFor
|
|
|
397
397
|
const isEnter = key === "Enter";
|
|
398
398
|
// Edit mode
|
|
399
399
|
if (isEditInProgress) {
|
|
400
|
+
// Tab has no browser default inside the grid: whether the editor
|
|
401
|
+
// committed on it or a function/mention dropdown swallowed it, the
|
|
402
|
+
// browser's sequential focus navigation must never pull focus off
|
|
403
|
+
// the cell editor onto the next tabbable element (sheet tab,
|
|
404
|
+
// toolbar) — the active cell moves right instead, as in Excel.
|
|
405
|
+
if (key === "Tab") {
|
|
406
|
+
e.preventDefault();
|
|
407
|
+
}
|
|
400
408
|
// Exit if editor prevented this keydown
|
|
401
409
|
// If dropdown is active
|
|
402
410
|
if (e.defaultPrevented) {
|
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
import type { DataValidationRuleAlert } from "@rowsncolumns/common-types";
|
|
2
|
-
import type { CellInterface } from "@rowsncolumns/grid";
|
|
2
|
+
import type { CellInterface, GridRange, SelectionArea } from "@rowsncolumns/grid";
|
|
3
3
|
import type { TextFormatRun } from "@rowsncolumns/ui";
|
|
4
4
|
import type { ValidationAlertRequest } from "../atoms/validation-alert.atom";
|
|
5
|
-
import type { CanvasGridProps } from "../components/canvas-grid/typings";
|
|
5
|
+
import type { CanvasGridProps, SelectionAttributes } from "../components/canvas-grid/typings";
|
|
6
6
|
import type { EditorSubmitOptions } from "./use-editable";
|
|
7
7
|
import type { useSelection } from "./use-selection";
|
|
8
|
+
type EntryValue = string | boolean;
|
|
9
|
+
/** One `onChangeBatch` write: a rectangle of the selection and its per-cell values. */
|
|
10
|
+
export type EntryFillWrite = {
|
|
11
|
+
range: GridRange;
|
|
12
|
+
values: EntryValue[][];
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* The value Ctrl+Enter writes into `cell` for an entry typed at `activeCell`: constants verbatim,
|
|
16
|
+
* formulas with their relative references shifted by the cell offset — exactly what a copy-fill
|
|
17
|
+
* from the active cell would produce (`=A1` typed in B2 with B2:B4 selected → B3 gets `=A2`).
|
|
18
|
+
*/
|
|
19
|
+
export declare const entryValueForCell: (value: EntryValue, activeCell: CellInterface, cell: CellInterface) => EntryValue;
|
|
20
|
+
/**
|
|
21
|
+
* Plan the Ctrl+Enter writes for `selections`: every selected cell except `activeCell` (already
|
|
22
|
+
* committed) gets the entry, formulas shifted per cell. Empty when nothing but the active cell is
|
|
23
|
+
* selected — a single-cell Ctrl+Enter is just an in-place commit.
|
|
24
|
+
*/
|
|
25
|
+
export declare const planEntryFill: (value: EntryValue, activeCell: CellInterface, selections: SelectionArea<SelectionAttributes>[]) => EntryFillWrite[];
|
|
8
26
|
/**
|
|
9
27
|
* Commit-time data-validation enforcement decision for a value about to be
|
|
10
28
|
* written. `block` rejects the value (Excel `errorStyle="stop"`); `confirm`
|
|
@@ -40,6 +58,17 @@ type UseEditorSubmitProps = {
|
|
|
40
58
|
* Oncomplete callback
|
|
41
59
|
*/
|
|
42
60
|
onComplete?(): void;
|
|
61
|
+
/**
|
|
62
|
+
* The grid's current selections — the target of a Ctrl+Enter commit
|
|
63
|
+
* (`options.fillSelection`). Read through a ref, so the identity may change freely.
|
|
64
|
+
*/
|
|
65
|
+
selections?: SelectionArea<SelectionAttributes>[];
|
|
66
|
+
/**
|
|
67
|
+
* Batch write used for the Ctrl+Enter spread of an entry into the selection. Every cell
|
|
68
|
+
* except the active one (committed through `onChange`) goes through here, so the same path
|
|
69
|
+
* serves both engines (legacy `changeBatch`, rnc `change-batch`).
|
|
70
|
+
*/
|
|
71
|
+
onChangeBatch?: CanvasGridProps["onChangeBatch"];
|
|
43
72
|
/**
|
|
44
73
|
* Resolve the data-validation enforcement decision for a value about to be
|
|
45
74
|
* committed at a cell. Returns `undefined` when there is nothing to enforce
|
|
@@ -53,6 +82,6 @@ type UseEditorSubmitProps = {
|
|
|
53
82
|
*/
|
|
54
83
|
showValidationAlert?: (request: ValidationAlertRequest) => Promise<boolean>;
|
|
55
84
|
};
|
|
56
|
-
export declare const useEditorSubmit: ({ sheetId, onChangeActiveSheet, setActiveCell, onChange, onComplete, getCommitValidation, showValidationAlert, }: UseEditorSubmitProps) => (value: string | boolean, textFormatRuns: TextFormatRun[] | undefined | null, previousValue: string | boolean | undefined | null, editingSheetId: number, activeCell: CellInterface, nextActiveCell?: CellInterface | null, isDirty?: boolean, options?: EditorSubmitOptions) => Promise<void>;
|
|
85
|
+
export declare const useEditorSubmit: ({ sheetId, onChangeActiveSheet, setActiveCell, onChange, onComplete, getCommitValidation, showValidationAlert, selections, onChangeBatch, }: UseEditorSubmitProps) => (value: string | boolean, textFormatRuns: TextFormatRun[] | undefined | null, previousValue: string | boolean | undefined | null, editingSheetId: number, activeCell: CellInterface, nextActiveCell?: CellInterface | null, isDirty?: boolean, options?: EditorSubmitOptions) => Promise<void>;
|
|
57
86
|
export {};
|
|
58
87
|
//# sourceMappingURL=use-editor-submit.d.ts.map
|