@rowsncolumns/spreadsheet 10.2.74 → 10.2.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/api/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/fill-series.d.ts +38 -0
- package/dist/cjs/api/fill-series.d.ts.map +1 -0
- package/dist/cjs/api/fill-series.js +89 -0
- package/dist/cjs/api/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/spreadsheet-api.d.ts +6 -2
- package/dist/cjs/api/spreadsheet-api.d.ts.map +1 -1
- package/dist/cjs/api/spreadsheet-api.js +9 -3
- package/dist/cjs/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/fill-options.atom.d.ts +36 -0
- package/dist/cjs/atoms/fill-options.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/fill-options.atom.js +11 -0
- package/dist/cjs/atoms/fill-series-dialog.atom.d.ts +26 -0
- package/dist/cjs/atoms/fill-series-dialog.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/fill-series-dialog.atom.js +14 -0
- package/dist/cjs/atoms/go-to-dialog.atom.d.ts +11 -1
- package/dist/cjs/atoms/go-to-dialog.atom.d.ts.map +1 -1
- 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 +3 -0
- package/dist/cjs/atoms/index.d.ts.map +1 -1
- package/dist/cjs/atoms/index.js +3 -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 +328 -71
- package/dist/cjs/components/canvas-grid/typings.d.ts +31 -5
- 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/helpers.d.ts +9 -0
- package/dist/cjs/components/cell-editor/helpers.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/helpers.js +8 -1
- package/dist/cjs/components/cell-editor/helpers.spec.js +14 -0
- package/dist/cjs/components/cell-editor/index.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/index.js +7 -3
- package/dist/cjs/components/context-menu/index.d.ts +6 -1
- package/dist/cjs/components/context-menu/index.d.ts.map +1 -1
- package/dist/cjs/components/context-menu/index.js +146 -3
- 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/fill-series-dialog/index.d.ts +29 -0
- package/dist/cjs/components/fill-series-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/fill-series-dialog/index.js +156 -0
- package/dist/cjs/components/go-to-dialog/index.d.ts +11 -1
- package/dist/cjs/components/go-to-dialog/index.d.ts.map +1 -1
- package/dist/cjs/components/go-to-dialog/index.js +67 -24
- 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/selection/fill-options-menu.d.ts +32 -0
- package/dist/cjs/components/selection/fill-options-menu.d.ts.map +1 -0
- package/dist/cjs/components/selection/fill-options-menu.js +65 -0
- package/dist/cjs/components/selection/index.d.ts +1 -1
- package/dist/cjs/components/selection/index.d.ts.map +1 -1
- package/dist/cjs/components/selection/index.js +4 -2
- package/dist/cjs/components/selection/types.d.ts +11 -1
- package/dist/cjs/components/selection/types.d.ts.map +1 -1
- package/dist/cjs/components/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 +1 -0
- package/dist/cjs/components/toolbar/index.d.ts.map +1 -1
- package/dist/cjs/components/toolbar/index.js +1 -0
- package/dist/cjs/components/toolbar/text-format-selector.d.ts +9 -0
- package/dist/cjs/components/toolbar/text-format-selector.d.ts.map +1 -1
- package/dist/cjs/components/toolbar/text-format-selector.js +15 -3
- package/dist/cjs/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/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-editable.d.ts +11 -2
- package/dist/cjs/hooks/use-editable.d.ts.map +1 -1
- package/dist/cjs/hooks/use-editable.js +8 -0
- package/dist/cjs/hooks/use-editor-submit.d.ts +32 -3
- package/dist/cjs/hooks/use-editor-submit.d.ts.map +1 -1
- package/dist/cjs/hooks/use-editor-submit.js +111 -2
- package/dist/cjs/hooks/use-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.map +1 -1
- package/dist/cjs/hooks/use-keyboard-handler.js +27 -14
- package/dist/cjs/hooks/use-selection-renderer.d.ts +13 -2
- package/dist/cjs/hooks/use-selection-renderer.d.ts.map +1 -1
- package/dist/cjs/hooks/use-selection-renderer.js +21 -4
- package/dist/cjs/hooks/use-selection.d.ts +54 -4
- package/dist/cjs/hooks/use-selection.d.ts.map +1 -1
- package/dist/cjs/hooks/use-selection.js +232 -37
- package/dist/cjs/index.d.ts +12 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +11 -0
- package/dist/cjs/release-date.js +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/types.d.ts +156 -5
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/cjs/types.js +19 -1
- 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/fill-series.d.ts +38 -0
- package/dist/esm/api/fill-series.d.ts.map +1 -0
- package/dist/esm/api/fill-series.js +78 -0
- package/dist/esm/api/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/spreadsheet-api.d.ts +6 -2
- package/dist/esm/api/spreadsheet-api.d.ts.map +1 -1
- package/dist/esm/api/spreadsheet-api.js +8 -3
- package/dist/esm/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/fill-options.atom.d.ts +36 -0
- package/dist/esm/atoms/fill-options.atom.d.ts.map +1 -0
- package/dist/esm/atoms/fill-options.atom.js +5 -0
- package/dist/esm/atoms/fill-series-dialog.atom.d.ts +26 -0
- package/dist/esm/atoms/fill-series-dialog.atom.d.ts.map +1 -0
- package/dist/esm/atoms/fill-series-dialog.atom.js +9 -0
- package/dist/esm/atoms/go-to-dialog.atom.d.ts +11 -1
- package/dist/esm/atoms/go-to-dialog.atom.d.ts.map +1 -1
- 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 +3 -0
- package/dist/esm/atoms/index.d.ts.map +1 -1
- package/dist/esm/atoms/index.js +3 -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 +266 -26
- package/dist/esm/components/canvas-grid/typings.d.ts +31 -5
- 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/helpers.d.ts +9 -0
- package/dist/esm/components/cell-editor/helpers.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/helpers.js +6 -0
- package/dist/esm/components/cell-editor/helpers.spec.js +15 -1
- package/dist/esm/components/cell-editor/index.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/index.js +8 -4
- package/dist/esm/components/context-menu/index.d.ts +6 -1
- package/dist/esm/components/context-menu/index.d.ts.map +1 -1
- package/dist/esm/components/context-menu/index.js +139 -4
- 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/fill-series-dialog/index.d.ts +29 -0
- package/dist/esm/components/fill-series-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/fill-series-dialog/index.js +151 -0
- package/dist/esm/components/go-to-dialog/index.d.ts +11 -1
- package/dist/esm/components/go-to-dialog/index.d.ts.map +1 -1
- package/dist/esm/components/go-to-dialog/index.js +63 -23
- 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/selection/fill-options-menu.d.ts +32 -0
- package/dist/esm/components/selection/fill-options-menu.d.ts.map +1 -0
- package/dist/esm/components/selection/fill-options-menu.js +63 -0
- package/dist/esm/components/selection/index.d.ts +1 -1
- package/dist/esm/components/selection/index.d.ts.map +1 -1
- package/dist/esm/components/selection/index.js +4 -2
- package/dist/esm/components/selection/types.d.ts +11 -1
- package/dist/esm/components/selection/types.d.ts.map +1 -1
- package/dist/esm/components/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 +1 -0
- package/dist/esm/components/toolbar/index.d.ts.map +1 -1
- package/dist/esm/components/toolbar/index.js +1 -0
- package/dist/esm/components/toolbar/text-format-selector.d.ts +9 -0
- package/dist/esm/components/toolbar/text-format-selector.d.ts.map +1 -1
- package/dist/esm/components/toolbar/text-format-selector.js +14 -2
- package/dist/esm/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/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-editable.d.ts +11 -2
- package/dist/esm/hooks/use-editable.d.ts.map +1 -1
- package/dist/esm/hooks/use-editable.js +8 -0
- package/dist/esm/hooks/use-editor-submit.d.ts +32 -3
- package/dist/esm/hooks/use-editor-submit.d.ts.map +1 -1
- package/dist/esm/hooks/use-editor-submit.js +82 -3
- package/dist/esm/hooks/use-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.map +1 -1
- package/dist/esm/hooks/use-keyboard-handler.js +27 -14
- package/dist/esm/hooks/use-selection-renderer.d.ts +13 -2
- package/dist/esm/hooks/use-selection-renderer.d.ts.map +1 -1
- package/dist/esm/hooks/use-selection-renderer.js +22 -5
- package/dist/esm/hooks/use-selection.d.ts +54 -4
- package/dist/esm/hooks/use-selection.d.ts.map +1 -1
- package/dist/esm/hooks/use-selection.js +220 -36
- package/dist/esm/index.d.ts +12 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +11 -0
- package/dist/esm/release-date.js +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/types.d.ts +156 -5
- 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 +7 -7
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
import { Direction, isCellWithinBounds, selectionFromActiveCell, } from "@rowsncolumns/grid";
|
|
2
2
|
import { ArrowLeftIcon, ArrowRightIcon, CheckIcon, ChevronRightIcon, ClipboardIcon, CodeIcon, CopyIcon, Cross1Icon, DotsVerticalIcon, EyeNoneIcon, EyeOpenIcon, FunnelIcon, MdBrush, MdOutlineFactCheck, PaintBrush, PlusIcon, ReaderIcon, RemoveDuplicatesIcon, ScissorsIcon, SizeIcon, SortDownIcon, SortUpIcon, SpaceBetweenHorizontallyIcon, TableIcon, TrashIcon, ViewGridIcon, WandIcon, } from "@rowsncolumns/icons";
|
|
3
3
|
import { DropdownLeftSlot, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuItem, DropdownMenuItemIndicator, DropdownMenuPortal, DropdownMenuSeparator, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownRightSlot, } from "@rowsncolumns/ui";
|
|
4
|
-
import { number2Alpha } from "@rowsncolumns/utils";
|
|
4
|
+
import { addressToCell, cellToAddress, number2Alpha } from "@rowsncolumns/utils";
|
|
5
5
|
import React, { useCallback, useMemo, useRef } from "react";
|
|
6
6
|
import { getProtectedRange, isProtectedRange } from "../../api/validation";
|
|
7
7
|
import { useGetContentfulRangeAroundCell } from "../../atoms";
|
|
8
|
+
import { useIsAdvancedFilterDialogMounted, useOpenAdvancedFilterDialog, } from "../../atoms/advanced-filter-dialog.atom";
|
|
9
|
+
import { useIsGoalSeekDialogMounted, useOpenGoalSeekDialog, } from "../../atoms/goal-seek-dialog.atom";
|
|
8
10
|
import { useIsRemoveDuplicatesDialogMounted, useOpenRemoveDuplicatesDialog, } from "../../atoms/remove-duplicates-dialog.atom";
|
|
11
|
+
import { useIsSubtotalDialogMounted, useOpenSubtotalDialog, } from "../../atoms/subtotal-dialog.atom";
|
|
12
|
+
import { useIsTextToColumnsDialogMounted, useOpenTextToColumnsDialog, } from "../../atoms/text-to-columns-dialog.atom";
|
|
9
13
|
import { BLANK_LABEL } from "../../config";
|
|
10
14
|
import { createArrayRange, generateMultiDimTitle } from "../../helpers";
|
|
11
15
|
import { getTotalRowFunctionFormula, getTotalRowFunctionFromFormula, TOTAL_ROW_FUNCTIONS, } from "./total-row-functions";
|
|
12
|
-
export const ContextMenu = ({ isRowHeader, isColumnHeader, activeCell, selections, basicFilter, isTableHeader, onClearContents, onHideColumn, onHideRow, onGroupRows, onUngroupRows, onGroupColumns, onUngroupColumns, onDeleteRow, onDeleteColumn, onInsertColumn, onInsertRow, onInsertCellsShiftDown, onInsertCellsShiftRight, onDeleteCellsShiftLeft, onDeleteCellsShiftUp, onFreezeRow, onFreezeColumn, onCopy, onCut, onPaste, onRequestPasteSpecial, onRequestEvaluateFormula, isActiveCellFormula, onInsertNote, onProtectRange, onUnProtectRange, onSortRange, onSortColumn, onRequestDefineNamedRange, onRequestResize, onRequestEditTable, onRequestEditPivotTable, onRequestDeletePivotTable, onPivotDrillDown, onRequestFormatCells, onRequestConditionalFormat, onRequestDataValidation, onRemoveTable, onClearFormatting, onCreateTable, onCreateBasicFilter, onFilterTable, onSortTable, getFormattedValuesFromRange, focusSheet, isSheetFocused, getFormattedValue, onInsertTableColumn, onDeleteTableColumn, onInsertTableRow, onDeleteTableRow, onSplitTextToColumns, onRemoveDuplicates, onChange, getCellData, isHiddenColumn, isHiddenRow, onShowColumn, onShowRow, tables, pivotTables, protectedRanges, sheetId, frozenRows, frozenColumns, selectedRowHeadersIds, selectedColumnHeadersIds, readonly = false, onAddQuickEdit, enableMagicFill, }) => {
|
|
16
|
+
export const ContextMenu = ({ isRowHeader, isColumnHeader, activeCell, selections, basicFilter, isTableHeader, onClearContents, onHideColumn, onHideRow, onGroupRows, onUngroupRows, onGroupColumns, onUngroupColumns, onDeleteRow, onDeleteColumn, onInsertColumn, onInsertRow, onInsertCellsShiftDown, onInsertCellsShiftRight, onDeleteCellsShiftLeft, onDeleteCellsShiftUp, onFreezeRow, onFreezeColumn, onCopy, onCut, onPaste, onRequestPasteSpecial, onRequestEvaluateFormula, onRequestAddWatch, isActiveCellFormula, onInsertNote, onProtectRange, onUnProtectRange, onSortRange, onSortColumn, onRequestDefineNamedRange, onRequestResize, onRequestEditTable, onRequestEditPivotTable, onRequestDeletePivotTable, onPivotDrillDown, onRequestFormatCells, onRequestConditionalFormat, onRequestDataValidation, onRemoveTable, onClearFormatting, onCreateTable, onCreateBasicFilter, onFilterTable, onSortTable, getFormattedValuesFromRange, focusSheet, isSheetFocused, getFormattedValue, onInsertTableColumn, onDeleteTableColumn, onInsertTableRow, onDeleteTableRow, onSplitTextToColumns, onRemoveDuplicates, onGoalSeek, onSubtotal, onAdvancedFilter, onChange, getCellData, isHiddenColumn, isHiddenRow, onShowColumn, onShowRow, tables, pivotTables, protectedRanges, sheetId, frozenRows, frozenColumns, selectedRowHeadersIds, selectedColumnHeadersIds, readonly = false, onAddQuickEdit, enableMagicFill, }) => {
|
|
13
17
|
const isHeader = isColumnHeader || isRowHeader;
|
|
14
18
|
const shouldFocusSheetRef = useRef(true);
|
|
15
19
|
const multiColumnTitle = generateMultiDimTitle(selectedColumnHeadersIds, "y");
|
|
@@ -39,6 +43,114 @@ export const ContextMenu = ({ isRowHeader, isColumnHeader, activeCell, selection
|
|
|
39
43
|
const lastSelectedRowIndex = selectedRowHeadersIds.reduce((m, v) => (v > m ? v : m), -Infinity);
|
|
40
44
|
// Get contentful range
|
|
41
45
|
const getContentfulRangeAroundCell = useGetContentfulRangeAroundCell();
|
|
46
|
+
// The data block the data tools act on: a table's own rows, the selection,
|
|
47
|
+
// or (from a lone cell) the contentful region around it — like Excel.
|
|
48
|
+
const dataRangeAroundSelection = useCallback(() => {
|
|
49
|
+
if (activeTable) {
|
|
50
|
+
return {
|
|
51
|
+
...activeTable.range,
|
|
52
|
+
endRowIndex: activeTable.range.endRowIndex - (activeTable.totalRow ? 1 : 0),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (selections.length) {
|
|
56
|
+
return selection.range;
|
|
57
|
+
}
|
|
58
|
+
return getContentfulRangeAroundCell?.(sheetId, activeCell) ?? selection.range;
|
|
59
|
+
}, [activeTable, selections.length, selection.range, getContentfulRangeAroundCell, sheetId, activeCell]);
|
|
60
|
+
// Excel pre-ticks "my data has headers" when the first row reads as labels:
|
|
61
|
+
// every cell filled and none of them a number.
|
|
62
|
+
const headerColumnsOf = useCallback((range) => {
|
|
63
|
+
const columns = [];
|
|
64
|
+
for (let columnIndex = range.startColumnIndex; columnIndex <= range.endColumnIndex; columnIndex++) {
|
|
65
|
+
const header = activeTable?.columns?.[columnIndex - activeTable.range.startColumnIndex]
|
|
66
|
+
?.name ?? getFormattedValue(sheetId, range.startRowIndex, columnIndex);
|
|
67
|
+
columns.push({
|
|
68
|
+
columnIndex,
|
|
69
|
+
label: `Column ${number2Alpha(columnIndex - 1)}`,
|
|
70
|
+
header: header || undefined,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
const hasHeader = activeTable
|
|
74
|
+
? (activeTable.headerRow ?? true)
|
|
75
|
+
: range.endRowIndex > range.startRowIndex &&
|
|
76
|
+
columns.every((column) => !!column.header && Number.isNaN(Number(column.header)));
|
|
77
|
+
return { columns, hasHeader };
|
|
78
|
+
}, [activeTable, getFormattedValue, sheetId]);
|
|
79
|
+
const rangeAddress = (range) => `${cellToAddress({ rowIndex: range.startRowIndex, columnIndex: range.startColumnIndex })}:${cellToAddress({ rowIndex: range.endRowIndex, columnIndex: range.endColumnIndex })}`;
|
|
80
|
+
// Text to Columns → Fixed width (dialog with a ruler over the selected column).
|
|
81
|
+
const isTextToColumnsDialogMounted = useIsTextToColumnsDialogMounted();
|
|
82
|
+
const openTextToColumnsDialog = useOpenTextToColumnsDialog();
|
|
83
|
+
const handleTextToColumnsDialog = useCallback(() => {
|
|
84
|
+
const range = selections.length ? selection.range : dataRangeAroundSelection();
|
|
85
|
+
const columnIndex = selections.length ? range.startColumnIndex : activeCell.columnIndex;
|
|
86
|
+
const preview = [];
|
|
87
|
+
const firstRow = selections.length ? range.startRowIndex : activeCell.rowIndex;
|
|
88
|
+
const lastRow = selections.length ? range.endRowIndex : range.endRowIndex;
|
|
89
|
+
for (let rowIndex = firstRow; rowIndex <= lastRow && preview.length < 8; rowIndex++) {
|
|
90
|
+
preview.push(getFormattedValue(sheetId, rowIndex, columnIndex) ?? "");
|
|
91
|
+
}
|
|
92
|
+
const target = selections.length
|
|
93
|
+
? selections
|
|
94
|
+
: [
|
|
95
|
+
{
|
|
96
|
+
range: {
|
|
97
|
+
startRowIndex: activeCell.rowIndex,
|
|
98
|
+
endRowIndex: range.endRowIndex,
|
|
99
|
+
startColumnIndex: columnIndex,
|
|
100
|
+
endColumnIndex: columnIndex,
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
];
|
|
104
|
+
openTextToColumnsDialog({
|
|
105
|
+
preview,
|
|
106
|
+
onApply: ({ delimiter, columnBreaks }) => onSplitTextToColumns?.(sheetId, activeCell, target, delimiter, { columnBreaks }),
|
|
107
|
+
});
|
|
108
|
+
}, [
|
|
109
|
+
selections,
|
|
110
|
+
selection.range,
|
|
111
|
+
dataRangeAroundSelection,
|
|
112
|
+
activeCell,
|
|
113
|
+
getFormattedValue,
|
|
114
|
+
sheetId,
|
|
115
|
+
openTextToColumnsDialog,
|
|
116
|
+
onSplitTextToColumns,
|
|
117
|
+
]);
|
|
118
|
+
// Data → Subtotal.
|
|
119
|
+
const isSubtotalDialogMounted = useIsSubtotalDialogMounted();
|
|
120
|
+
const openSubtotalDialog = useOpenSubtotalDialog();
|
|
121
|
+
const handleSubtotal = useCallback(() => {
|
|
122
|
+
const range = dataRangeAroundSelection();
|
|
123
|
+
const { columns, hasHeader } = headerColumnsOf(range);
|
|
124
|
+
openSubtotalDialog({
|
|
125
|
+
columns,
|
|
126
|
+
hasHeader,
|
|
127
|
+
onApply: (choices) => onSubtotal?.(sheetId, { range, ...choices }),
|
|
128
|
+
});
|
|
129
|
+
}, [dataRangeAroundSelection, headerColumnsOf, openSubtotalDialog, onSubtotal, sheetId]);
|
|
130
|
+
// Data → Advanced filter.
|
|
131
|
+
const isAdvancedFilterDialogMounted = useIsAdvancedFilterDialogMounted();
|
|
132
|
+
const openAdvancedFilterDialog = useOpenAdvancedFilterDialog();
|
|
133
|
+
const handleAdvancedFilter = useCallback(() => {
|
|
134
|
+
openAdvancedFilterDialog({
|
|
135
|
+
listRange: rangeAddress(dataRangeAroundSelection()),
|
|
136
|
+
onApply: (options) => onAdvancedFilter?.(sheetId, options),
|
|
137
|
+
});
|
|
138
|
+
}, [openAdvancedFilterDialog, dataRangeAroundSelection, onAdvancedFilter, sheetId]);
|
|
139
|
+
// Data → What-If Analysis → Goal Seek.
|
|
140
|
+
const isGoalSeekDialogMounted = useIsGoalSeekDialogMounted();
|
|
141
|
+
const openGoalSeekDialog = useOpenGoalSeekDialog();
|
|
142
|
+
const handleGoalSeek = useCallback(() => {
|
|
143
|
+
openGoalSeekDialog({
|
|
144
|
+
setCell: cellToAddress(activeCell) ?? "",
|
|
145
|
+
onApply: async (setCellAddress, targetValue, changingCellAddress) => {
|
|
146
|
+
const setCell = addressToCell(setCellAddress);
|
|
147
|
+
const changingCell = addressToCell(changingCellAddress);
|
|
148
|
+
if (!setCell || !changingCell || !onGoalSeek)
|
|
149
|
+
return undefined;
|
|
150
|
+
return onGoalSeek(sheetId, setCell, targetValue, changingCell);
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
}, [openGoalSeekDialog, activeCell, onGoalSeek, sheetId]);
|
|
42
154
|
// Remove duplicates — Excel's dialog (column checklist + "my data has
|
|
43
155
|
// headers") when a host mounts `RemoveDuplicatesDialogHost`, otherwise the
|
|
44
156
|
// one-click de-dupe over the selection.
|
|
@@ -654,7 +766,14 @@ export const ContextMenu = ({ isRowHeader, isColumnHeader, activeCell, selection
|
|
|
654
766
|
} },
|
|
655
767
|
React.createElement(DropdownLeftSlot, null,
|
|
656
768
|
React.createElement(CodeIcon, null)),
|
|
657
|
-
"Evaluate formula")) : null
|
|
769
|
+
"Evaluate formula")) : null,
|
|
770
|
+
onRequestAddWatch ? (React.createElement(DropdownMenuItem, { onClick: () => {
|
|
771
|
+
shouldFocusSheetRef.current = false;
|
|
772
|
+
onRequestAddWatch(sheetId, activeCell);
|
|
773
|
+
} },
|
|
774
|
+
React.createElement(DropdownLeftSlot, null,
|
|
775
|
+
React.createElement(EyeOpenIcon, null)),
|
|
776
|
+
"Add to Watch Window")) : null)),
|
|
658
777
|
React.createElement(DropdownMenuSeparator, null),
|
|
659
778
|
React.createElement(DropdownMenuItem, { onClick: handleRemoveDuplicates, disabled: readonly },
|
|
660
779
|
React.createElement(DropdownLeftSlot, null,
|
|
@@ -672,7 +791,23 @@ export const ContextMenu = ({ isRowHeader, isColumnHeader, activeCell, selection
|
|
|
672
791
|
React.createElement(DropdownMenuItem, { onClick: () => onSplitTextToColumns?.(sheetId, activeCell, selections, ";") }, "Semicolon"),
|
|
673
792
|
React.createElement(DropdownMenuItem, { onClick: () => onSplitTextToColumns?.(sheetId, activeCell, selections, ".") }, "Period"),
|
|
674
793
|
React.createElement(DropdownMenuItem, { onClick: () => onSplitTextToColumns?.(sheetId, activeCell, selections, " ") }, "Space"),
|
|
675
|
-
React.createElement(DropdownMenuItem, { onClick: () => onSplitTextToColumns?.(sheetId, activeCell, selections, "|") }, "Pipe")
|
|
794
|
+
React.createElement(DropdownMenuItem, { onClick: () => onSplitTextToColumns?.(sheetId, activeCell, selections, "|") }, "Pipe"),
|
|
795
|
+
isTextToColumnsDialogMounted ? (React.createElement(React.Fragment, null,
|
|
796
|
+
React.createElement(DropdownMenuSeparator, null),
|
|
797
|
+
React.createElement(DropdownMenuItem, { onClick: handleTextToColumnsDialog }, "Fixed width\u2026"))) : null)),
|
|
798
|
+
(isSubtotalDialogMounted && onSubtotal) ||
|
|
799
|
+
(isAdvancedFilterDialogMounted && onAdvancedFilter) ||
|
|
800
|
+
(isGoalSeekDialogMounted && onGoalSeek) ? (React.createElement(DropdownMenuSub, null,
|
|
801
|
+
React.createElement(DropdownMenuSubTrigger, { disabled: readonly },
|
|
802
|
+
React.createElement(DropdownLeftSlot, null,
|
|
803
|
+
React.createElement(SpaceBetweenHorizontallyIcon, null)),
|
|
804
|
+
"Data tools",
|
|
805
|
+
React.createElement(DropdownRightSlot, null,
|
|
806
|
+
React.createElement(ChevronRightIcon, null))),
|
|
807
|
+
React.createElement(DropdownMenuSubContent, { sideOffset: 2, alignOffset: -5 },
|
|
808
|
+
isSubtotalDialogMounted && onSubtotal ? (React.createElement(DropdownMenuItem, { onClick: handleSubtotal }, "Subtotal\u2026")) : null,
|
|
809
|
+
isAdvancedFilterDialogMounted && onAdvancedFilter ? (React.createElement(DropdownMenuItem, { onClick: handleAdvancedFilter }, "Advanced filter\u2026")) : null,
|
|
810
|
+
isGoalSeekDialogMounted && onGoalSeek ? (React.createElement(DropdownMenuItem, { onClick: handleGoalSeek }, "Goal seek\u2026")) : null))) : null,
|
|
676
811
|
React.createElement(DropdownMenuSub, null,
|
|
677
812
|
React.createElement(DropdownMenuSubTrigger, { disabled: readonly },
|
|
678
813
|
React.createElement(DropdownLeftSlot, null,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"embed-component.d.ts","sourceRoot":"","sources":["../../../../components/embeds/embed-component.tsx"],"names":[],"mappings":"AASA,OAAO,KAAe,MAAM,OAAO,CAAC;AAEpC,OAAO,KAAK,EACV,cAAc,
|
|
1
|
+
{"version":3,"file":"embed-component.d.ts","sourceRoot":"","sources":["../../../../components/embeds/embed-component.tsx"],"names":[],"mappings":"AASA,OAAO,KAAe,MAAM,OAAO,CAAC;AAEpC,OAAO,KAAK,EACV,cAAc,EAKf,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAKhF,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,cAAc,CAAC;IACtB,KAAK,EAAE,gBAAgB,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;IAChD,kBAAkB,EAAE,eAAe,CAAC,oBAAoB,CAAC,CAAC;CAC3D,CAAC;AAEF,eAAO,MAAM,cAAc,wHAUtB,mBAAmB,uBA4NvB,CAAC"}
|
|
@@ -2,6 +2,7 @@ import { DotsVerticalIcon } from "@rowsncolumns/icons";
|
|
|
2
2
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuPortal, DropdownMenuTrigger, IconButton, } from "@rowsncolumns/ui";
|
|
3
3
|
import React, { memo } from "react";
|
|
4
4
|
import { getStringifiedColor } from "../../themes";
|
|
5
|
+
import { resolveCanvasTextAlign } from "../cell/alignment";
|
|
5
6
|
import { ShapeSvg } from "./shape-svg";
|
|
6
7
|
export const EmbedComponent = memo(({ embed, width, height, readonly, isSelected, onDeleteEmbed, onRequestEditEmbed, theme, }) => {
|
|
7
8
|
const renderTextBox = (spec) => {
|
|
@@ -39,7 +40,9 @@ export const EmbedComponent = memo(({ embed, width, height, readonly, isSelected
|
|
|
39
40
|
height: "100%",
|
|
40
41
|
backgroundColor,
|
|
41
42
|
padding: spec.padding ? `${spec.padding}px` : "4px",
|
|
42
|
-
textAlign: spec.horizontalAlignment
|
|
43
|
+
textAlign: spec.horizontalAlignment
|
|
44
|
+
? resolveCanvasTextAlign(spec.horizontalAlignment)
|
|
45
|
+
: undefined,
|
|
43
46
|
display: "flex",
|
|
44
47
|
flexDirection: "column",
|
|
45
48
|
justifyContent: spec.verticalAlignment === "top"
|
|
@@ -110,6 +113,19 @@ export const EmbedComponent = memo(({ embed, width, height, readonly, isSelected
|
|
|
110
113
|
type: "textbox",
|
|
111
114
|
...embed.spec.textBody,
|
|
112
115
|
}))) : null)) : null,
|
|
116
|
+
embed?.spec.type === "formControl" ? (
|
|
117
|
+
// Excel form controls round-trip but are not interactive here: draw
|
|
118
|
+
// the caption in a control-shaped placeholder so the layout reads.
|
|
119
|
+
React.createElement("div", { className: "flex h-full w-full items-center gap-1 overflow-hidden whitespace-nowrap px-1 text-xs", title: embed.spec.name ?? undefined },
|
|
120
|
+
embed.spec.objectType === "CheckBox" ||
|
|
121
|
+
embed.spec.objectType === "Radio" ? (React.createElement("span", { className: "inline-block h-3 w-3 shrink-0 border border-current", style: {
|
|
122
|
+
borderRadius: embed.spec.objectType === "Radio"
|
|
123
|
+
? "50%"
|
|
124
|
+
: 2,
|
|
125
|
+
} })) : null,
|
|
126
|
+
React.createElement("span", { className: "truncate" }, embed.spec.text ??
|
|
127
|
+
embed.spec.name ??
|
|
128
|
+
embed.spec.objectType))) : null,
|
|
113
129
|
readonly || !isSelected ? null : (React.createElement(DropdownMenu, null,
|
|
114
130
|
React.createElement(DropdownMenuTrigger, { asChild: true, className: "print:hidden" },
|
|
115
131
|
React.createElement(IconButton, { className: "absolute right-1 top-1 z-10" },
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { FillSeriesSpec } from "../../types";
|
|
3
|
+
export type FillSeriesDialogProps = {
|
|
4
|
+
/** Controls visibility. */
|
|
5
|
+
open: boolean;
|
|
6
|
+
onOpenChange(open: boolean): void;
|
|
7
|
+
/** Pre-selected axis (a right-drag seeds it from its direction). */
|
|
8
|
+
initialIn?: FillSeriesSpec["in"];
|
|
9
|
+
onApply(spec: FillSeriesSpec): void;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Excel's Series dialog (Home > Fill > Series…). Series in Rows/Columns, Type
|
|
13
|
+
* Linear/Growth/Date/AutoFill, Date unit (Type = Date only), Trend
|
|
14
|
+
* (Linear/Growth only — disables Step/Stop), Step value (default 1, may be
|
|
15
|
+
* negative or fractional) and Stop value. UI-only: the opener turns the spec
|
|
16
|
+
* into a fill.
|
|
17
|
+
*/
|
|
18
|
+
export declare const FillSeriesDialog: React.MemoExoticComponent<({ open, onOpenChange, initialIn, onApply }: FillSeriesDialogProps) => React.JSX.Element>;
|
|
19
|
+
/**
|
|
20
|
+
* Host-mounted, atom-driven wrapper around {@link FillSeriesDialog}. Mount it
|
|
21
|
+
* once alongside the other editor dialogs; the grid opens it via
|
|
22
|
+
* `useOpenFillSeriesDialog` (right-drag menu "Series…", or
|
|
23
|
+
* `SpreadsheetApi.openFillSeriesDialog()` from a Fill toolbar/menu).
|
|
24
|
+
*/
|
|
25
|
+
export declare const FillSeriesDialogHost: {
|
|
26
|
+
(): React.JSX.Element;
|
|
27
|
+
displayName: string;
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/fill-series-dialog/index.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAGtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,qBAAqB,GAAG;IAClC,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,oEAAoE;IACpE,SAAS,CAAC,EAAE,cAAc,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;CACrC,CAAC;AA0BF;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB,yEACkB,qBAAqB,uBA4MnE,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB;;;CAahC,CAAC"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { Button, Dialog, DialogBody, DialogCloseButton, DialogContent, DialogTitle, Input, Separator, } from "@rowsncolumns/ui";
|
|
2
|
+
import React, { memo, useCallback, useEffect, useState } from "react";
|
|
3
|
+
import { useFillSeriesDialogState } from "../../atoms/fill-series-dialog.atom";
|
|
4
|
+
const SERIES_TYPES = [
|
|
5
|
+
{ value: "linear", label: "Linear" },
|
|
6
|
+
{ value: "growth", label: "Growth" },
|
|
7
|
+
{ value: "date", label: "Date" },
|
|
8
|
+
{ value: "autofill", label: "AutoFill" },
|
|
9
|
+
];
|
|
10
|
+
const DATE_UNITS = [
|
|
11
|
+
{ value: "day", label: "Day" },
|
|
12
|
+
{ value: "weekday", label: "Weekday" },
|
|
13
|
+
{ value: "month", label: "Month" },
|
|
14
|
+
{ value: "year", label: "Year" },
|
|
15
|
+
];
|
|
16
|
+
const parseNumber = (text) => {
|
|
17
|
+
const trimmed = text.trim();
|
|
18
|
+
if (!trimmed)
|
|
19
|
+
return undefined;
|
|
20
|
+
const n = Number(trimmed);
|
|
21
|
+
return Number.isFinite(n) ? n : undefined;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Excel's Series dialog (Home > Fill > Series…). Series in Rows/Columns, Type
|
|
25
|
+
* Linear/Growth/Date/AutoFill, Date unit (Type = Date only), Trend
|
|
26
|
+
* (Linear/Growth only — disables Step/Stop), Step value (default 1, may be
|
|
27
|
+
* negative or fractional) and Stop value. UI-only: the opener turns the spec
|
|
28
|
+
* into a fill.
|
|
29
|
+
*/
|
|
30
|
+
export const FillSeriesDialog = memo(({ open, onOpenChange, initialIn, onApply }) => {
|
|
31
|
+
const [axis, setAxis] = useState(initialIn ?? "columns");
|
|
32
|
+
const [type, setType] = useState("linear");
|
|
33
|
+
const [dateUnit, setDateUnit] = useState("day");
|
|
34
|
+
const [trend, setTrend] = useState(false);
|
|
35
|
+
const [step, setStep] = useState("1");
|
|
36
|
+
const [stop, setStop] = useState("");
|
|
37
|
+
const [error, setError] = useState(undefined);
|
|
38
|
+
// Re-seed on every open (the request decides the default axis).
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (open) {
|
|
41
|
+
setAxis(initialIn ?? "columns");
|
|
42
|
+
setType("linear");
|
|
43
|
+
setDateUnit("day");
|
|
44
|
+
setTrend(false);
|
|
45
|
+
setStep("1");
|
|
46
|
+
setStop("");
|
|
47
|
+
setError(undefined);
|
|
48
|
+
}
|
|
49
|
+
}, [open, initialIn]);
|
|
50
|
+
const trendAllowed = type === "linear" || type === "growth";
|
|
51
|
+
const stepStopDisabled = trendAllowed && trend;
|
|
52
|
+
const apply = useCallback(() => {
|
|
53
|
+
const stepValue = parseNumber(step);
|
|
54
|
+
if (!stepStopDisabled && step.trim() && stepValue === undefined) {
|
|
55
|
+
setError("Step value must be a number.");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const stopValue = parseNumber(stop);
|
|
59
|
+
if (!stepStopDisabled && stop.trim() && stopValue === undefined) {
|
|
60
|
+
setError("Stop value must be a number.");
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const spec = {
|
|
64
|
+
in: axis,
|
|
65
|
+
type,
|
|
66
|
+
...(type === "date" ? { dateUnit } : {}),
|
|
67
|
+
...(trendAllowed && trend ? { trend: true } : {}),
|
|
68
|
+
...(!stepStopDisabled && stepValue !== undefined
|
|
69
|
+
? { step: stepValue }
|
|
70
|
+
: {}),
|
|
71
|
+
...(!stepStopDisabled && stopValue !== undefined
|
|
72
|
+
? { stop: stopValue }
|
|
73
|
+
: {}),
|
|
74
|
+
};
|
|
75
|
+
onApply(spec);
|
|
76
|
+
onOpenChange(false);
|
|
77
|
+
}, [
|
|
78
|
+
axis,
|
|
79
|
+
type,
|
|
80
|
+
dateUnit,
|
|
81
|
+
trend,
|
|
82
|
+
trendAllowed,
|
|
83
|
+
step,
|
|
84
|
+
stop,
|
|
85
|
+
stepStopDisabled,
|
|
86
|
+
onApply,
|
|
87
|
+
onOpenChange,
|
|
88
|
+
]);
|
|
89
|
+
return (React.createElement(Dialog, { open: open, onOpenChange: onOpenChange, modal: true },
|
|
90
|
+
React.createElement(DialogContent, { className: "w-[420px] max-w-[92vw] pointer-events-auto" },
|
|
91
|
+
React.createElement(DialogTitle, null, "Series"),
|
|
92
|
+
React.createElement(DialogCloseButton, null),
|
|
93
|
+
React.createElement(DialogBody, { className: "flex flex-col gap-3" },
|
|
94
|
+
React.createElement("form", { className: "flex flex-col gap-3", onSubmit: (e) => {
|
|
95
|
+
e.preventDefault();
|
|
96
|
+
apply();
|
|
97
|
+
} },
|
|
98
|
+
React.createElement("div", { className: "grid grid-cols-3 gap-3" },
|
|
99
|
+
React.createElement("fieldset", { className: "flex flex-col gap-1 border-0 p-0 m-0" },
|
|
100
|
+
React.createElement("legend", { className: "text-xs font-medium pb-1" }, "Series in"),
|
|
101
|
+
["rows", "columns"].map((value) => (React.createElement("label", { key: value, className: "flex items-center gap-2 text-xs cursor-pointer" },
|
|
102
|
+
React.createElement("input", { type: "radio", name: "fillSeriesIn", value: value, checked: axis === value, onChange: () => setAxis(value) }),
|
|
103
|
+
value === "rows" ? "Rows" : "Columns")))),
|
|
104
|
+
React.createElement("fieldset", { className: "flex flex-col gap-1 border-0 p-0 m-0" },
|
|
105
|
+
React.createElement("legend", { className: "text-xs font-medium pb-1" }, "Type"),
|
|
106
|
+
SERIES_TYPES.map(({ value, label }) => (React.createElement("label", { key: value, className: "flex items-center gap-2 text-xs cursor-pointer" },
|
|
107
|
+
React.createElement("input", { type: "radio", name: "fillSeriesType", value: value, checked: type === value, onChange: () => setType(value) }),
|
|
108
|
+
label)))),
|
|
109
|
+
React.createElement("fieldset", { className: "flex flex-col gap-1 border-0 p-0 m-0", disabled: type !== "date" },
|
|
110
|
+
React.createElement("legend", { className: "text-xs font-medium pb-1" }, "Date unit"),
|
|
111
|
+
DATE_UNITS.map(({ value, label }) => (React.createElement("label", { key: value, className: "flex items-center gap-2 text-xs cursor-pointer disabled:opacity-50" },
|
|
112
|
+
React.createElement("input", { type: "radio", name: "fillSeriesDateUnit", value: value, checked: dateUnit === value, onChange: () => setDateUnit(value), disabled: type !== "date" }),
|
|
113
|
+
React.createElement("span", { className: type !== "date" ? "opacity-50" : "" }, label)))))),
|
|
114
|
+
React.createElement("label", { className: "flex items-center gap-2 text-xs cursor-pointer" },
|
|
115
|
+
React.createElement("input", { type: "checkbox", name: "fillSeriesTrend", checked: trendAllowed && trend, disabled: !trendAllowed, onChange: (e) => setTrend(e.target.checked) }),
|
|
116
|
+
React.createElement("span", { className: !trendAllowed ? "opacity-50" : "" }, "Trend")),
|
|
117
|
+
React.createElement("div", { className: "grid grid-cols-2 gap-3" },
|
|
118
|
+
React.createElement("label", { className: "flex flex-col gap-1 text-xs" },
|
|
119
|
+
"Step value",
|
|
120
|
+
React.createElement(Input, { name: "fillSeriesStep", value: step, disabled: stepStopDisabled, onChange: (e) => {
|
|
121
|
+
setStep(e.target.value);
|
|
122
|
+
setError(undefined);
|
|
123
|
+
}, inputMode: "decimal" })),
|
|
124
|
+
React.createElement("label", { className: "flex flex-col gap-1 text-xs" },
|
|
125
|
+
"Stop value",
|
|
126
|
+
React.createElement(Input, { name: "fillSeriesStop", value: stop, disabled: stepStopDisabled, onChange: (e) => {
|
|
127
|
+
setStop(e.target.value);
|
|
128
|
+
setError(undefined);
|
|
129
|
+
}, inputMode: "decimal" }))),
|
|
130
|
+
error ? (React.createElement("div", { role: "alert", className: "text-xs text-rnc-destructive" }, error)) : null,
|
|
131
|
+
React.createElement(Separator, null),
|
|
132
|
+
React.createElement("div", { className: "flex justify-end gap-2" },
|
|
133
|
+
React.createElement(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => onOpenChange(false) }, "Cancel"),
|
|
134
|
+
React.createElement(Button, { type: "submit", size: "sm" }, "OK")))))));
|
|
135
|
+
});
|
|
136
|
+
FillSeriesDialog.displayName = "FillSeriesDialog";
|
|
137
|
+
/**
|
|
138
|
+
* Host-mounted, atom-driven wrapper around {@link FillSeriesDialog}. Mount it
|
|
139
|
+
* once alongside the other editor dialogs; the grid opens it via
|
|
140
|
+
* `useOpenFillSeriesDialog` (right-drag menu "Series…", or
|
|
141
|
+
* `SpreadsheetApi.openFillSeriesDialog()` from a Fill toolbar/menu).
|
|
142
|
+
*/
|
|
143
|
+
export const FillSeriesDialogHost = () => {
|
|
144
|
+
const [request, setRequest] = useFillSeriesDialogState();
|
|
145
|
+
const close = useCallback(() => setRequest(null), [setRequest]);
|
|
146
|
+
return (React.createElement(FillSeriesDialog, { open: request != null, onOpenChange: (open) => {
|
|
147
|
+
if (!open)
|
|
148
|
+
close();
|
|
149
|
+
}, initialIn: request?.initialIn, onApply: (spec) => request?.onApply(spec) }));
|
|
150
|
+
};
|
|
151
|
+
FillSeriesDialogHost.displayName = "FillSeriesDialogHost";
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { GridRange } from "@rowsncolumns/grid";
|
|
1
2
|
import React from "react";
|
|
3
|
+
import { type GoToSpecialKind } from "../../api/go-to-special";
|
|
2
4
|
import type { NamedRange, SheetRange } from "../../types";
|
|
3
5
|
export type GoToDialogProps = {
|
|
4
6
|
/** Controls visibility. */
|
|
@@ -15,6 +17,14 @@ export type GoToDialogProps = {
|
|
|
15
17
|
resolve(reference: string): SheetRange | undefined;
|
|
16
18
|
/** Receives the resolved range; the host selects and scrolls to it. */
|
|
17
19
|
onNavigate(range: SheetRange): void;
|
|
20
|
+
/**
|
|
21
|
+
* Go To Special. `resolve` returns the matching cell runs for a category;
|
|
22
|
+
* `onSelectRanges` receives them. Omit to hide the "Special…" panel.
|
|
23
|
+
*/
|
|
24
|
+
special?: {
|
|
25
|
+
resolve(kind: GoToSpecialKind): GridRange[];
|
|
26
|
+
onSelectRanges(ranges: GridRange[]): void;
|
|
27
|
+
};
|
|
18
28
|
};
|
|
19
29
|
/**
|
|
20
30
|
* Excel's Go To dialog (`Ctrl+G` / `F5`): type a cell or range reference,
|
|
@@ -22,7 +32,7 @@ export type GoToDialogProps = {
|
|
|
22
32
|
* jumps there. Resolution is delegated to `resolve` so the dialog stays
|
|
23
33
|
* UI-only.
|
|
24
34
|
*/
|
|
25
|
-
export declare const GoToDialog: React.MemoExoticComponent<({ open, onOpenChange, namedRanges, currentAddress, resolve, onNavigate, }: GoToDialogProps) => React.JSX.Element>;
|
|
35
|
+
export declare const GoToDialog: React.MemoExoticComponent<({ open, onOpenChange, namedRanges, currentAddress, resolve, onNavigate, special, }: GoToDialogProps) => React.JSX.Element>;
|
|
26
36
|
/**
|
|
27
37
|
* Host-mounted, atom-driven wrapper around {@link GoToDialog}. Mount it once
|
|
28
38
|
* in the host alongside the other editor dialogs; the grid opens it on
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/go-to-dialog/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/go-to-dialog/index.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,KAAsC,MAAM,OAAO,CAAC;AAG3D,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAMjC,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE1D,MAAM,MAAM,eAAe,GAAG;IAC5B,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,gFAAgF;IAChF,WAAW,CAAC,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;IAClC,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IACnD,uEAAuE;IACvE,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,IAAI,EAAE,eAAe,GAAG,SAAS,EAAE,CAAC;QAC5C,cAAc,CAAC,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;KAC3C,CAAC;CACH,CAAC;AAKF;;;;;GAKG;AACH,eAAO,MAAM,UAAU,iHASlB,eAAe,uBA0MnB,CAAC;AAUF;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;CA+B1B,CAAC"}
|
|
@@ -2,17 +2,32 @@ import { Button, cn, Dialog, DialogBody, DialogCloseButton, DialogContent, Dialo
|
|
|
2
2
|
import { cellToAddress } from "@rowsncolumns/utils";
|
|
3
3
|
import React, { memo, useCallback, useState } from "react";
|
|
4
4
|
import { resolveGoToReference } from "../../api/go-to";
|
|
5
|
+
import { GO_TO_SPECIAL_OPTIONS, } from "../../api/go-to-special";
|
|
5
6
|
import { useGoToDialogState, useRegisterGoToDialogHost, } from "../../atoms/go-to-dialog.atom";
|
|
6
7
|
const INVALID_REFERENCE = "Reference is not valid.";
|
|
8
|
+
const NO_CELLS_FOUND = "No cells were found.";
|
|
7
9
|
/**
|
|
8
10
|
* Excel's Go To dialog (`Ctrl+G` / `F5`): type a cell or range reference,
|
|
9
11
|
* optionally sheet-qualified, or pick a defined name, and the selection
|
|
10
12
|
* jumps there. Resolution is delegated to `resolve` so the dialog stays
|
|
11
13
|
* UI-only.
|
|
12
14
|
*/
|
|
13
|
-
export const GoToDialog = memo(({ open, onOpenChange, namedRanges, currentAddress, resolve, onNavigate, }) => {
|
|
15
|
+
export const GoToDialog = memo(({ open, onOpenChange, namedRanges, currentAddress, resolve, onNavigate, special, }) => {
|
|
14
16
|
const [reference, setReference] = useState("");
|
|
15
17
|
const [error, setError] = useState(undefined);
|
|
18
|
+
const [showSpecial, setShowSpecial] = useState(false);
|
|
19
|
+
const [specialKind, setSpecialKind] = useState("blanks");
|
|
20
|
+
const selectSpecial = useCallback(() => {
|
|
21
|
+
if (!special)
|
|
22
|
+
return;
|
|
23
|
+
const ranges = special.resolve(specialKind);
|
|
24
|
+
if (!ranges.length) {
|
|
25
|
+
setError(NO_CELLS_FOUND);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
special.onSelectRanges(ranges);
|
|
29
|
+
onOpenChange(false);
|
|
30
|
+
}, [special, specialKind, onOpenChange]);
|
|
16
31
|
const navigate = useCallback((text) => {
|
|
17
32
|
const range = resolve(text);
|
|
18
33
|
if (!range) {
|
|
@@ -25,30 +40,55 @@ export const GoToDialog = memo(({ open, onOpenChange, namedRanges, currentAddres
|
|
|
25
40
|
const names = (namedRanges ?? []).filter((range) => range.range && !range.hidden);
|
|
26
41
|
return (React.createElement(Dialog, { open: open, onOpenChange: onOpenChange, modal: true },
|
|
27
42
|
React.createElement(DialogContent, { className: "w-[360px] max-w-[92vw] pointer-events-auto" },
|
|
28
|
-
React.createElement(DialogTitle, null, "Go To"),
|
|
43
|
+
React.createElement(DialogTitle, null, showSpecial ? "Go To Special" : "Go To"),
|
|
29
44
|
React.createElement(DialogCloseButton, null),
|
|
30
|
-
React.createElement(DialogBody, { className: "flex flex-col gap-3" },
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
React.createElement("
|
|
36
|
-
|
|
37
|
-
React.createElement("
|
|
38
|
-
|
|
39
|
-
setError(undefined);
|
|
40
|
-
}, onDoubleClick: () => navigate(range.name) }, range.name)))))),
|
|
41
|
-
React.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
|
|
42
|
-
"Reference:",
|
|
43
|
-
React.createElement(Input, { autoFocus: true, value: reference, placeholder: currentAddress, "aria-invalid": error ? true : undefined, onChange: (e) => {
|
|
44
|
-
setReference(e.target.value);
|
|
45
|
+
React.createElement(DialogBody, { className: "flex flex-col gap-3" }, showSpecial && special ? (React.createElement("form", { className: "flex flex-col gap-3", onSubmit: (e) => {
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
selectSpecial();
|
|
48
|
+
} },
|
|
49
|
+
React.createElement("fieldset", { className: "flex flex-col gap-1 border-0 p-0 m-0" },
|
|
50
|
+
React.createElement("legend", { className: "text-xs font-medium pb-1" }, "Select"),
|
|
51
|
+
GO_TO_SPECIAL_OPTIONS.map(({ kind, label }) => (React.createElement("label", { key: kind, className: "flex items-center gap-2 text-xs cursor-pointer" },
|
|
52
|
+
React.createElement("input", { type: "radio", name: "goToSpecial", value: kind, checked: specialKind === kind, onChange: () => {
|
|
53
|
+
setSpecialKind(kind);
|
|
45
54
|
setError(undefined);
|
|
46
|
-
} })
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
55
|
+
} }),
|
|
56
|
+
label)))),
|
|
57
|
+
error ? (React.createElement("div", { role: "alert", className: "text-xs text-rnc-destructive" }, error)) : null,
|
|
58
|
+
React.createElement(Separator, null),
|
|
59
|
+
React.createElement("div", { className: "flex justify-between gap-2" },
|
|
60
|
+
React.createElement(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => {
|
|
61
|
+
setShowSpecial(false);
|
|
62
|
+
setError(undefined);
|
|
63
|
+
} }, "Back"),
|
|
64
|
+
React.createElement("div", { className: "flex gap-2" },
|
|
65
|
+
React.createElement(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onOpenChange(false) }, "Cancel"),
|
|
66
|
+
React.createElement(Button, { type: "submit", size: "sm" }, "OK"))))) : (React.createElement("form", { className: "flex flex-col gap-3", onSubmit: (e) => {
|
|
67
|
+
e.preventDefault();
|
|
68
|
+
navigate(reference);
|
|
69
|
+
} },
|
|
70
|
+
React.createElement("div", { className: "flex flex-col gap-1" },
|
|
71
|
+
React.createElement("span", { className: "text-xs font-medium" }, "Go to:"),
|
|
72
|
+
React.createElement("div", { role: "listbox", "aria-label": "Defined names", className: "h-[140px] overflow-auto rounded border border-rnc-border text-xs" }, names.length === 0 ? (React.createElement("div", { className: "px-2 py-1.5 text-rnc-foreground/60" }, "No defined names")) : (names.map((range) => (React.createElement("div", { key: String(range.namedRangeId), role: "option", "aria-selected": reference === range.name, className: cn("px-2 py-1 cursor-default select-none hover:bg-rnc-accent", reference === range.name && "bg-rnc-accent"), onClick: () => {
|
|
73
|
+
setReference(range.name);
|
|
74
|
+
setError(undefined);
|
|
75
|
+
}, onDoubleClick: () => navigate(range.name) }, range.name)))))),
|
|
76
|
+
React.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
|
|
77
|
+
"Reference:",
|
|
78
|
+
React.createElement(Input, { autoFocus: true, value: reference, placeholder: currentAddress, "aria-invalid": error ? true : undefined, onChange: (e) => {
|
|
79
|
+
setReference(e.target.value);
|
|
80
|
+
setError(undefined);
|
|
81
|
+
} })),
|
|
82
|
+
error ? (React.createElement("div", { role: "alert", className: "text-xs text-rnc-destructive" }, error)) : null,
|
|
83
|
+
React.createElement(Separator, null),
|
|
84
|
+
React.createElement("div", { className: "flex justify-between gap-2" },
|
|
85
|
+
special ? (React.createElement(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => {
|
|
86
|
+
setShowSpecial(true);
|
|
87
|
+
setError(undefined);
|
|
88
|
+
} }, "Special\u2026")) : (React.createElement("span", null)),
|
|
89
|
+
React.createElement("div", { className: "flex gap-2" },
|
|
50
90
|
React.createElement(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onOpenChange(false) }, "Cancel"),
|
|
51
|
-
React.createElement(Button, { type: "submit", size: "sm", disabled: !reference.trim() }, "OK")))))));
|
|
91
|
+
React.createElement(Button, { type: "submit", size: "sm", disabled: !reference.trim() }, "OK")))))))));
|
|
52
92
|
});
|
|
53
93
|
GoToDialog.displayName = "GoToDialog";
|
|
54
94
|
const currentAddressOf = (request) => {
|
|
@@ -79,6 +119,6 @@ export const GoToDialogHost = () => {
|
|
|
79
119
|
return (React.createElement(GoToDialog, { open: true, onOpenChange: (open) => {
|
|
80
120
|
if (!open)
|
|
81
121
|
close();
|
|
82
|
-
}, namedRanges: request.namedRanges, currentAddress: currentAddressOf(request), resolve: resolve, onNavigate: request.onNavigate }));
|
|
122
|
+
}, namedRanges: request.namedRanges, currentAddress: currentAddressOf(request), resolve: resolve, onNavigate: request.onNavigate, special: request.special }));
|
|
83
123
|
};
|
|
84
124
|
GoToDialogHost.displayName = "GoToDialogHost";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { GoalSeekResult } from "../../types";
|
|
3
|
+
export type GoalSeekDialogProps = {
|
|
4
|
+
/** Controls visibility. */
|
|
5
|
+
open: boolean;
|
|
6
|
+
onOpenChange(open: boolean): void;
|
|
7
|
+
/** Default "Set cell" (A1 reference of the active cell). */
|
|
8
|
+
initialSetCell: string;
|
|
9
|
+
/**
|
|
10
|
+
* Runs the search with the three fields (A1 references + the numeric
|
|
11
|
+
* target). Resolves to the result, or `undefined` when the engine reports
|
|
12
|
+
* none (the rnc engine iterates natively and streams the cells back).
|
|
13
|
+
*/
|
|
14
|
+
onApply(setCell: string, targetValue: number, changingCell: string): Promise<GoalSeekResult | undefined>;
|
|
15
|
+
};
|
|
16
|
+
/** Excel's status sentence for a finished search. */
|
|
17
|
+
export declare const goalSeekStatusText: (setCell: string, result: GoalSeekResult | undefined) => string;
|
|
18
|
+
/**
|
|
19
|
+
* Excel's Goal Seek dialog: Set cell / To value / By changing cell, then the
|
|
20
|
+
* Goal Seek Status sentence with target and current value.
|
|
21
|
+
*/
|
|
22
|
+
export declare const GoalSeekDialog: React.MemoExoticComponent<({ open, onOpenChange, initialSetCell, onApply }: GoalSeekDialogProps) => React.JSX.Element>;
|
|
23
|
+
/**
|
|
24
|
+
* Host-mounted, atom-driven wrapper around {@link GoalSeekDialog}. Mount
|
|
25
|
+
* once in the host; the context menu opens it via `useOpenGoalSeekDialog`
|
|
26
|
+
* and only offers the item while a host is mounted.
|
|
27
|
+
*/
|
|
28
|
+
export declare const GoalSeekDialogHost: {
|
|
29
|
+
(): React.JSX.Element;
|
|
30
|
+
displayName: string;
|
|
31
|
+
};
|
|
32
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/goal-seek-dialog/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAMtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,MAAM,MAAM,mBAAmB,GAAG;IAChC,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,4DAA4D;IAC5D,cAAc,EAAE,MAAM,CAAC;IACvB;;;;OAIG;IACH,OAAO,CACL,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;CACxC,CAAC;AAKF,qDAAqD;AACrD,eAAO,MAAM,kBAAkB,GAC7B,SAAS,MAAM,EACf,QAAQ,cAAc,GAAG,SAAS,KACjC,MAKF,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,8EACyB,mBAAmB,uBAyJtE,CAAC;AAIF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;CAkB9B,CAAC"}
|