@rowsncolumns/spreadsheet 10.2.73 → 10.2.75
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/evaluate-formula.d.ts +17 -0
- package/dist/cjs/api/evaluate-formula.d.ts.map +1 -0
- package/dist/cjs/api/evaluate-formula.js +141 -0
- package/dist/cjs/api/excel-validation-kinds.d.ts +71 -0
- package/dist/cjs/api/excel-validation-kinds.d.ts.map +1 -0
- package/dist/cjs/api/excel-validation-kinds.js +304 -0
- package/dist/cjs/api/go-to-special.d.ts +32 -0
- package/dist/cjs/api/go-to-special.d.ts.map +1 -0
- package/dist/cjs/api/go-to-special.js +111 -0
- package/dist/cjs/api/go-to.d.ts +19 -0
- package/dist/cjs/api/go-to.d.ts.map +1 -0
- package/dist/cjs/api/go-to.js +49 -0
- package/dist/cjs/api/validation-tooltip.d.ts +17 -0
- package/dist/cjs/api/validation-tooltip.d.ts.map +1 -0
- package/dist/cjs/api/validation-tooltip.js +42 -0
- package/dist/cjs/atoms/advanced-filter-dialog.atom.d.ts +28 -0
- package/dist/cjs/atoms/advanced-filter-dialog.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/advanced-filter-dialog.atom.js +32 -0
- package/dist/cjs/atoms/evaluate-formula-dialog.atom.d.ts +36 -0
- package/dist/cjs/atoms/evaluate-formula-dialog.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/evaluate-formula-dialog.atom.js +36 -0
- package/dist/cjs/atoms/go-to-dialog.atom.d.ts +46 -0
- package/dist/cjs/atoms/go-to-dialog.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/go-to-dialog.atom.js +34 -0
- package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts +29 -0
- package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/goal-seek-dialog.atom.js +30 -0
- package/dist/cjs/atoms/index.d.ts +5 -0
- package/dist/cjs/atoms/index.d.ts.map +1 -1
- package/dist/cjs/atoms/index.js +5 -0
- package/dist/cjs/atoms/paste-special-dialog.atom.d.ts +29 -0
- package/dist/cjs/atoms/paste-special-dialog.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/paste-special-dialog.atom.js +34 -0
- package/dist/cjs/atoms/remove-duplicates-dialog.atom.d.ts +45 -0
- package/dist/cjs/atoms/remove-duplicates-dialog.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/remove-duplicates-dialog.atom.js +37 -0
- package/dist/cjs/atoms/subtotal-dialog.atom.d.ts +39 -0
- package/dist/cjs/atoms/subtotal-dialog.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/subtotal-dialog.atom.js +30 -0
- package/dist/cjs/atoms/text-to-columns-dialog.atom.d.ts +34 -0
- package/dist/cjs/atoms/text-to-columns-dialog.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/text-to-columns-dialog.atom.js +36 -0
- package/dist/cjs/atoms/watch-window.atom.d.ts +37 -0
- package/dist/cjs/atoms/watch-window.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/watch-window.atom.js +61 -0
- package/dist/cjs/components/advanced-filter-dialog/index.d.ts +28 -0
- package/dist/cjs/components/advanced-filter-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/advanced-filter-dialog/index.js +134 -0
- package/dist/cjs/components/calculation-options-dialog/index.d.ts +33 -0
- package/dist/cjs/components/calculation-options-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/calculation-options-dialog/index.js +69 -0
- package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
- package/dist/cjs/components/canvas-grid/index.js +208 -19
- package/dist/cjs/components/canvas-grid/typings.d.ts +72 -9
- package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
- package/dist/cjs/components/cell/alignment.d.ts +30 -0
- package/dist/cjs/components/cell/alignment.d.ts.map +1 -1
- package/dist/cjs/components/cell/alignment.js +56 -1
- package/dist/cjs/components/cell/index.d.ts.map +1 -1
- package/dist/cjs/components/cell/index.js +15 -7
- package/dist/cjs/components/cell-diff/index.d.ts +3 -2
- package/dist/cjs/components/cell-diff/index.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/index.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/index.js +2 -1
- package/dist/cjs/components/context-menu/index.d.ts +21 -3
- package/dist/cjs/components/context-menu/index.d.ts.map +1 -1
- package/dist/cjs/components/context-menu/index.js +256 -6
- package/dist/cjs/components/context-menu/total-row-functions.d.ts +32 -0
- package/dist/cjs/components/context-menu/total-row-functions.d.ts.map +1 -0
- package/dist/cjs/components/context-menu/total-row-functions.js +62 -0
- package/dist/cjs/components/embeds/embed-component.d.ts.map +1 -1
- package/dist/cjs/components/embeds/embed-component.js +16 -1
- package/dist/cjs/components/evaluate-formula-dialog/index.d.ts +34 -0
- package/dist/cjs/components/evaluate-formula-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/evaluate-formula-dialog/index.js +106 -0
- package/dist/cjs/components/go-to-dialog/index.d.ts +45 -0
- package/dist/cjs/components/go-to-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/go-to-dialog/index.js +136 -0
- package/dist/cjs/components/goal-seek-dialog/index.d.ts +32 -0
- package/dist/cjs/components/goal-seek-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/goal-seek-dialog/index.js +149 -0
- package/dist/cjs/components/paste-special-dialog/index.d.ts +29 -0
- package/dist/cjs/components/paste-special-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/paste-special-dialog/index.js +99 -0
- package/dist/cjs/components/remove-duplicates-dialog/index.d.ts +37 -0
- package/dist/cjs/components/remove-duplicates-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/remove-duplicates-dialog/index.js +91 -0
- package/dist/cjs/components/subtotal-dialog/index.d.ts +30 -0
- package/dist/cjs/components/subtotal-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/subtotal-dialog/index.js +126 -0
- package/dist/cjs/components/text-to-columns-dialog/index.d.ts +37 -0
- package/dist/cjs/components/text-to-columns-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/text-to-columns-dialog/index.js +166 -0
- package/dist/cjs/components/toolbar/background-color-selector.d.ts +13 -1
- package/dist/cjs/components/toolbar/background-color-selector.d.ts.map +1 -1
- package/dist/cjs/components/toolbar/background-color-selector.js +57 -11
- package/dist/cjs/components/toolbar/cell-style-selector.d.ts +15 -2
- package/dist/cjs/components/toolbar/cell-style-selector.d.ts.map +1 -1
- package/dist/cjs/components/toolbar/cell-style-selector.js +56 -3
- package/dist/cjs/components/toolbar/fill-selectors.d.ts +49 -0
- package/dist/cjs/components/toolbar/fill-selectors.d.ts.map +1 -0
- package/dist/cjs/components/toolbar/fill-selectors.js +196 -0
- package/dist/cjs/components/toolbar/index.d.ts +2 -0
- package/dist/cjs/components/toolbar/index.d.ts.map +1 -1
- package/dist/cjs/components/toolbar/index.js +2 -0
- package/dist/cjs/components/toolbar/text-horizontal-align-selector.d.ts +8 -0
- package/dist/cjs/components/toolbar/text-horizontal-align-selector.d.ts.map +1 -1
- package/dist/cjs/components/toolbar/text-horizontal-align-selector.js +23 -4
- package/dist/cjs/components/toolbar/text-rotation-selector.d.ts +29 -0
- package/dist/cjs/components/toolbar/text-rotation-selector.d.ts.map +1 -0
- package/dist/cjs/components/toolbar/text-rotation-selector.js +78 -0
- package/dist/cjs/components/toolbar/text-wrap-selector.d.ts +7 -1
- package/dist/cjs/components/toolbar/text-wrap-selector.d.ts.map +1 -1
- package/dist/cjs/components/toolbar/text-wrap-selector.js +10 -3
- package/dist/cjs/components/watch-window/index.d.ts +25 -0
- package/dist/cjs/components/watch-window/index.d.ts.map +1 -0
- package/dist/cjs/components/watch-window/index.js +63 -0
- package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
- package/dist/cjs/hooks/use-cell-renderer.js +17 -6
- package/dist/cjs/hooks/use-copy-paste-cut.d.ts +20 -1
- package/dist/cjs/hooks/use-copy-paste-cut.d.ts.map +1 -1
- package/dist/cjs/hooks/use-copy-paste-cut.js +25 -20
- package/dist/cjs/hooks/use-get-tooltip.d.ts.map +1 -1
- package/dist/cjs/hooks/use-get-tooltip.js +7 -2
- package/dist/cjs/hooks/use-keyboard-handler.d.ts +17 -2
- package/dist/cjs/hooks/use-keyboard-handler.d.ts.map +1 -1
- package/dist/cjs/hooks/use-keyboard-handler.js +206 -31
- package/dist/cjs/index.d.ts +14 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +15 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/types.d.ts +289 -4
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/types.js +19 -1
- package/dist/esm/api/evaluate-formula.d.ts +17 -0
- package/dist/esm/api/evaluate-formula.d.ts.map +1 -0
- package/dist/esm/api/evaluate-formula.js +109 -0
- package/dist/esm/api/excel-validation-kinds.d.ts +71 -0
- package/dist/esm/api/excel-validation-kinds.d.ts.map +1 -0
- package/dist/esm/api/excel-validation-kinds.js +287 -0
- package/dist/esm/api/go-to-special.d.ts +32 -0
- package/dist/esm/api/go-to-special.d.ts.map +1 -0
- package/dist/esm/api/go-to-special.js +96 -0
- package/dist/esm/api/go-to.d.ts +19 -0
- package/dist/esm/api/go-to.d.ts.map +1 -0
- package/dist/esm/api/go-to.js +41 -0
- package/dist/esm/api/validation-tooltip.d.ts +17 -0
- package/dist/esm/api/validation-tooltip.d.ts.map +1 -0
- package/dist/esm/api/validation-tooltip.js +34 -0
- package/dist/esm/atoms/advanced-filter-dialog.atom.d.ts +28 -0
- package/dist/esm/atoms/advanced-filter-dialog.atom.d.ts.map +1 -0
- package/dist/esm/atoms/advanced-filter-dialog.atom.js +21 -0
- package/dist/esm/atoms/evaluate-formula-dialog.atom.d.ts +36 -0
- package/dist/esm/atoms/evaluate-formula-dialog.atom.d.ts.map +1 -0
- package/dist/esm/atoms/evaluate-formula-dialog.atom.js +25 -0
- package/dist/esm/atoms/go-to-dialog.atom.d.ts +46 -0
- package/dist/esm/atoms/go-to-dialog.atom.d.ts.map +1 -0
- package/dist/esm/atoms/go-to-dialog.atom.js +25 -0
- package/dist/esm/atoms/goal-seek-dialog.atom.d.ts +29 -0
- package/dist/esm/atoms/goal-seek-dialog.atom.d.ts.map +1 -0
- package/dist/esm/atoms/goal-seek-dialog.atom.js +21 -0
- package/dist/esm/atoms/index.d.ts +5 -0
- package/dist/esm/atoms/index.d.ts.map +1 -1
- package/dist/esm/atoms/index.js +5 -0
- package/dist/esm/atoms/paste-special-dialog.atom.d.ts +29 -0
- package/dist/esm/atoms/paste-special-dialog.atom.d.ts.map +1 -0
- package/dist/esm/atoms/paste-special-dialog.atom.js +25 -0
- package/dist/esm/atoms/remove-duplicates-dialog.atom.d.ts +45 -0
- package/dist/esm/atoms/remove-duplicates-dialog.atom.d.ts.map +1 -0
- package/dist/esm/atoms/remove-duplicates-dialog.atom.js +26 -0
- package/dist/esm/atoms/subtotal-dialog.atom.d.ts +39 -0
- package/dist/esm/atoms/subtotal-dialog.atom.d.ts.map +1 -0
- package/dist/esm/atoms/subtotal-dialog.atom.js +21 -0
- package/dist/esm/atoms/text-to-columns-dialog.atom.d.ts +34 -0
- package/dist/esm/atoms/text-to-columns-dialog.atom.d.ts.map +1 -0
- package/dist/esm/atoms/text-to-columns-dialog.atom.js +25 -0
- package/dist/esm/atoms/watch-window.atom.d.ts +37 -0
- package/dist/esm/atoms/watch-window.atom.d.ts.map +1 -0
- package/dist/esm/atoms/watch-window.atom.js +37 -0
- package/dist/esm/components/advanced-filter-dialog/index.d.ts +28 -0
- package/dist/esm/components/advanced-filter-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/advanced-filter-dialog/index.js +125 -0
- package/dist/esm/components/calculation-options-dialog/index.d.ts +33 -0
- package/dist/esm/components/calculation-options-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/calculation-options-dialog/index.js +61 -0
- package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
- package/dist/esm/components/canvas-grid/index.js +202 -19
- package/dist/esm/components/canvas-grid/typings.d.ts +72 -9
- package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
- package/dist/esm/components/cell/alignment.d.ts +30 -0
- package/dist/esm/components/cell/alignment.d.ts.map +1 -1
- package/dist/esm/components/cell/alignment.js +51 -0
- package/dist/esm/components/cell/index.d.ts.map +1 -1
- package/dist/esm/components/cell/index.js +16 -8
- package/dist/esm/components/cell-diff/index.d.ts +3 -2
- package/dist/esm/components/cell-diff/index.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/index.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/index.js +2 -1
- package/dist/esm/components/context-menu/index.d.ts +21 -3
- package/dist/esm/components/context-menu/index.d.ts.map +1 -1
- package/dist/esm/components/context-menu/index.js +251 -9
- package/dist/esm/components/context-menu/total-row-functions.d.ts +32 -0
- package/dist/esm/components/context-menu/total-row-functions.d.ts.map +1 -0
- package/dist/esm/components/context-menu/total-row-functions.js +50 -0
- package/dist/esm/components/embeds/embed-component.d.ts.map +1 -1
- package/dist/esm/components/embeds/embed-component.js +17 -1
- package/dist/esm/components/evaluate-formula-dialog/index.d.ts +34 -0
- package/dist/esm/components/evaluate-formula-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/evaluate-formula-dialog/index.js +86 -0
- package/dist/esm/components/go-to-dialog/index.d.ts +45 -0
- package/dist/esm/components/go-to-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/go-to-dialog/index.js +124 -0
- package/dist/esm/components/goal-seek-dialog/index.d.ts +32 -0
- package/dist/esm/components/goal-seek-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/goal-seek-dialog/index.js +125 -0
- package/dist/esm/components/paste-special-dialog/index.d.ts +29 -0
- package/dist/esm/components/paste-special-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/paste-special-dialog/index.js +90 -0
- package/dist/esm/components/remove-duplicates-dialog/index.d.ts +37 -0
- package/dist/esm/components/remove-duplicates-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/remove-duplicates-dialog/index.js +82 -0
- package/dist/esm/components/subtotal-dialog/index.d.ts +30 -0
- package/dist/esm/components/subtotal-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/subtotal-dialog/index.js +115 -0
- package/dist/esm/components/text-to-columns-dialog/index.d.ts +37 -0
- package/dist/esm/components/text-to-columns-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/text-to-columns-dialog/index.js +147 -0
- package/dist/esm/components/toolbar/background-color-selector.d.ts +13 -1
- package/dist/esm/components/toolbar/background-color-selector.d.ts.map +1 -1
- package/dist/esm/components/toolbar/background-color-selector.js +61 -11
- package/dist/esm/components/toolbar/cell-style-selector.d.ts +15 -2
- package/dist/esm/components/toolbar/cell-style-selector.d.ts.map +1 -1
- package/dist/esm/components/toolbar/cell-style-selector.js +46 -2
- package/dist/esm/components/toolbar/fill-selectors.d.ts +49 -0
- package/dist/esm/components/toolbar/fill-selectors.d.ts.map +1 -0
- package/dist/esm/components/toolbar/fill-selectors.js +162 -0
- package/dist/esm/components/toolbar/index.d.ts +2 -0
- package/dist/esm/components/toolbar/index.d.ts.map +1 -1
- package/dist/esm/components/toolbar/index.js +2 -0
- package/dist/esm/components/toolbar/text-horizontal-align-selector.d.ts +8 -0
- package/dist/esm/components/toolbar/text-horizontal-align-selector.d.ts.map +1 -1
- package/dist/esm/components/toolbar/text-horizontal-align-selector.js +21 -5
- package/dist/esm/components/toolbar/text-rotation-selector.d.ts +29 -0
- package/dist/esm/components/toolbar/text-rotation-selector.d.ts.map +1 -0
- package/dist/esm/components/toolbar/text-rotation-selector.js +71 -0
- package/dist/esm/components/toolbar/text-wrap-selector.d.ts +7 -1
- package/dist/esm/components/toolbar/text-wrap-selector.d.ts.map +1 -1
- package/dist/esm/components/toolbar/text-wrap-selector.js +10 -3
- package/dist/esm/components/watch-window/index.d.ts +25 -0
- package/dist/esm/components/watch-window/index.d.ts.map +1 -0
- package/dist/esm/components/watch-window/index.js +54 -0
- package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
- package/dist/esm/hooks/use-cell-renderer.js +17 -6
- package/dist/esm/hooks/use-copy-paste-cut.d.ts +20 -1
- package/dist/esm/hooks/use-copy-paste-cut.d.ts.map +1 -1
- package/dist/esm/hooks/use-copy-paste-cut.js +8 -3
- package/dist/esm/hooks/use-get-tooltip.d.ts.map +1 -1
- package/dist/esm/hooks/use-get-tooltip.js +7 -2
- package/dist/esm/hooks/use-keyboard-handler.d.ts +17 -2
- package/dist/esm/hooks/use-keyboard-handler.d.ts.map +1 -1
- package/dist/esm/hooks/use-keyboard-handler.js +193 -31
- package/dist/esm/index.d.ts +14 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +13 -0
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/types.d.ts +289 -4
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/esm/types.js +18 -0
- package/dist/spreadsheet.min.css +1 -1
- package/package.json +6 -6
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type RemoveDuplicatesDialogColumn } from "../../atoms/remove-duplicates-dialog.atom";
|
|
3
|
+
import type { RemoveDuplicatesOptions } from "../../types";
|
|
4
|
+
export type { RemoveDuplicatesDialogColumn };
|
|
5
|
+
export type RemoveDuplicatesDialogProps = {
|
|
6
|
+
/** Controls visibility. */
|
|
7
|
+
open: boolean;
|
|
8
|
+
onOpenChange(open: boolean): void;
|
|
9
|
+
/** Columns of the range, in sheet order. All start checked. */
|
|
10
|
+
columns: RemoveDuplicatesDialogColumn[];
|
|
11
|
+
/** Initial state of "My data has headers". */
|
|
12
|
+
initialHasHeader?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Emits the chosen compare columns and header flag. The host routes these
|
|
15
|
+
* to `onRemoveDuplicates`; the dialog never touches state directly.
|
|
16
|
+
*/
|
|
17
|
+
onApply(options: RemoveDuplicatesOptions): void;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Excel's "Remove Duplicates" dialog: a "My data has headers" toggle plus a
|
|
21
|
+
* checklist of the columns that decide whether two rows are duplicates.
|
|
22
|
+
* Unchecked columns still travel with their row — only the comparison
|
|
23
|
+
* narrows.
|
|
24
|
+
*/
|
|
25
|
+
export declare const RemoveDuplicatesDialog: React.MemoExoticComponent<({ open, onOpenChange, columns, initialHasHeader, onApply, }: RemoveDuplicatesDialogProps) => React.JSX.Element>;
|
|
26
|
+
/**
|
|
27
|
+
* Host-mounted, atom-driven wrapper around {@link RemoveDuplicatesDialog}.
|
|
28
|
+
* Mount this once in the host (alongside the other editor dialogs); the
|
|
29
|
+
* context menu opens it via `useOpenRemoveDuplicatesDialog`. While no host is
|
|
30
|
+
* mounted the context menu keeps its one-click de-dupe, so adopting the
|
|
31
|
+
* dialog is opt-in per host.
|
|
32
|
+
*/
|
|
33
|
+
export declare const RemoveDuplicatesDialogHost: {
|
|
34
|
+
(): React.JSX.Element;
|
|
35
|
+
displayName: string;
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/remove-duplicates-dialog/index.tsx"],"names":[],"mappings":"AAWA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAE/E,OAAO,EACL,KAAK,4BAA4B,EAGlC,MAAM,2CAA2C,CAAC;AACnD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAE3D,YAAY,EAAE,4BAA4B,EAAE,CAAC;AAE7C,MAAM,MAAM,2BAA2B,GAAG;IACxC,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,+DAA+D;IAC/D,OAAO,EAAE,4BAA4B,EAAE,CAAC;IACxC,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAAC;CACjD,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,0FAO9B,2BAA2B,uBAqI/B,CAAC;AAIF;;;;;;GAMG;AACH,eAAO,MAAM,0BAA0B;;;CAetC,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RemoveDuplicatesDialogHost = exports.RemoveDuplicatesDialog = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var icons_1 = require("@rowsncolumns/icons");
|
|
6
|
+
var ui_1 = require("@rowsncolumns/ui");
|
|
7
|
+
var react_1 = tslib_1.__importStar(require("react"));
|
|
8
|
+
var remove_duplicates_dialog_atom_1 = require("../../atoms/remove-duplicates-dialog.atom");
|
|
9
|
+
/**
|
|
10
|
+
* Excel's "Remove Duplicates" dialog: a "My data has headers" toggle plus a
|
|
11
|
+
* checklist of the columns that decide whether two rows are duplicates.
|
|
12
|
+
* Unchecked columns still travel with their row — only the comparison
|
|
13
|
+
* narrows.
|
|
14
|
+
*/
|
|
15
|
+
exports.RemoveDuplicatesDialog = (0, react_1.memo)(function (_a) {
|
|
16
|
+
var open = _a.open, onOpenChange = _a.onOpenChange, columns = _a.columns, _b = _a.initialHasHeader, initialHasHeader = _b === void 0 ? false : _b, onApply = _a.onApply;
|
|
17
|
+
var allColumnIndexes = (0, react_1.useMemo)(function () { return columns.map(function (column) { return column.columnIndex; }); }, [columns]);
|
|
18
|
+
var _c = tslib_1.__read((0, react_1.useState)(initialHasHeader), 2), hasHeader = _c[0], setHasHeader = _c[1];
|
|
19
|
+
var _d = tslib_1.__read((0, react_1.useState)(function () { return new Set(allColumnIndexes); }), 2), checked = _d[0], setChecked = _d[1];
|
|
20
|
+
// Re-seed when reopened for a different range.
|
|
21
|
+
(0, react_1.useEffect)(function () {
|
|
22
|
+
if (open) {
|
|
23
|
+
setHasHeader(initialHasHeader);
|
|
24
|
+
setChecked(new Set(allColumnIndexes));
|
|
25
|
+
}
|
|
26
|
+
// Only reset on open transitions.
|
|
27
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
28
|
+
}, [open]);
|
|
29
|
+
var toggleColumn = (0, react_1.useCallback)(function (columnIndex) {
|
|
30
|
+
setChecked(function (prev) {
|
|
31
|
+
var next = new Set(prev);
|
|
32
|
+
if (next.has(columnIndex)) {
|
|
33
|
+
next.delete(columnIndex);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
next.add(columnIndex);
|
|
37
|
+
}
|
|
38
|
+
return next;
|
|
39
|
+
});
|
|
40
|
+
}, []);
|
|
41
|
+
var commit = (0, react_1.useCallback)(function () {
|
|
42
|
+
var columnIndices = allColumnIndexes.filter(function (columnIndex) {
|
|
43
|
+
return checked.has(columnIndex);
|
|
44
|
+
});
|
|
45
|
+
onApply({ columnIndices: columnIndices, hasHeader: hasHeader });
|
|
46
|
+
onOpenChange(false);
|
|
47
|
+
}, [allColumnIndexes, checked, hasHeader, onApply, onOpenChange]);
|
|
48
|
+
return (react_1.default.createElement(ui_1.Dialog, { open: open, onOpenChange: onOpenChange },
|
|
49
|
+
react_1.default.createElement(ui_1.DialogContent, { className: "w-[420px] max-w-[92vw] pointer-events-auto" },
|
|
50
|
+
react_1.default.createElement(ui_1.DialogTitle, null, "Remove duplicates"),
|
|
51
|
+
react_1.default.createElement(ui_1.DialogDescription, null, "Select the columns that contain duplicate values. Rows that match in every selected column are removed, keeping the first one."),
|
|
52
|
+
react_1.default.createElement(ui_1.DialogCloseButton, { onClick: function () { return onOpenChange(false); } },
|
|
53
|
+
react_1.default.createElement(icons_1.Cross1Icon, null)),
|
|
54
|
+
react_1.default.createElement(ui_1.DialogBody, { className: "flex flex-col gap-3" },
|
|
55
|
+
react_1.default.createElement("label", { className: "font-system text-sm flex items-center gap-1" },
|
|
56
|
+
react_1.default.createElement("input", { type: "checkbox", name: "hasHeader", checked: hasHeader, onChange: function (e) { return setHasHeader(e.target.checked); } }),
|
|
57
|
+
"My data has headers"),
|
|
58
|
+
react_1.default.createElement("div", { className: "flex gap-2" },
|
|
59
|
+
react_1.default.createElement(ui_1.Button, { variant: "outline", size: "xs", type: "button", onClick: function () { return setChecked(new Set(allColumnIndexes)); } }, "Select all"),
|
|
60
|
+
react_1.default.createElement(ui_1.Button, { variant: "outline", size: "xs", type: "button", onClick: function () { return setChecked(new Set()); } }, "Unselect all")),
|
|
61
|
+
react_1.default.createElement("div", { className: "flex flex-col gap-1 max-h-[240px] overflow-y-auto border border-rnc-border rounded p-2", role: "group", "aria-label": "Columns" }, columns.map(function (column) {
|
|
62
|
+
var text = hasHeader && column.header ? column.header : column.label;
|
|
63
|
+
return (react_1.default.createElement("label", { key: column.columnIndex, className: "font-system text-sm flex items-center gap-1" },
|
|
64
|
+
react_1.default.createElement("input", { type: "checkbox", name: "column-".concat(column.columnIndex), checked: checked.has(column.columnIndex), onChange: function () { return toggleColumn(column.columnIndex); } }),
|
|
65
|
+
react_1.default.createElement("span", { className: "truncate", title: text }, text)));
|
|
66
|
+
})),
|
|
67
|
+
react_1.default.createElement(ui_1.Separator, null),
|
|
68
|
+
react_1.default.createElement("div", { className: "flex justify-end gap-2" },
|
|
69
|
+
react_1.default.createElement(ui_1.Button, { variant: "outline", size: "sm", type: "button", onClick: function () { return onOpenChange(false); } }, "Cancel"),
|
|
70
|
+
react_1.default.createElement(ui_1.Button, { size: "sm", type: "button", onClick: commit, disabled: checked.size === 0 }, "OK"))))));
|
|
71
|
+
});
|
|
72
|
+
exports.RemoveDuplicatesDialog.displayName = "RemoveDuplicatesDialog";
|
|
73
|
+
/**
|
|
74
|
+
* Host-mounted, atom-driven wrapper around {@link RemoveDuplicatesDialog}.
|
|
75
|
+
* Mount this once in the host (alongside the other editor dialogs); the
|
|
76
|
+
* context menu opens it via `useOpenRemoveDuplicatesDialog`. While no host is
|
|
77
|
+
* mounted the context menu keeps its one-click de-dupe, so adopting the
|
|
78
|
+
* dialog is opt-in per host.
|
|
79
|
+
*/
|
|
80
|
+
var RemoveDuplicatesDialogHost = function () {
|
|
81
|
+
var _a;
|
|
82
|
+
(0, remove_duplicates_dialog_atom_1.useRegisterRemoveDuplicatesDialogHost)();
|
|
83
|
+
var _b = tslib_1.__read((0, remove_duplicates_dialog_atom_1.useRemoveDuplicatesDialogState)(), 2), request = _b[0], setRequest = _b[1];
|
|
84
|
+
var close = (0, react_1.useCallback)(function () { return setRequest(null); }, [setRequest]);
|
|
85
|
+
return (react_1.default.createElement(exports.RemoveDuplicatesDialog, { open: request != null, onOpenChange: function (open) {
|
|
86
|
+
if (!open)
|
|
87
|
+
close();
|
|
88
|
+
}, columns: (_a = request === null || request === void 0 ? void 0 : request.columns) !== null && _a !== void 0 ? _a : [], initialHasHeader: request === null || request === void 0 ? void 0 : request.hasHeader, onApply: function (options) { return request === null || request === void 0 ? void 0 : request.onApply(options); } }));
|
|
89
|
+
};
|
|
90
|
+
exports.RemoveDuplicatesDialogHost = RemoveDuplicatesDialogHost;
|
|
91
|
+
exports.RemoveDuplicatesDialogHost.displayName = "RemoveDuplicatesDialogHost";
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type SubtotalDialogChoices, type SubtotalDialogColumn } from "../../atoms/subtotal-dialog.atom";
|
|
3
|
+
export type { SubtotalDialogChoices, SubtotalDialogColumn };
|
|
4
|
+
export type SubtotalDialogProps = {
|
|
5
|
+
/** Controls visibility. */
|
|
6
|
+
open: boolean;
|
|
7
|
+
onOpenChange(open: boolean): void;
|
|
8
|
+
/** Columns of the range, in sheet order. */
|
|
9
|
+
columns: SubtotalDialogColumn[];
|
|
10
|
+
/** Initial state of "My data has headers". */
|
|
11
|
+
initialHasHeader?: boolean;
|
|
12
|
+
/** Emits the choices; the host adds the range and routes to `onSubtotal`. */
|
|
13
|
+
onApply(choices: SubtotalDialogChoices): void;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Excel's Subtotal dialog: "At each change in" (group column), "Use
|
|
17
|
+
* function", "Add subtotal to" (aggregate columns), "Replace current
|
|
18
|
+
* subtotals". Summary rows are always placed below the data.
|
|
19
|
+
*/
|
|
20
|
+
export declare const SubtotalDialog: React.MemoExoticComponent<({ open, onOpenChange, columns, initialHasHeader, onApply, }: SubtotalDialogProps) => React.JSX.Element>;
|
|
21
|
+
/**
|
|
22
|
+
* Host-mounted, atom-driven wrapper around {@link SubtotalDialog}. Mount
|
|
23
|
+
* once in the host; the context menu opens it via `useOpenSubtotalDialog`
|
|
24
|
+
* and only offers the item while a host is mounted.
|
|
25
|
+
*/
|
|
26
|
+
export declare const SubtotalDialogHost: {
|
|
27
|
+
(): React.JSX.Element;
|
|
28
|
+
displayName: string;
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/subtotal-dialog/index.tsx"],"names":[],"mappings":"AAWA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAE/E,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EAG1B,MAAM,kCAAkC,CAAC;AAG1C,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,CAAC;AAoB5D,MAAM,MAAM,mBAAmB,GAAG;IAChC,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,4CAA4C;IAC5C,OAAO,EAAE,oBAAoB,EAAE,CAAC;IAChC,8CAA8C;IAC9C,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6EAA6E;IAC7E,OAAO,CAAC,OAAO,EAAE,qBAAqB,GAAG,IAAI,CAAC;CAC/C,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,cAAc,0FAOtB,mBAAmB,uBAoKvB,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;CAe9B,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SubtotalDialogHost = exports.SubtotalDialog = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var icons_1 = require("@rowsncolumns/icons");
|
|
6
|
+
var ui_1 = require("@rowsncolumns/ui");
|
|
7
|
+
var react_1 = tslib_1.__importStar(require("react"));
|
|
8
|
+
var subtotal_dialog_atom_1 = require("../../atoms/subtotal-dialog.atom");
|
|
9
|
+
var types_1 = require("../../types");
|
|
10
|
+
/**
|
|
11
|
+
* Excel's "Use function" labels. Excel's "Count" is COUNTA (non-empty cells,
|
|
12
|
+
* `SUBTOTAL(3,…)`) and "Count Numbers" is COUNT (`SUBTOTAL(2,…)`).
|
|
13
|
+
*/
|
|
14
|
+
var FUNCTION_LABELS = {
|
|
15
|
+
SUM: "Sum",
|
|
16
|
+
COUNTA: "Count",
|
|
17
|
+
AVERAGE: "Average",
|
|
18
|
+
MAX: "Max",
|
|
19
|
+
MIN: "Min",
|
|
20
|
+
PRODUCT: "Product",
|
|
21
|
+
COUNT: "Count Numbers",
|
|
22
|
+
STDEV: "StdDev",
|
|
23
|
+
STDEVP: "StdDevp",
|
|
24
|
+
VAR: "Var",
|
|
25
|
+
VARP: "Varp",
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Excel's Subtotal dialog: "At each change in" (group column), "Use
|
|
29
|
+
* function", "Add subtotal to" (aggregate columns), "Replace current
|
|
30
|
+
* subtotals". Summary rows are always placed below the data.
|
|
31
|
+
*/
|
|
32
|
+
exports.SubtotalDialog = (0, react_1.memo)(function (_a) {
|
|
33
|
+
var _b;
|
|
34
|
+
var open = _a.open, onOpenChange = _a.onOpenChange, columns = _a.columns, _c = _a.initialHasHeader, initialHasHeader = _c === void 0 ? true : _c, onApply = _a.onApply;
|
|
35
|
+
var _d = tslib_1.__read((0, react_1.useState)(initialHasHeader), 2), hasHeader = _d[0], setHasHeader = _d[1];
|
|
36
|
+
var _e = tslib_1.__read((0, react_1.useState)((_b = columns[0]) === null || _b === void 0 ? void 0 : _b.columnIndex), 2), groupBy = _e[0], setGroupBy = _e[1];
|
|
37
|
+
var _f = tslib_1.__read((0, react_1.useState)("SUM"), 2), fn = _f[0], setFn = _f[1];
|
|
38
|
+
var _g = tslib_1.__read((0, react_1.useState)(function () { return new Set(columns.length ? [columns[columns.length - 1].columnIndex] : []); }), 2), aggregates = _g[0], setAggregates = _g[1];
|
|
39
|
+
var _h = tslib_1.__read((0, react_1.useState)(true), 2), replaceCurrent = _h[0], setReplaceCurrent = _h[1];
|
|
40
|
+
// Re-seed when reopened for a different range.
|
|
41
|
+
(0, react_1.useEffect)(function () {
|
|
42
|
+
var _a;
|
|
43
|
+
if (open) {
|
|
44
|
+
setHasHeader(initialHasHeader);
|
|
45
|
+
setGroupBy((_a = columns[0]) === null || _a === void 0 ? void 0 : _a.columnIndex);
|
|
46
|
+
setFn("SUM");
|
|
47
|
+
setAggregates(new Set(columns.length ? [columns[columns.length - 1].columnIndex] : []));
|
|
48
|
+
setReplaceCurrent(true);
|
|
49
|
+
}
|
|
50
|
+
// Only reset on open transitions.
|
|
51
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
52
|
+
}, [open]);
|
|
53
|
+
var labelOf = (0, react_1.useCallback)(function (column) {
|
|
54
|
+
return hasHeader && column.header ? column.header : column.label;
|
|
55
|
+
}, [hasHeader]);
|
|
56
|
+
var toggleAggregate = (0, react_1.useCallback)(function (columnIndex) {
|
|
57
|
+
setAggregates(function (prev) {
|
|
58
|
+
var next = new Set(prev);
|
|
59
|
+
if (next.has(columnIndex))
|
|
60
|
+
next.delete(columnIndex);
|
|
61
|
+
else
|
|
62
|
+
next.add(columnIndex);
|
|
63
|
+
return next;
|
|
64
|
+
});
|
|
65
|
+
}, []);
|
|
66
|
+
var canApply = groupBy !== undefined && aggregates.size > 0;
|
|
67
|
+
var orderedAggregates = (0, react_1.useMemo)(function () { return columns.map(function (c) { return c.columnIndex; }).filter(function (c) { return aggregates.has(c); }); }, [columns, aggregates]);
|
|
68
|
+
var commit = (0, react_1.useCallback)(function () {
|
|
69
|
+
if (groupBy === undefined)
|
|
70
|
+
return;
|
|
71
|
+
onApply({
|
|
72
|
+
groupByColumnIndex: groupBy,
|
|
73
|
+
aggregateColumnIndices: orderedAggregates,
|
|
74
|
+
fn: fn,
|
|
75
|
+
hasHeader: hasHeader,
|
|
76
|
+
replaceCurrent: replaceCurrent,
|
|
77
|
+
});
|
|
78
|
+
onOpenChange(false);
|
|
79
|
+
}, [groupBy, orderedAggregates, fn, hasHeader, replaceCurrent, onApply, onOpenChange]);
|
|
80
|
+
return (react_1.default.createElement(ui_1.Dialog, { open: open, onOpenChange: onOpenChange },
|
|
81
|
+
react_1.default.createElement(ui_1.DialogContent, { className: "w-[420px] max-w-[92vw] pointer-events-auto" },
|
|
82
|
+
react_1.default.createElement(ui_1.DialogTitle, null, "Subtotal"),
|
|
83
|
+
react_1.default.createElement(ui_1.DialogDescription, null, "Insert a total row after every change in a column, plus a grand total, and outline the groups."),
|
|
84
|
+
react_1.default.createElement(ui_1.DialogCloseButton, { onClick: function () { return onOpenChange(false); } },
|
|
85
|
+
react_1.default.createElement(icons_1.Cross1Icon, null)),
|
|
86
|
+
react_1.default.createElement(ui_1.DialogBody, { className: "flex flex-col gap-3 font-system text-sm" },
|
|
87
|
+
react_1.default.createElement("label", { className: "flex items-center gap-1" },
|
|
88
|
+
react_1.default.createElement("input", { type: "checkbox", name: "hasHeader", checked: hasHeader, onChange: function (e) { return setHasHeader(e.target.checked); } }),
|
|
89
|
+
"My data has headers"),
|
|
90
|
+
react_1.default.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
|
|
91
|
+
"At each change in:",
|
|
92
|
+
react_1.default.createElement("select", { className: "h-8 rounded border border-rnc-border bg-transparent px-2 text-sm", "aria-label": "At each change in", value: groupBy !== null && groupBy !== void 0 ? groupBy : "", onChange: function (e) { return setGroupBy(Number(e.target.value)); } }, columns.map(function (column) { return (react_1.default.createElement("option", { key: column.columnIndex, value: column.columnIndex }, labelOf(column))); }))),
|
|
93
|
+
react_1.default.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
|
|
94
|
+
"Use function:",
|
|
95
|
+
react_1.default.createElement("select", { className: "h-8 rounded border border-rnc-border bg-transparent px-2 text-sm", "aria-label": "Use function", value: fn, onChange: function (e) { return setFn(e.target.value); } }, types_1.SUBTOTAL_FUNCTIONS.map(function (name) { return (react_1.default.createElement("option", { key: name, value: name }, FUNCTION_LABELS[name])); }))),
|
|
96
|
+
react_1.default.createElement("div", { className: "flex flex-col gap-1" },
|
|
97
|
+
react_1.default.createElement("span", { className: "text-xs font-medium" }, "Add subtotal to:"),
|
|
98
|
+
react_1.default.createElement("div", { className: "flex flex-col gap-1 max-h-[180px] overflow-y-auto border border-rnc-border rounded p-2", role: "group", "aria-label": "Add subtotal to" }, columns.map(function (column) { return (react_1.default.createElement("label", { key: column.columnIndex, className: "flex items-center gap-1" },
|
|
99
|
+
react_1.default.createElement("input", { type: "checkbox", name: "subtotal-column-".concat(column.columnIndex), checked: aggregates.has(column.columnIndex), onChange: function () { return toggleAggregate(column.columnIndex); } }),
|
|
100
|
+
react_1.default.createElement("span", { className: "truncate", title: labelOf(column) }, labelOf(column)))); }))),
|
|
101
|
+
react_1.default.createElement("label", { className: "flex items-center gap-1" },
|
|
102
|
+
react_1.default.createElement("input", { type: "checkbox", name: "replaceCurrent", checked: replaceCurrent, onChange: function (e) { return setReplaceCurrent(e.target.checked); } }),
|
|
103
|
+
"Replace current subtotals"),
|
|
104
|
+
react_1.default.createElement(ui_1.Separator, null),
|
|
105
|
+
react_1.default.createElement("div", { className: "flex justify-end gap-2" },
|
|
106
|
+
react_1.default.createElement(ui_1.Button, { variant: "outline", size: "sm", type: "button", onClick: function () { return onOpenChange(false); } }, "Cancel"),
|
|
107
|
+
react_1.default.createElement(ui_1.Button, { size: "sm", type: "button", onClick: commit, disabled: !canApply }, "OK"))))));
|
|
108
|
+
});
|
|
109
|
+
exports.SubtotalDialog.displayName = "SubtotalDialog";
|
|
110
|
+
/**
|
|
111
|
+
* Host-mounted, atom-driven wrapper around {@link SubtotalDialog}. Mount
|
|
112
|
+
* once in the host; the context menu opens it via `useOpenSubtotalDialog`
|
|
113
|
+
* and only offers the item while a host is mounted.
|
|
114
|
+
*/
|
|
115
|
+
var SubtotalDialogHost = function () {
|
|
116
|
+
var _a;
|
|
117
|
+
(0, subtotal_dialog_atom_1.useRegisterSubtotalDialogHost)();
|
|
118
|
+
var _b = tslib_1.__read((0, subtotal_dialog_atom_1.useSubtotalDialogState)(), 2), request = _b[0], setRequest = _b[1];
|
|
119
|
+
var close = (0, react_1.useCallback)(function () { return setRequest(null); }, [setRequest]);
|
|
120
|
+
return (react_1.default.createElement(exports.SubtotalDialog, { open: request != null, onOpenChange: function (open) {
|
|
121
|
+
if (!open)
|
|
122
|
+
close();
|
|
123
|
+
}, columns: (_a = request === null || request === void 0 ? void 0 : request.columns) !== null && _a !== void 0 ? _a : [], initialHasHeader: request === null || request === void 0 ? void 0 : request.hasHeader, onApply: function (choices) { return request === null || request === void 0 ? void 0 : request.onApply(choices); } }));
|
|
124
|
+
};
|
|
125
|
+
exports.SubtotalDialogHost = SubtotalDialogHost;
|
|
126
|
+
exports.SubtotalDialogHost.displayName = "SubtotalDialogHost";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { SplitTextOptions } from "../../types";
|
|
3
|
+
export type TextToColumnsMode = "delimited" | "fixed";
|
|
4
|
+
export type TextToColumnsDialogProps = {
|
|
5
|
+
/** Controls visibility. */
|
|
6
|
+
open: boolean;
|
|
7
|
+
onOpenChange(open: boolean): void;
|
|
8
|
+
/** Texts of the first cells of the selected column — the preview / ruler. */
|
|
9
|
+
preview: string[];
|
|
10
|
+
/** Initial wizard step-1 choice (default Delimited). */
|
|
11
|
+
initialMode?: TextToColumnsMode;
|
|
12
|
+
/**
|
|
13
|
+
* Emits the chosen delimiter (Delimited) or column breaks (Fixed width).
|
|
14
|
+
* The host routes it to `onSplitTextToColumns`.
|
|
15
|
+
*/
|
|
16
|
+
onApply(options: {
|
|
17
|
+
delimiter: string;
|
|
18
|
+
} & SplitTextOptions): void;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Excel's Convert Text to Columns wizard, condensed: choose Delimited (pick
|
|
22
|
+
* a delimiter or type another) or Fixed width (click the ruler to add or
|
|
23
|
+
* remove break lines, or type the positions), with a live preview of the
|
|
24
|
+
* first rows.
|
|
25
|
+
*/
|
|
26
|
+
export declare const TextToColumnsDialog: React.MemoExoticComponent<({ open, onOpenChange, preview, initialMode, onApply, }: TextToColumnsDialogProps) => React.JSX.Element>;
|
|
27
|
+
/**
|
|
28
|
+
* Host-mounted, atom-driven wrapper around {@link TextToColumnsDialog}.
|
|
29
|
+
* Mount once in the host (alongside the other editor dialogs); the context
|
|
30
|
+
* menu opens it via `useOpenTextToColumnsDialog`. Without a host the menu
|
|
31
|
+
* keeps its one-click delimiter items only.
|
|
32
|
+
*/
|
|
33
|
+
export declare const TextToColumnsDialogHost: {
|
|
34
|
+
(): React.JSX.Element;
|
|
35
|
+
displayName: string;
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/text-to-columns-dialog/index.tsx"],"names":[],"mappings":"AAYA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAM/E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,OAAO,CAAC;AAEtD,MAAM,MAAM,wBAAwB,GAAG;IACrC,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,6EAA6E;IAC7E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,wDAAwD;IACxD,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAChC;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,gBAAgB,GAAG,IAAI,CAAC;CAClE,CAAC;AAiCF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,qFAO3B,wBAAwB,uBAgO5B,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB;;;CAenC,CAAC"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TextToColumnsDialogHost = exports.TextToColumnsDialog = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
5
|
+
var icons_1 = require("@rowsncolumns/icons");
|
|
6
|
+
var ui_1 = require("@rowsncolumns/ui");
|
|
7
|
+
var react_1 = tslib_1.__importStar(require("react"));
|
|
8
|
+
var text_to_columns_dialog_atom_1 = require("../../atoms/text-to-columns-dialog.atom");
|
|
9
|
+
var DELIMITERS = [
|
|
10
|
+
{ label: "Comma", value: "," },
|
|
11
|
+
{ label: "Semicolon", value: ";" },
|
|
12
|
+
{ label: "Tab", value: "\t" },
|
|
13
|
+
{ label: "Space", value: " " },
|
|
14
|
+
{ label: "Period", value: "." },
|
|
15
|
+
{ label: "Pipe", value: "|" },
|
|
16
|
+
];
|
|
17
|
+
/** Cuts `text` at ascending character positions (the dialog's own preview). */
|
|
18
|
+
var cutAt = function (text, breaks) {
|
|
19
|
+
var e_1, _a;
|
|
20
|
+
var parts = [];
|
|
21
|
+
var start = 0;
|
|
22
|
+
try {
|
|
23
|
+
for (var breaks_1 = tslib_1.__values(breaks), breaks_1_1 = breaks_1.next(); !breaks_1_1.done; breaks_1_1 = breaks_1.next()) {
|
|
24
|
+
var position = breaks_1_1.value;
|
|
25
|
+
parts.push(text.slice(start, position));
|
|
26
|
+
start = position;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
30
|
+
finally {
|
|
31
|
+
try {
|
|
32
|
+
if (breaks_1_1 && !breaks_1_1.done && (_a = breaks_1.return)) _a.call(breaks_1);
|
|
33
|
+
}
|
|
34
|
+
finally { if (e_1) throw e_1.error; }
|
|
35
|
+
}
|
|
36
|
+
parts.push(text.slice(start));
|
|
37
|
+
return parts;
|
|
38
|
+
};
|
|
39
|
+
var parseBreaks = function (text) {
|
|
40
|
+
return tslib_1.__spreadArray([], tslib_1.__read(new Set(text
|
|
41
|
+
.split(/[\s,;]+/)
|
|
42
|
+
.map(function (part) { return Number.parseInt(part, 10); })
|
|
43
|
+
.filter(function (n) { return Number.isInteger(n) && n > 0; }))), false).sort(function (a, b) { return a - b; });
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Excel's Convert Text to Columns wizard, condensed: choose Delimited (pick
|
|
47
|
+
* a delimiter or type another) or Fixed width (click the ruler to add or
|
|
48
|
+
* remove break lines, or type the positions), with a live preview of the
|
|
49
|
+
* first rows.
|
|
50
|
+
*/
|
|
51
|
+
exports.TextToColumnsDialog = (0, react_1.memo)(function (_a) {
|
|
52
|
+
var open = _a.open, onOpenChange = _a.onOpenChange, preview = _a.preview, _b = _a.initialMode, initialMode = _b === void 0 ? "delimited" : _b, onApply = _a.onApply;
|
|
53
|
+
var _c = tslib_1.__read((0, react_1.useState)(initialMode), 2), mode = _c[0], setMode = _c[1];
|
|
54
|
+
var _d = tslib_1.__read((0, react_1.useState)(","), 2), delimiter = _d[0], setDelimiter = _d[1];
|
|
55
|
+
var _e = tslib_1.__read((0, react_1.useState)(""), 2), customDelimiter = _e[0], setCustomDelimiter = _e[1];
|
|
56
|
+
var _f = tslib_1.__read((0, react_1.useState)([]), 2), breaks = _f[0], setBreaks = _f[1];
|
|
57
|
+
var _g = tslib_1.__read((0, react_1.useState)(""), 2), breaksText = _g[0], setBreaksText = _g[1];
|
|
58
|
+
(0, react_1.useEffect)(function () {
|
|
59
|
+
if (open) {
|
|
60
|
+
setMode(initialMode);
|
|
61
|
+
setDelimiter(",");
|
|
62
|
+
setCustomDelimiter("");
|
|
63
|
+
setBreaks([]);
|
|
64
|
+
setBreaksText("");
|
|
65
|
+
}
|
|
66
|
+
// Only reset on open transitions.
|
|
67
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
68
|
+
}, [open]);
|
|
69
|
+
var sample = (0, react_1.useMemo)(function () { return preview.slice(0, 6); }, [preview]);
|
|
70
|
+
var rulerLength = (0, react_1.useMemo)(function () { return Math.min(120, Math.max.apply(Math, tslib_1.__spreadArray([10], tslib_1.__read(sample.map(function (text) { return text.length; })), false))); }, [sample]);
|
|
71
|
+
var toggleBreak = (0, react_1.useCallback)(function (position) {
|
|
72
|
+
setBreaks(function (prev) {
|
|
73
|
+
var next = prev.includes(position)
|
|
74
|
+
? prev.filter(function (p) { return p !== position; })
|
|
75
|
+
: tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read(prev), false), [position], false).sort(function (a, b) { return a - b; });
|
|
76
|
+
setBreaksText(next.join(", "));
|
|
77
|
+
return next;
|
|
78
|
+
});
|
|
79
|
+
}, []);
|
|
80
|
+
var effectiveDelimiter = delimiter === "custom" ? customDelimiter : delimiter;
|
|
81
|
+
var canApply = mode === "delimited" ? effectiveDelimiter.length > 0 : breaks.length > 0;
|
|
82
|
+
var commit = (0, react_1.useCallback)(function () {
|
|
83
|
+
if (mode === "fixed") {
|
|
84
|
+
onApply({ delimiter: ",", columnBreaks: breaks });
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
onApply({ delimiter: effectiveDelimiter });
|
|
88
|
+
}
|
|
89
|
+
onOpenChange(false);
|
|
90
|
+
}, [mode, breaks, effectiveDelimiter, onApply, onOpenChange]);
|
|
91
|
+
return (react_1.default.createElement(ui_1.Dialog, { open: open, onOpenChange: onOpenChange },
|
|
92
|
+
react_1.default.createElement(ui_1.DialogContent, { className: "w-[520px] max-w-[92vw] pointer-events-auto" },
|
|
93
|
+
react_1.default.createElement(ui_1.DialogTitle, null, "Text to columns"),
|
|
94
|
+
react_1.default.createElement(ui_1.DialogDescription, null, "Split the selected column into several columns."),
|
|
95
|
+
react_1.default.createElement(ui_1.DialogCloseButton, { onClick: function () { return onOpenChange(false); } },
|
|
96
|
+
react_1.default.createElement(icons_1.Cross1Icon, null)),
|
|
97
|
+
react_1.default.createElement(ui_1.DialogBody, { className: "flex flex-col gap-3 font-system text-sm" },
|
|
98
|
+
react_1.default.createElement("div", { className: "flex gap-4", role: "radiogroup", "aria-label": "Original data type" },
|
|
99
|
+
react_1.default.createElement("label", { className: "flex items-center gap-1" },
|
|
100
|
+
react_1.default.createElement("input", { type: "radio", name: "text-to-columns-mode", value: "delimited", checked: mode === "delimited", onChange: function () { return setMode("delimited"); } }),
|
|
101
|
+
"Delimited"),
|
|
102
|
+
react_1.default.createElement("label", { className: "flex items-center gap-1" },
|
|
103
|
+
react_1.default.createElement("input", { type: "radio", name: "text-to-columns-mode", value: "fixed", checked: mode === "fixed", onChange: function () { return setMode("fixed"); } }),
|
|
104
|
+
"Fixed width")),
|
|
105
|
+
mode === "delimited" ? (react_1.default.createElement("div", { className: "flex flex-col gap-2" },
|
|
106
|
+
react_1.default.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
|
|
107
|
+
"Delimiter",
|
|
108
|
+
react_1.default.createElement("select", { className: "h-8 rounded border border-rnc-border bg-transparent px-2 text-sm", value: delimiter, onChange: function (e) { return setDelimiter(e.target.value); }, "aria-label": "Delimiter" },
|
|
109
|
+
DELIMITERS.map(function (option) { return (react_1.default.createElement("option", { key: option.value, value: option.value }, option.label)); }),
|
|
110
|
+
react_1.default.createElement("option", { value: "custom" }, "Other\u2026"))),
|
|
111
|
+
delimiter === "custom" ? (react_1.default.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
|
|
112
|
+
"Other delimiter",
|
|
113
|
+
react_1.default.createElement(ui_1.Input, { value: customDelimiter, maxLength: 5, "aria-label": "Other delimiter", onChange: function (e) { return setCustomDelimiter(e.target.value); } }))) : null)) : (react_1.default.createElement("div", { className: "flex flex-col gap-2" },
|
|
114
|
+
react_1.default.createElement("div", { className: "text-xs text-rnc-foreground/70" }, "Click the ruler to create a break line; click it again to remove it."),
|
|
115
|
+
react_1.default.createElement("div", { className: "overflow-x-auto rounded border border-rnc-border p-2 font-mono text-xs leading-5", "data-testid": "fixed-width-ruler" },
|
|
116
|
+
react_1.default.createElement("div", { className: "flex select-none" }, Array.from({ length: rulerLength }, function (_, index) {
|
|
117
|
+
var position = index + 1;
|
|
118
|
+
var active = breaks.includes(position);
|
|
119
|
+
return (react_1.default.createElement("button", { key: position, type: "button", "aria-label": "Break after character ".concat(position), "aria-pressed": active, className: "w-[1ch] shrink-0 border-r ".concat(active ? "border-rnc-primary bg-rnc-primary/20" : "border-transparent", " hover:bg-rnc-accent"), onClick: function () { return toggleBreak(position); } }, position % 10 === 0 ? String(position / 10) : "·"));
|
|
120
|
+
})),
|
|
121
|
+
sample.map(function (text, rowIndex) { return (react_1.default.createElement("div", { key: rowIndex, className: "flex whitespace-pre" }, Array.from({ length: rulerLength }, function (_, index) {
|
|
122
|
+
var _a;
|
|
123
|
+
var position = index + 1;
|
|
124
|
+
var active = breaks.includes(position);
|
|
125
|
+
return (react_1.default.createElement("span", { key: position, className: "w-[1ch] shrink-0 border-r ".concat(active ? "border-rnc-primary" : "border-transparent") }, (_a = text[index]) !== null && _a !== void 0 ? _a : " "));
|
|
126
|
+
}))); })),
|
|
127
|
+
react_1.default.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
|
|
128
|
+
"Break positions (characters before each break)",
|
|
129
|
+
react_1.default.createElement(ui_1.Input, { value: breaksText, placeholder: "e.g. 4, 10", "aria-label": "Break positions", onChange: function (e) {
|
|
130
|
+
setBreaksText(e.target.value);
|
|
131
|
+
setBreaks(parseBreaks(e.target.value));
|
|
132
|
+
} })))),
|
|
133
|
+
react_1.default.createElement("div", { className: "flex flex-col gap-1" },
|
|
134
|
+
react_1.default.createElement("span", { className: "text-xs font-medium" }, "Data preview"),
|
|
135
|
+
react_1.default.createElement("div", { className: "max-h-[120px] overflow-auto rounded border border-rnc-border p-2 font-mono text-xs", "data-testid": "text-to-columns-preview" }, sample.map(function (text, rowIndex) {
|
|
136
|
+
var parts = mode === "fixed"
|
|
137
|
+
? cutAt(text, breaks)
|
|
138
|
+
: effectiveDelimiter
|
|
139
|
+
? text.split(effectiveDelimiter)
|
|
140
|
+
: [text];
|
|
141
|
+
return (react_1.default.createElement("div", { key: rowIndex, className: "flex gap-1 whitespace-pre" }, parts.map(function (part, partIndex) { return (react_1.default.createElement("span", { key: partIndex, className: "border-r border-rnc-border pr-1 last:border-r-0" }, part.trim() || " ")); })));
|
|
142
|
+
}))),
|
|
143
|
+
react_1.default.createElement(ui_1.Separator, null),
|
|
144
|
+
react_1.default.createElement("div", { className: "flex justify-end gap-2" },
|
|
145
|
+
react_1.default.createElement(ui_1.Button, { variant: "outline", size: "sm", type: "button", onClick: function () { return onOpenChange(false); } }, "Cancel"),
|
|
146
|
+
react_1.default.createElement(ui_1.Button, { size: "sm", type: "button", onClick: commit, disabled: !canApply }, "Finish"))))));
|
|
147
|
+
});
|
|
148
|
+
exports.TextToColumnsDialog.displayName = "TextToColumnsDialog";
|
|
149
|
+
/**
|
|
150
|
+
* Host-mounted, atom-driven wrapper around {@link TextToColumnsDialog}.
|
|
151
|
+
* Mount once in the host (alongside the other editor dialogs); the context
|
|
152
|
+
* menu opens it via `useOpenTextToColumnsDialog`. Without a host the menu
|
|
153
|
+
* keeps its one-click delimiter items only.
|
|
154
|
+
*/
|
|
155
|
+
var TextToColumnsDialogHost = function () {
|
|
156
|
+
var _a;
|
|
157
|
+
(0, text_to_columns_dialog_atom_1.useRegisterTextToColumnsDialogHost)();
|
|
158
|
+
var _b = tslib_1.__read((0, text_to_columns_dialog_atom_1.useTextToColumnsDialogState)(), 2), request = _b[0], setRequest = _b[1];
|
|
159
|
+
var close = (0, react_1.useCallback)(function () { return setRequest(null); }, [setRequest]);
|
|
160
|
+
return (react_1.default.createElement(exports.TextToColumnsDialog, { open: request != null, onOpenChange: function (open) {
|
|
161
|
+
if (!open)
|
|
162
|
+
close();
|
|
163
|
+
}, preview: (_a = request === null || request === void 0 ? void 0 : request.preview) !== null && _a !== void 0 ? _a : [], initialMode: "fixed", onApply: function (options) { return request === null || request === void 0 ? void 0 : request.onApply(options); } }));
|
|
164
|
+
};
|
|
165
|
+
exports.TextToColumnsDialogHost = TextToColumnsDialogHost;
|
|
166
|
+
exports.TextToColumnsDialogHost.displayName = "TextToColumnsDialogHost";
|
|
@@ -4,16 +4,28 @@ import type { Color } from "../../types";
|
|
|
4
4
|
import type { SpreadsheetTheme } from "../canvas-grid/typings";
|
|
5
5
|
import type { ColorSelectorProps } from "./color-selector";
|
|
6
6
|
import { ColorSelector } from "./color-selector";
|
|
7
|
+
import { type CellFill } from "./fill-selectors";
|
|
7
8
|
type BackgroundColorSelectorProps = {
|
|
8
9
|
disabled?: boolean;
|
|
9
10
|
color?: Color | null;
|
|
10
11
|
theme?: SpreadsheetTheme;
|
|
11
12
|
onChange?(color: Color | undefined): void;
|
|
13
|
+
/**
|
|
14
|
+
* The active cell's fill (pattern / gradient fields) — enables the
|
|
15
|
+
* Pattern and Gradient tabs together with `onChangeFill`. Without
|
|
16
|
+
* `onChangeFill` the popover is the solid colour picker only.
|
|
17
|
+
*/
|
|
18
|
+
fill?: CellFill | null;
|
|
19
|
+
/**
|
|
20
|
+
* Apply a pattern or gradient fill (Excel: Format Cells → Fill → Pattern /
|
|
21
|
+
* Fill Effects). Receives the full fill slice so cleared fields reset.
|
|
22
|
+
*/
|
|
23
|
+
onChangeFill?(fill: CellFill): void;
|
|
12
24
|
/**
|
|
13
25
|
* Custom color selector component
|
|
14
26
|
*/
|
|
15
27
|
ColorSelector?: ComponentType<ColorSelectorProps>;
|
|
16
28
|
} & Pick<ComponentProps<typeof ColorSelector>, "userDefinedColors" | "onAddUserDefinedColor">;
|
|
17
|
-
export declare const BackgroundColorSelector: ({ color, theme, onChange, onAddUserDefinedColor, userDefinedColors, disabled, ColorSelector: ColorSelectorComponent, }: BackgroundColorSelectorProps) => React.JSX.Element;
|
|
29
|
+
export declare const BackgroundColorSelector: ({ color, theme, onChange, fill, onChangeFill, onAddUserDefinedColor, userDefinedColors, disabled, ColorSelector: ColorSelectorComponent, }: BackgroundColorSelectorProps) => React.JSX.Element;
|
|
18
30
|
export {};
|
|
19
31
|
//# sourceMappingURL=background-color-selector.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"background-color-selector.d.ts","sourceRoot":"","sources":["../../../../components/toolbar/background-color-selector.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"background-color-selector.d.ts","sourceRoot":"","sources":["../../../../components/toolbar/background-color-selector.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EACL,KAAK,QAAQ,EAId,MAAM,kBAAkB,CAAC;AAE1B,KAAK,4BAA4B,GAAG;IAClC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,QAAQ,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI,CAAC;IAC1C;;;;OAIG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAC;IACvB;;;OAGG;IACH,YAAY,CAAC,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;IACpC;;OAEG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CACnD,GAAG,IAAI,CACN,cAAc,CAAC,OAAO,aAAa,CAAC,EACpC,mBAAmB,GAAG,uBAAuB,CAC9C,CAAC;AACF,eAAO,MAAM,uBAAuB,GAAI,4IAUrC,4BAA4B,sBA+G9B,CAAC"}
|