@rowsncolumns/spreadsheet 10.6.4 → 10.7.0
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/autocomplete.d.ts +42 -0
- package/dist/cjs/api/autocomplete.d.ts.map +1 -0
- package/dist/cjs/api/autocomplete.js +114 -0
- package/dist/cjs/api/banded-ranges.d.ts.map +1 -1
- package/dist/cjs/api/banded-ranges.js +51 -1
- package/dist/cjs/api/error-checking.d.ts +82 -0
- package/dist/cjs/api/error-checking.d.ts.map +1 -0
- package/dist/cjs/api/error-checking.js +207 -0
- package/dist/cjs/api/move-overwrite.d.ts +8 -2
- package/dist/cjs/api/move-overwrite.d.ts.map +1 -1
- package/dist/cjs/api/move-overwrite.js +19 -3
- package/dist/cjs/api/selections.d.ts +2 -2
- package/dist/cjs/api/validation.d.ts +39 -1
- package/dist/cjs/api/validation.d.ts.map +1 -1
- package/dist/cjs/api/validation.js +87 -1
- package/dist/cjs/atoms/cell-input-context.atom.d.ts +4 -1
- package/dist/cjs/atoms/cell-input-context.atom.d.ts.map +1 -1
- package/dist/cjs/atoms/enter-key-direction.atom.d.ts +11 -0
- package/dist/cjs/atoms/enter-key-direction.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/enter-key-direction.atom.js +13 -0
- package/dist/cjs/atoms/index.d.ts +1 -0
- package/dist/cjs/atoms/index.d.ts.map +1 -1
- package/dist/cjs/atoms/index.js +1 -0
- package/dist/cjs/atoms/paste-menu.atom.d.ts +22 -0
- package/dist/cjs/atoms/paste-menu.atom.d.ts.map +1 -1
- package/dist/cjs/atoms/paste-menu.atom.js +13 -1
- package/dist/cjs/atoms/pick-list.atom.d.ts +15 -0
- package/dist/cjs/atoms/pick-list.atom.d.ts.map +1 -0
- package/dist/cjs/atoms/pick-list.atom.js +7 -0
- package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
- package/dist/cjs/components/canvas-grid/index.js +305 -70
- package/dist/cjs/components/canvas-grid/typings.d.ts +96 -11
- package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
- package/dist/cjs/components/cell/alignment.d.ts +25 -0
- package/dist/cjs/components/cell/alignment.d.ts.map +1 -1
- package/dist/cjs/components/cell/alignment.js +39 -1
- package/dist/cjs/components/cell/cell-background.d.ts +16 -0
- package/dist/cjs/components/cell/cell-background.d.ts.map +1 -1
- package/dist/cjs/components/cell/cell-background.js +141 -54
- package/dist/cjs/components/cell/cell-text-runs.d.ts +12 -5
- package/dist/cjs/components/cell/cell-text-runs.d.ts.map +1 -1
- package/dist/cjs/components/cell/cell-text-runs.js +18 -20
- package/dist/cjs/components/cell/index.d.ts.map +1 -1
- package/dist/cjs/components/cell/index.js +26 -21
- package/dist/cjs/components/cell/typings.d.ts +9 -0
- package/dist/cjs/components/cell/typings.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/helpers.d.ts +22 -2
- package/dist/cjs/components/cell-editor/helpers.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/helpers.js +32 -8
- package/dist/cjs/components/cell-editor/index.d.ts +7 -1
- package/dist/cjs/components/cell-editor/index.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/index.js +85 -13
- package/dist/cjs/components/cell-indicator/index.d.ts +41 -0
- package/dist/cjs/components/cell-indicator/index.d.ts.map +1 -0
- package/dist/cjs/components/cell-indicator/index.js +90 -0
- package/dist/cjs/components/cell-input/cell-input.d.ts +10 -2
- package/dist/cjs/components/cell-input/cell-input.d.ts.map +1 -1
- package/dist/cjs/components/cell-input/cell-input.js +5 -3
- package/dist/cjs/components/cell-input/formula-bar-cell-input.d.ts.map +1 -1
- package/dist/cjs/components/cell-input/formula-bar-cell-input.js +9 -2
- package/dist/cjs/components/cell-structured/sparkline-math.d.ts +27 -1
- package/dist/cjs/components/cell-structured/sparkline-math.d.ts.map +1 -1
- package/dist/cjs/components/cell-structured/sparkline-math.js +48 -1
- package/dist/cjs/components/cell-structured/sparkline.d.ts +1 -1
- package/dist/cjs/components/cell-structured/sparkline.d.ts.map +1 -1
- package/dist/cjs/components/cell-structured/sparkline.js +36 -92
- package/dist/cjs/components/cell-structured/types.d.ts +6 -0
- package/dist/cjs/components/cell-structured/types.d.ts.map +1 -1
- package/dist/cjs/components/data-table-dialog/index.d.ts +22 -0
- package/dist/cjs/components/data-table-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/data-table-dialog/index.js +93 -0
- package/dist/cjs/components/error-check-smart-tag/index.d.ts +27 -0
- package/dist/cjs/components/error-check-smart-tag/index.d.ts.map +1 -0
- package/dist/cjs/components/error-check-smart-tag/index.js +39 -0
- package/dist/cjs/components/forecast-sheet-dialog/index.d.ts +26 -0
- package/dist/cjs/components/forecast-sheet-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/forecast-sheet-dialog/index.js +92 -0
- package/dist/cjs/components/paste-special-dialog/index.d.ts +3 -3
- package/dist/cjs/components/paste-special-dialog/index.d.ts.map +1 -1
- package/dist/cjs/components/paste-special-dialog/index.js +61 -23
- package/dist/cjs/components/protect-sheet-dialog/allow-edit-ranges-dialog.d.ts +57 -0
- package/dist/cjs/components/protect-sheet-dialog/allow-edit-ranges-dialog.d.ts.map +1 -0
- package/dist/cjs/components/protect-sheet-dialog/allow-edit-ranges-dialog.js +196 -0
- package/dist/cjs/components/protect-sheet-dialog/constants.d.ts +3 -0
- package/dist/cjs/components/protect-sheet-dialog/constants.d.ts.map +1 -0
- package/dist/cjs/components/protect-sheet-dialog/constants.js +5 -0
- package/dist/cjs/components/protect-sheet-dialog/index.d.ts +2 -2
- package/dist/cjs/components/protect-sheet-dialog/index.d.ts.map +1 -1
- package/dist/cjs/components/protect-sheet-dialog/index.js +5 -3
- package/dist/cjs/components/scenario-manager-dialog/index.d.ts +51 -0
- package/dist/cjs/components/scenario-manager-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/scenario-manager-dialog/index.js +257 -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 +9 -4
- package/dist/cjs/components/selection/paste-menu.d.ts +14 -1
- package/dist/cjs/components/selection/paste-menu.d.ts.map +1 -1
- package/dist/cjs/components/selection/paste-menu.js +78 -6
- package/dist/cjs/components/selection/paste-options.d.ts +28 -0
- package/dist/cjs/components/selection/paste-options.d.ts.map +1 -0
- package/dist/cjs/components/selection/paste-options.js +70 -0
- package/dist/cjs/components/selection/types.d.ts +12 -1
- package/dist/cjs/components/selection/types.d.ts.map +1 -1
- package/dist/cjs/components/selection-drop-menu/index.d.ts +18 -0
- package/dist/cjs/components/selection-drop-menu/index.d.ts.map +1 -0
- package/dist/cjs/components/selection-drop-menu/index.js +62 -0
- package/dist/cjs/components/solver-dialog/index.d.ts +57 -0
- package/dist/cjs/components/solver-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/solver-dialog/index.js +204 -0
- package/dist/cjs/components/toolbar/sparkline-actions.d.ts +3 -2
- package/dist/cjs/components/toolbar/sparkline-actions.d.ts.map +1 -1
- package/dist/cjs/components/toolbar/sparkline-actions.js +6 -2
- package/dist/cjs/components/toolbar/table-style-selector.d.ts.map +1 -1
- package/dist/cjs/components/toolbar/table-style-selector.js +33 -2
- package/dist/cjs/config.d.ts +5 -4
- package/dist/cjs/config.d.ts.map +1 -1
- package/dist/cjs/config.js +13 -9
- package/dist/cjs/helpers.d.ts +5 -0
- package/dist/cjs/helpers.d.ts.map +1 -1
- package/dist/cjs/helpers.js +8 -4
- package/dist/cjs/hooks/use-cell-renderer.d.ts +12 -1
- package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
- package/dist/cjs/hooks/use-cell-renderer.js +6 -3
- package/dist/cjs/hooks/use-copy-paste-cut.d.ts +36 -2
- package/dist/cjs/hooks/use-copy-paste-cut.d.ts.map +1 -1
- package/dist/cjs/hooks/use-copy-paste-cut.js +131 -5
- package/dist/cjs/hooks/use-editable.d.ts +6 -0
- package/dist/cjs/hooks/use-editable.d.ts.map +1 -1
- package/dist/cjs/hooks/use-editor-submit.d.ts +45 -3
- package/dist/cjs/hooks/use-editor-submit.d.ts.map +1 -1
- package/dist/cjs/hooks/use-editor-submit.js +91 -7
- package/dist/cjs/hooks/use-keyboard-handler.d.ts +5 -1
- package/dist/cjs/hooks/use-keyboard-handler.d.ts.map +1 -1
- package/dist/cjs/hooks/use-keyboard-handler.js +10 -1
- package/dist/cjs/hooks/use-selection-drag-copy.d.ts +55 -0
- package/dist/cjs/hooks/use-selection-drag-copy.d.ts.map +1 -0
- package/dist/cjs/hooks/use-selection-drag-copy.js +274 -0
- package/dist/cjs/hooks/use-selection-renderer.d.ts +8 -1
- package/dist/cjs/hooks/use-selection-renderer.d.ts.map +1 -1
- package/dist/cjs/hooks/use-selection-renderer.js +7 -2
- package/dist/cjs/hooks/use-selection.d.ts +59 -1
- package/dist/cjs/hooks/use-selection.d.ts.map +1 -1
- package/dist/cjs/hooks/use-selection.js +270 -61
- package/dist/cjs/index.d.ts +6 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +5 -0
- package/dist/cjs/release-date.js +1 -1
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/types.d.ts +50 -1
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/api/autocomplete.d.ts +42 -0
- package/dist/esm/api/autocomplete.d.ts.map +1 -0
- package/dist/esm/api/autocomplete.js +91 -0
- package/dist/esm/api/banded-ranges.d.ts.map +1 -1
- package/dist/esm/api/banded-ranges.js +52 -2
- package/dist/esm/api/error-checking.d.ts +82 -0
- package/dist/esm/api/error-checking.d.ts.map +1 -0
- package/dist/esm/api/error-checking.js +156 -0
- package/dist/esm/api/move-overwrite.d.ts +8 -2
- package/dist/esm/api/move-overwrite.d.ts.map +1 -1
- package/dist/esm/api/move-overwrite.js +17 -2
- package/dist/esm/api/selections.d.ts +2 -2
- package/dist/esm/api/validation.d.ts +39 -1
- package/dist/esm/api/validation.d.ts.map +1 -1
- package/dist/esm/api/validation.js +70 -0
- package/dist/esm/atoms/cell-input-context.atom.d.ts +4 -1
- package/dist/esm/atoms/cell-input-context.atom.d.ts.map +1 -1
- package/dist/esm/atoms/enter-key-direction.atom.d.ts +11 -0
- package/dist/esm/atoms/enter-key-direction.atom.d.ts.map +1 -0
- package/dist/esm/atoms/enter-key-direction.atom.js +8 -0
- package/dist/esm/atoms/index.d.ts +1 -0
- package/dist/esm/atoms/index.d.ts.map +1 -1
- package/dist/esm/atoms/index.js +1 -0
- package/dist/esm/atoms/paste-menu.atom.d.ts +22 -0
- package/dist/esm/atoms/paste-menu.atom.d.ts.map +1 -1
- package/dist/esm/atoms/paste-menu.atom.js +10 -1
- package/dist/esm/atoms/pick-list.atom.d.ts +15 -0
- package/dist/esm/atoms/pick-list.atom.d.ts.map +1 -0
- package/dist/esm/atoms/pick-list.atom.js +3 -0
- package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
- package/dist/esm/components/canvas-grid/index.js +239 -13
- package/dist/esm/components/canvas-grid/typings.d.ts +96 -11
- package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
- package/dist/esm/components/cell/alignment.d.ts +25 -0
- package/dist/esm/components/cell/alignment.d.ts.map +1 -1
- package/dist/esm/components/cell/alignment.js +33 -0
- package/dist/esm/components/cell/cell-background.d.ts +16 -0
- package/dist/esm/components/cell/cell-background.d.ts.map +1 -1
- package/dist/esm/components/cell/cell-background.js +106 -36
- package/dist/esm/components/cell/cell-text-runs.d.ts +12 -5
- package/dist/esm/components/cell/cell-text-runs.d.ts.map +1 -1
- package/dist/esm/components/cell/cell-text-runs.js +17 -22
- package/dist/esm/components/cell/index.d.ts.map +1 -1
- package/dist/esm/components/cell/index.js +25 -20
- package/dist/esm/components/cell/typings.d.ts +9 -0
- package/dist/esm/components/cell/typings.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/helpers.d.ts +22 -2
- package/dist/esm/components/cell-editor/helpers.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/helpers.js +25 -7
- package/dist/esm/components/cell-editor/index.d.ts +7 -1
- package/dist/esm/components/cell-editor/index.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/index.js +80 -9
- package/dist/esm/components/cell-indicator/index.d.ts +41 -0
- package/dist/esm/components/cell-indicator/index.d.ts.map +1 -0
- package/dist/esm/components/cell-indicator/index.js +76 -0
- package/dist/esm/components/cell-input/cell-input.d.ts +10 -2
- package/dist/esm/components/cell-input/cell-input.d.ts.map +1 -1
- package/dist/esm/components/cell-input/cell-input.js +5 -3
- package/dist/esm/components/cell-input/formula-bar-cell-input.d.ts.map +1 -1
- package/dist/esm/components/cell-input/formula-bar-cell-input.js +9 -2
- package/dist/esm/components/cell-structured/sparkline-math.d.ts +27 -1
- package/dist/esm/components/cell-structured/sparkline-math.d.ts.map +1 -1
- package/dist/esm/components/cell-structured/sparkline-math.js +35 -0
- package/dist/esm/components/cell-structured/sparkline.d.ts +1 -1
- package/dist/esm/components/cell-structured/sparkline.d.ts.map +1 -1
- package/dist/esm/components/cell-structured/sparkline.js +34 -88
- package/dist/esm/components/cell-structured/types.d.ts +6 -0
- package/dist/esm/components/cell-structured/types.d.ts.map +1 -1
- package/dist/esm/components/data-table-dialog/index.d.ts +22 -0
- package/dist/esm/components/data-table-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/data-table-dialog/index.js +75 -0
- package/dist/esm/components/error-check-smart-tag/index.d.ts +27 -0
- package/dist/esm/components/error-check-smart-tag/index.d.ts.map +1 -0
- package/dist/esm/components/error-check-smart-tag/index.js +33 -0
- package/dist/esm/components/forecast-sheet-dialog/index.d.ts +26 -0
- package/dist/esm/components/forecast-sheet-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/forecast-sheet-dialog/index.js +83 -0
- package/dist/esm/components/paste-special-dialog/index.d.ts +3 -3
- package/dist/esm/components/paste-special-dialog/index.d.ts.map +1 -1
- package/dist/esm/components/paste-special-dialog/index.js +58 -23
- package/dist/esm/components/protect-sheet-dialog/allow-edit-ranges-dialog.d.ts +57 -0
- package/dist/esm/components/protect-sheet-dialog/allow-edit-ranges-dialog.d.ts.map +1 -0
- package/dist/esm/components/protect-sheet-dialog/allow-edit-ranges-dialog.js +177 -0
- package/dist/esm/components/protect-sheet-dialog/constants.d.ts +3 -0
- package/dist/esm/components/protect-sheet-dialog/constants.d.ts.map +1 -0
- package/dist/esm/components/protect-sheet-dialog/constants.js +2 -0
- package/dist/esm/components/protect-sheet-dialog/index.d.ts +2 -2
- package/dist/esm/components/protect-sheet-dialog/index.d.ts.map +1 -1
- package/dist/esm/components/protect-sheet-dialog/index.js +3 -2
- package/dist/esm/components/scenario-manager-dialog/index.d.ts +51 -0
- package/dist/esm/components/scenario-manager-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/scenario-manager-dialog/index.js +213 -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 +9 -4
- package/dist/esm/components/selection/paste-menu.d.ts +14 -1
- package/dist/esm/components/selection/paste-menu.d.ts.map +1 -1
- package/dist/esm/components/selection/paste-menu.js +76 -8
- package/dist/esm/components/selection/paste-options.d.ts +28 -0
- package/dist/esm/components/selection/paste-options.d.ts.map +1 -0
- package/dist/esm/components/selection/paste-options.js +62 -0
- package/dist/esm/components/selection/types.d.ts +12 -1
- package/dist/esm/components/selection/types.d.ts.map +1 -1
- package/dist/esm/components/selection-drop-menu/index.d.ts +18 -0
- package/dist/esm/components/selection-drop-menu/index.d.ts.map +1 -0
- package/dist/esm/components/selection-drop-menu/index.js +56 -0
- package/dist/esm/components/solver-dialog/index.d.ts +57 -0
- package/dist/esm/components/solver-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/solver-dialog/index.js +176 -0
- package/dist/esm/components/toolbar/sparkline-actions.d.ts +3 -2
- package/dist/esm/components/toolbar/sparkline-actions.d.ts.map +1 -1
- package/dist/esm/components/toolbar/sparkline-actions.js +6 -2
- package/dist/esm/components/toolbar/table-style-selector.d.ts.map +1 -1
- package/dist/esm/components/toolbar/table-style-selector.js +29 -3
- package/dist/esm/config.d.ts +5 -4
- package/dist/esm/config.d.ts.map +1 -1
- package/dist/esm/config.js +12 -8
- package/dist/esm/helpers.d.ts +5 -0
- package/dist/esm/helpers.d.ts.map +1 -1
- package/dist/esm/helpers.js +8 -4
- package/dist/esm/hooks/use-cell-renderer.d.ts +12 -1
- package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
- package/dist/esm/hooks/use-cell-renderer.js +5 -2
- package/dist/esm/hooks/use-copy-paste-cut.d.ts +36 -2
- package/dist/esm/hooks/use-copy-paste-cut.d.ts.map +1 -1
- package/dist/esm/hooks/use-copy-paste-cut.js +117 -6
- package/dist/esm/hooks/use-editable.d.ts +6 -0
- package/dist/esm/hooks/use-editable.d.ts.map +1 -1
- package/dist/esm/hooks/use-editor-submit.d.ts +45 -3
- package/dist/esm/hooks/use-editor-submit.d.ts.map +1 -1
- package/dist/esm/hooks/use-editor-submit.js +81 -6
- package/dist/esm/hooks/use-keyboard-handler.d.ts +5 -1
- package/dist/esm/hooks/use-keyboard-handler.d.ts.map +1 -1
- package/dist/esm/hooks/use-keyboard-handler.js +10 -1
- package/dist/esm/hooks/use-selection-drag-copy.d.ts +55 -0
- package/dist/esm/hooks/use-selection-drag-copy.d.ts.map +1 -0
- package/dist/esm/hooks/use-selection-drag-copy.js +245 -0
- package/dist/esm/hooks/use-selection-renderer.d.ts +8 -1
- package/dist/esm/hooks/use-selection-renderer.d.ts.map +1 -1
- package/dist/esm/hooks/use-selection-renderer.js +7 -2
- package/dist/esm/hooks/use-selection.d.ts +59 -1
- package/dist/esm/hooks/use-selection.d.ts.map +1 -1
- package/dist/esm/hooks/use-selection.js +245 -52
- package/dist/esm/index.d.ts +6 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +5 -0
- package/dist/esm/release-date.js +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/types.d.ts +50 -1
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/spreadsheet.min.css +1 -1
- package/package.json +6 -5
- package/dist/cjs/components/cell-error/index.d.ts +0 -14
- package/dist/cjs/components/cell-error/index.d.ts.map +0 -1
- package/dist/cjs/components/cell-error/index.js +0 -24
- package/dist/esm/components/cell-error/index.d.ts +0 -14
- package/dist/esm/components/cell-error/index.d.ts.map +0 -1
- package/dist/esm/components/cell-error/index.js +0 -18
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { useCallback } from "react";
|
|
3
3
|
import { Shape } from "react-konva";
|
|
4
|
-
import { clampToExtents, resolveSparklineSeries, resolveSparklineExtents, } from "./sparkline-math";
|
|
4
|
+
import { clampToExtents, OFFICE_DEFAULT_SPARKLINE_COLORS, resolveSparklineSeries, resolveSparklineExtents, } from "./sparkline-math";
|
|
5
5
|
// Draw a diamond marker at the specified position
|
|
6
6
|
const drawDiamond = (ctx, x, y, size, fillColor) => {
|
|
7
7
|
ctx.beginPath();
|
|
@@ -13,7 +13,7 @@ const drawDiamond = (ctx, x, y, size, fillColor) => {
|
|
|
13
13
|
ctx.fillStyle = fillColor;
|
|
14
14
|
ctx.fill();
|
|
15
15
|
};
|
|
16
|
-
export const Sparkline = ({ x, y, width, height, data, options,
|
|
16
|
+
export const Sparkline = ({ x, y, width, height, data, options, sparklineGroupAxis, sparklineDefaultColors: defaultColors = OFFICE_DEFAULT_SPARKLINE_COLORS, }) => {
|
|
17
17
|
const sparkLineFunction = useCallback((ctx, shape) => {
|
|
18
18
|
// Guard against undefined data (formula not yet evaluated)
|
|
19
19
|
if (!data || !Array.isArray(data)) {
|
|
@@ -21,8 +21,9 @@ export const Sparkline = ({ x, y, width, height, data, options, color, sparkline
|
|
|
21
21
|
}
|
|
22
22
|
const padding = 4;
|
|
23
23
|
const paddingTop = 4;
|
|
24
|
-
|
|
25
|
-
const
|
|
24
|
+
// Excel paints the series in the group's colour, Style 1's when it has none — never the cell's.
|
|
25
|
+
const lineColor = options?.color ?? defaultColors.series;
|
|
26
|
+
const fillColor = lineColor;
|
|
26
27
|
const lineWidth = typeof options?.lineweight === "number" && options.lineweight > 0
|
|
27
28
|
? options.lineweight
|
|
28
29
|
: 1;
|
|
@@ -68,35 +69,27 @@ export const Sparkline = ({ x, y, width, height, data, options, color, sparkline
|
|
|
68
69
|
const lastDataIndex = slots.reduce((m, slot) => (slot.dataIndex > m ? slot.dataIndex : m), -1);
|
|
69
70
|
// Store points for markers
|
|
70
71
|
const points = [];
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
// its own color.
|
|
77
|
-
const pickColumnColor = (value, slotIndex, dataIndex) => {
|
|
78
|
-
const isHigh = slotIndex === maxSlotIndex;
|
|
79
|
-
const isLow = slotIndex === minSlotIndex;
|
|
80
|
-
const isFirst = dataIndex === 0;
|
|
81
|
-
const isLast = dataIndex >= 0 && dataIndex === lastDataIndex;
|
|
82
|
-
const isNegative = value < 0;
|
|
83
|
-
if (options?.negative && isNegative) {
|
|
84
|
-
return options.colorNegative ?? "#FF0000";
|
|
72
|
+
// Excel's point highlights: each of Negative / High / Low / First / Last Points colours its
|
|
73
|
+
// point (a column, a bar or a line marker) only while it is checked — none is by default.
|
|
74
|
+
const pointHighlight = (value, slotIndex, dataIndex) => {
|
|
75
|
+
if (options?.negative && value < 0) {
|
|
76
|
+
return options.colorNegative ?? defaultColors.negative;
|
|
85
77
|
}
|
|
86
|
-
if (options?.high &&
|
|
87
|
-
return options.colorHigh ??
|
|
78
|
+
if (options?.high && slotIndex === maxSlotIndex) {
|
|
79
|
+
return options.colorHigh ?? defaultColors.high;
|
|
88
80
|
}
|
|
89
|
-
if (options?.low &&
|
|
90
|
-
return options.colorLow ??
|
|
81
|
+
if (options?.low && slotIndex === minSlotIndex) {
|
|
82
|
+
return options.colorLow ?? defaultColors.low;
|
|
91
83
|
}
|
|
92
|
-
if (options?.first &&
|
|
93
|
-
return options.colorFirst ??
|
|
84
|
+
if (options?.first && dataIndex === 0) {
|
|
85
|
+
return options.colorFirst ?? defaultColors.first;
|
|
94
86
|
}
|
|
95
|
-
if (options?.last &&
|
|
96
|
-
return options.colorLast ??
|
|
87
|
+
if (options?.last && dataIndex >= 0 && dataIndex === lastDataIndex) {
|
|
88
|
+
return options.colorLast ?? defaultColors.last;
|
|
97
89
|
}
|
|
98
|
-
return
|
|
90
|
+
return undefined;
|
|
99
91
|
};
|
|
92
|
+
const pickColumnColor = (value, slotIndex, dataIndex) => pointHighlight(value, slotIndex, dataIndex) ?? fillColor;
|
|
100
93
|
// Draw the horizontal (zero) axis when requested via the `axis`
|
|
101
94
|
// (displayXAxis) option. Only meaningful when zero falls inside
|
|
102
95
|
// the vertical extents; winloss already anchors bars on zeroY.
|
|
@@ -169,21 +162,10 @@ export const Sparkline = ({ x, y, width, height, data, options, color, sparkline
|
|
|
169
162
|
const columnX = pointX + (xScale - columnWidth) / 2;
|
|
170
163
|
const barHeight = Math.abs(clamped) * yScale;
|
|
171
164
|
const barY = clamped >= 0 ? zeroY - barHeight : zeroY;
|
|
172
|
-
//
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
? options?.color ?? "#00B050"
|
|
176
|
-
: options?.colorNegative ?? "#FF0000";
|
|
165
|
+
// Wins and losses both paint in the series colour; Negative Points (and the other
|
|
166
|
+
// point toggles) recolour their bars, as on a column sparkline.
|
|
167
|
+
ctx.fillStyle = pickColumnColor(value, index, slot.dataIndex);
|
|
177
168
|
ctx.fillRect(columnX, barY, columnWidth, Math.max(barHeight, 2));
|
|
178
|
-
// Store points for diamond markers
|
|
179
|
-
const markerY = clamped >= 0 ? zeroY - barHeight : zeroY + barHeight;
|
|
180
|
-
points.push({
|
|
181
|
-
x: pointX + xScale / 2,
|
|
182
|
-
y: markerY,
|
|
183
|
-
value,
|
|
184
|
-
slotIndex: index,
|
|
185
|
-
dataIndex: slot.dataIndex,
|
|
186
|
-
});
|
|
187
169
|
}
|
|
188
170
|
});
|
|
189
171
|
// Stroke the line for 'line' type. Column sparklines are filled
|
|
@@ -191,56 +173,20 @@ export const Sparkline = ({ x, y, width, height, data, options, color, sparkline
|
|
|
191
173
|
if (type === "line") {
|
|
192
174
|
ctx.stroke();
|
|
193
175
|
}
|
|
194
|
-
//
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
const markerSize = isWinLoss ? 4 : 3;
|
|
176
|
+
// Excel's markers are a line sparkline's: every point gets one only with "Markers" checked,
|
|
177
|
+
// and a checked point toggle marks its own point in its colour. Nothing by default.
|
|
178
|
+
if (type === "line") {
|
|
179
|
+
const markerSize = 3;
|
|
199
180
|
points.forEach((point) => {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
const isHigh = point.slotIndex === maxSlotIndex;
|
|
207
|
-
const isLow = point.slotIndex === minSlotIndex;
|
|
208
|
-
const isNegative = point.value < 0;
|
|
209
|
-
if (isWinLoss) {
|
|
210
|
-
// Win/loss: green for positive, red for negative
|
|
211
|
-
markerColor = isNegative
|
|
212
|
-
? options?.colorNegative ?? "#FF0000"
|
|
213
|
-
: options?.colorHigh ?? options?.color ?? "#00B050";
|
|
214
|
-
}
|
|
215
|
-
else {
|
|
216
|
-
// Line sparkline: use high/low colors for min/max points
|
|
217
|
-
if (isHigh && isLow) {
|
|
218
|
-
// Same point is both high and low (single point or all same)
|
|
219
|
-
markerColor = options?.colorHigh ?? options?.color ?? lineColor;
|
|
220
|
-
}
|
|
221
|
-
else if (isHigh) {
|
|
222
|
-
markerColor = options?.colorHigh ?? "#00B050";
|
|
223
|
-
}
|
|
224
|
-
else if (isLow) {
|
|
225
|
-
markerColor = options?.colorLow ?? "#FF0000";
|
|
226
|
-
}
|
|
227
|
-
else if (isFirst && options?.colorFirst) {
|
|
228
|
-
markerColor = options.colorFirst;
|
|
229
|
-
}
|
|
230
|
-
else if (isLast && options?.colorLast) {
|
|
231
|
-
markerColor = options.colorLast;
|
|
232
|
-
}
|
|
233
|
-
else if (isNegative) {
|
|
234
|
-
markerColor = options?.colorNegative ?? "#FF0000";
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
markerColor =
|
|
238
|
-
options?.colorMarkers ?? options?.color ?? lineColor;
|
|
239
|
-
}
|
|
181
|
+
const markerColor = pointHighlight(point.value, point.slotIndex, point.dataIndex) ??
|
|
182
|
+
(options?.markers
|
|
183
|
+
? options.colorMarkers ?? defaultColors.markers
|
|
184
|
+
: undefined);
|
|
185
|
+
if (markerColor) {
|
|
186
|
+
drawDiamond(ctx, point.x, point.y, markerSize, markerColor);
|
|
240
187
|
}
|
|
241
|
-
drawDiamond(ctx, point.x, point.y, markerSize, markerColor);
|
|
242
188
|
});
|
|
243
189
|
}
|
|
244
|
-
}, [data, options,
|
|
190
|
+
}, [data, options, sparklineGroupAxis, defaultColors]);
|
|
245
191
|
return (React.createElement(Shape, { x: x, y: y, width: width, height: height, sceneFunc: sparkLineFunction, listening: false }));
|
|
246
192
|
};
|
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
import type { StructuredResult } from "@rowsncolumns/common-types";
|
|
2
2
|
import type { CellProps } from "../cell/typings";
|
|
3
|
+
import type { SparklineDefaultColors } from "./sparkline-math";
|
|
3
4
|
export type StructuredResultProps<S extends StructuredResult = StructuredResult> = Pick<CellProps<S>, "structuredValue" | "sparklineGroupAxis"> & {
|
|
4
5
|
x: number;
|
|
5
6
|
y: number;
|
|
6
7
|
width: number;
|
|
7
8
|
height: number;
|
|
8
9
|
color?: string;
|
|
10
|
+
/**
|
|
11
|
+
* The colours a sparkline paints where its formula sets none: Excel's Style 1 through the
|
|
12
|
+
* workbook theme. Without it, Style 1 under the Office 2013–2022 theme.
|
|
13
|
+
*/
|
|
14
|
+
sparklineDefaultColors?: SparklineDefaultColors;
|
|
9
15
|
textX?: number;
|
|
10
16
|
textY?: number;
|
|
11
17
|
textWidth?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../components/cell-structured/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../components/cell-structured/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,MAAM,MAAM,qBAAqB,CAC/B,CAAC,SAAS,gBAAgB,GAAG,gBAAgB,IAC3C,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,iBAAiB,GAAG,oBAAoB,CAAC,GAAG;IACjE,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,sBAAsB,CAAC,EAAE,sBAAsB,CAAC;IAEhD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/** Excel's refusal for an empty dialog or a reference that is not one cell. */
|
|
3
|
+
export declare const DATA_TABLE_INPUT_MESSAGE = "Input cell reference is not valid.";
|
|
4
|
+
export type DataTableDialogProps = {
|
|
5
|
+
/** Controls visibility. */
|
|
6
|
+
open: boolean;
|
|
7
|
+
onOpenChange(open: boolean): void;
|
|
8
|
+
/**
|
|
9
|
+
* Creates the table over the current selection (formula row / column and
|
|
10
|
+
* input values included) with the given A1 input cells, either of which may
|
|
11
|
+
* be empty. Resolves to Excel's refusal message when the engine refused
|
|
12
|
+
* (e.g. "Cannot change part of a data table."), `undefined` on success.
|
|
13
|
+
*/
|
|
14
|
+
onApply(rowInputCell: string | undefined, columnInputCell: string | undefined): Promise<string | undefined> | string | undefined;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Excel's Data ▸ What-If Analysis ▸ Data Table… dialog: Row input cell /
|
|
18
|
+
* Column input cell. One of them makes a one-variable table, both a
|
|
19
|
+
* two-variable table.
|
|
20
|
+
*/
|
|
21
|
+
export declare const DataTableDialog: React.MemoExoticComponent<({ open, onOpenChange, onApply }: DataTableDialogProps) => React.JSX.Element>;
|
|
22
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/data-table-dialog/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,+EAA+E;AAC/E,eAAO,MAAM,wBAAwB,uCAAuC,CAAC;AAE7E,MAAM,MAAM,oBAAoB,GAAG;IACjC,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC;;;;;OAKG;IACH,OAAO,CACL,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,eAAe,EAAE,MAAM,GAAG,SAAS,GAClC,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;CACrD,CAAC;AAKF;;;;GAIG;AACH,eAAO,MAAM,eAAe,8DAA0C,oBAAoB,uBAoGxF,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Cross1Icon } from "@rowsncolumns/icons";
|
|
2
|
+
import { Button, Dialog, DialogBody, DialogCloseButton, DialogContent, DialogDescription, DialogTitle, Input, Separator, } from "@rowsncolumns/ui";
|
|
3
|
+
import { addressToCell } from "@rowsncolumns/utils";
|
|
4
|
+
import React, { memo, useCallback, useEffect, useState } from "react";
|
|
5
|
+
/** Excel's refusal for an empty dialog or a reference that is not one cell. */
|
|
6
|
+
export const DATA_TABLE_INPUT_MESSAGE = "Input cell reference is not valid.";
|
|
7
|
+
const isCellReference = (text) => /^\$?[A-Za-z]{1,3}\$?\d+$/.test(text.trim()) && addressToCell(text.trim()) != null;
|
|
8
|
+
/**
|
|
9
|
+
* Excel's Data ▸ What-If Analysis ▸ Data Table… dialog: Row input cell /
|
|
10
|
+
* Column input cell. One of them makes a one-variable table, both a
|
|
11
|
+
* two-variable table.
|
|
12
|
+
*/
|
|
13
|
+
export const DataTableDialog = memo(({ open, onOpenChange, onApply }) => {
|
|
14
|
+
const [rowInput, setRowInput] = useState("");
|
|
15
|
+
const [columnInput, setColumnInput] = useState("");
|
|
16
|
+
const [error, setError] = useState(undefined);
|
|
17
|
+
const [busy, setBusy] = useState(false);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (open) {
|
|
20
|
+
setRowInput("");
|
|
21
|
+
setColumnInput("");
|
|
22
|
+
setError(undefined);
|
|
23
|
+
setBusy(false);
|
|
24
|
+
}
|
|
25
|
+
}, [open]);
|
|
26
|
+
const submit = useCallback(async (event) => {
|
|
27
|
+
event.preventDefault();
|
|
28
|
+
const row = rowInput.trim();
|
|
29
|
+
const column = columnInput.trim();
|
|
30
|
+
if ((row === "" && column === "") ||
|
|
31
|
+
(row !== "" && !isCellReference(row)) ||
|
|
32
|
+
(column !== "" && !isCellReference(column))) {
|
|
33
|
+
setError(DATA_TABLE_INPUT_MESSAGE);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
setBusy(true);
|
|
37
|
+
try {
|
|
38
|
+
const refusal = await onApply(row === "" ? undefined : row.replace(/\$/g, "").toUpperCase(), column === "" ? undefined : column.replace(/\$/g, "").toUpperCase());
|
|
39
|
+
if (refusal) {
|
|
40
|
+
setError(refusal);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
onOpenChange(false);
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
setBusy(false);
|
|
47
|
+
}
|
|
48
|
+
}, [rowInput, columnInput, onApply, onOpenChange]);
|
|
49
|
+
return (React.createElement(Dialog, { open: open, onOpenChange: onOpenChange },
|
|
50
|
+
React.createElement(DialogContent, { className: "w-[320px] max-w-[92vw] pointer-events-auto" },
|
|
51
|
+
React.createElement(DialogTitle, null, "Data Table"),
|
|
52
|
+
React.createElement(DialogDescription, null, "Substitute each value of the selection's first row and column into the input cells."),
|
|
53
|
+
React.createElement(DialogCloseButton, { onClick: () => onOpenChange(false) },
|
|
54
|
+
React.createElement(Cross1Icon, null)),
|
|
55
|
+
React.createElement(DialogBody, { className: "flex flex-col gap-3 font-system text-sm" },
|
|
56
|
+
React.createElement("form", { className: "flex flex-col gap-3", onSubmit: submit },
|
|
57
|
+
React.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
|
|
58
|
+
"Row input cell:",
|
|
59
|
+
React.createElement(Input, { autoFocus: true, value: rowInput, "aria-label": "Row input cell", onChange: (e) => {
|
|
60
|
+
setRowInput(e.target.value);
|
|
61
|
+
setError(undefined);
|
|
62
|
+
} })),
|
|
63
|
+
React.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
|
|
64
|
+
"Column input cell:",
|
|
65
|
+
React.createElement(Input, { value: columnInput, "aria-label": "Column input cell", onChange: (e) => {
|
|
66
|
+
setColumnInput(e.target.value);
|
|
67
|
+
setError(undefined);
|
|
68
|
+
} })),
|
|
69
|
+
error ? (React.createElement("div", { role: "alert", className: "text-xs text-rnc-destructive" }, error)) : null,
|
|
70
|
+
React.createElement(Separator, null),
|
|
71
|
+
React.createElement("div", { className: "flex justify-end gap-2" },
|
|
72
|
+
React.createElement(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onOpenChange(false) }, "Cancel"),
|
|
73
|
+
React.createElement(Button, { type: "submit", size: "sm", disabled: busy }, "OK")))))));
|
|
74
|
+
});
|
|
75
|
+
DataTableDialog.displayName = "DataTableDialog";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { type ErrorCheckKind, type ErrorCheckOption } from "../../api/error-checking";
|
|
3
|
+
export type ErrorCheckSmartTagProps = {
|
|
4
|
+
/** The active cell's rectangle; the button sits beside it (left, or right in column A). */
|
|
5
|
+
x: number;
|
|
6
|
+
y: number;
|
|
7
|
+
width: number;
|
|
8
|
+
height: number;
|
|
9
|
+
kind: ErrorCheckKind;
|
|
10
|
+
/** The error value's name (`#VALUE!`) for a formula error. */
|
|
11
|
+
errorName?: string;
|
|
12
|
+
open: boolean;
|
|
13
|
+
onOpenChange(open: boolean): void;
|
|
14
|
+
onChooseOption(option: ErrorCheckOption): void;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Excel's error-checking smart tag: beside the active cell when that cell carries the green ◤.
|
|
18
|
+
* The menu names the error, then offers Convert to Number (numbers stored as text), Help on this
|
|
19
|
+
* Error, Ignore Error, Edit in Formula Bar and Error Checking Options. Alt+Shift+F10 opens it
|
|
20
|
+
* ("Alt+Shift+F10: displays the menu or message for an Error Checking button" —
|
|
21
|
+
* https://support.microsoft.com/en-us/office/keyboard-shortcuts-in-excel-1798d9d5-842a-42b8-9c99-9b7213f0040f).
|
|
22
|
+
*/
|
|
23
|
+
export declare const ErrorCheckSmartTag: {
|
|
24
|
+
({ x, y, width, kind, errorName, open, onOpenChange, onChooseOption, }: ErrorCheckSmartTagProps): React.JSX.Element;
|
|
25
|
+
displayName: string;
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/error-check-smart-tag/index.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAEtB,MAAM,0BAA0B,CAAC;AAElC,MAAM,MAAM,uBAAuB,GAAG;IACpC,2FAA2F;IAC3F,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,cAAc,CAAC;IACrB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,cAAc,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAChD,CAAC;AAYF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB;4EAS5B,uBAAuB;;CAgDzB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuSeparator, DropdownMenuTrigger, IconButton, } from "@rowsncolumns/ui";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import { getErrorCheckTitle, } from "../../api/error-checking";
|
|
4
|
+
const BUTTON_SIZE = 22;
|
|
5
|
+
/** Excel's error-checking button: a yellow diamond with an exclamation mark. */
|
|
6
|
+
const WarningIcon = () => (React.createElement("svg", { width: "14", height: "14", viewBox: "0 0 24 24", "aria-hidden": "true" },
|
|
7
|
+
React.createElement("path", { d: "M12 1.5 22.5 12 12 22.5 1.5 12z", fill: "#F2C811", stroke: "#8A6D00", strokeWidth: "1" }),
|
|
8
|
+
React.createElement("path", { d: "M11 6.5h2v8h-2zM11 16.5h2v2h-2z", fill: "#1F1F1F" })));
|
|
9
|
+
/**
|
|
10
|
+
* Excel's error-checking smart tag: beside the active cell when that cell carries the green ◤.
|
|
11
|
+
* The menu names the error, then offers Convert to Number (numbers stored as text), Help on this
|
|
12
|
+
* Error, Ignore Error, Edit in Formula Bar and Error Checking Options. Alt+Shift+F10 opens it
|
|
13
|
+
* ("Alt+Shift+F10: displays the menu or message for an Error Checking button" —
|
|
14
|
+
* https://support.microsoft.com/en-us/office/keyboard-shortcuts-in-excel-1798d9d5-842a-42b8-9c99-9b7213f0040f).
|
|
15
|
+
*/
|
|
16
|
+
export const ErrorCheckSmartTag = ({ x, y, width, kind, errorName, open, onOpenChange, onChooseOption, }) => {
|
|
17
|
+
const left = x >= BUTTON_SIZE + 2 ? x - BUTTON_SIZE - 2 : x + width + 2;
|
|
18
|
+
return (React.createElement("div", { className: "absolute pointer-events-auto flex items-start justify-start", style: { left, top: y }, onMouseDown: (e) => e.stopPropagation(), "data-testid": "error-check-smart-tag" },
|
|
19
|
+
React.createElement(DropdownMenu, { modal: false, open: open, onOpenChange: onOpenChange },
|
|
20
|
+
React.createElement(DropdownMenuTrigger, { asChild: true },
|
|
21
|
+
React.createElement(IconButton, { tooltip: "Error Checking", "aria-label": "Error Checking", className: "shadow-sm bg-rnc-background border-rnc-border border border-solid rounded-md" },
|
|
22
|
+
React.createElement(WarningIcon, null))),
|
|
23
|
+
React.createElement(DropdownMenuPortal, null,
|
|
24
|
+
React.createElement(DropdownMenuContent, { align: "start", onCloseAutoFocus: (event) => event.preventDefault() },
|
|
25
|
+
React.createElement(DropdownMenuLabel, null, getErrorCheckTitle(kind, errorName)),
|
|
26
|
+
kind === "numberStoredAsText" ? (React.createElement(DropdownMenuItem, { onSelect: () => onChooseOption("convertToNumber") }, "Convert to Number")) : null,
|
|
27
|
+
React.createElement(DropdownMenuItem, { onSelect: () => onChooseOption("help") }, "Help on this Error"),
|
|
28
|
+
React.createElement(DropdownMenuItem, { onSelect: () => onChooseOption("ignore") }, "Ignore Error"),
|
|
29
|
+
React.createElement(DropdownMenuItem, { onSelect: () => onChooseOption("editInFormulaBar") }, "Edit in Formula Bar"),
|
|
30
|
+
React.createElement(DropdownMenuSeparator, null),
|
|
31
|
+
React.createElement(DropdownMenuItem, { onSelect: () => onChooseOption("options") }, "Error Checking Options\u2026"))))));
|
|
32
|
+
};
|
|
33
|
+
ErrorCheckSmartTag.displayName = "ErrorCheckSmartTag";
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
/** What the dialog asks for (the `create-forecast-sheet` command's options). */
|
|
3
|
+
export type ForecastSheetOptions = {
|
|
4
|
+
chartType: "line" | "column";
|
|
5
|
+
/** Forecast End as typed (a number or a date the host parses). */
|
|
6
|
+
forecastEnd?: string;
|
|
7
|
+
/** Fraction, e.g. 0.95; 0 = no confidence bounds. */
|
|
8
|
+
confidenceInterval: number;
|
|
9
|
+
/** `undefined` = detect automatically. */
|
|
10
|
+
seasonality?: number;
|
|
11
|
+
};
|
|
12
|
+
export type ForecastSheetDialogProps = {
|
|
13
|
+
open: boolean;
|
|
14
|
+
onOpenChange(open: boolean): void;
|
|
15
|
+
/** Default Forecast End shown in the field (the host's suggestion), optional. */
|
|
16
|
+
initialForecastEnd?: string;
|
|
17
|
+
/** Creates the sheet; resolves to Excel's refusal message, or `undefined` once done. */
|
|
18
|
+
onCreate(options: ForecastSheetOptions): Promise<string | undefined> | string | undefined;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Excel's Create Forecast Worksheet dialog: Line or Column chart, Forecast
|
|
22
|
+
* End, and the Options — Confidence Interval and Seasonality (automatic or
|
|
23
|
+
* set manually). The timeline and values are the host's selection.
|
|
24
|
+
*/
|
|
25
|
+
export declare const ForecastSheetDialog: React.MemoExoticComponent<({ open, onOpenChange, initialForecastEnd, onCreate }: ForecastSheetDialogProps) => React.JSX.Element>;
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/forecast-sheet-dialog/index.tsx"],"names":[],"mappings":"AAYA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAEtE,gFAAgF;AAChF,MAAM,MAAM,oBAAoB,GAAG;IACjC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC7B,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,kBAAkB,EAAE,MAAM,CAAC;IAC3B,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,wFAAwF;IACxF,QAAQ,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM,GAAG,SAAS,CAAC;CAC3F,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,mFACyB,wBAAwB,uBA6HhF,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Cross1Icon } from "@rowsncolumns/icons";
|
|
2
|
+
import { Button, Dialog, DialogBody, DialogCloseButton, DialogContent, DialogDescription, DialogTitle, Input, Separator, } from "@rowsncolumns/ui";
|
|
3
|
+
import React, { memo, useCallback, useEffect, useState } from "react";
|
|
4
|
+
/**
|
|
5
|
+
* Excel's Create Forecast Worksheet dialog: Line or Column chart, Forecast
|
|
6
|
+
* End, and the Options — Confidence Interval and Seasonality (automatic or
|
|
7
|
+
* set manually). The timeline and values are the host's selection.
|
|
8
|
+
*/
|
|
9
|
+
export const ForecastSheetDialog = memo(({ open, onOpenChange, initialForecastEnd, onCreate }) => {
|
|
10
|
+
const [chartType, setChartType] = useState("line");
|
|
11
|
+
const [end, setEnd] = useState(initialForecastEnd ?? "");
|
|
12
|
+
const [withInterval, setWithInterval] = useState(true);
|
|
13
|
+
const [interval, setInterval] = useState("95");
|
|
14
|
+
const [autoSeason, setAutoSeason] = useState(true);
|
|
15
|
+
const [season, setSeason] = useState("");
|
|
16
|
+
const [error, setError] = useState(undefined);
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (open) {
|
|
19
|
+
setEnd(initialForecastEnd ?? "");
|
|
20
|
+
setError(undefined);
|
|
21
|
+
}
|
|
22
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
23
|
+
}, [open]);
|
|
24
|
+
const submit = useCallback(async (event) => {
|
|
25
|
+
event.preventDefault();
|
|
26
|
+
const percent = Number(interval);
|
|
27
|
+
if (withInterval && !(percent > 0 && percent < 100)) {
|
|
28
|
+
setError("Confidence Interval must be between 0% and 100%.");
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const length = Number(season);
|
|
32
|
+
if (!autoSeason && !(Number.isInteger(length) && length >= 0)) {
|
|
33
|
+
setError("Seasonality must be a whole number.");
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const refusal = await onCreate({
|
|
37
|
+
chartType,
|
|
38
|
+
...(end.trim() !== "" ? { forecastEnd: end.trim() } : {}),
|
|
39
|
+
confidenceInterval: withInterval ? percent / 100 : 0,
|
|
40
|
+
...(autoSeason ? {} : { seasonality: length }),
|
|
41
|
+
});
|
|
42
|
+
if (refusal) {
|
|
43
|
+
setError(refusal);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
onOpenChange(false);
|
|
47
|
+
}, [interval, withInterval, season, autoSeason, chartType, end, onCreate, onOpenChange]);
|
|
48
|
+
return (React.createElement(Dialog, { open: open, onOpenChange: onOpenChange },
|
|
49
|
+
React.createElement(DialogContent, { className: "w-[380px] max-w-[92vw] pointer-events-auto" },
|
|
50
|
+
React.createElement(DialogTitle, null, "Create Forecast Worksheet"),
|
|
51
|
+
React.createElement(DialogDescription, null, "Forecast the selected timeline and values on a new sheet with a chart."),
|
|
52
|
+
React.createElement(DialogCloseButton, { onClick: () => onOpenChange(false) },
|
|
53
|
+
React.createElement(Cross1Icon, null)),
|
|
54
|
+
React.createElement(DialogBody, { className: "flex flex-col gap-3 font-system text-sm" },
|
|
55
|
+
React.createElement("form", { className: "flex flex-col gap-3", onSubmit: submit },
|
|
56
|
+
React.createElement("div", { className: "flex items-center gap-3 text-xs" }, ["line", "column"].map((t) => (React.createElement("label", { key: t, className: "flex items-center gap-1" },
|
|
57
|
+
React.createElement("input", { type: "radio", checked: chartType === t, onChange: () => setChartType(t) }),
|
|
58
|
+
t === "line" ? "Line chart" : "Column chart")))),
|
|
59
|
+
React.createElement("label", { className: "flex flex-col gap-1 text-xs font-medium" },
|
|
60
|
+
"Forecast End:",
|
|
61
|
+
React.createElement(Input, { autoFocus: true, "aria-label": "Forecast End", value: end, onChange: (e) => setEnd(e.target.value) })),
|
|
62
|
+
React.createElement("div", { className: "flex items-center gap-2 text-xs" },
|
|
63
|
+
React.createElement("label", { className: "flex items-center gap-2" },
|
|
64
|
+
React.createElement("input", { type: "checkbox", checked: withInterval, onChange: (e) => setWithInterval(e.target.checked) }),
|
|
65
|
+
"Confidence Interval"),
|
|
66
|
+
React.createElement(Input, { className: "w-16", "aria-label": "Confidence Interval (%)", value: interval, disabled: !withInterval, onChange: (e) => setInterval(e.target.value) }),
|
|
67
|
+
"%"),
|
|
68
|
+
React.createElement("div", { className: "flex flex-col gap-1 text-xs" },
|
|
69
|
+
"Seasonality",
|
|
70
|
+
React.createElement("label", { className: "flex items-center gap-2" },
|
|
71
|
+
React.createElement("input", { type: "radio", checked: autoSeason, onChange: () => setAutoSeason(true) }),
|
|
72
|
+
"Detect Automatically"),
|
|
73
|
+
React.createElement("label", { className: "flex items-center gap-2" },
|
|
74
|
+
React.createElement("input", { type: "radio", checked: !autoSeason, onChange: () => setAutoSeason(false) }),
|
|
75
|
+
"Set Manually",
|
|
76
|
+
React.createElement(Input, { className: "w-16", "aria-label": "Season length", value: season, disabled: autoSeason, onChange: (e) => setSeason(e.target.value) }))),
|
|
77
|
+
error ? (React.createElement("div", { role: "alert", className: "text-xs text-rnc-destructive" }, error)) : null,
|
|
78
|
+
React.createElement(Separator, null),
|
|
79
|
+
React.createElement("div", { className: "flex justify-end gap-2" },
|
|
80
|
+
React.createElement(Button, { type: "button", variant: "outline", size: "sm", onClick: () => onOpenChange(false) }, "Cancel"),
|
|
81
|
+
React.createElement(Button, { type: "submit", size: "sm" }, "Create")))))));
|
|
82
|
+
});
|
|
83
|
+
ForecastSheetDialog.displayName = "ForecastSheetDialog";
|
|
@@ -11,9 +11,9 @@ export type PasteSpecialDialogProps = {
|
|
|
11
11
|
onApply(options: PasteSpecialOptions): void;
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
|
-
* Excel's Paste Special dialog: what to paste (
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* Excel's Paste Special dialog: what to paste (Excel's twelve Paste choices),
|
|
15
|
+
* an arithmetic operation against the destination, skip blanks, transpose and
|
|
16
|
+
* Paste Link. Every choice composes into one `PasteSpecialOptions` request.
|
|
17
17
|
*/
|
|
18
18
|
export declare const PasteSpecialDialog: React.MemoExoticComponent<({ open, onOpenChange, onApply }: PasteSpecialDialogProps) => React.JSX.Element>;
|
|
19
19
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/paste-special-dialog/index.tsx"],"names":[],"mappings":"AASA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAM3D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/paste-special-dialog/index.tsx"],"names":[],"mappings":"AASA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAM3D,OAAO,KAAK,EAGV,mBAAmB,EACpB,MAAM,gCAAgC,CAAC;AA+CxC,MAAM,MAAM,uBAAuB,GAAG;IACpC,2BAA2B;IAC3B,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAClC;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAC;CAC7C,CAAC;AAoEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,8DACK,uBAAuB,uBAsG1D,CAAC;AAIF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB;;;CAclC,CAAC"}
|