@rowsncolumns/spreadsheet 10.5.17 → 10.6.4
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/cf-data-bar.d.ts +73 -0
- package/dist/cjs/api/cf-data-bar.d.ts.map +1 -0
- package/dist/cjs/api/cf-data-bar.js +182 -0
- package/dist/cjs/api/cf-icons.d.ts +73 -0
- package/dist/cjs/api/cf-icons.d.ts.map +1 -0
- package/dist/cjs/api/cf-icons.js +322 -0
- package/dist/cjs/api/cf-overlays.d.ts +89 -3
- package/dist/cjs/api/cf-overlays.d.ts.map +1 -1
- package/dist/cjs/api/cf-overlays.js +256 -80
- package/dist/cjs/api/cf-priority.d.ts +34 -0
- package/dist/cjs/api/cf-priority.d.ts.map +1 -0
- package/dist/cjs/api/cf-priority.js +94 -0
- package/dist/cjs/api/heatmap.d.ts +7 -1
- package/dist/cjs/api/heatmap.d.ts.map +1 -1
- package/dist/cjs/api/heatmap.js +27 -11
- package/dist/cjs/api/selections.d.ts +2 -2
- package/dist/cjs/api/validation.d.ts +6 -0
- package/dist/cjs/api/validation.d.ts.map +1 -1
- package/dist/cjs/api/validation.js +10 -1
- package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts +8 -3
- package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts.map +1 -1
- package/dist/cjs/atoms/index.d.ts +4 -0
- package/dist/cjs/atoms/index.d.ts.map +1 -1
- package/dist/cjs/atoms/index.js +4 -0
- package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
- package/dist/cjs/components/canvas-grid/index.js +194 -51
- package/dist/cjs/components/canvas-grid/overflow.d.ts +37 -0
- package/dist/cjs/components/canvas-grid/overflow.d.ts.map +1 -0
- package/dist/cjs/components/canvas-grid/overflow.js +49 -0
- package/dist/cjs/components/canvas-grid/page-breaks.d.ts +15 -0
- package/dist/cjs/components/canvas-grid/page-breaks.d.ts.map +1 -0
- package/dist/cjs/components/canvas-grid/page-breaks.js +77 -0
- package/dist/cjs/components/canvas-grid/typings.d.ts +32 -3
- package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
- package/dist/cjs/components/cell/alignment.d.ts +58 -1
- package/dist/cjs/components/cell/alignment.d.ts.map +1 -1
- package/dist/cjs/components/cell/alignment.js +144 -1
- package/dist/cjs/components/cell/cell-background.d.ts +2 -0
- package/dist/cjs/components/cell/cell-background.d.ts.map +1 -1
- package/dist/cjs/components/cell/cell-background.js +5 -6
- package/dist/cjs/components/cell/cell-backgrounds.d.ts.map +1 -1
- package/dist/cjs/components/cell/cell-backgrounds.js +5 -1
- package/dist/cjs/components/cell/cell-text-runs.js +1 -1
- package/dist/cjs/components/cell/index.d.ts.map +1 -1
- package/dist/cjs/components/cell/index.js +378 -37
- package/dist/cjs/components/cell/number-format-layout.d.ts +35 -0
- package/dist/cjs/components/cell/number-format-layout.d.ts.map +1 -0
- package/dist/cjs/components/cell/number-format-layout.js +106 -0
- package/dist/cjs/components/cell/typings.d.ts +22 -0
- package/dist/cjs/components/cell/typings.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/index.js +2 -2
- package/dist/cjs/components/cell-filter/index.d.ts.map +1 -1
- package/dist/cjs/components/cell-filter/index.js +3 -3
- package/dist/cjs/components/cell-overlay/index.d.ts +20 -0
- package/dist/cjs/components/cell-overlay/index.d.ts.map +1 -1
- package/dist/cjs/components/cell-overlay/index.js +155 -28
- package/dist/cjs/components/cf-icon-preview/index.d.ts +16 -0
- package/dist/cjs/components/cf-icon-preview/index.d.ts.map +1 -0
- package/dist/cjs/components/cf-icon-preview/index.js +48 -0
- package/dist/cjs/components/context-menu/index.d.ts.map +1 -1
- package/dist/cjs/components/context-menu/index.js +11 -3
- package/dist/cjs/components/embeds/embed-component.d.ts.map +1 -1
- package/dist/cjs/components/embeds/embed-component.js +3 -2
- package/dist/cjs/components/goal-seek-dialog/index.d.ts +15 -5
- package/dist/cjs/components/goal-seek-dialog/index.d.ts.map +1 -1
- package/dist/cjs/components/goal-seek-dialog/index.js +145 -42
- package/dist/cjs/components/hidden-markers/index.d.ts.map +1 -1
- package/dist/cjs/components/hidden-markers/index.js +8 -7
- package/dist/cjs/components/hidden-markers/style.d.ts +7 -0
- package/dist/cjs/components/hidden-markers/style.d.ts.map +1 -1
- package/dist/cjs/components/hidden-markers/style.js +13 -2
- package/dist/cjs/components/protect-sheet-dialog/index.d.ts +67 -0
- package/dist/cjs/components/protect-sheet-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/protect-sheet-dialog/index.js +196 -0
- package/dist/cjs/components/toolbar/types.d.ts +1 -1
- package/dist/cjs/components/toolbar/types.d.ts.map +1 -1
- package/dist/cjs/config.d.ts +13 -1
- package/dist/cjs/config.d.ts.map +1 -1
- package/dist/cjs/config.js +15 -3
- package/dist/cjs/helpers.d.ts +10 -5
- package/dist/cjs/helpers.d.ts.map +1 -1
- package/dist/cjs/helpers.js +43 -31
- package/dist/cjs/hooks/use-border-styles.d.ts.map +1 -1
- package/dist/cjs/hooks/use-border-styles.js +5 -28
- package/dist/cjs/hooks/use-cell-renderer.d.ts +35 -3
- package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
- package/dist/cjs/hooks/use-cell-renderer.js +85 -47
- package/dist/cjs/hooks/use-conditional-formatting.d.ts +13 -1
- package/dist/cjs/hooks/use-conditional-formatting.d.ts.map +1 -1
- package/dist/cjs/hooks/use-conditional-formatting.js +281 -230
- package/dist/cjs/index.d.ts +7 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +13 -1
- package/dist/cjs/release-date.js +1 -1
- package/dist/cjs/themes.d.ts +8 -0
- package/dist/cjs/themes.d.ts.map +1 -1
- package/dist/cjs/themes.js +21 -3
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/types.d.ts +115 -5
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/api/cf-data-bar.d.ts +73 -0
- package/dist/esm/api/cf-data-bar.d.ts.map +1 -0
- package/dist/esm/api/cf-data-bar.js +178 -0
- package/dist/esm/api/cf-icons.d.ts +73 -0
- package/dist/esm/api/cf-icons.d.ts.map +1 -0
- package/dist/esm/api/cf-icons.js +306 -0
- package/dist/esm/api/cf-overlays.d.ts +89 -3
- package/dist/esm/api/cf-overlays.d.ts.map +1 -1
- package/dist/esm/api/cf-overlays.js +223 -67
- package/dist/esm/api/cf-priority.d.ts +34 -0
- package/dist/esm/api/cf-priority.d.ts.map +1 -0
- package/dist/esm/api/cf-priority.js +61 -0
- package/dist/esm/api/heatmap.d.ts +7 -1
- package/dist/esm/api/heatmap.d.ts.map +1 -1
- package/dist/esm/api/heatmap.js +24 -9
- package/dist/esm/api/selections.d.ts +2 -2
- package/dist/esm/api/validation.d.ts +6 -0
- package/dist/esm/api/validation.d.ts.map +1 -1
- package/dist/esm/api/validation.js +6 -0
- package/dist/esm/atoms/goal-seek-dialog.atom.d.ts +8 -3
- package/dist/esm/atoms/goal-seek-dialog.atom.d.ts.map +1 -1
- package/dist/esm/atoms/index.d.ts +4 -0
- package/dist/esm/atoms/index.d.ts.map +1 -1
- package/dist/esm/atoms/index.js +4 -0
- package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
- package/dist/esm/components/canvas-grid/index.js +163 -47
- package/dist/esm/components/canvas-grid/overflow.d.ts +37 -0
- package/dist/esm/components/canvas-grid/overflow.d.ts.map +1 -0
- package/dist/esm/components/canvas-grid/overflow.js +39 -0
- package/dist/esm/components/canvas-grid/page-breaks.d.ts +15 -0
- package/dist/esm/components/canvas-grid/page-breaks.d.ts.map +1 -0
- package/dist/esm/components/canvas-grid/page-breaks.js +50 -0
- package/dist/esm/components/canvas-grid/typings.d.ts +32 -3
- package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
- package/dist/esm/components/cell/alignment.d.ts +58 -1
- package/dist/esm/components/cell/alignment.d.ts.map +1 -1
- package/dist/esm/components/cell/alignment.js +110 -1
- package/dist/esm/components/cell/cell-background.d.ts +2 -0
- package/dist/esm/components/cell/cell-background.d.ts.map +1 -1
- package/dist/esm/components/cell/cell-background.js +4 -5
- package/dist/esm/components/cell/cell-backgrounds.d.ts.map +1 -1
- package/dist/esm/components/cell/cell-backgrounds.js +5 -1
- package/dist/esm/components/cell/cell-text-runs.js +2 -2
- package/dist/esm/components/cell/index.d.ts.map +1 -1
- package/dist/esm/components/cell/index.js +339 -39
- package/dist/esm/components/cell/number-format-layout.d.ts +35 -0
- package/dist/esm/components/cell/number-format-layout.d.ts.map +1 -0
- package/dist/esm/components/cell/number-format-layout.js +99 -0
- package/dist/esm/components/cell/typings.d.ts +22 -0
- package/dist/esm/components/cell/typings.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/index.js +2 -2
- package/dist/esm/components/cell-filter/index.d.ts.map +1 -1
- package/dist/esm/components/cell-filter/index.js +4 -4
- package/dist/esm/components/cell-overlay/index.d.ts +20 -0
- package/dist/esm/components/cell-overlay/index.d.ts.map +1 -1
- package/dist/esm/components/cell-overlay/index.js +111 -25
- package/dist/esm/components/cf-icon-preview/index.d.ts +16 -0
- package/dist/esm/components/cf-icon-preview/index.d.ts.map +1 -0
- package/dist/esm/components/cf-icon-preview/index.js +41 -0
- package/dist/esm/components/context-menu/index.d.ts.map +1 -1
- package/dist/esm/components/context-menu/index.js +11 -3
- package/dist/esm/components/embeds/embed-component.d.ts.map +1 -1
- package/dist/esm/components/embeds/embed-component.js +4 -3
- package/dist/esm/components/goal-seek-dialog/index.d.ts +15 -5
- package/dist/esm/components/goal-seek-dialog/index.d.ts.map +1 -1
- package/dist/esm/components/goal-seek-dialog/index.js +126 -29
- package/dist/esm/components/hidden-markers/index.d.ts.map +1 -1
- package/dist/esm/components/hidden-markers/index.js +9 -8
- package/dist/esm/components/hidden-markers/style.d.ts +7 -0
- package/dist/esm/components/hidden-markers/style.d.ts.map +1 -1
- package/dist/esm/components/hidden-markers/style.js +8 -1
- package/dist/esm/components/protect-sheet-dialog/index.d.ts +67 -0
- package/dist/esm/components/protect-sheet-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/protect-sheet-dialog/index.js +154 -0
- package/dist/esm/components/toolbar/types.d.ts +1 -1
- package/dist/esm/components/toolbar/types.d.ts.map +1 -1
- package/dist/esm/config.d.ts +13 -1
- package/dist/esm/config.d.ts.map +1 -1
- package/dist/esm/config.js +13 -1
- package/dist/esm/helpers.d.ts +10 -5
- package/dist/esm/helpers.d.ts.map +1 -1
- package/dist/esm/helpers.js +40 -28
- package/dist/esm/hooks/use-border-styles.d.ts.map +1 -1
- package/dist/esm/hooks/use-border-styles.js +5 -26
- package/dist/esm/hooks/use-cell-renderer.d.ts +35 -3
- package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
- package/dist/esm/hooks/use-cell-renderer.js +83 -42
- package/dist/esm/hooks/use-conditional-formatting.d.ts +13 -1
- package/dist/esm/hooks/use-conditional-formatting.d.ts.map +1 -1
- package/dist/esm/hooks/use-conditional-formatting.js +215 -120
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +7 -0
- package/dist/esm/release-date.js +1 -1
- package/dist/esm/themes.d.ts +8 -0
- package/dist/esm/themes.d.ts.map +1 -1
- package/dist/esm/themes.js +20 -3
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/types.d.ts +115 -5
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/spreadsheet.min.css +1 -1
- package/package.json +4 -4
package/dist/esm/atoms/index.js
CHANGED
|
@@ -23,6 +23,10 @@ export * from "./go-to-dialog.atom";
|
|
|
23
23
|
export * from "./move-overwrite-confirm.atom";
|
|
24
24
|
export * from "./evaluate-formula-dialog.atom";
|
|
25
25
|
export * from "./remove-duplicates-dialog.atom";
|
|
26
|
+
export * from "./text-to-columns-dialog.atom";
|
|
27
|
+
export * from "./subtotal-dialog.atom";
|
|
28
|
+
export * from "./goal-seek-dialog.atom";
|
|
29
|
+
export * from "./advanced-filter-dialog.atom";
|
|
26
30
|
export * from "./watch-window.atom";
|
|
27
31
|
export * from "./insert-cells-dialog.atom";
|
|
28
32
|
export * from "./insert-options.atom";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/canvas-grid/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/canvas-grid/index.tsx"],"names":[],"mappings":"AAsDA,OAAO,KASN,MAAM,OAAO,CAAC;AAgOf,OAAO,KAAK,EAGV,QAAQ,EAWT,MAAM,aAAa,CAAC;AAoBrB,OAAO,KAAK,EACV,wBAAwB,EACxB,iBAAiB,EACjB,eAAe,EAEhB,MAAM,WAAW,CAAC;AA6sMnB,eAAO,MAAM,UAAU,EAA4C,CACjE,CAAC,SAAS,QAAQ,CAAC,GAAG,CAAC,EAEvB,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,GACvB,wBAAwB,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;CAAE,KAChE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC"}
|
|
@@ -5,7 +5,7 @@ import { getBoundedCells, MouseButtonCodes } from "@rowsncolumns/grid";
|
|
|
5
5
|
import { isCellWithinBounds } from "@rowsncolumns/grid";
|
|
6
6
|
import { cellIdentifier, Grid as BaseGrid, isEqualCells, } from "@rowsncolumns/grid";
|
|
7
7
|
import { cn, DropdownMenuContent, DropdownMenuPortal, Skeleton, tryParseRichText, } from "@rowsncolumns/ui";
|
|
8
|
-
import { cellToAddress, getCellEffectiveFormat, getContrastColor, getFormulaLocale, getEffectiveDataValidationConditionType, isConditionalFormatFormulaRule, isDataValidationFormulaRule, isNil, isNilOrBlank, iterateCellsInRange, localizeCellInput, localizeFormula, localizeFunctionDescriptions, log, resolveDefaultHorizontalAlignment, ssfFormatColor, uuid, } from "@rowsncolumns/utils";
|
|
8
|
+
import { cellToAddress, getCellEffectiveFormat, getContrastColor, getFormulaLocale, getEffectiveDataValidationConditionType, isConditionalFormatFormulaRule, isDataValidationFormulaRule, isNil, isNilOrBlank, iterateCellsInRange, localizeCellInput, localizeFormula, localizeFunctionDescriptions, log, resolveDefaultHorizontalAlignment, ssfFormat, ssfFormatColor, uuid, } from "@rowsncolumns/utils";
|
|
9
9
|
import { useStore } from "jotai";
|
|
10
10
|
import merge from "lodash/merge";
|
|
11
11
|
import throttle from "lodash/throttle";
|
|
@@ -14,6 +14,7 @@ import { getBandedCells } from "../../api/banded-ranges";
|
|
|
14
14
|
import { clearRangeForInsertedBand, formatsForInsertOption, insertedBandHasValues, } from "../../api/insert-options";
|
|
15
15
|
import { keepsCalculatedColumnTag, } from "../../api/calculated-column-fill";
|
|
16
16
|
import { keepsTableAutoExpansionTag, } from "../../api/table-auto-expansion";
|
|
17
|
+
import { isConditionalFormatNumberCell, isDarkCssColor, } from "../../api/cf-overlays";
|
|
17
18
|
import { CF_INITIAL_WINDOW, cfWindowForViewport, isSameCfWindow, } from "../../api/cf-window";
|
|
18
19
|
import { generateSelectionsFromFormula } from "../../api/selections";
|
|
19
20
|
import { SpreadsheetApi } from "../../api/spreadsheet-api";
|
|
@@ -21,7 +22,7 @@ import { findActiveTableWithinCell } from "../../api/table";
|
|
|
21
22
|
import { getDataValidationTooltipContent } from "../../api/validation-tooltip";
|
|
22
23
|
import { resolveGoToSpecial } from "../../api/go-to-special";
|
|
23
24
|
import { checkExcelValidationValue, isFormulaEntry, } from "../../api/excel-validation-kinds";
|
|
24
|
-
import { checkBooleanRule, decideValidationCommit, isCellLockedUnderProtection, isProtectedCell, isProtectedSheet,
|
|
25
|
+
import { checkBooleanRule, decideValidationCommit, isCellFormulaHiddenUnderProtection, isCellLockedUnderProtection, isProtectedCell, isProtectedSheet, } from "../../api/validation";
|
|
25
26
|
import { useFormulaModeValue, useIsEvaluateFormulaDialogMounted, useIsGoToDialogMounted, useIsMoveOverwriteConfirmMounted, useIsPasteSpecialDialogMounted, useOpenEvaluateFormulaDialog, useOpenGoToDialog, useOpenMoveOverwriteConfirm, useOpenPasteSpecialDialog, useSetNoteEditorCell, useSetPinnedTooltip, useFillOptionsState, useInsertOptionsState, useTableAutoExpansionState, useCalculatedColumnFillState, useOpenFillSeriesDialog, useShowPasteMenu, useShowValidationAlert, } from "../../atoms";
|
|
26
27
|
import { useActiveEditor } from "../../atoms/active-editor.atom";
|
|
27
28
|
import { useAddWatch, useIsWatchWindowMounted, useSetWatchWindowContext, } from "../../atoms/watch-window.atom";
|
|
@@ -32,12 +33,14 @@ import { useFormulaSelections } from "../../atoms/formula-selections.atom";
|
|
|
32
33
|
import { useQuickEditState } from "../../atoms/magic-fill-state.atom";
|
|
33
34
|
import { useOnHideFormulaHelp, useOnShowFormulaHelp, useShowFormulaHelpValue, } from "../../atoms/show-formula-help.atom";
|
|
34
35
|
import { useSetSpreadsheetApi } from "../../atoms/spreadsheet-api.atom";
|
|
35
|
-
import { ARROW_DOWN_WIDTH, CALCULATED_ICON_WIDTH, CELL_HORIZONTAL_ALIGNMENT, CF_ICON_SPACING, CF_ICON_WIDTH, CHIP_COLOR, CHIP_SPACING, COLUMN_HEADER_HEIGHT, DEFAULT_ACTIVE_CELL, DEFAULT_ARRAY, DEFAULT_CELL_BACKGROUND_COLOR, DEFAULT_CELL_COLOR, DEFAULT_CELL_SPACING, DEFAULT_COLUMN_COUNT, DEFAULT_COLUMN_WIDTH, DEFAULT_FONT_SIZE_PT, DEFAULT_HEADER_ACTIVE_BG, DEFAULT_HEADER_ACTIVE_TABLE_BG, DEFAULT_HEADER_BG, DEFAULT_HEADER_BORDER_COLOR, DEFAULT_HEADER_COLOR, DEFAULT_HEADER_SELECTED_BG, DEFAULT_HEADER_SELECTED_TABLE_BG, DEFAULT_HEADER_TABLE_BG, DEFAULT_ROW_COUNT, DEFAULT_ROW_HEIGHT, DEFAULT_SCROLL_POSITION, defaultSpreadsheetTheme, EXPAND_COLLAPSE_ICON_WIDTH, FILTER_ICON_WIDTH, GRIDLINE_COLOR, HEADER_TEXT_FORMAT, INDENT_SPACING, MAX_COLUMN_COUNT, MAX_ROW_COUNT, MIN_COLUMN_WIDTH, ROW_HEADER_WIDTH, SCROLLBAR_SIZE, SELECTION_BG, SELECTION_BORDER, } from "../../config";
|
|
36
|
+
import { ARROW_DOWN_WIDTH, CALCULATED_ICON_WIDTH, CELL_HORIZONTAL_ALIGNMENT, CF_ICON_SPACING, CF_ICON_WIDTH, CHIP_COLOR, CHIP_SPACING, COLUMN_HEADER_HEIGHT, DEFAULT_ACTIVE_CELL, DEFAULT_ARRAY, DEFAULT_CELL_BACKGROUND_COLOR, DEFAULT_CELL_COLOR, DEFAULT_CELL_SPACING, DEFAULT_COLUMN_COUNT, DEFAULT_COLUMN_WIDTH, DEFAULT_FONT_SIZE_PT, DEFAULT_HEADER_ACTIVE_BG, DEFAULT_HEADER_ACTIVE_TABLE_BG, DEFAULT_HEADER_BG, DEFAULT_HEADER_BORDER_COLOR, DEFAULT_HEADER_COLOR, DEFAULT_HEADER_SELECTED_BG, DEFAULT_HEADER_SELECTED_TABLE_BG, DEFAULT_HEADER_TABLE_BG, DEFAULT_ROW_COUNT, DEFAULT_ROW_HEIGHT, DEFAULT_SCROLL_POSITION, defaultSpreadsheetTheme, EXPAND_COLLAPSE_ICON_WIDTH, FILTER_ICON_WIDTH, GRIDLINE_COLOR, HEADER_TEXT_FORMAT, FILTER_BUTTON_GLYPH_COLOR, INDENT_SPACING, MAX_COLUMN_COUNT, MAX_ROW_COUNT, MIN_COLUMN_WIDTH, ROW_HEADER_WIDTH, SCROLLBAR_SIZE, SELECTION_BG, SELECTION_BORDER, } from "../../config";
|
|
36
37
|
import { definedProps, getCellEffectiveValue, getCellFormattedValue, getCellUserEnteredValue, getDefaultColumnHeader, getDefaultRowHeader, getExtendedValueBool, getExtendedValueError, getExtendedValueFormula, getExtendedValueNumber, getExtendedValueString, getTableHeaderCells, isFirefox, isStyleReference, isTouchDevice, toEditorRangeValuesAsync, } from "../../helpers";
|
|
37
38
|
import { useBorderStyles } from "../../hooks/use-border-styles";
|
|
38
39
|
import { useCallbackRef } from "../../hooks/use-callback-ref";
|
|
39
40
|
import { useCellPopover } from "../../hooks/use-cell-popover";
|
|
40
41
|
import { useCellRenderer } from "../../hooks/use-cell-renderer";
|
|
42
|
+
import { blocksOverflow, walkOverflowColumns } from "./overflow";
|
|
43
|
+
import { getPageBreakBorderStyles } from "./page-breaks";
|
|
41
44
|
import { useChartSourceRanges } from "../../hooks/use-chart-source-ranges";
|
|
42
45
|
import { useConditionalFormatting } from "../../hooks/use-conditional-formatting";
|
|
43
46
|
import { DefaultContextMenuWrapper, useContextMenu, } from "../../hooks/use-context-menu";
|
|
@@ -127,7 +130,7 @@ function isDetachedEditor(editor) {
|
|
|
127
130
|
return element != null && !element.isConnected;
|
|
128
131
|
}
|
|
129
132
|
function CanvasGridComponent(props, forwardedRef) {
|
|
130
|
-
const { licenseKey, sheetId, sheetType, ChartSheetView: ChartSheetViewComponent = ChartSheetView, instanceId, activeCell = DEFAULT_ACTIVE_CELL, selections = DEFAULT_ARRAY, frozenColumnCount = 0, frozenRowCount = 0, rowCount = DEFAULT_ROW_COUNT, columnCount = DEFAULT_COLUMN_COUNT, autoFocus, basicFilter, tables, namedRanges, bandedRanges = DEFAULT_ARRAY, tableBorderColor = "#008000", filterIconColor =
|
|
133
|
+
const { licenseKey, sheetId, sheetType, ChartSheetView: ChartSheetViewComponent = ChartSheetView, instanceId, activeCell = DEFAULT_ACTIVE_CELL, selections = DEFAULT_ARRAY, frozenColumnCount = 0, frozenRowCount = 0, rowCount = DEFAULT_ROW_COUNT, columnCount = DEFAULT_COLUMN_COUNT, autoFocus, basicFilter, tables, namedRanges, bandedRanges = DEFAULT_ARRAY, tableBorderColor = "#008000", filterIconColor = FILTER_BUTTON_GLYPH_COLOR, conditionalFormats, showFilterIcon = true, showCalculatedColumnIcon = true, showHeaders = true, defaultColumnWidth = DEFAULT_COLUMN_WIDTH, defaultRowHeight = DEFAULT_ROW_HEIGHT, lineHeightMode = "fontMetrics", columnHeaderHeight = COLUMN_HEADER_HEIGHT, rowHeaderWidth = ROW_HEADER_WIDTH, gridLineColor = GRIDLINE_COLOR, cellBackgroundColor = DEFAULT_CELL_BACKGROUND_COLOR, cellColor = DEFAULT_CELL_COLOR, headerBorderColor = DEFAULT_HEADER_BORDER_COLOR, headerBackgroundColor = DEFAULT_HEADER_BG, headerColor = DEFAULT_HEADER_COLOR, headerActiveBackgroundColor = DEFAULT_HEADER_ACTIVE_BG, headerSelectedBackgroundColor = DEFAULT_HEADER_SELECTED_BG, headerSelectedColor = "white", headerTableBackgroundColor = DEFAULT_HEADER_TABLE_BG, headerTableActiveBackgroundColor = DEFAULT_HEADER_ACTIVE_TABLE_BG, headerTableSelectedBackgroundColor = DEFAULT_HEADER_SELECTED_TABLE_BG, frozenShadowColor = headerBorderColor, frozenShadowThickness = 1, selectionBackgroundColor = SELECTION_BG, selectionBorderColor = SELECTION_BORDER, selectionStrokeWidth, showActiveCellBorderInSelection, selectionDragBorderColor = SELECTION_BORDER, chartSelectedColor, chipBackgroundColor = CHIP_COLOR, merges = DEFAULT_ARRAY, borderStyles, protectedRanges, isWorkbookProtected: isWorkbookProtectedProp = false, getSheetProtection, pivotTables, charts, onUpdateChart, onChangeZOrder, embeds, slicers, rowMetadata = DEFAULT_ARRAY, columnMetadata = DEFAULT_ARRAY, scale = 1, zoomSpeed = 1, overscanCount = 3, enableEditOnEnterKey: enableEditOnEnterKeyProp, shouldHandleKeyDown, enableTextOverflow = true, showGridLines: _showGridLines, showZeros, pageBreaks, showFormulas = false, protectFormulas = false, showFrozenSeparator = true, HeaderCell = DefaultHeaderCell, Cell = DefaultCell, SelectionTitleComponent = SelectionTitle, CellEditor = DefaultCellEditor, CellTooltip, ContextMenu = DefaultContextMenu, ContextMenuWrapper = DefaultContextMenuWrapper, FilterBox = DefaultFilterBox, HeaderMoveDragComponent = DefaultHeaderMoveDragComponent, SuggestionsDropdown, stickyEditor = true, scrollSnap = false, scrollThrottleTimeout, preventBrowserDefaultScroll, mouseMoveThrottleTimeout = 60, tooltipIntentInterval = 60, selectionPolicy, users, userId, renderCollaboratorCursor, functionDescriptions, showHeaderMenuButton = true, scrollbarSize = SCROLLBAR_SIZE, theme = defaultSpreadsheetTheme, showNotes = true, showComments = true, locale, formulaLocale: formulaLocaleProp, agentSuggestions, onReviewSuggestion, onShowFormulas, getDataRowCount, getDataRegion, getChartComponent, getEmbedComponent, getSlicerComponent, onChange, onChangeBatch, onExpandCollapse, onPivotDrillDown, onDelete, onChangeEditorValue, onFill, onRequestCalculate, onChangeActiveCell, onChangeActiveSheet, onChangeSelections, getSheetName, getSheetId, getCellData, getNote: getNoteProp, getTextFormatRuns, getDataValidation, getEffectiveFormat, getFormattedValue: getFormattedValueProp, getTooltipContent, errorResolutionComponent, getEffectiveValue: getEffectiveValueProp, getSparklineGroup, getUserEnteredExtendedValue, getEffectiveExtendedValue, getSheetRowCount, getSheetColumnCount, getCellPopoverContent, onScroll, onViewPortChange, windowConditionalFormats = false, engineConditionalFormatResults = false, getConditionalFormatRuleStats, onResize, onAutoResize, onHideColumn, onHideRow, onShowColumn, onShowRow, onGroupRows, onUngroupRows, onCollapseRowGroup, onExpandRowGroup, onGroupColumns, onUngroupColumns, onCollapseColumnGroup, onExpandColumnGroup, onSetOutlineDepth, onDeleteRow, onDeleteColumn, onInsertRow, onInsertColumn, onChangeAutoExpandTables, onChangeAutoCalculatedColumns, onInsertCellsShiftDown, onInsertCellsShiftRight, onDeleteCellsShiftLeft, onDeleteCellsShiftUp, onClearContents, onMoveColumns, onMoveRows, onSelectNextSheet, onSelectPreviousSheet, onCreateNewSheet, onKeyDown, onChangeFormatting, onRepeatFormatting, onClearFormatting, onRequestEditProtectedRange, onMoveChart, onResizeChart, onDeleteChart, onCutChart, onCopyChart, onMoveEmbed, onResizeEmbed, onDeleteEmbed, onRequestEditEmbed, onMoveSlicer, onResizeSlicer, onDeleteSlicer, onRequestEditSlicer, onFillRange, disableFillRightShortcut, keymap, onCalculateNow, onRequestGoTo, onMoveSelection, onInsertCutCells, onInsertTime, onInsertDate, onInsertDateTime, onInsertAutoSum, onUndo, onRedo, batchHistory, onPaste, onCopy, onCut, onSortColumn, onSortTable, onFilterTable, onFilterPivot, onResizeTable, onUndoTableAutoExpansion, onUndoCalculatedColumn, onOverwriteCalculatedColumn, onRequestEditTable, onRequestEditPivotTable, onRequestDeletePivotTable, onRequestCreatePivotChart, onRemoveTable, onCreateTable, onRequestCreateTable, onInsertTableColumn, onDeleteTableColumn, onInsertTableRow, onDeleteTableRow, onUpdateTable, onRequestResizeTable, onRequestInsertSlicer, onCreateBasicFilter, onRequestDefineNamedRange, onRequestFormatCells, onRequestConditionalFormat, onRequestDataValidation, onRequestInsertComment, onRequestInsertLink, onFreezeColumn, onFreezeRow, onUpdateNote, onProtectRange, onUnProtectRange, onSortRange, onRequestSearch, onRequestReplace, onRequestResize, getRowHeaderText = getDefaultRowHeader, getColumnHeaderText = getDefaultColumnHeader, getAdditionalCellSpacing, tokenizer: defaultTokenizer = defaultFormulaTokenizer, onChangeScale, onRemoveLink, onSelectLink, onSplitTextToColumns, onRemoveDuplicates, onGoalSeek, onSubtotal, onAdvancedFilter, onRequestExpand, cellExpandPredicate, StructuredResult = DefaultStructuredResult, getMentions, getStructuredProperties: getStructuredPropertiesProp, getFunctionParameterSuggestions, shouldFetchFunctionParameters, MentionTagComponent, MentionDropdownItemComponent, showSelectionResizeHandles = true, enableMagicFill, enableQuickEdit = true, MagicFillComponent, MagicFillContent, QuickEdit, PasteMenu, SuggestionAction, HiddenRowMarkers, HiddenColumnMarkers, enableResizerOverflow, className, defaultFontSizePoint = DEFAULT_FONT_SIZE_PT, defaultCellFormat, readonly, isComparing = false, getCellDiff, enableDataBoundaryNavigation, footerHeight, footerComponent, arrowComponents,
|
|
131
134
|
// Host-driven filter props. `hostHiddenRowRanges`
|
|
132
135
|
// supplies compact [start, end] hidden-row tuples; `getFilterValues` supplies a
|
|
133
136
|
// column's distinct values. Both let a million-row filter render without scanning
|
|
@@ -978,10 +981,7 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
978
981
|
/**
|
|
979
982
|
* Check if a cell data is a number
|
|
980
983
|
*/
|
|
981
|
-
const isNumberValue = useCallback((sheetId, rowIndex, columnIndex) =>
|
|
982
|
-
const cellFormat = getCellFormat?.(sheetId, rowIndex, columnIndex);
|
|
983
|
-
return !!cellFormat?.numberFormat?.type;
|
|
984
|
-
}, [getCellFormat]);
|
|
984
|
+
const isNumberValue = useCallback((sheetId, rowIndex, columnIndex) => isConditionalFormatNumberCell(getEffectiveValue(sheetId, rowIndex, columnIndex), getCellFormat?.(sheetId, rowIndex, columnIndex)), [getCellFormat, getEffectiveValue]);
|
|
985
985
|
/**
|
|
986
986
|
* Get value entered by the user in a cell
|
|
987
987
|
* If its a formula cell, formulaValue is used
|
|
@@ -1098,6 +1098,7 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
1098
1098
|
getConditionalFormatResult: engineConditionalFormatResults
|
|
1099
1099
|
? getFormulaValidationValue
|
|
1100
1100
|
: undefined,
|
|
1101
|
+
getConditionalFormatRuleStats,
|
|
1101
1102
|
});
|
|
1102
1103
|
/**
|
|
1103
1104
|
* Get conditional format of a cell
|
|
@@ -1105,6 +1106,28 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
1105
1106
|
const getConditionalCellFormat = useCallback((sheetId, rowIndex, columnIndex) => {
|
|
1106
1107
|
return conditionalFormatByCell.get(cellIdentifier(rowIndex, columnIndex));
|
|
1107
1108
|
}, [conditionalFormatByCell]);
|
|
1109
|
+
/**
|
|
1110
|
+
* The text a cell paints: a true conditional format's number format
|
|
1111
|
+
* (Format Cells ▸ Number in the rule) re-formats a numeric value, as in
|
|
1112
|
+
* Excel; otherwise the cell's own formatted value.
|
|
1113
|
+
*/
|
|
1114
|
+
const getDisplayFormattedValue = useCallback((sheetId, rowIndex, columnIndex) => {
|
|
1115
|
+
const pattern = conditionalFormatByCell.get(cellIdentifier(rowIndex, columnIndex))?.numberFormat?.pattern;
|
|
1116
|
+
if (pattern && !(showFormulas && !protectFormulas)) {
|
|
1117
|
+
const numberValue = getExtendedValueNumber(getEffectiveValue(sheetId, rowIndex, columnIndex));
|
|
1118
|
+
if (typeof numberValue === "number") {
|
|
1119
|
+
return ssfFormat(pattern, numberValue, locale);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
return getFormattedValue(sheetId, rowIndex, columnIndex);
|
|
1123
|
+
}, [
|
|
1124
|
+
conditionalFormatByCell,
|
|
1125
|
+
getEffectiveValue,
|
|
1126
|
+
getFormattedValue,
|
|
1127
|
+
locale,
|
|
1128
|
+
protectFormulas,
|
|
1129
|
+
showFormulas,
|
|
1130
|
+
]);
|
|
1108
1131
|
/**
|
|
1109
1132
|
* Get conditional format of a cell
|
|
1110
1133
|
*/
|
|
@@ -1163,14 +1186,17 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
1163
1186
|
const { textFormat: _textFormat, ...rest } = defaultCellFormat;
|
|
1164
1187
|
return Object.keys(rest).length ? rest : undefined;
|
|
1165
1188
|
}, [defaultCellFormat]);
|
|
1189
|
+
const isDarkGrid = useMemo(() => isDarkCssColor(getStringifiedColor(cellBackgroundColor, theme)), [cellBackgroundColor, theme]);
|
|
1166
1190
|
const getEffectiveCellFormat = useCallback((sheetId, rowIndex, columnIndex) => {
|
|
1167
1191
|
const cellFormat = getCellFormat(sheetId, rowIndex, columnIndex);
|
|
1168
1192
|
const isHyperlink = Boolean(getHyperlink(sheetId, rowIndex, columnIndex));
|
|
1169
1193
|
const conditionalCellFormat = getConditionalCellFormat(sheetId, rowIndex, columnIndex);
|
|
1170
1194
|
const bandedCellFormat = getBandedCellFormat(sheetId, rowIndex, columnIndex);
|
|
1171
|
-
//
|
|
1172
|
-
//
|
|
1173
|
-
|
|
1195
|
+
// A fill-only rule keeps the cell's font colour (Excel). Only a dark
|
|
1196
|
+
// grid swaps to a contrasting text colour, so the default light text
|
|
1197
|
+
// stays readable on the rule's (usually light) fill.
|
|
1198
|
+
const conditionalFormatColor = isDarkGrid &&
|
|
1199
|
+
conditionalCellFormat?.backgroundColor &&
|
|
1174
1200
|
!conditionalCellFormat?.textFormat?.color
|
|
1175
1201
|
? getContrastColor(getStringifiedColor(conditionalCellFormat.backgroundColor, theme), getStringifiedColor({ theme: 1 }, theme), getStringifiedColor({ theme: 1, tint: 1 }, theme))
|
|
1176
1202
|
: undefined;
|
|
@@ -1253,6 +1279,7 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
1253
1279
|
cellColor,
|
|
1254
1280
|
defaultCellTextFormat,
|
|
1255
1281
|
defaultCellFormatRest,
|
|
1282
|
+
isDarkGrid,
|
|
1256
1283
|
]);
|
|
1257
1284
|
/**
|
|
1258
1285
|
* Get horizontal alignment of editor
|
|
@@ -1614,37 +1641,24 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
1614
1641
|
* Can a cell overflow to adjoining cell
|
|
1615
1642
|
*/
|
|
1616
1643
|
const canOverflowToNextCell = useCallback(({ rowIndex, columnIndex }) => {
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
return false;
|
|
1628
|
-
}
|
|
1629
|
-
const [expandable] = getCellGroupingInfo(sheetId, rowIndex, columnIndex);
|
|
1630
|
-
if (expandable) {
|
|
1631
|
-
return false;
|
|
1632
|
-
}
|
|
1633
|
-
const formattedValue = getFormattedValue?.(sheetId, rowIndex, columnIndex);
|
|
1634
|
-
return (getNote(sheetId, rowIndex, columnIndex) === undefined &&
|
|
1635
|
-
isNilOrBlank(formattedValue) &&
|
|
1636
|
-
getCellImageUrl(sheetId, rowIndex, columnIndex) === undefined);
|
|
1644
|
+
// Only content stops the spill (Excel): a value, a formula result
|
|
1645
|
+
// (`=""` included), an image. Data validation, notes, tables and
|
|
1646
|
+
// banding are not content.
|
|
1647
|
+
return !blocksOverflow({
|
|
1648
|
+
isHeader: isRowHeader(columnIndex) || isColumnHeader(rowIndex),
|
|
1649
|
+
isExpandable: getCellGroupingInfo(sheetId, rowIndex, columnIndex)[0],
|
|
1650
|
+
formattedValue: getFormattedValue?.(sheetId, rowIndex, columnIndex),
|
|
1651
|
+
effectiveValue: getEffectiveValue(sheetId, rowIndex, columnIndex),
|
|
1652
|
+
hasImage: getCellImageUrl(sheetId, rowIndex, columnIndex) !== undefined,
|
|
1653
|
+
});
|
|
1637
1654
|
}, [
|
|
1638
1655
|
sheetId,
|
|
1639
1656
|
getFormattedValue,
|
|
1657
|
+
getEffectiveValue,
|
|
1640
1658
|
getCellGroupingInfo,
|
|
1641
1659
|
getCellImageUrl,
|
|
1642
|
-
getNote,
|
|
1643
|
-
getDataValidationRule,
|
|
1644
1660
|
isRowHeader,
|
|
1645
1661
|
isColumnHeader,
|
|
1646
|
-
isTableHeader,
|
|
1647
|
-
isBandedCell,
|
|
1648
1662
|
]);
|
|
1649
1663
|
/**
|
|
1650
1664
|
* If a cell is hidden,
|
|
@@ -1863,18 +1877,19 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
1863
1877
|
if (axis === "x") {
|
|
1864
1878
|
return 0;
|
|
1865
1879
|
}
|
|
1866
|
-
/* Data validation arrow */
|
|
1867
|
-
const dataValidation = getDataValidationRule(sheetId, rowIndex, columnIndex);
|
|
1868
1880
|
const additionalCellSpacing = getAdditionalCellSpacing?.(sheetId, rowIndex, columnIndex) ?? 0;
|
|
1869
|
-
|
|
1870
|
-
|
|
1881
|
+
// A data-validation list's dropdown paints beside the active cell, so
|
|
1882
|
+
// only the table totals arrow takes room inside the cell.
|
|
1883
|
+
const showArrow = isTableTotalsCell(rowIndex, columnIndex);
|
|
1871
1884
|
const showChip = getCellMetaType(sheetId, rowIndex, columnIndex) === "people";
|
|
1872
1885
|
const [expandable] = getCellGroupingInfo(sheetId, rowIndex, columnIndex);
|
|
1873
1886
|
const iconSpacing = DEFAULT_CELL_SPACING;
|
|
1874
1887
|
const expandableSpacing = expandable
|
|
1875
1888
|
? (EXPAND_COLLAPSE_ICON_WIDTH + iconSpacing) * scale
|
|
1876
1889
|
: 0;
|
|
1877
|
-
const indentSpacing = (getCellIndent(sheetId, rowIndex, columnIndex) ?? 0) *
|
|
1890
|
+
const indentSpacing = (getCellIndent(sheetId, rowIndex, columnIndex) ?? 0) *
|
|
1891
|
+
INDENT_SPACING *
|
|
1892
|
+
scale;
|
|
1878
1893
|
// Cell has dropdown icon
|
|
1879
1894
|
const arrowSpacing = showArrow
|
|
1880
1895
|
? (ARROW_DOWN_WIDTH + iconSpacing) * scale
|
|
@@ -1907,7 +1922,6 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
1907
1922
|
additionalCellSpacing);
|
|
1908
1923
|
}, [
|
|
1909
1924
|
isTableFilterVisible,
|
|
1910
|
-
getDataValidationRule,
|
|
1911
1925
|
getCellMetaType,
|
|
1912
1926
|
getCellIndent,
|
|
1913
1927
|
showCalculatedColumnIcon,
|
|
@@ -1937,7 +1951,7 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
1937
1951
|
isHiddenColumn,
|
|
1938
1952
|
getTextFormat,
|
|
1939
1953
|
getTextFormatRuns,
|
|
1940
|
-
getTextValue:
|
|
1954
|
+
getTextValue: getDisplayFormattedValue,
|
|
1941
1955
|
getSpacing: getCellSpacing,
|
|
1942
1956
|
getActualCellWidth,
|
|
1943
1957
|
shouldWrapCell,
|
|
@@ -3615,11 +3629,58 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
3615
3629
|
}
|
|
3616
3630
|
onKeyDownEditable(e);
|
|
3617
3631
|
}, [onKeyDownEditable]);
|
|
3632
|
+
/**
|
|
3633
|
+
* Center Across Selection: a `centerContinuous` cell centres its text over
|
|
3634
|
+
* the empty neighbours on either side that carry the same alignment
|
|
3635
|
+
* (Format Cells ▸ Alignment ▸ Horizontal).
|
|
3636
|
+
*/
|
|
3637
|
+
const getCenterAcrossSelectionSpan = useCallback((sheetId, rowIndex, columnIndex) => {
|
|
3638
|
+
const canSpan = (index) => getEffectiveCellFormat(sheetId, rowIndex, index)
|
|
3639
|
+
?.horizontalAlignment === "centerContinuous" &&
|
|
3640
|
+
canOverflowToNextCell({ rowIndex, columnIndex: index });
|
|
3641
|
+
const scaledWidth = (index) => columnWidth(index) * scale;
|
|
3642
|
+
const left = walkOverflowColumns({
|
|
3643
|
+
start: columnIndex,
|
|
3644
|
+
step: -1,
|
|
3645
|
+
need: Infinity,
|
|
3646
|
+
canOverflow: canSpan,
|
|
3647
|
+
columnWidth: scaledWidth,
|
|
3648
|
+
});
|
|
3649
|
+
const right = walkOverflowColumns({
|
|
3650
|
+
start: columnIndex,
|
|
3651
|
+
step: 1,
|
|
3652
|
+
need: Infinity,
|
|
3653
|
+
canOverflow: canSpan,
|
|
3654
|
+
columnWidth: scaledWidth,
|
|
3655
|
+
});
|
|
3656
|
+
if (!left.columns.length && !right.columns.length)
|
|
3657
|
+
return undefined;
|
|
3658
|
+
const spans = [];
|
|
3659
|
+
for (const index of [...left.columns, ...right.columns]) {
|
|
3660
|
+
spans.push([
|
|
3661
|
+
index,
|
|
3662
|
+
getColumnOffset(index),
|
|
3663
|
+
scaledWidth(index),
|
|
3664
|
+
getEffectiveCellFormat(sheetId, rowIndex, index)?.backgroundColor,
|
|
3665
|
+
]);
|
|
3666
|
+
}
|
|
3667
|
+
return [
|
|
3668
|
+
scaledWidth(columnIndex) + left.width + right.width,
|
|
3669
|
+
spans,
|
|
3670
|
+
left.width,
|
|
3671
|
+
];
|
|
3672
|
+
}, [
|
|
3673
|
+
canOverflowToNextCell,
|
|
3674
|
+
columnWidth,
|
|
3675
|
+
getColumnOffset,
|
|
3676
|
+
getEffectiveCellFormat,
|
|
3677
|
+
scale,
|
|
3678
|
+
]);
|
|
3618
3679
|
/**
|
|
3619
3680
|
* Get maximum text width
|
|
3620
3681
|
* before it overflows into next cell
|
|
3621
3682
|
*/
|
|
3622
|
-
const getMaximumOverflowTextWidth = useCallback((formattedValue, sheetId, rowIndex, columnIndex, canOverflowToNextCell, textFormat, shouldWrapOverride, direction = Direction.Right) => {
|
|
3683
|
+
const getMaximumOverflowTextWidth = useCallback((formattedValue, sheetId, rowIndex, columnIndex, canOverflowToNextCell, textFormat, shouldWrapOverride, direction = Direction.Right, centered = false) => {
|
|
3623
3684
|
// A format override makes the sizer measure the whole text
|
|
3624
3685
|
// uniformly, ignoring per-segment rich-text runs. For cells that
|
|
3625
3686
|
// carry runs (e.g. imported xlsx titles with mixed font sizes),
|
|
@@ -3634,6 +3695,41 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
3634
3695
|
if (textWidth < colWidth) {
|
|
3635
3696
|
return [textWidth, DEFAULT_ARRAY];
|
|
3636
3697
|
}
|
|
3698
|
+
if (centered) {
|
|
3699
|
+
// Centred text spills half its excess each way (Excel); a blocked
|
|
3700
|
+
// side clips while the text stays centred on its own cell.
|
|
3701
|
+
const need = (textWidth - colWidth) / 2;
|
|
3702
|
+
const scaledWidth = (index) => columnWidth(index) * scale;
|
|
3703
|
+
const canOverflow = (index) => canOverflowToNextCell({ rowIndex, columnIndex: index });
|
|
3704
|
+
const left = walkOverflowColumns({
|
|
3705
|
+
start: columnIndex,
|
|
3706
|
+
step: -1,
|
|
3707
|
+
need,
|
|
3708
|
+
canOverflow,
|
|
3709
|
+
columnWidth: scaledWidth,
|
|
3710
|
+
});
|
|
3711
|
+
const right = walkOverflowColumns({
|
|
3712
|
+
start: columnIndex,
|
|
3713
|
+
step: 1,
|
|
3714
|
+
need,
|
|
3715
|
+
canOverflow,
|
|
3716
|
+
columnWidth: scaledWidth,
|
|
3717
|
+
});
|
|
3718
|
+
const spans = [];
|
|
3719
|
+
for (const index of [...left.columns, ...right.columns]) {
|
|
3720
|
+
spans.push([
|
|
3721
|
+
index,
|
|
3722
|
+
getColumnOffset(index),
|
|
3723
|
+
scaledWidth(index),
|
|
3724
|
+
getEffectiveCellFormat(sheetId, rowIndex, index)?.backgroundColor,
|
|
3725
|
+
]);
|
|
3726
|
+
}
|
|
3727
|
+
return [
|
|
3728
|
+
colWidth + Math.min(left.width, need) + Math.min(right.width, need),
|
|
3729
|
+
spans,
|
|
3730
|
+
Math.min(left.width, need),
|
|
3731
|
+
];
|
|
3732
|
+
}
|
|
3637
3733
|
let start = columnIndex;
|
|
3638
3734
|
const columnSpans = [];
|
|
3639
3735
|
const isMovingRight = direction === Direction.Right;
|
|
@@ -3672,7 +3768,9 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
3672
3768
|
isTableTotalsCell,
|
|
3673
3769
|
onTotalsArrowClick: handleTotalsArrowClick,
|
|
3674
3770
|
formulaLocale,
|
|
3771
|
+
locale,
|
|
3675
3772
|
showGridLines,
|
|
3773
|
+
showZeros,
|
|
3676
3774
|
scale,
|
|
3677
3775
|
enableTextOverflow,
|
|
3678
3776
|
isRowHeader,
|
|
@@ -3710,7 +3808,7 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
3710
3808
|
getComment,
|
|
3711
3809
|
getEffectiveValue,
|
|
3712
3810
|
getSparklineGroup,
|
|
3713
|
-
getFormattedValue,
|
|
3811
|
+
getFormattedValue: getDisplayFormattedValue,
|
|
3714
3812
|
getCellImageUrl,
|
|
3715
3813
|
getEffectiveCellFormat,
|
|
3716
3814
|
getCellBounds,
|
|
@@ -3718,6 +3816,8 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
3718
3816
|
getRowHeaderText,
|
|
3719
3817
|
getColumnHeaderText,
|
|
3720
3818
|
getMaximumOverflowTextWidth,
|
|
3819
|
+
getCenterAcrossSelectionSpan,
|
|
3820
|
+
activeCell,
|
|
3721
3821
|
getTextDimension,
|
|
3722
3822
|
getCellGroupingInfo,
|
|
3723
3823
|
getTextFormatRuns,
|
|
@@ -3906,9 +4006,16 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
3906
4006
|
quickEditValues,
|
|
3907
4007
|
});
|
|
3908
4008
|
// A selected chart's source outlines draw on top of the other range borders.
|
|
3909
|
-
|
|
3910
|
-
|
|
3911
|
-
|
|
4009
|
+
// Page breaks (when the host shows them) dash across the sheet, Excel's
|
|
4010
|
+
// Normal-view page-break lines.
|
|
4011
|
+
const pageBreakBorderStyles = useMemo(() => getPageBreakBorderStyles(pageBreaks, rowCount, columnCount), [pageBreaks, rowCount, columnCount]);
|
|
4012
|
+
const gridBorderStyles = useMemo(() => chartSourceBorderStyles.length || pageBreakBorderStyles.length
|
|
4013
|
+
? [
|
|
4014
|
+
...pageBreakBorderStyles,
|
|
4015
|
+
...finalBorderStyles,
|
|
4016
|
+
...chartSourceBorderStyles,
|
|
4017
|
+
]
|
|
4018
|
+
: finalBorderStyles, [finalBorderStyles, chartSourceBorderStyles, pageBreakBorderStyles]);
|
|
3912
4019
|
// Hidden column markers
|
|
3913
4020
|
const [hiddenColumnMarkers, frozenHiddenColumnMarkers, hiddenRowMarkers, frozenHiddenRowMarkers,] = useHiddenDimensionMarkers({
|
|
3914
4021
|
sheetId,
|
|
@@ -4217,6 +4324,13 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
4217
4324
|
return;
|
|
4218
4325
|
}
|
|
4219
4326
|
const { rowIndex, columnIndex } = activeCell;
|
|
4327
|
+
// Excel's Format Cells ▸ Protection ▸ Hidden: while the sheet is protected, a hidden
|
|
4328
|
+
// cell's contents never show in the formula bar ("Protect a worksheet").
|
|
4329
|
+
if (isCellFormulaHiddenUnderProtection(getSheetProtection?.(sheetId), getCellData?.(sheetId, rowIndex, columnIndex)?.protection)) {
|
|
4330
|
+
setFormulabarEditorValue("");
|
|
4331
|
+
setFormulaBarTextFormatRuns(undefined);
|
|
4332
|
+
return;
|
|
4333
|
+
}
|
|
4220
4334
|
const value = getUserEnteredStringValue(sheetId, rowIndex, columnIndex);
|
|
4221
4335
|
const textFormatRuns = getTextFormatRuns?.(sheetId, rowIndex, columnIndex);
|
|
4222
4336
|
// Update formula bar input (in the grid's formula locale, like the cell editor)
|
|
@@ -4227,6 +4341,8 @@ function CanvasGridComponent(props, forwardedRef) {
|
|
|
4227
4341
|
formulaMode,
|
|
4228
4342
|
sheetId,
|
|
4229
4343
|
editingCellCoordinate,
|
|
4344
|
+
getSheetProtection,
|
|
4345
|
+
getCellData,
|
|
4230
4346
|
getUserEnteredStringValue,
|
|
4231
4347
|
formulaLocale,
|
|
4232
4348
|
setFormulabarEditorValue,
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ExtendedValue } from "@rowsncolumns/common-types";
|
|
2
|
+
/** What the grid knows about the cell text wants to spill into. */
|
|
3
|
+
export type OverflowNeighbour = {
|
|
4
|
+
formattedValue?: string | null;
|
|
5
|
+
effectiveValue?: ExtendedValue | null;
|
|
6
|
+
hasImage?: boolean;
|
|
7
|
+
/** An outline expand / collapse button paints in the cell. */
|
|
8
|
+
isExpandable?: boolean;
|
|
9
|
+
/** Row / column header cells. */
|
|
10
|
+
isHeader?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Present for the matrix test's sake: none of these block overflow in
|
|
13
|
+
* Excel, so the decision below never reads them.
|
|
14
|
+
*/
|
|
15
|
+
hasDataValidation?: boolean;
|
|
16
|
+
hasNote?: boolean;
|
|
17
|
+
isTableCell?: boolean;
|
|
18
|
+
isBanded?: boolean;
|
|
19
|
+
};
|
|
20
|
+
/** Does this cell stop text spilling from its neighbour? */
|
|
21
|
+
export declare const blocksOverflow: (cell: OverflowNeighbour) => boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Columns text claims walking from `start` by `step` (±1) until `need`
|
|
24
|
+
* pixels are covered or a blocking cell stops it.
|
|
25
|
+
*/
|
|
26
|
+
export declare const walkOverflowColumns: ({ start, step, need, canOverflow, columnWidth, maxSteps, }: {
|
|
27
|
+
start: number;
|
|
28
|
+
step: 1 | -1;
|
|
29
|
+
need: number;
|
|
30
|
+
canOverflow: (columnIndex: number) => boolean;
|
|
31
|
+
columnWidth: (columnIndex: number) => number;
|
|
32
|
+
maxSteps?: number;
|
|
33
|
+
}) => {
|
|
34
|
+
columns: number[];
|
|
35
|
+
width: number;
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=overflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"overflow.d.ts","sourceRoot":"","sources":["../../../../components/canvas-grid/overflow.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAGhE,mEAAmE;AACnE,MAAM,MAAM,iBAAiB,GAAG;IAC9B,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,cAAc,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,iCAAiC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAaF,4DAA4D;AAC5D,eAAO,MAAM,cAAc,GAAI,MAAM,iBAAiB,KAAG,OAK1B,CAAC;AAEhC;;;GAGG;AACH,eAAO,MAAM,mBAAmB,GAAI,4DAOjC;IACD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,WAAW,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,KAAG;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAWrC,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Text overflow into neighbouring cells, the way Excel decides it.
|
|
2
|
+
//
|
|
3
|
+
// Excel lets text spill over a neighbour only while that neighbour is empty:
|
|
4
|
+
// a cell holding anything — a formula returning "" included — stops it.
|
|
5
|
+
// Formatting, data validation, notes, table membership and banding never
|
|
6
|
+
// do; they are not content.
|
|
7
|
+
import { isNilOrBlank } from "@rowsncolumns/utils";
|
|
8
|
+
const hasValue = (value) => !!value &&
|
|
9
|
+
(value.nv != null ||
|
|
10
|
+
value.numberValue != null ||
|
|
11
|
+
value.sv != null ||
|
|
12
|
+
value.stringValue != null ||
|
|
13
|
+
value.bv != null ||
|
|
14
|
+
value.boolValue != null ||
|
|
15
|
+
value.ev != null ||
|
|
16
|
+
value.errorValue != null);
|
|
17
|
+
/** Does this cell stop text spilling from its neighbour? */
|
|
18
|
+
export const blocksOverflow = (cell) => !!cell.isHeader ||
|
|
19
|
+
!!cell.isExpandable ||
|
|
20
|
+
!!cell.hasImage ||
|
|
21
|
+
!isNilOrBlank(cell.formattedValue) ||
|
|
22
|
+
hasValue(cell.effectiveValue);
|
|
23
|
+
/**
|
|
24
|
+
* Columns text claims walking from `start` by `step` (±1) until `need`
|
|
25
|
+
* pixels are covered or a blocking cell stops it.
|
|
26
|
+
*/
|
|
27
|
+
export const walkOverflowColumns = ({ start, step, need, canOverflow, columnWidth, maxSteps = 512, }) => {
|
|
28
|
+
const columns = [];
|
|
29
|
+
let width = 0;
|
|
30
|
+
let column = start;
|
|
31
|
+
for (let i = 0; i < maxSteps && width < need; i++) {
|
|
32
|
+
column += step;
|
|
33
|
+
if (column < 0 || !canOverflow(column))
|
|
34
|
+
break;
|
|
35
|
+
columns.push(column);
|
|
36
|
+
width += columnWidth(column);
|
|
37
|
+
}
|
|
38
|
+
return { columns, width };
|
|
39
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AreaStyle } from "@rowsncolumns/grid";
|
|
2
|
+
export type SheetPageBreaks = {
|
|
3
|
+
/** 1-based rows AFTER which a page break falls (`<rowBreaks><brk id>`). */
|
|
4
|
+
rowBreaks?: number[] | null;
|
|
5
|
+
/** 1-based columns after which a page break falls. */
|
|
6
|
+
columnBreaks?: number[] | null;
|
|
7
|
+
};
|
|
8
|
+
export declare const PAGE_BREAK_COLOR = "#7F7F7F";
|
|
9
|
+
/**
|
|
10
|
+
* Range styles that paint the page-break dashes. Grid rows and columns are
|
|
11
|
+
* 1-based like the break ids, so a break after row N is the bottom edge of
|
|
12
|
+
* grid row N.
|
|
13
|
+
*/
|
|
14
|
+
export declare const getPageBreakBorderStyles: (pageBreaks: SheetPageBreaks | null | undefined, rowCount: number, columnCount: number) => AreaStyle[];
|
|
15
|
+
//# sourceMappingURL=page-breaks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-breaks.d.ts","sourceRoot":"","sources":["../../../../components/canvas-grid/page-breaks.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,MAAM,eAAe,GAAG;IAC5B,2EAA2E;IAC3E,SAAS,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAC5B,sDAAsD;IACtD,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,eAAO,MAAM,gBAAgB,YAAY,CAAC;AAE1C;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,GACnC,YAAY,eAAe,GAAG,IAAI,GAAG,SAAS,EAC9C,UAAU,MAAM,EAChB,aAAa,MAAM,KAClB,SAAS,EAyCX,CAAC"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export const PAGE_BREAK_COLOR = "#7F7F7F";
|
|
2
|
+
/**
|
|
3
|
+
* Range styles that paint the page-break dashes. Grid rows and columns are
|
|
4
|
+
* 1-based like the break ids, so a break after row N is the bottom edge of
|
|
5
|
+
* grid row N.
|
|
6
|
+
*/
|
|
7
|
+
export const getPageBreakBorderStyles = (pageBreaks, rowCount, columnCount) => {
|
|
8
|
+
const styles = [];
|
|
9
|
+
for (const row of pageBreaks?.rowBreaks ?? []) {
|
|
10
|
+
if (row < 1 || row >= rowCount)
|
|
11
|
+
continue;
|
|
12
|
+
styles.push({
|
|
13
|
+
index: `page-break-row-${row}`,
|
|
14
|
+
type: "border",
|
|
15
|
+
range: {
|
|
16
|
+
startRowIndex: row,
|
|
17
|
+
endRowIndex: row,
|
|
18
|
+
startColumnIndex: 1,
|
|
19
|
+
endColumnIndex: columnCount - 1,
|
|
20
|
+
},
|
|
21
|
+
style: {
|
|
22
|
+
strokeWidth: 0,
|
|
23
|
+
strokeBottomWidth: 1,
|
|
24
|
+
strokeBottomColor: PAGE_BREAK_COLOR,
|
|
25
|
+
strokeStyle: "dashed",
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
for (const column of pageBreaks?.columnBreaks ?? []) {
|
|
30
|
+
if (column < 1 || column >= columnCount)
|
|
31
|
+
continue;
|
|
32
|
+
styles.push({
|
|
33
|
+
index: `page-break-column-${column}`,
|
|
34
|
+
type: "border",
|
|
35
|
+
range: {
|
|
36
|
+
startRowIndex: 1,
|
|
37
|
+
endRowIndex: rowCount - 1,
|
|
38
|
+
startColumnIndex: column,
|
|
39
|
+
endColumnIndex: column,
|
|
40
|
+
},
|
|
41
|
+
style: {
|
|
42
|
+
strokeWidth: 0,
|
|
43
|
+
strokeRightWidth: 1,
|
|
44
|
+
strokeRightColor: PAGE_BREAK_COLOR,
|
|
45
|
+
strokeStyle: "dashed",
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return styles;
|
|
50
|
+
};
|