@rowsncolumns/spreadsheet 10.2.77 → 10.3.1
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/insert-options.d.ts +67 -0
- package/dist/cjs/api/insert-options.d.ts.map +1 -0
- package/dist/cjs/api/insert-options.js +104 -0
- package/dist/cjs/api/move-overwrite.d.ts +14 -0
- package/dist/cjs/api/move-overwrite.d.ts.map +1 -0
- package/dist/cjs/api/move-overwrite.js +29 -0
- package/dist/cjs/api/multi-selection.d.ts +59 -0
- package/dist/cjs/api/multi-selection.d.ts.map +1 -0
- package/dist/cjs/api/multi-selection.js +166 -0
- package/dist/cjs/atoms/index.d.ts +3 -0
- package/dist/cjs/atoms/index.d.ts.map +1 -1
- package/dist/cjs/atoms/index.js +3 -0
- package/dist/cjs/atoms/insert-cells-dialog.atom.d.ts +36 -0
- package/dist/cjs/atoms/insert-cells-dialog.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/insert-cells-dialog.atom.js +34 -0
- package/dist/cjs/atoms/insert-options.atom.d.ts +21 -0
- package/dist/cjs/atoms/insert-options.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/insert-options.atom.js +11 -0
- package/dist/cjs/atoms/move-overwrite-confirm.atom.d.ts +24 -0
- package/dist/cjs/atoms/move-overwrite-confirm.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/move-overwrite-confirm.atom.js +42 -0
- package/dist/cjs/atoms/sheet-context.atom.d.ts +2 -0
- package/dist/cjs/atoms/sheet-context.atom.d.ts.map +1 -1
- package/dist/cjs/atoms/sheet-context.atom.js +15 -2
- package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
- package/dist/cjs/components/canvas-grid/index.js +298 -68
- package/dist/cjs/components/canvas-grid/typings.d.ts +47 -5
- package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/formula-result-preview.d.ts +4 -1
- package/dist/cjs/components/cell-editor/formula-result-preview.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/formula-result-preview.js +2 -2
- package/dist/cjs/components/cell-editor/index.d.ts +7 -1
- package/dist/cjs/components/cell-editor/index.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/index.js +3 -3
- package/dist/cjs/components/cell-input/cell-input.d.ts +13 -0
- package/dist/cjs/components/cell-input/cell-input.d.ts.map +1 -1
- package/dist/cjs/components/cell-input/cell-input.js +8 -3
- package/dist/cjs/components/cell-input/formula-bar-cell-input.d.ts.map +1 -1
- package/dist/cjs/components/cell-input/formula-bar-cell-input.js +3 -1
- package/dist/cjs/components/context-menu/index.d.ts +16 -1
- package/dist/cjs/components/context-menu/index.d.ts.map +1 -1
- package/dist/cjs/components/context-menu/index.js +245 -24
- package/dist/cjs/components/embeds/embed-draggable.d.ts.map +1 -1
- package/dist/cjs/components/embeds/embed-draggable.js +4 -3
- package/dist/cjs/components/floating-cell-editor/index.d.ts.map +1 -1
- package/dist/cjs/components/floating-cell-editor/index.js +13 -5
- package/dist/cjs/components/insert-cells-dialog/index.d.ts +35 -0
- package/dist/cjs/components/insert-cells-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/insert-cells-dialog/index.js +84 -0
- package/dist/cjs/components/insert-options-smart-tag/index.d.ts +25 -0
- package/dist/cjs/components/insert-options-smart-tag/index.d.ts.map +1 -0
- package/dist/cjs/components/insert-options-smart-tag/index.js +41 -0
- package/dist/cjs/components/move-overwrite-confirm-dialog/index.d.ts +8 -0
- package/dist/cjs/components/move-overwrite-confirm-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/move-overwrite-confirm-dialog/index.js +34 -0
- package/dist/cjs/components/resizer/index.d.ts.map +1 -1
- package/dist/cjs/components/resizer/index.js +10 -5
- 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 +8 -0
- package/dist/cjs/components/selection/types.d.ts.map +1 -1
- package/dist/cjs/components/sheet-search/index.d.ts.map +1 -1
- package/dist/cjs/components/sheet-search/index.js +6 -2
- package/dist/cjs/config.d.ts +6 -0
- package/dist/cjs/config.d.ts.map +1 -1
- package/dist/cjs/config.js +7 -1
- package/dist/cjs/hooks/use-cell-renderer.d.ts +7 -1
- package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
- package/dist/cjs/hooks/use-cell-renderer.js +8 -3
- package/dist/cjs/hooks/use-context-setter.d.ts.map +1 -1
- package/dist/cjs/hooks/use-context-setter.js +5 -1
- package/dist/cjs/hooks/use-copy-paste-cut.d.ts +5 -0
- package/dist/cjs/hooks/use-copy-paste-cut.d.ts.map +1 -1
- package/dist/cjs/hooks/use-copy-paste-cut.js +25 -3
- package/dist/cjs/hooks/use-editor-change.d.ts +4 -1
- package/dist/cjs/hooks/use-editor-change.d.ts.map +1 -1
- package/dist/cjs/hooks/use-editor-change.js +4 -3
- package/dist/cjs/hooks/use-editor-submit.d.ts +8 -1
- package/dist/cjs/hooks/use-editor-submit.d.ts.map +1 -1
- package/dist/cjs/hooks/use-editor-submit.js +9 -1
- package/dist/cjs/hooks/use-header-actions.d.ts.map +1 -1
- package/dist/cjs/hooks/use-header-actions.js +17 -10
- package/dist/cjs/hooks/use-move-columns-rows.d.ts.map +1 -1
- package/dist/cjs/hooks/use-move-columns-rows.js +27 -15
- package/dist/cjs/hooks/use-selection-move.d.ts.map +1 -1
- package/dist/cjs/hooks/use-selection-move.js +14 -6
- package/dist/cjs/hooks/use-selection-renderer.d.ts +9 -1
- package/dist/cjs/hooks/use-selection-renderer.d.ts.map +1 -1
- package/dist/cjs/hooks/use-selection-renderer.js +26 -2
- package/dist/cjs/hooks/use-selection-resize.d.ts.map +1 -1
- package/dist/cjs/hooks/use-selection-resize.js +13 -6
- package/dist/cjs/hooks/use-selection.d.ts +13 -5
- package/dist/cjs/hooks/use-selection.d.ts.map +1 -1
- package/dist/cjs/hooks/use-selection.js +107 -31
- package/dist/cjs/hooks/use-table-resizer.d.ts.map +1 -1
- package/dist/cjs/hooks/use-table-resizer.js +16 -8
- package/dist/cjs/hooks/use-touch.d.ts.map +1 -1
- package/dist/cjs/hooks/use-touch.js +16 -8
- package/dist/cjs/index.d.ts +7 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +7 -0
- package/dist/cjs/release-date.js +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/esm/api/insert-options.d.ts +67 -0
- package/dist/esm/api/insert-options.d.ts.map +1 -0
- package/dist/esm/api/insert-options.js +91 -0
- package/dist/esm/api/move-overwrite.d.ts +14 -0
- package/dist/esm/api/move-overwrite.d.ts.map +1 -0
- package/dist/esm/api/move-overwrite.js +25 -0
- package/dist/esm/api/multi-selection.d.ts +59 -0
- package/dist/esm/api/multi-selection.d.ts.map +1 -0
- package/dist/esm/api/multi-selection.js +92 -0
- package/dist/esm/atoms/index.d.ts +3 -0
- package/dist/esm/atoms/index.d.ts.map +1 -1
- package/dist/esm/atoms/index.js +3 -0
- package/dist/esm/atoms/insert-cells-dialog.atom.d.ts +36 -0
- package/dist/esm/atoms/insert-cells-dialog.atom.d.ts.map +1 -0
- package/dist/esm/atoms/insert-cells-dialog.atom.js +25 -0
- package/dist/esm/atoms/insert-options.atom.d.ts +21 -0
- package/dist/esm/atoms/insert-options.atom.d.ts.map +1 -0
- package/dist/esm/atoms/insert-options.atom.js +5 -0
- package/dist/esm/atoms/move-overwrite-confirm.atom.d.ts +24 -0
- package/dist/esm/atoms/move-overwrite-confirm.atom.d.ts.map +1 -0
- package/dist/esm/atoms/move-overwrite-confirm.atom.js +29 -0
- package/dist/esm/atoms/sheet-context.atom.d.ts +2 -0
- package/dist/esm/atoms/sheet-context.atom.d.ts.map +1 -1
- package/dist/esm/atoms/sheet-context.atom.js +10 -0
- package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
- package/dist/esm/components/canvas-grid/index.js +250 -24
- package/dist/esm/components/canvas-grid/typings.d.ts +47 -5
- package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/formula-result-preview.d.ts +4 -1
- package/dist/esm/components/cell-editor/formula-result-preview.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/formula-result-preview.js +3 -3
- package/dist/esm/components/cell-editor/index.d.ts +7 -1
- package/dist/esm/components/cell-editor/index.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/index.js +3 -3
- package/dist/esm/components/cell-input/cell-input.d.ts +13 -0
- package/dist/esm/components/cell-input/cell-input.d.ts.map +1 -1
- package/dist/esm/components/cell-input/cell-input.js +10 -5
- package/dist/esm/components/cell-input/formula-bar-cell-input.d.ts.map +1 -1
- package/dist/esm/components/cell-input/formula-bar-cell-input.js +3 -1
- package/dist/esm/components/context-menu/index.d.ts +16 -1
- package/dist/esm/components/context-menu/index.d.ts.map +1 -1
- package/dist/esm/components/context-menu/index.js +193 -16
- package/dist/esm/components/embeds/embed-draggable.d.ts.map +1 -1
- package/dist/esm/components/embeds/embed-draggable.js +3 -2
- package/dist/esm/components/floating-cell-editor/index.d.ts.map +1 -1
- package/dist/esm/components/floating-cell-editor/index.js +12 -6
- package/dist/esm/components/insert-cells-dialog/index.d.ts +35 -0
- package/dist/esm/components/insert-cells-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/insert-cells-dialog/index.js +79 -0
- package/dist/esm/components/insert-options-smart-tag/index.d.ts +25 -0
- package/dist/esm/components/insert-options-smart-tag/index.d.ts.map +1 -0
- package/dist/esm/components/insert-options-smart-tag/index.js +35 -0
- package/dist/esm/components/move-overwrite-confirm-dialog/index.d.ts +8 -0
- package/dist/esm/components/move-overwrite-confirm-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/move-overwrite-confirm-dialog/index.js +30 -0
- package/dist/esm/components/resizer/index.d.ts.map +1 -1
- package/dist/esm/components/resizer/index.js +8 -4
- 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 +8 -0
- package/dist/esm/components/selection/types.d.ts.map +1 -1
- package/dist/esm/components/sheet-search/index.d.ts.map +1 -1
- package/dist/esm/components/sheet-search/index.js +5 -2
- package/dist/esm/config.d.ts +6 -0
- package/dist/esm/config.d.ts.map +1 -1
- package/dist/esm/config.js +6 -0
- package/dist/esm/hooks/use-cell-renderer.d.ts +7 -1
- package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
- package/dist/esm/hooks/use-cell-renderer.js +9 -4
- package/dist/esm/hooks/use-context-setter.d.ts.map +1 -1
- package/dist/esm/hooks/use-context-setter.js +5 -1
- package/dist/esm/hooks/use-copy-paste-cut.d.ts +5 -0
- package/dist/esm/hooks/use-copy-paste-cut.d.ts.map +1 -1
- package/dist/esm/hooks/use-copy-paste-cut.js +25 -4
- package/dist/esm/hooks/use-editor-change.d.ts +4 -1
- package/dist/esm/hooks/use-editor-change.d.ts.map +1 -1
- package/dist/esm/hooks/use-editor-change.js +5 -4
- package/dist/esm/hooks/use-editor-submit.d.ts +8 -1
- package/dist/esm/hooks/use-editor-submit.d.ts.map +1 -1
- package/dist/esm/hooks/use-editor-submit.js +10 -2
- package/dist/esm/hooks/use-header-actions.d.ts.map +1 -1
- package/dist/esm/hooks/use-header-actions.js +11 -4
- package/dist/esm/hooks/use-move-columns-rows.d.ts.map +1 -1
- package/dist/esm/hooks/use-move-columns-rows.js +18 -6
- package/dist/esm/hooks/use-selection-move.d.ts.map +1 -1
- package/dist/esm/hooks/use-selection-move.js +11 -4
- package/dist/esm/hooks/use-selection-renderer.d.ts +9 -1
- package/dist/esm/hooks/use-selection-renderer.d.ts.map +1 -1
- package/dist/esm/hooks/use-selection-renderer.js +26 -2
- package/dist/esm/hooks/use-selection-resize.d.ts.map +1 -1
- package/dist/esm/hooks/use-selection-resize.js +11 -5
- package/dist/esm/hooks/use-selection.d.ts +13 -5
- package/dist/esm/hooks/use-selection.d.ts.map +1 -1
- package/dist/esm/hooks/use-selection.js +89 -27
- package/dist/esm/hooks/use-table-resizer.d.ts.map +1 -1
- package/dist/esm/hooks/use-table-resizer.js +15 -9
- package/dist/esm/hooks/use-touch.d.ts.map +1 -1
- package/dist/esm/hooks/use-touch.js +15 -7
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +7 -0
- package/dist/esm/release-date.js +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/spreadsheet.min.css +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { CellInterface, GridRange, SelectionArea } from "@rowsncolumns/grid";
|
|
2
|
+
import type { CellFormat } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* The paint-format call shape both engines accept from `onChangeFormatting`
|
|
5
|
+
* (`use-paint-format.ts` / rnc `change-formatting` with a `CellFormatOrGrid`):
|
|
6
|
+
* a row-major format grid tiled over the selections, `replace` clearing each
|
|
7
|
+
* target cell first.
|
|
8
|
+
*/
|
|
9
|
+
export type ChangeFormattingWithGrid = (sheetId: number, activeCell: CellInterface, selections: SelectionArea[], formats: (CellFormat | null)[][], options: {
|
|
10
|
+
replace: boolean;
|
|
11
|
+
}) => void;
|
|
12
|
+
export type InsertOptionsAxis = "row" | "column";
|
|
13
|
+
/**
|
|
14
|
+
* Excel's Insert Options smart tag choices after a row insert ("Format Same
|
|
15
|
+
* As Above" / "Format Same As Below" / "Clear Formatting") — for a column
|
|
16
|
+
* insert the first two read "Left" / "Right". `before` is the neighbour the
|
|
17
|
+
* insert already copied (above / left), `after` the neighbour on the other
|
|
18
|
+
* side (below / right).
|
|
19
|
+
*/
|
|
20
|
+
export type InsertFormatOption = "before" | "after" | "clear";
|
|
21
|
+
/** An inserted band: `count` rows (or columns) starting at `start`. */
|
|
22
|
+
export type InsertedBand = {
|
|
23
|
+
axis: InsertOptionsAxis;
|
|
24
|
+
start: number;
|
|
25
|
+
count: number;
|
|
26
|
+
};
|
|
27
|
+
/** Reads a cell's user-entered format; `null`/`undefined` for an unformatted cell. */
|
|
28
|
+
export type FormatReader = (rowIndex: number, columnIndex: number) => CellFormat | null | undefined;
|
|
29
|
+
export type InsertFormatPlan = {
|
|
30
|
+
/** The band cells the formats are written over (one area). */
|
|
31
|
+
selections: SelectionArea[];
|
|
32
|
+
/**
|
|
33
|
+
* Row-major format grid tiled over `selections` by `onChangeFormatting`'s
|
|
34
|
+
* paint-format path (`{ replace: true }`): one source row for a row band
|
|
35
|
+
* (tiles down), one source column for a column band (tiles right). `null`
|
|
36
|
+
* entries clear the target cell's format.
|
|
37
|
+
*/
|
|
38
|
+
formats: (CellFormat | null)[][];
|
|
39
|
+
};
|
|
40
|
+
/** The neighbour line an option copies from: `before` = above/left, `after` = below/right. */
|
|
41
|
+
export declare const neighbourIndexForOption: (band: InsertedBand, option: Exclude<InsertFormatOption, "clear">) => number;
|
|
42
|
+
/**
|
|
43
|
+
* The band as one grid area spanning the first `extent` cells across the
|
|
44
|
+
* other axis — `extent` bounds the write to the formatted part of the sheet
|
|
45
|
+
* instead of all 16,384 columns / 1,048,576 rows.
|
|
46
|
+
*/
|
|
47
|
+
export declare const insertedBandRange: (band: InsertedBand, extent: number) => GridRange;
|
|
48
|
+
/**
|
|
49
|
+
* What re-choosing an Insert Options entry writes: the neighbour line's
|
|
50
|
+
* per-cell formats tiled over the inserted band (`{ replace: true }` so the
|
|
51
|
+
* previous choice's formats do not linger), or `null` when the neighbour has
|
|
52
|
+
* no formats at all — the caller then clears the band instead. `limit` caps
|
|
53
|
+
* the scan across the other axis (the sheet's column / row count).
|
|
54
|
+
*/
|
|
55
|
+
export declare const formatsForInsertOption: (band: InsertedBand, option: Exclude<InsertFormatOption, "clear">, read: FormatReader, limit: number) => InsertFormatPlan | null;
|
|
56
|
+
/**
|
|
57
|
+
* The area "Clear Formatting" wipes: the formatted extent of the band itself
|
|
58
|
+
* (nothing to clear → `null`).
|
|
59
|
+
*/
|
|
60
|
+
export declare const clearRangeForInsertedBand: (band: InsertedBand, read: FormatReader, limit: number) => GridRange | null;
|
|
61
|
+
/**
|
|
62
|
+
* True when any cell of the band (within the first `limit` cells across the
|
|
63
|
+
* other axis) holds a user-entered value. A fresh insert is blank, so a value
|
|
64
|
+
* means the insert was refused or the user has since typed into it.
|
|
65
|
+
*/
|
|
66
|
+
export declare const insertedBandHasValues: (band: InsertedBand, hasValue: (rowIndex: number, columnIndex: number) => boolean, limit: number) => boolean;
|
|
67
|
+
//# sourceMappingURL=insert-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insert-options.d.ts","sourceRoot":"","sources":["../../../api/insert-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE3C;;;;;GAKG;AACH,MAAM,MAAM,wBAAwB,GAAG,CACrC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,aAAa,EACzB,UAAU,EAAE,aAAa,EAAE,EAC3B,OAAO,EAAE,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,EAChC,OAAO,EAAE;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,KAC1B,IAAI,CAAC;AAEV,MAAM,MAAM,iBAAiB,GAAG,KAAK,GAAG,QAAQ,CAAC;AAEjD;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAE9D,uEAAuE;AACvE,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,sFAAsF;AACtF,MAAM,MAAM,YAAY,GAAG,CACzB,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,KAChB,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC;AAEnC,MAAM,MAAM,gBAAgB,GAAG;IAC7B,8DAA8D;IAC9D,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B;;;;;OAKG;IACH,OAAO,EAAE,CAAC,UAAU,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;CAClC,CAAC;AAwBF,8FAA8F;AAC9F,eAAO,MAAM,uBAAuB,GAClC,MAAM,YAAY,EAClB,QAAQ,OAAO,CAAC,kBAAkB,EAAE,OAAO,CAAC,WACuB,CAAC;AAEtE;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAC5B,MAAM,YAAY,EAClB,QAAQ,MAAM,KACb,SAaI,CAAC;AAER;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,GACjC,MAAM,YAAY,EAClB,QAAQ,OAAO,CAAC,kBAAkB,EAAE,OAAO,CAAC,EAC5C,MAAM,YAAY,EAClB,OAAO,MAAM,KACZ,gBAAgB,GAAG,IAqBrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,yBAAyB,GACpC,MAAM,YAAY,EAClB,MAAM,YAAY,EAClB,OAAO,MAAM,KACZ,SAAS,GAAG,IASd,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAChC,MAAM,YAAY,EAClB,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,EAC5D,OAAO,MAAM,YAWd,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
const hasFormat = (format) => !!format && Object.keys(format).length > 0;
|
|
2
|
+
/**
|
|
3
|
+
* Last formatted index along `axis` of the neighbour line `index` (a row when
|
|
4
|
+
* `axis` is `"row"`), scanning at most `limit` cells. `0` when the line holds
|
|
5
|
+
* no formats.
|
|
6
|
+
*/
|
|
7
|
+
const formattedExtent = (read, axis, index, limit) => {
|
|
8
|
+
let extent = 0;
|
|
9
|
+
for (let i = 1; i <= limit; i++) {
|
|
10
|
+
const format = axis === "row" ? read(index, i) : read(i, index);
|
|
11
|
+
if (hasFormat(format))
|
|
12
|
+
extent = i;
|
|
13
|
+
}
|
|
14
|
+
return extent;
|
|
15
|
+
};
|
|
16
|
+
/** The neighbour line an option copies from: `before` = above/left, `after` = below/right. */
|
|
17
|
+
export const neighbourIndexForOption = (band, option) => (option === "before" ? band.start - 1 : band.start + band.count);
|
|
18
|
+
/**
|
|
19
|
+
* The band as one grid area spanning the first `extent` cells across the
|
|
20
|
+
* other axis — `extent` bounds the write to the formatted part of the sheet
|
|
21
|
+
* instead of all 16,384 columns / 1,048,576 rows.
|
|
22
|
+
*/
|
|
23
|
+
export const insertedBandRange = (band, extent) => band.axis === "row"
|
|
24
|
+
? {
|
|
25
|
+
startRowIndex: band.start,
|
|
26
|
+
endRowIndex: band.start + band.count - 1,
|
|
27
|
+
startColumnIndex: 1,
|
|
28
|
+
endColumnIndex: Math.max(1, extent),
|
|
29
|
+
}
|
|
30
|
+
: {
|
|
31
|
+
startRowIndex: 1,
|
|
32
|
+
endRowIndex: Math.max(1, extent),
|
|
33
|
+
startColumnIndex: band.start,
|
|
34
|
+
endColumnIndex: band.start + band.count - 1,
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* What re-choosing an Insert Options entry writes: the neighbour line's
|
|
38
|
+
* per-cell formats tiled over the inserted band (`{ replace: true }` so the
|
|
39
|
+
* previous choice's formats do not linger), or `null` when the neighbour has
|
|
40
|
+
* no formats at all — the caller then clears the band instead. `limit` caps
|
|
41
|
+
* the scan across the other axis (the sheet's column / row count).
|
|
42
|
+
*/
|
|
43
|
+
export const formatsForInsertOption = (band, option, read, limit) => {
|
|
44
|
+
const neighbour = neighbourIndexForOption(band, option);
|
|
45
|
+
if (neighbour < 1)
|
|
46
|
+
return null;
|
|
47
|
+
const sourceExtent = formattedExtent(read, band.axis, neighbour, limit);
|
|
48
|
+
// The band currently carries the formats of the earlier choice; the write
|
|
49
|
+
// must span those too so `replace` clears them.
|
|
50
|
+
const bandExtent = formattedExtent(read, band.axis, band.start, limit);
|
|
51
|
+
const extent = Math.max(sourceExtent, bandExtent);
|
|
52
|
+
if (extent === 0)
|
|
53
|
+
return null;
|
|
54
|
+
const line = [];
|
|
55
|
+
for (let i = 1; i <= extent; i++) {
|
|
56
|
+
const format = band.axis === "row" ? read(neighbour, i) : read(i, neighbour);
|
|
57
|
+
line.push(hasFormat(format) ? { ...format } : null);
|
|
58
|
+
}
|
|
59
|
+
const formats = band.axis === "row" ? [line] : line.map((format) => [format]);
|
|
60
|
+
return {
|
|
61
|
+
selections: [{ range: insertedBandRange(band, extent) }],
|
|
62
|
+
formats,
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* The area "Clear Formatting" wipes: the formatted extent of the band itself
|
|
67
|
+
* (nothing to clear → `null`).
|
|
68
|
+
*/
|
|
69
|
+
export const clearRangeForInsertedBand = (band, read, limit) => {
|
|
70
|
+
let extent = 0;
|
|
71
|
+
for (let k = 0; k < band.count; k++) {
|
|
72
|
+
extent = Math.max(extent, formattedExtent(read, band.axis, band.start + k, limit));
|
|
73
|
+
}
|
|
74
|
+
return extent === 0 ? null : insertedBandRange(band, extent);
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* True when any cell of the band (within the first `limit` cells across the
|
|
78
|
+
* other axis) holds a user-entered value. A fresh insert is blank, so a value
|
|
79
|
+
* means the insert was refused or the user has since typed into it.
|
|
80
|
+
*/
|
|
81
|
+
export const insertedBandHasValues = (band, hasValue, limit) => {
|
|
82
|
+
for (let k = 0; k < band.count; k++) {
|
|
83
|
+
const line = band.start + k;
|
|
84
|
+
for (let i = 1; i <= limit; i++) {
|
|
85
|
+
if (band.axis === "row" ? hasValue(line, i) : hasValue(i, line)) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return false;
|
|
91
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { GridRange } from "@rowsncolumns/grid";
|
|
2
|
+
/** Excel's prompt before a plain drag-move overwrites non-empty destination cells. */
|
|
3
|
+
export declare const MOVE_OVERWRITE_PROMPT = "There's already data here. Do you want to replace it?";
|
|
4
|
+
/**
|
|
5
|
+
* Whether a plain (overwrite) drag-move from `from` to `to` needs Excel's
|
|
6
|
+
* "There's already data here. Do you want to replace it?" prompt: true when any
|
|
7
|
+
* destination cell OUTSIDE the source block holds a value. Cells the block itself
|
|
8
|
+
* currently occupies are never "data here" — they leave with the move — so an
|
|
9
|
+
* overlapping drag one cell over prompts only for the newly covered strip. An
|
|
10
|
+
* empty destination never prompts; Shift+drag (insert) and Ctrl+drag (copy) never
|
|
11
|
+
* reach this check.
|
|
12
|
+
*/
|
|
13
|
+
export declare const needsOverwritePrompt: (from: GridRange, to: GridRange, hasValue: (rowIndex: number, columnIndex: number) => boolean) => boolean;
|
|
14
|
+
//# sourceMappingURL=move-overwrite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move-overwrite.d.ts","sourceRoot":"","sources":["../../../api/move-overwrite.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,sFAAsF;AACtF,eAAO,MAAM,qBAAqB,0DACuB,CAAC;AAE1D;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,GAC/B,MAAM,SAAS,EACf,IAAI,SAAS,EACb,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,KAC3D,OAkBF,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Excel's prompt before a plain drag-move overwrites non-empty destination cells. */
|
|
2
|
+
export const MOVE_OVERWRITE_PROMPT = "There's already data here. Do you want to replace it?";
|
|
3
|
+
/**
|
|
4
|
+
* Whether a plain (overwrite) drag-move from `from` to `to` needs Excel's
|
|
5
|
+
* "There's already data here. Do you want to replace it?" prompt: true when any
|
|
6
|
+
* destination cell OUTSIDE the source block holds a value. Cells the block itself
|
|
7
|
+
* currently occupies are never "data here" — they leave with the move — so an
|
|
8
|
+
* overlapping drag one cell over prompts only for the newly covered strip. An
|
|
9
|
+
* empty destination never prompts; Shift+drag (insert) and Ctrl+drag (copy) never
|
|
10
|
+
* reach this check.
|
|
11
|
+
*/
|
|
12
|
+
export const needsOverwritePrompt = (from, to, hasValue) => {
|
|
13
|
+
for (let rowIndex = to.startRowIndex; rowIndex <= to.endRowIndex; rowIndex++) {
|
|
14
|
+
for (let columnIndex = to.startColumnIndex; columnIndex <= to.endColumnIndex; columnIndex++) {
|
|
15
|
+
const insideSource = rowIndex >= from.startRowIndex &&
|
|
16
|
+
rowIndex <= from.endRowIndex &&
|
|
17
|
+
columnIndex >= from.startColumnIndex &&
|
|
18
|
+
columnIndex <= from.endColumnIndex;
|
|
19
|
+
if (!insideSource && hasValue(rowIndex, columnIndex)) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { GridRange, SelectionArea } from "@rowsncolumns/grid";
|
|
2
|
+
/**
|
|
3
|
+
* How Excel treats the areas of a multi-area (Ctrl-click) selection for the
|
|
4
|
+
* structural commands (rowsncolumns/spreadsheet#647 INS-08 / UI-07):
|
|
5
|
+
*
|
|
6
|
+
* - `single` — one area (or none): the normal Insert / Delete dialog path.
|
|
7
|
+
* - `all-rows` — every area is an entire-row band: insert / delete one block
|
|
8
|
+
* per area, sized to that area, applied bottom-up.
|
|
9
|
+
* - `all-columns` — every area is an entire-column band: same, per column band.
|
|
10
|
+
* - `mixed` — any partial area, or rows mixed with columns: Excel refuses
|
|
11
|
+
* with "That command cannot be used on multiple selections."
|
|
12
|
+
*/
|
|
13
|
+
export type MultiSelectionKind = "single" | "all-rows" | "all-columns" | "mixed";
|
|
14
|
+
export type WholeBandPredicates = {
|
|
15
|
+
isWholeRow(range: GridRange): boolean;
|
|
16
|
+
isWholeColumn(range: GridRange): boolean;
|
|
17
|
+
};
|
|
18
|
+
/** Entire-row test for a sheet `columnCount` wide (the grid's left bound is column 1). */
|
|
19
|
+
export declare const wholeRowPredicate: (columnCount: number, selectionLeftBound?: number) => (range: GridRange) => boolean;
|
|
20
|
+
/** Entire-column test for a sheet `rowCount` tall (the grid's top bound is row 1). */
|
|
21
|
+
export declare const wholeColumnPredicate: (rowCount: number, selectionTopBound?: number) => (range: GridRange) => boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Entire-row test when the sheet extent is unknown: the grid's row-header
|
|
24
|
+
* bookkeeping (`selectedRowHeadersIds`) already lists every row that belongs
|
|
25
|
+
* to a whole-row area, so an area is whole-row when its first and last rows
|
|
26
|
+
* are both listed.
|
|
27
|
+
*/
|
|
28
|
+
export declare const wholeRowPredicateFromHeaderIds: (rowHeaderIds: readonly number[]) => (range: GridRange) => boolean;
|
|
29
|
+
export declare const wholeColumnPredicateFromHeaderIds: (columnHeaderIds: readonly number[]) => (range: GridRange) => boolean;
|
|
30
|
+
export declare const classifyMultiSelection: (selections: readonly SelectionArea[], { isWholeRow, isWholeColumn }: WholeBandPredicates) => MultiSelectionKind;
|
|
31
|
+
export type IndexBand = {
|
|
32
|
+
start: number;
|
|
33
|
+
end: number;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* The bands (start..end, inclusive) a per-area structural command acts on,
|
|
37
|
+
* deduplicated and ordered bottom-up / right-to-left so inserting one block
|
|
38
|
+
* per band never shifts a band that is still to be processed (INS-08).
|
|
39
|
+
*/
|
|
40
|
+
export declare const bandsForAreas: (selections: readonly SelectionArea[], axis: "row" | "column") => IndexBand[];
|
|
41
|
+
/**
|
|
42
|
+
* Groups header ids (e.g. `selectedRowHeadersIds`) into contiguous bands,
|
|
43
|
+
* bottom-up. Fallback for callers that only know which rows/columns are
|
|
44
|
+
* selected, not the areas they came from.
|
|
45
|
+
*/
|
|
46
|
+
export declare const bandsFromIndexes: (indexes: readonly number[]) => IndexBand[];
|
|
47
|
+
/** Sorted, de-duplicated row (or column) indexes covered by ALL areas. */
|
|
48
|
+
export declare const indexesForAreas: (selections: readonly SelectionArea[], axis: "row" | "column") => number[];
|
|
49
|
+
export type InsertCellsChoice = "shift-right" | "shift-down" | "entire-row" | "entire-column";
|
|
50
|
+
export type DeleteCellsChoice = "shift-left" | "shift-up" | "entire-row" | "entire-column";
|
|
51
|
+
/**
|
|
52
|
+
* Excel pre-selects the shift that moves the fewest neighbours: a selection
|
|
53
|
+
* taller than it is wide shifts cells right; a wider-than-tall or square one
|
|
54
|
+
* shifts cells down (UI-06).
|
|
55
|
+
*/
|
|
56
|
+
export declare const defaultInsertCellsChoice: (range: GridRange) => InsertCellsChoice;
|
|
57
|
+
/** Delete mirrors Insert: taller-than-wide → shift left, otherwise shift up. */
|
|
58
|
+
export declare const defaultDeleteCellsChoice: (range: GridRange) => DeleteCellsChoice;
|
|
59
|
+
//# sourceMappingURL=multi-selection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"multi-selection.d.ts","sourceRoot":"","sources":["../../../api/multi-selection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnE;;;;;;;;;;GAUG;AACH,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,UAAU,GAAG,aAAa,GAAG,OAAO,CAAC;AAEjF,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC;IACtC,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC;CAC1C,CAAC;AAEF,0FAA0F;AAC1F,eAAO,MAAM,iBAAiB,GAC3B,aAAa,MAAM,EAAE,2BAAsB,MAC3C,OAAO,SAAS,YAEoB,CAAC;AAExC,sFAAsF;AACtF,eAAO,MAAM,oBAAoB,GAC9B,UAAU,MAAM,EAAE,0BAAqB,MACvC,OAAO,SAAS,YAC0D,CAAC;AAE9E;;;;;GAKG;AACH,eAAO,MAAM,8BAA8B,GACxC,cAAc,SAAS,MAAM,EAAE,MAEtB,OAAO,SAAS,YAEzB,CAAC;AAEJ,eAAO,MAAM,iCAAiC,GAC3C,iBAAiB,SAAS,MAAM,EAAE,MAEzB,OAAO,SAAS,YAIzB,CAAC;AAEJ,eAAO,MAAM,sBAAsB,GACjC,YAAY,SAAS,aAAa,EAAE,EACpC,+BAA+B,mBAAmB,KACjD,kBAOF,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,aAAa,GACxB,YAAY,SAAS,aAAa,EAAE,EACpC,MAAM,KAAK,GAAG,QAAQ,KACrB,SAAS,EAcX,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,SAAS,SAAS,MAAM,EAAE,KAAG,SAAS,EAYtE,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,eAAe,GAC1B,YAAY,SAAS,aAAa,EAAE,EACpC,MAAM,KAAK,GAAG,QAAQ,KACrB,MAAM,EAUR,CAAC;AAEF,MAAM,MAAM,iBAAiB,GACzB,aAAa,GACb,YAAY,GACZ,YAAY,GACZ,eAAe,CAAC;AAEpB,MAAM,MAAM,iBAAiB,GACzB,YAAY,GACZ,UAAU,GACV,YAAY,GACZ,eAAe,CAAC;AAMpB;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GAAI,OAAO,SAAS,KAAG,iBACJ,CAAC;AAEzD,gFAAgF;AAChF,eAAO,MAAM,wBAAwB,GAAI,OAAO,SAAS,KAAG,iBACP,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/** Entire-row test for a sheet `columnCount` wide (the grid's left bound is column 1). */
|
|
2
|
+
export const wholeRowPredicate = (columnCount, selectionLeftBound = 1) => (range) => range.startColumnIndex <= selectionLeftBound &&
|
|
3
|
+
range.endColumnIndex >= columnCount;
|
|
4
|
+
/** Entire-column test for a sheet `rowCount` tall (the grid's top bound is row 1). */
|
|
5
|
+
export const wholeColumnPredicate = (rowCount, selectionTopBound = 1) => (range) => range.startRowIndex <= selectionTopBound && range.endRowIndex >= rowCount;
|
|
6
|
+
/**
|
|
7
|
+
* Entire-row test when the sheet extent is unknown: the grid's row-header
|
|
8
|
+
* bookkeeping (`selectedRowHeadersIds`) already lists every row that belongs
|
|
9
|
+
* to a whole-row area, so an area is whole-row when its first and last rows
|
|
10
|
+
* are both listed.
|
|
11
|
+
*/
|
|
12
|
+
export const wholeRowPredicateFromHeaderIds = (rowHeaderIds) => {
|
|
13
|
+
const ids = new Set(rowHeaderIds);
|
|
14
|
+
return (range) => ids.size > 0 && ids.has(range.startRowIndex) && ids.has(range.endRowIndex);
|
|
15
|
+
};
|
|
16
|
+
export const wholeColumnPredicateFromHeaderIds = (columnHeaderIds) => {
|
|
17
|
+
const ids = new Set(columnHeaderIds);
|
|
18
|
+
return (range) => ids.size > 0 &&
|
|
19
|
+
ids.has(range.startColumnIndex) &&
|
|
20
|
+
ids.has(range.endColumnIndex);
|
|
21
|
+
};
|
|
22
|
+
export const classifyMultiSelection = (selections, { isWholeRow, isWholeColumn }) => {
|
|
23
|
+
if (selections.length <= 1)
|
|
24
|
+
return "single";
|
|
25
|
+
if (selections.every(({ range }) => isWholeRow(range)))
|
|
26
|
+
return "all-rows";
|
|
27
|
+
if (selections.every(({ range }) => isWholeColumn(range))) {
|
|
28
|
+
return "all-columns";
|
|
29
|
+
}
|
|
30
|
+
return "mixed";
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* The bands (start..end, inclusive) a per-area structural command acts on,
|
|
34
|
+
* deduplicated and ordered bottom-up / right-to-left so inserting one block
|
|
35
|
+
* per band never shifts a band that is still to be processed (INS-08).
|
|
36
|
+
*/
|
|
37
|
+
export const bandsForAreas = (selections, axis) => {
|
|
38
|
+
const seen = new Set();
|
|
39
|
+
const bands = [];
|
|
40
|
+
for (const { range } of selections) {
|
|
41
|
+
const band = axis === "row"
|
|
42
|
+
? { start: range.startRowIndex, end: range.endRowIndex }
|
|
43
|
+
: { start: range.startColumnIndex, end: range.endColumnIndex };
|
|
44
|
+
const key = `${band.start}:${band.end}`;
|
|
45
|
+
if (seen.has(key))
|
|
46
|
+
continue;
|
|
47
|
+
seen.add(key);
|
|
48
|
+
bands.push(band);
|
|
49
|
+
}
|
|
50
|
+
return bands.sort((a, b) => b.start - a.start);
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Groups header ids (e.g. `selectedRowHeadersIds`) into contiguous bands,
|
|
54
|
+
* bottom-up. Fallback for callers that only know which rows/columns are
|
|
55
|
+
* selected, not the areas they came from.
|
|
56
|
+
*/
|
|
57
|
+
export const bandsFromIndexes = (indexes) => {
|
|
58
|
+
const sorted = Array.from(new Set(indexes)).sort((a, b) => a - b);
|
|
59
|
+
const bands = [];
|
|
60
|
+
for (const index of sorted) {
|
|
61
|
+
const last = bands[bands.length - 1];
|
|
62
|
+
if (last && index === last.end + 1) {
|
|
63
|
+
last.end = index;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
bands.push({ start: index, end: index });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return bands.sort((a, b) => b.start - a.start);
|
|
70
|
+
};
|
|
71
|
+
/** Sorted, de-duplicated row (or column) indexes covered by ALL areas. */
|
|
72
|
+
export const indexesForAreas = (selections, axis) => {
|
|
73
|
+
const indexes = new Set();
|
|
74
|
+
for (const { range } of selections) {
|
|
75
|
+
const [start, end] = axis === "row"
|
|
76
|
+
? [range.startRowIndex, range.endRowIndex]
|
|
77
|
+
: [range.startColumnIndex, range.endColumnIndex];
|
|
78
|
+
for (let index = start; index <= end; index++)
|
|
79
|
+
indexes.add(index);
|
|
80
|
+
}
|
|
81
|
+
return Array.from(indexes).sort((a, b) => a - b);
|
|
82
|
+
};
|
|
83
|
+
const isTallerThanWide = (range) => range.endRowIndex - range.startRowIndex >
|
|
84
|
+
range.endColumnIndex - range.startColumnIndex;
|
|
85
|
+
/**
|
|
86
|
+
* Excel pre-selects the shift that moves the fewest neighbours: a selection
|
|
87
|
+
* taller than it is wide shifts cells right; a wider-than-tall or square one
|
|
88
|
+
* shifts cells down (UI-06).
|
|
89
|
+
*/
|
|
90
|
+
export const defaultInsertCellsChoice = (range) => isTallerThanWide(range) ? "shift-right" : "shift-down";
|
|
91
|
+
/** Delete mirrors Insert: taller-than-wide → shift left, otherwise shift up. */
|
|
92
|
+
export const defaultDeleteCellsChoice = (range) => isTallerThanWide(range) ? "shift-left" : "shift-up";
|
|
@@ -19,7 +19,10 @@ export * from "./validation-alert.atom";
|
|
|
19
19
|
export * from "./sort-dialog.atom";
|
|
20
20
|
export * from "./paste-special-dialog.atom";
|
|
21
21
|
export * from "./go-to-dialog.atom";
|
|
22
|
+
export * from "./move-overwrite-confirm.atom";
|
|
22
23
|
export * from "./evaluate-formula-dialog.atom";
|
|
23
24
|
export * from "./remove-duplicates-dialog.atom";
|
|
24
25
|
export * from "./watch-window.atom";
|
|
26
|
+
export * from "./insert-cells-dialog.atom";
|
|
27
|
+
export * from "./insert-options.atom";
|
|
25
28
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../atoms/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iCAAiC,CAAC;AAChD,cAAc,qBAAqB,CAAC;AACpC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAChD,cAAc,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../atoms/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iCAAiC,CAAC;AAChD,cAAc,qBAAqB,CAAC;AACpC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,cAAc,6BAA6B,CAAC;AAC5C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAChD,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC"}
|
package/dist/esm/atoms/index.js
CHANGED
|
@@ -19,6 +19,9 @@ export * from "./validation-alert.atom";
|
|
|
19
19
|
export * from "./sort-dialog.atom";
|
|
20
20
|
export * from "./paste-special-dialog.atom";
|
|
21
21
|
export * from "./go-to-dialog.atom";
|
|
22
|
+
export * from "./move-overwrite-confirm.atom";
|
|
22
23
|
export * from "./evaluate-formula-dialog.atom";
|
|
23
24
|
export * from "./remove-duplicates-dialog.atom";
|
|
24
25
|
export * from "./watch-window.atom";
|
|
26
|
+
export * from "./insert-cells-dialog.atom";
|
|
27
|
+
export * from "./insert-options.atom";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { DeleteCellsChoice, InsertCellsChoice } from "../api/multi-selection";
|
|
2
|
+
/**
|
|
3
|
+
* Open-state + payload for Excel's Insert / Delete cells dialog (right-click a
|
|
4
|
+
* cell → "Insert…" / "Delete…", `Ctrl` + `+` / `-` on a cell selection). The
|
|
5
|
+
* grid opens it with the shape-derived default; the host-mounted dialog routes
|
|
6
|
+
* the chosen entry back through `onApply`, and the opener dispatches the
|
|
7
|
+
* matching structural command (shift cells / entire row / entire column).
|
|
8
|
+
*/
|
|
9
|
+
export type InsertCellsDialogRequest = {
|
|
10
|
+
mode: "insert";
|
|
11
|
+
defaultChoice: InsertCellsChoice;
|
|
12
|
+
onApply: (choice: InsertCellsChoice) => void;
|
|
13
|
+
} | {
|
|
14
|
+
mode: "delete";
|
|
15
|
+
defaultChoice: DeleteCellsChoice;
|
|
16
|
+
onApply: (choice: DeleteCellsChoice) => void;
|
|
17
|
+
};
|
|
18
|
+
export declare const insertCellsDialogAtom: import("jotai").PrimitiveAtom<InsertCellsDialogRequest | null> & {
|
|
19
|
+
init: InsertCellsDialogRequest | null;
|
|
20
|
+
};
|
|
21
|
+
export declare const useInsertCellsDialogState: () => [InsertCellsDialogRequest | null, (args_0: InsertCellsDialogRequest | ((prev: InsertCellsDialogRequest | null) => InsertCellsDialogRequest | null) | null) => void];
|
|
22
|
+
/**
|
|
23
|
+
* Number of mounted `InsertCellsDialogHost`s. The context menu only offers the
|
|
24
|
+
* dialog entry while a host is mounted; without one it keeps the direct
|
|
25
|
+
* submenu so a host that has not adopted the dialog never gets a dead item.
|
|
26
|
+
*/
|
|
27
|
+
export declare const insertCellsDialogHostCountAtom: import("jotai").PrimitiveAtom<number> & {
|
|
28
|
+
init: number;
|
|
29
|
+
};
|
|
30
|
+
/** True when at least one `InsertCellsDialogHost` is mounted. */
|
|
31
|
+
export declare const useIsInsertCellsDialogMounted: () => boolean;
|
|
32
|
+
/** Registers the calling component as a dialog host for its lifetime. */
|
|
33
|
+
export declare const useRegisterInsertCellsDialogHost: () => void;
|
|
34
|
+
/** Returns a function that opens the host-mounted Insert / Delete cells dialog. */
|
|
35
|
+
export declare const useOpenInsertCellsDialog: () => (request: InsertCellsDialogRequest) => void;
|
|
36
|
+
//# sourceMappingURL=insert-cells-dialog.atom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insert-cells-dialog.atom.d.ts","sourceRoot":"","sources":["../../../atoms/insert-cells-dialog.atom.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,wBAAwB,CAAC;AAEhC;;;;;;GAMG;AACH,MAAM,MAAM,wBAAwB,GAChC;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,aAAa,EAAE,iBAAiB,CAAC;IACjC,OAAO,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC9C,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,aAAa,EAAE,iBAAiB,CAAC;IACjC,OAAO,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC9C,CAAC;AAEN,eAAO,MAAM,qBAAqB;;CAEjC,CAAC;AAEF,eAAO,MAAM,yBAAyB,2KAAuC,CAAC;AAE9E;;;;GAIG;AACH,eAAO,MAAM,8BAA8B;;CAAU,CAAC;AAEtD,iEAAiE;AACjE,eAAO,MAAM,6BAA6B,eACQ,CAAC;AAEnD,yEAAyE;AACzE,eAAO,MAAM,gCAAgC,YAM5C,CAAC;AAEF,mFAAmF;AACnF,eAAO,MAAM,wBAAwB,kBAGvB,wBAAwB,SAGrC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
|
|
2
|
+
import { useCallback, useEffect } from "react";
|
|
3
|
+
export const insertCellsDialogAtom = atom(null);
|
|
4
|
+
export const useInsertCellsDialogState = () => useAtom(insertCellsDialogAtom);
|
|
5
|
+
/**
|
|
6
|
+
* Number of mounted `InsertCellsDialogHost`s. The context menu only offers the
|
|
7
|
+
* dialog entry while a host is mounted; without one it keeps the direct
|
|
8
|
+
* submenu so a host that has not adopted the dialog never gets a dead item.
|
|
9
|
+
*/
|
|
10
|
+
export const insertCellsDialogHostCountAtom = atom(0);
|
|
11
|
+
/** True when at least one `InsertCellsDialogHost` is mounted. */
|
|
12
|
+
export const useIsInsertCellsDialogMounted = () => useAtomValue(insertCellsDialogHostCountAtom) > 0;
|
|
13
|
+
/** Registers the calling component as a dialog host for its lifetime. */
|
|
14
|
+
export const useRegisterInsertCellsDialogHost = () => {
|
|
15
|
+
const setCount = useSetAtom(insertCellsDialogHostCountAtom);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
setCount((count) => count + 1);
|
|
18
|
+
return () => setCount((count) => count - 1);
|
|
19
|
+
}, [setCount]);
|
|
20
|
+
};
|
|
21
|
+
/** Returns a function that opens the host-mounted Insert / Delete cells dialog. */
|
|
22
|
+
export const useOpenInsertCellsDialog = () => {
|
|
23
|
+
const setRequest = useSetAtom(insertCellsDialogAtom);
|
|
24
|
+
return useCallback((request) => setRequest(request), [setRequest]);
|
|
25
|
+
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { InsertedBand, InsertFormatOption } from "../api/insert-options";
|
|
2
|
+
/**
|
|
3
|
+
* A just-inserted row / column band waiting for the user to (re)choose how it
|
|
4
|
+
* is formatted — Excel's Insert Options smart tag ("Format Same As Above /
|
|
5
|
+
* Below / Clear Formatting"; "Left / Right" for columns). The insert already
|
|
6
|
+
* applied `before` (the row above / column to the left); choosing another
|
|
7
|
+
* entry re-formats the band from the other neighbour, or clears it. Dropped
|
|
8
|
+
* on the next click elsewhere (a new active cell) or sheet switch.
|
|
9
|
+
*/
|
|
10
|
+
export type InsertOptionsRequest = InsertedBand & {
|
|
11
|
+
sheetId: number;
|
|
12
|
+
/** The entry currently applied to the band. */
|
|
13
|
+
option: InsertFormatOption;
|
|
14
|
+
};
|
|
15
|
+
export declare const insertOptionsAtom: import("jotai").PrimitiveAtom<InsertOptionsRequest | null> & {
|
|
16
|
+
init: InsertOptionsRequest | null;
|
|
17
|
+
};
|
|
18
|
+
export declare const useInsertOptionsState: () => [InsertOptionsRequest | null, (args_0: InsertOptionsRequest | ((prev: InsertOptionsRequest | null) => InsertOptionsRequest | null) | null) => void];
|
|
19
|
+
export declare const useInsertOptionsValue: () => InsertOptionsRequest | null;
|
|
20
|
+
export declare const useSetInsertOptions: () => (args_0: InsertOptionsRequest | ((prev: InsertOptionsRequest | null) => InsertOptionsRequest | null) | null) => void;
|
|
21
|
+
//# sourceMappingURL=insert-options.atom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"insert-options.atom.d.ts","sourceRoot":"","sources":["../../../atoms/insert-options.atom.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE9E;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,+CAA+C;IAC/C,MAAM,EAAE,kBAAkB,CAAC;CAC5B,CAAC;AAEF,eAAO,MAAM,iBAAiB;;CAA0C,CAAC;AAEzE,eAAO,MAAM,qBAAqB,2JAAmC,CAAC;AACtE,eAAO,MAAM,qBAAqB,mCAAwC,CAAC;AAC3E,eAAO,MAAM,mBAAmB,4HAAsC,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
|
|
2
|
+
export const insertOptionsAtom = atom(null);
|
|
3
|
+
export const useInsertOptionsState = () => useAtom(insertOptionsAtom);
|
|
4
|
+
export const useInsertOptionsValue = () => useAtomValue(insertOptionsAtom);
|
|
5
|
+
export const useSetInsertOptions = () => useSetAtom(insertOptionsAtom);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Open-state + payload for the drag-move overwrite prompt (Excel: "There's
|
|
3
|
+
* already data here. Do you want to replace it?"). The grid raises it from the
|
|
4
|
+
* selection-border drop; the host-mounted dialog answers through `resolve`.
|
|
5
|
+
*/
|
|
6
|
+
export type MoveOverwriteConfirmRequest = {
|
|
7
|
+
message: string;
|
|
8
|
+
resolve: (replace: boolean) => void;
|
|
9
|
+
};
|
|
10
|
+
export declare const moveOverwriteConfirmAtom: import("jotai").PrimitiveAtom<MoveOverwriteConfirmRequest | null> & {
|
|
11
|
+
init: MoveOverwriteConfirmRequest | null;
|
|
12
|
+
};
|
|
13
|
+
export declare const useMoveOverwriteConfirmState: () => [MoveOverwriteConfirmRequest | null, (args_0: MoveOverwriteConfirmRequest | ((prev: MoveOverwriteConfirmRequest | null) => MoveOverwriteConfirmRequest | null) | null) => void];
|
|
14
|
+
/** Number of mounted `MoveOverwriteConfirmDialogHost`s. */
|
|
15
|
+
export declare const moveOverwriteConfirmHostCountAtom: import("jotai").PrimitiveAtom<number> & {
|
|
16
|
+
init: number;
|
|
17
|
+
};
|
|
18
|
+
/** True when a host has mounted the dialog; otherwise the grid falls back to `window.confirm`. */
|
|
19
|
+
export declare const useIsMoveOverwriteConfirmMounted: () => boolean;
|
|
20
|
+
/** Registers the calling component as a dialog host for its lifetime. */
|
|
21
|
+
export declare const useRegisterMoveOverwriteConfirmHost: () => void;
|
|
22
|
+
/** Returns a function that opens the host-mounted prompt and resolves with the user's answer. */
|
|
23
|
+
export declare const useOpenMoveOverwriteConfirm: () => (message: string) => Promise<boolean>;
|
|
24
|
+
//# sourceMappingURL=move-overwrite-confirm.atom.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"move-overwrite-confirm.atom.d.ts","sourceRoot":"","sources":["../../../atoms/move-overwrite-confirm.atom.ts"],"names":[],"mappings":"AAGA;;;;GAIG;AACH,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;CACrC,CAAC;AAEF,eAAO,MAAM,wBAAwB;;CAEpC,CAAC;AAEF,eAAO,MAAM,4BAA4B,uLACN,CAAC;AAEpC,2DAA2D;AAC3D,eAAO,MAAM,iCAAiC;;CAAU,CAAC;AAEzD,kGAAkG;AAClG,eAAO,MAAM,gCAAgC,eACQ,CAAC;AAEtD,yEAAyE;AACzE,eAAO,MAAM,mCAAmC,YAM/C,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,2BAA2B,kBAG1B,MAAM,qBAYnB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { atom, useAtom, useAtomValue, useSetAtom } from "jotai";
|
|
2
|
+
import { useCallback, useEffect } from "react";
|
|
3
|
+
export const moveOverwriteConfirmAtom = atom(null);
|
|
4
|
+
export const useMoveOverwriteConfirmState = () => useAtom(moveOverwriteConfirmAtom);
|
|
5
|
+
/** Number of mounted `MoveOverwriteConfirmDialogHost`s. */
|
|
6
|
+
export const moveOverwriteConfirmHostCountAtom = atom(0);
|
|
7
|
+
/** True when a host has mounted the dialog; otherwise the grid falls back to `window.confirm`. */
|
|
8
|
+
export const useIsMoveOverwriteConfirmMounted = () => useAtomValue(moveOverwriteConfirmHostCountAtom) > 0;
|
|
9
|
+
/** Registers the calling component as a dialog host for its lifetime. */
|
|
10
|
+
export const useRegisterMoveOverwriteConfirmHost = () => {
|
|
11
|
+
const setCount = useSetAtom(moveOverwriteConfirmHostCountAtom);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
setCount((count) => count + 1);
|
|
14
|
+
return () => setCount((count) => count - 1);
|
|
15
|
+
}, [setCount]);
|
|
16
|
+
};
|
|
17
|
+
/** Returns a function that opens the host-mounted prompt and resolves with the user's answer. */
|
|
18
|
+
export const useOpenMoveOverwriteConfirm = () => {
|
|
19
|
+
const setRequest = useSetAtom(moveOverwriteConfirmAtom);
|
|
20
|
+
return useCallback((message) => new Promise((resolve) => {
|
|
21
|
+
setRequest({
|
|
22
|
+
message,
|
|
23
|
+
resolve: (replace) => {
|
|
24
|
+
setRequest(null);
|
|
25
|
+
resolve(replace);
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}), [setRequest]);
|
|
29
|
+
};
|
|
@@ -5,6 +5,8 @@ export declare const spreadsheetContextAtom: import("jotai").PrimitiveAtom<Canva
|
|
|
5
5
|
export declare const useSpreadsheet: () => CanvasGridMethods;
|
|
6
6
|
export declare const tokenizerSelector: import("jotai").Atom<(str: string) => import("..").ParsedToken[]>;
|
|
7
7
|
export declare const useTokenizer: () => (str: string) => import("..").ParsedToken[];
|
|
8
|
+
export declare const useLocaleTokenizer: () => (str: string) => import("..").ParsedToken[];
|
|
9
|
+
export declare const useFormulaLocale: () => import("@rowsncolumns/utils").FormulaLocale;
|
|
8
10
|
export declare const useSetSpreadsheetContext: () => (args_0: CanvasGridMethods | ((prev: CanvasGridMethods) => CanvasGridMethods)) => void;
|
|
9
11
|
export declare const useGetCellBounds: () => ((coords: import("@rowsncolumns/grid").CellInterface, spanMerges?: boolean | undefined) => import("@rowsncolumns/grid").GridRange) | undefined;
|
|
10
12
|
export declare const useGetSelectionsFromFormula: () => ((value: string, anchorCell?: import("@rowsncolumns/grid").CellInterface) => import("@rowsncolumns/grid").SelectionArea<import("../components/canvas-grid/typings").SelectionAttributes>[]) | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sheet-context.atom.d.ts","sourceRoot":"","sources":["../../../atoms/sheet-context.atom.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"sheet-context.atom.d.ts","sourceRoot":"","sources":["../../../atoms/sheet-context.atom.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAE3E,eAAO,MAAM,sBAAsB;;CAEjC,CAAC;AAEH,eAAO,MAAM,cAAc,yBAA6C,CAAC;AAGzE,eAAO,MAAM,iBAAiB,mEAE7B,CAAC;AAEF,eAAO,MAAM,YAAY,mDAAwC,CAAC;AAQlE,eAAO,MAAM,kBAAkB,mDAA8C,CAAC;AAO9E,eAAO,MAAM,gBAAgB,mDAA4C,CAAC;AAE1E,eAAO,MAAM,wBAAwB,8FACD,CAAC;AAOrC,eAAO,MAAM,gBAAgB,sJAA4C,CAAC;AAO1E,eAAO,MAAM,2BAA2B,+MACK,CAAC;AAO9C,eAAO,MAAM,0BAA0B,uQACM,CAAC;AAO9C,eAAO,MAAM,8BAA8B,+GACM,CAAC;AAMlD,eAAO,MAAM,oBAAoB;;;cACQ,CAAC;AAM1C,eAAO,MAAM,eAAe,+GAA2C,CAAC;AAMxE,eAAO,MAAM,iBAAiB;;;;yBAA6C,CAAC;AAM5E,eAAO,MAAM,+BAA+B,wIACY,CAAC;AAMzD,eAAO,MAAM,0BAA0B,8HACQ,CAAC;AAMhD,eAAO,MAAM,0BAA0B,iIACQ,CAAC;AAEhD,eAAO,MAAM,wCAAwC,oPAEpD,CAAC;AAEF,eAAO,MAAM,mCAAmC,oOACQ,CAAC;AAEzD,eAAO,MAAM,mBAAmB,oHAE/B,CAAC;AAEF,eAAO,MAAM,cAAc,oGAA0C,CAAC;AAEtE,eAAO,MAAM,wBAAwB,kEAEpC,CAAC;AAEF,eAAO,MAAM,mBAAmB,kDAA+C,CAAC;AAEhF,eAAO,MAAM,2BAA2B,mDAEvC,CAAC;AAEF,eAAO,MAAM,sBAAsB,mCACQ,CAAC;AAE5C,eAAO,MAAM,0BAA0B,0GAEtC,CAAC;AAEF,eAAO,MAAM,qBAAqB,0FACQ,CAAC;AAE3C,eAAO,MAAM,mCAAmC,gHAE/C,CAAC;AAEF,eAAO,MAAM,8BAA8B,gGACQ,CAAC;AAEpD,eAAO,MAAM,kBAAkB,4OAE9B,CAAC;AAEF,eAAO,MAAM,aAAa,4NAAyC,CAAC;AAEpE,eAAO,MAAM,kBAAkB,gDAE9B,CAAC;AAEF,eAAO,MAAM,aAAa,gCAAyC,CAAC;AAEpE,eAAO,MAAM,0BAA0B,oFAEtC,CAAC;AAEF,eAAO,MAAM,qBAAqB,oEACQ,CAAC;AAE3C,eAAO,MAAM,yBAAyB,oMAErC,CAAC;AAEF,eAAO,MAAM,oBAAoB,oLACQ,CAAC;AAE1C,eAAO,MAAM,uBAAuB,sFAEnC,CAAC;AAEF,eAAO,MAAM,kBAAkB,sEAA8C,CAAC;AAE9E,eAAO,MAAM,oBAAoB,iEAEhC,CAAC;AAEF,eAAO,MAAM,eAAe,iDAA2C,CAAC;AAExE,eAAO,MAAM,kBAAkB,+EAE9B,CAAC;AAEF,eAAO,MAAM,aAAa,+DAAyC,CAAC;AAEpE,eAAO,MAAM,0BAA0B,wOAEtC,CAAC;AAEF,eAAO,MAAM,kBAAkB,wNACW,CAAC;AAE3C,eAAO,MAAM,oBAAoB,oJAEhC,CAAC;AAEF,eAAO,MAAM,eAAe,oIAA2C,CAAC;AAExE,eAAO,MAAM,kBAAkB,gDAE9B,CAAC;AAEF,eAAO,MAAM,aAAa,gCAAyC,CAAC;AAEpE,eAAO,MAAM,mBAAmB,sFAE/B,CAAC;AAEF,eAAO,MAAM,cAAc,sEAA0C,CAAC;AAEtE,eAAO,MAAM,sBAAsB,+FAElC,CAAC;AAEF,eAAO,MAAM,iBAAiB,+EAA6C,CAAC;AAE5E,eAAO,MAAM,kBAAkB,uFAE9B,CAAC;AACF,eAAO,MAAM,aAAa,uEAAyC,CAAC;AAEpE,eAAO,MAAM,4BAA4B,kLAExC,CAAC;AACF,eAAO,MAAM,uBAAuB,kKACQ,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CANONICAL_FORMULA_LOCALE } from "@rowsncolumns/utils";
|
|
1
2
|
import { atom, useAtomValue, useSetAtom } from "jotai";
|
|
2
3
|
export const spreadsheetContextAtom = atom({
|
|
3
4
|
tokenizer: () => [],
|
|
@@ -6,6 +7,15 @@ export const useSpreadsheet = () => useAtomValue(spreadsheetContextAtom);
|
|
|
6
7
|
// Tokenizer selector
|
|
7
8
|
export const tokenizerSelector = atom((get) => get(spreadsheetContextAtom).tokenizer);
|
|
8
9
|
export const useTokenizer = () => useAtomValue(tokenizerSelector);
|
|
10
|
+
// Formula-locale tokenizer (falls back to the canonical one before the grid publishes it)
|
|
11
|
+
const localeTokenizerSelector = atom((get) => {
|
|
12
|
+
const context = get(spreadsheetContextAtom);
|
|
13
|
+
return context.localeTokenizer ?? context.tokenizer;
|
|
14
|
+
});
|
|
15
|
+
export const useLocaleTokenizer = () => useAtomValue(localeTokenizerSelector);
|
|
16
|
+
// The grid's resolved formula locale (canonical until the grid publishes one)
|
|
17
|
+
const formulaLocaleSelector = atom((get) => get(spreadsheetContextAtom).formulaLocale ?? CANONICAL_FORMULA_LOCALE);
|
|
18
|
+
export const useFormulaLocale = () => useAtomValue(formulaLocaleSelector);
|
|
9
19
|
export const useSetSpreadsheetContext = () => useSetAtom(spreadsheetContextAtom);
|
|
10
20
|
// Cellbounds selector
|
|
11
21
|
const getCellBoundsSelector = atom((get) => get(spreadsheetContextAtom).getCellBounds);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/canvas-grid/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/canvas-grid/index.tsx"],"names":[],"mappings":"AA+CA,OAAO,KASN,MAAM,OAAO,CAAC;AAuMf,OAAO,KAAK,EAGV,QAAQ,EAUT,MAAM,aAAa,CAAC;AAcrB,OAAO,KAAK,EACV,wBAAwB,EACxB,iBAAiB,EACjB,eAAe,EAEhB,MAAM,WAAW,CAAC;AAy1KnB,eAAO,MAAM,UAAU,EAA4C,CACjE,CAAC,SAAS,QAAQ,CAAC,GAAG,CAAC,EAEvB,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,GACvB,wBAAwB,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;CAAE,KAChE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC"}
|