@dxos/plugin-sheet 0.6.11-staging.e6894a4 → 0.6.12-main.15a606f
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/lib/browser/SheetContainer-V4GCCZTX.mjs +261 -0
- package/dist/lib/browser/SheetContainer-V4GCCZTX.mjs.map +7 -0
- package/dist/lib/browser/{chunk-P7SSL3EG.mjs → chunk-6ZMQVB4Z.mjs} +359 -671
- package/dist/lib/browser/chunk-6ZMQVB4Z.mjs.map +7 -0
- package/dist/lib/browser/{chunk-JRL5LGCE.mjs → chunk-QILRZNE5.mjs} +2 -5
- package/dist/lib/browser/chunk-QILRZNE5.mjs.map +7 -0
- package/dist/lib/browser/{chunk-FUAGSXA4.mjs → chunk-T3NJFTD4.mjs} +8 -15
- package/dist/lib/browser/chunk-T3NJFTD4.mjs.map +7 -0
- package/dist/lib/browser/{SheetContainer-4XOKHKKZ.mjs → chunk-U2JHW3L6.mjs} +1043 -261
- package/dist/lib/browser/chunk-U2JHW3L6.mjs.map +7 -0
- package/dist/lib/browser/graph-T27BOBOV.mjs +21 -0
- package/dist/lib/browser/graph-T27BOBOV.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +80 -66
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/meta.mjs +1 -1
- package/dist/lib/browser/types.mjs +4 -6
- package/dist/lib/node/SheetContainer-3ZY7MPWJ.cjs +279 -0
- package/dist/lib/node/SheetContainer-3ZY7MPWJ.cjs.map +7 -0
- package/dist/lib/node/{chunk-BJ6ZD7MN.cjs → chunk-BNARJ5GM.cjs} +5 -18
- package/dist/lib/node/chunk-BNARJ5GM.cjs.map +7 -0
- package/dist/lib/node/{chunk-SVAIIXWQ.cjs → chunk-DD6FIXWC.cjs} +360 -667
- package/dist/lib/node/chunk-DD6FIXWC.cjs.map +7 -0
- package/dist/lib/node/{SheetContainer-IQT6TR4Z.cjs → chunk-OTTD7FBK.cjs} +1062 -289
- package/dist/lib/node/chunk-OTTD7FBK.cjs.map +7 -0
- package/dist/lib/node/{chunk-DSYKOI4E.cjs → chunk-Q3HBHPRL.cjs} +12 -20
- package/dist/lib/node/chunk-Q3HBHPRL.cjs.map +7 -0
- package/dist/lib/node/graph-SPKGX7W4.cjs +43 -0
- package/dist/lib/node/graph-SPKGX7W4.cjs.map +7 -0
- package/dist/lib/node/index.cjs +93 -72
- package/dist/lib/node/index.cjs.map +3 -3
- package/dist/lib/node/meta.cjs +3 -3
- package/dist/lib/node/meta.cjs.map +1 -1
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/types.cjs +10 -12
- package/dist/lib/node/types.cjs.map +2 -2
- package/dist/lib/node-esm/SheetContainer-PXSJX6XK.mjs +262 -0
- package/dist/lib/node-esm/SheetContainer-PXSJX6XK.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-7HVSOTGA.mjs +2553 -0
- package/dist/lib/node-esm/chunk-7HVSOTGA.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-BMNA27EX.mjs +76 -0
- package/dist/lib/node-esm/chunk-BMNA27EX.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-D6KU5MI7.mjs +2925 -0
- package/dist/lib/node-esm/chunk-D6KU5MI7.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-IU2L277A.mjs +17 -0
- package/dist/lib/node-esm/chunk-IU2L277A.mjs.map +7 -0
- package/dist/lib/node-esm/graph-U67IO4UC.mjs +22 -0
- package/dist/lib/node-esm/graph-U67IO4UC.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +261 -0
- package/dist/lib/node-esm/index.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -0
- package/dist/lib/node-esm/meta.mjs +10 -0
- package/dist/lib/node-esm/meta.mjs.map +7 -0
- package/dist/lib/node-esm/types.mjs +21 -0
- package/dist/lib/node-esm/types.mjs.map +7 -0
- package/dist/types/src/SheetPlugin.d.ts.map +1 -1
- package/dist/types/src/components/CellEditor/CellEditor.d.ts +23 -3
- package/dist/types/src/components/CellEditor/CellEditor.d.ts.map +1 -1
- package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts +2 -2
- package/dist/types/src/components/CellEditor/CellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/CellEditor/extension.d.ts +1 -1
- package/dist/types/src/components/CellEditor/extension.d.ts.map +1 -1
- package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +11 -0
- package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +1 -0
- package/dist/types/src/components/ComputeGraph/index.d.ts +1 -3
- package/dist/types/src/components/ComputeGraph/index.d.ts.map +1 -1
- package/dist/types/src/components/GridSheet/GridSheet.d.ts +10 -0
- package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +1 -0
- package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts +9 -0
- package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +1 -0
- package/dist/types/src/components/GridSheet/util.d.ts +6 -0
- package/dist/types/src/components/GridSheet/util.d.ts.map +1 -0
- package/dist/types/src/components/Sheet/Sheet.d.ts +1 -1
- package/dist/types/src/components/Sheet/Sheet.d.ts.map +1 -1
- package/dist/types/src/components/Sheet/Sheet.stories.d.ts +5 -6
- package/dist/types/src/components/Sheet/Sheet.stories.d.ts.map +1 -1
- package/dist/types/src/components/Sheet/decorations.d.ts +24 -0
- package/dist/types/src/components/Sheet/decorations.d.ts.map +1 -0
- package/dist/types/src/components/Sheet/grid.d.ts +2 -2
- package/dist/types/src/components/Sheet/grid.d.ts.map +1 -1
- package/dist/types/src/components/Sheet/nav.d.ts +3 -3
- package/dist/types/src/components/Sheet/nav.d.ts.map +1 -1
- package/dist/types/src/components/Sheet/sheet-context.d.ts +6 -5
- package/dist/types/src/components/Sheet/sheet-context.d.ts.map +1 -1
- package/dist/types/src/components/Sheet/threads.d.ts +2 -0
- package/dist/types/src/components/Sheet/threads.d.ts.map +1 -0
- package/dist/types/src/components/SheetContainer.d.ts +2 -3
- package/dist/types/src/components/SheetContainer.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +19 -3
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +18 -13
- package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +2 -2
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/defs/index.d.ts +3 -0
- package/dist/types/src/defs/index.d.ts.map +1 -0
- package/dist/types/src/{model → defs}/types.d.ts +8 -3
- package/dist/types/src/defs/types.d.ts.map +1 -0
- package/dist/types/src/defs/types.test.d.ts.map +1 -0
- package/dist/types/src/defs/util.d.ts +43 -0
- package/dist/types/src/defs/util.d.ts.map +1 -0
- package/dist/types/src/extensions/compute.d.ts +5 -0
- package/dist/types/src/extensions/compute.d.ts.map +1 -0
- package/dist/types/src/extensions/compute.stories.d.ts +26 -0
- package/dist/types/src/extensions/compute.stories.d.ts.map +1 -0
- package/dist/types/src/extensions/index.d.ts +2 -0
- package/dist/types/src/extensions/index.d.ts.map +1 -0
- package/dist/types/src/{components/ComputeGraph → graph}/async-function.d.ts +1 -1
- package/dist/types/src/graph/async-function.d.ts.map +1 -0
- package/dist/types/src/graph/compute-graph.browser.test.d.ts +2 -0
- package/dist/types/src/graph/compute-graph.browser.test.d.ts.map +1 -0
- package/dist/types/src/graph/compute-graph.d.ts +81 -0
- package/dist/types/src/graph/compute-graph.d.ts.map +1 -0
- package/dist/types/src/graph/compute-graph.stories.d.ts +10 -0
- package/dist/types/src/graph/compute-graph.stories.d.ts.map +1 -0
- package/dist/types/src/graph/compute-node.d.ts +19 -0
- package/dist/types/src/graph/compute-node.d.ts.map +1 -0
- package/dist/types/src/{components/ComputeGraph/custom.d.ts → graph/custom-function.d.ts} +1 -1
- package/dist/types/src/graph/custom-function.d.ts.map +1 -0
- package/dist/types/src/graph/edge-function.d.ts.map +1 -0
- package/dist/types/src/{model/functions.d.ts → graph/function-defs.d.ts} +1 -1
- package/dist/types/src/graph/function-defs.d.ts.map +1 -0
- package/dist/types/src/graph/hyperformula.test.d.ts +2 -0
- package/dist/types/src/graph/hyperformula.test.d.ts.map +1 -0
- package/dist/types/src/graph/index.d.ts +4 -0
- package/dist/types/src/graph/index.d.ts.map +1 -0
- package/dist/types/src/graph/util.d.ts +2 -0
- package/dist/types/src/graph/util.d.ts.map +1 -0
- package/dist/types/src/hooks/hooks.stories.d.ts +11 -0
- package/dist/types/src/hooks/hooks.stories.d.ts.map +1 -0
- package/dist/types/src/hooks/index.d.ts +4 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -0
- package/dist/types/src/hooks/useComputeGraph.d.ts +7 -0
- package/dist/types/src/hooks/useComputeGraph.d.ts.map +1 -0
- package/dist/types/src/hooks/useFormattingModel.d.ts +3 -0
- package/dist/types/src/hooks/useFormattingModel.d.ts.map +1 -0
- package/dist/types/src/hooks/useSheetModel.d.ts +8 -0
- package/dist/types/src/hooks/useSheetModel.d.ts.map +1 -0
- package/dist/types/src/meta.d.ts +1 -4
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/model/formatting-model.d.ts +16 -0
- package/dist/types/src/model/formatting-model.d.ts.map +1 -0
- package/dist/types/src/model/index.d.ts +2 -3
- package/dist/types/src/model/index.d.ts.map +1 -1
- package/dist/types/src/model/{model.d.ts → sheet-model.d.ts} +9 -64
- package/dist/types/src/model/sheet-model.d.ts.map +1 -0
- package/dist/types/src/sanity.test.d.ts +2 -0
- package/dist/types/src/sanity.test.d.ts.map +1 -0
- package/dist/types/src/testing/index.d.ts +2 -0
- package/dist/types/src/testing/index.d.ts.map +1 -0
- package/dist/types/src/testing/testing.d.ts +9 -0
- package/dist/types/src/testing/testing.d.ts.map +1 -0
- package/dist/types/src/translations.d.ts +17 -12
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +83 -3
- package/dist/types/src/types.d.ts.map +1 -1
- package/dist/vendor/hyperformula.mjs +37145 -0
- package/package.json +48 -41
- package/src/SheetPlugin.tsx +51 -72
- package/src/components/CellEditor/CellEditor.stories.tsx +4 -3
- package/src/components/CellEditor/CellEditor.tsx +59 -9
- package/src/components/CellEditor/extension.test.ts +4 -5
- package/src/components/CellEditor/extension.ts +1 -3
- package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +20 -0
- package/src/components/ComputeGraph/index.ts +1 -3
- package/src/components/GridSheet/GridSheet.stories.tsx +35 -0
- package/src/components/GridSheet/GridSheet.tsx +153 -0
- package/src/components/GridSheet/util.ts +89 -0
- package/src/components/Sheet/Sheet.stories.tsx +48 -87
- package/src/components/Sheet/Sheet.tsx +69 -39
- package/src/components/Sheet/decorations.ts +62 -0
- package/src/components/Sheet/grid.ts +3 -3
- package/src/components/Sheet/nav.ts +19 -19
- package/src/components/Sheet/sheet-context.tsx +16 -78
- package/src/components/Sheet/threads.tsx +205 -0
- package/src/components/SheetContainer.tsx +73 -21
- package/src/components/Toolbar/Toolbar.stories.tsx +5 -10
- package/src/components/Toolbar/Toolbar.tsx +53 -12
- package/src/components/index.ts +1 -0
- package/src/defs/index.ts +6 -0
- package/src/{model → defs}/types.test.ts +8 -9
- package/src/{model → defs}/types.ts +23 -14
- package/src/defs/util.ts +135 -0
- package/src/extensions/compute.stories.tsx +151 -0
- package/src/extensions/compute.ts +98 -0
- package/src/extensions/index.ts +5 -0
- package/src/{components/ComputeGraph → graph}/async-function.ts +3 -1
- package/src/graph/compute-graph.browser.test.ts +104 -0
- package/src/graph/compute-graph.stories.tsx +92 -0
- package/src/graph/compute-graph.ts +290 -0
- package/src/graph/compute-node.ts +51 -0
- package/src/{components/ComputeGraph/custom.ts → graph/custom-function.ts} +2 -6
- package/src/{components/ComputeGraph → graph}/edge-function.ts +2 -1
- package/src/graph/hyperformula.test.ts +15 -0
- package/src/graph/index.ts +7 -0
- package/src/graph/util.ts +8 -0
- package/src/hooks/hooks.stories.tsx +50 -0
- package/src/hooks/index.ts +7 -0
- package/src/hooks/useComputeGraph.ts +20 -0
- package/src/hooks/useFormattingModel.ts +11 -0
- package/src/hooks/useSheetModel.ts +43 -0
- package/src/meta.tsx +1 -5
- package/src/{components/Sheet/formatting.ts → model/formatting-model.ts} +20 -13
- package/src/model/index.ts +2 -3
- package/src/model/sheet-model.ts +399 -0
- package/src/sanity.test.ts +40 -0
- package/src/testing/index.ts +5 -0
- package/src/testing/testing.tsx +66 -0
- package/src/translations.ts +6 -1
- package/src/types.ts +30 -5
- package/dist/lib/browser/SheetContainer-4XOKHKKZ.mjs.map +0 -7
- package/dist/lib/browser/chunk-FUAGSXA4.mjs.map +0 -7
- package/dist/lib/browser/chunk-FWGRE3EG.mjs +0 -175
- package/dist/lib/browser/chunk-FWGRE3EG.mjs.map +0 -7
- package/dist/lib/browser/chunk-JRL5LGCE.mjs.map +0 -7
- package/dist/lib/browser/chunk-P7SSL3EG.mjs.map +0 -7
- package/dist/lib/browser/chunk-YPU3R7FA.mjs +0 -8
- package/dist/lib/browser/chunk-YPU3R7FA.mjs.map +0 -7
- package/dist/lib/browser/testing.mjs +0 -92
- package/dist/lib/browser/testing.mjs.map +0 -7
- package/dist/lib/node/SheetContainer-IQT6TR4Z.cjs.map +0 -7
- package/dist/lib/node/chunk-5EPCDAZC.cjs +0 -40
- package/dist/lib/node/chunk-5EPCDAZC.cjs.map +0 -7
- package/dist/lib/node/chunk-727C6YNP.cjs +0 -202
- package/dist/lib/node/chunk-727C6YNP.cjs.map +0 -7
- package/dist/lib/node/chunk-BJ6ZD7MN.cjs.map +0 -7
- package/dist/lib/node/chunk-DSYKOI4E.cjs.map +0 -7
- package/dist/lib/node/chunk-SVAIIXWQ.cjs.map +0 -7
- package/dist/lib/node/testing.cjs +0 -111
- package/dist/lib/node/testing.cjs.map +0 -7
- package/dist/types/src/components/ComputeGraph/async-function.d.ts.map +0 -1
- package/dist/types/src/components/ComputeGraph/custom.d.ts.map +0 -1
- package/dist/types/src/components/ComputeGraph/edge-function.d.ts.map +0 -1
- package/dist/types/src/components/ComputeGraph/graph-context.d.ts +0 -12
- package/dist/types/src/components/ComputeGraph/graph-context.d.ts.map +0 -1
- package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts +0 -2
- package/dist/types/src/components/ComputeGraph/graph.browser.test.d.ts.map +0 -1
- package/dist/types/src/components/ComputeGraph/graph.d.ts +0 -26
- package/dist/types/src/components/ComputeGraph/graph.d.ts.map +0 -1
- package/dist/types/src/components/Sheet/formatting.d.ts +0 -14
- package/dist/types/src/components/Sheet/formatting.d.ts.map +0 -1
- package/dist/types/src/model/functions.d.ts.map +0 -1
- package/dist/types/src/model/model.browser.test.d.ts +0 -2
- package/dist/types/src/model/model.browser.test.d.ts.map +0 -1
- package/dist/types/src/model/model.d.ts.map +0 -1
- package/dist/types/src/model/types.d.ts.map +0 -1
- package/dist/types/src/model/types.test.d.ts.map +0 -1
- package/dist/types/src/model/util.d.ts +0 -15
- package/dist/types/src/model/util.d.ts.map +0 -1
- package/dist/types/src/testing.d.ts +0 -9
- package/dist/types/src/testing.d.ts.map +0 -1
- package/src/components/ComputeGraph/graph-context.tsx +0 -50
- package/src/components/ComputeGraph/graph.browser.test.ts +0 -50
- package/src/components/ComputeGraph/graph.ts +0 -62
- package/src/model/model.browser.test.ts +0 -100
- package/src/model/model.ts +0 -551
- package/src/model/util.ts +0 -36
- package/src/testing.ts +0 -50
- /package/dist/types/src/{model → defs}/types.test.d.ts +0 -0
- /package/dist/types/src/{components/ComputeGraph → graph}/edge-function.d.ts +0 -0
- /package/src/{model/functions.ts → graph/function-defs.ts} +0 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { effect } from '@preact/signals-core';
|
|
6
|
+
import React, { type PropsWithChildren, useCallback, useEffect, useMemo } from 'react';
|
|
7
|
+
|
|
8
|
+
import { type IntentResolver, LayoutAction, useIntentDispatcher, useIntentResolver } from '@dxos/app-framework';
|
|
9
|
+
import { debounce } from '@dxos/async';
|
|
10
|
+
import { fullyQualifiedId } from '@dxos/react-client/echo';
|
|
11
|
+
import { Icon, useTranslation } from '@dxos/react-ui';
|
|
12
|
+
|
|
13
|
+
import { type Decoration } from './decorations';
|
|
14
|
+
import { useSheetContext } from './sheet-context';
|
|
15
|
+
import { addressFromIndex, addressToIndex, type CellAddress, closest } from '../../defs';
|
|
16
|
+
import { SHEET_PLUGIN } from '../../meta';
|
|
17
|
+
|
|
18
|
+
// TODO(burdon): Move into folder; split hooks.
|
|
19
|
+
|
|
20
|
+
const CommentIndicator = () => {
|
|
21
|
+
return (
|
|
22
|
+
<div
|
|
23
|
+
role='none'
|
|
24
|
+
className='absolute top-0 right-0 w-0 h-0 border-t-8 border-l-8 border-t-cmCommentSurface border-l-transparent'
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const ThreadedCellWrapper = ({ children }: PropsWithChildren) => {
|
|
30
|
+
const dispatch = useIntentDispatcher();
|
|
31
|
+
const [isHovered, setIsHovered] = React.useState(false);
|
|
32
|
+
const { t } = useTranslation(SHEET_PLUGIN);
|
|
33
|
+
|
|
34
|
+
const handleClick = React.useCallback(
|
|
35
|
+
(_event: React.MouseEvent) => {
|
|
36
|
+
void dispatch({ action: LayoutAction.SET_LAYOUT, data: { element: 'complementary', state: true } });
|
|
37
|
+
},
|
|
38
|
+
[dispatch],
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<div
|
|
43
|
+
role='none'
|
|
44
|
+
className='relative h-full is-full'
|
|
45
|
+
onMouseEnter={() => {
|
|
46
|
+
setIsHovered(true);
|
|
47
|
+
}}
|
|
48
|
+
onMouseLeave={() => {
|
|
49
|
+
setIsHovered(false);
|
|
50
|
+
}}
|
|
51
|
+
>
|
|
52
|
+
<CommentIndicator />
|
|
53
|
+
{isHovered && (
|
|
54
|
+
<div className='absolute inset-0 flex items-center justify-end pr-1'>
|
|
55
|
+
<button
|
|
56
|
+
className='ch-button text-xs min-bs-0 p-1'
|
|
57
|
+
onClick={handleClick}
|
|
58
|
+
aria-label={t('open comment for sheet cell')}
|
|
59
|
+
>
|
|
60
|
+
<Icon icon='ph--chat--regular' aria-hidden={true} />
|
|
61
|
+
</button>
|
|
62
|
+
</div>
|
|
63
|
+
)}
|
|
64
|
+
{children}
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const createThreadDecoration = (cellIndex: string, threadId: string, sheetId: string): Decoration => {
|
|
70
|
+
return {
|
|
71
|
+
type: 'comment',
|
|
72
|
+
cellIndex,
|
|
73
|
+
decorate: (props) => <ThreadedCellWrapper {...props} />,
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// TODO(burdon): Factor out hooks.
|
|
78
|
+
|
|
79
|
+
const useUpdateCursorOnThreadSelection = () => {
|
|
80
|
+
const { setCursor, model } = useSheetContext();
|
|
81
|
+
|
|
82
|
+
const handleScrollIntoView: IntentResolver = useCallback(
|
|
83
|
+
({ action, data }) => {
|
|
84
|
+
switch (action) {
|
|
85
|
+
case LayoutAction.SCROLL_INTO_VIEW: {
|
|
86
|
+
if (!data?.id || data?.cursor === undefined || data?.id !== fullyQualifiedId(model.sheet)) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// TODO(Zan): Everywhere we refer to the cursor in a thread context should change to `anchor`.
|
|
91
|
+
const cellAddress = addressFromIndex(model.sheet, data.cursor);
|
|
92
|
+
setCursor(cellAddress);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
[model.sheet, setCursor],
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
useIntentResolver(SHEET_PLUGIN, handleScrollIntoView);
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const useSelectThreadOnCursorChange = () => {
|
|
103
|
+
const { cursor, model } = useSheetContext();
|
|
104
|
+
const dispatch = useIntentDispatcher();
|
|
105
|
+
|
|
106
|
+
const activeThreads = useMemo(
|
|
107
|
+
() =>
|
|
108
|
+
model.sheet.threads?.filter(
|
|
109
|
+
(thread): thread is NonNullable<typeof thread> => !!thread && thread.status === 'active',
|
|
110
|
+
) ?? [],
|
|
111
|
+
[JSON.stringify(model.sheet.threads)],
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
const activeThreadAddresses = useMemo(
|
|
115
|
+
() =>
|
|
116
|
+
activeThreads
|
|
117
|
+
.map((thread) => thread.anchor)
|
|
118
|
+
.filter((anchor): anchor is NonNullable<typeof anchor> => anchor !== undefined)
|
|
119
|
+
.map((anchor) => addressFromIndex(model.sheet, anchor)),
|
|
120
|
+
[activeThreads, model.sheet],
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const selectClosestThread = useCallback(
|
|
124
|
+
(cellAddress: CellAddress) => {
|
|
125
|
+
if (!cellAddress || !activeThreads) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const closestThreadAnchor = closest(cellAddress, activeThreadAddresses);
|
|
130
|
+
if (closestThreadAnchor) {
|
|
131
|
+
const closestThread = activeThreads.find(
|
|
132
|
+
(thread) => thread && thread.anchor === addressToIndex(model.sheet, closestThreadAnchor),
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
if (closestThread) {
|
|
136
|
+
void dispatch([
|
|
137
|
+
{ action: 'dxos.org/plugin/thread/action/select', data: { current: fullyQualifiedId(closestThread) } },
|
|
138
|
+
]);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
[dispatch, activeThreads, activeThreadAddresses, model.sheet],
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const debounced = useMemo(() => {
|
|
146
|
+
return debounce((cursor: CellAddress) => requestAnimationFrame(() => selectClosestThread(cursor)), 50);
|
|
147
|
+
}, [selectClosestThread]);
|
|
148
|
+
|
|
149
|
+
useEffect(() => {
|
|
150
|
+
if (!cursor) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
debounced(cursor);
|
|
154
|
+
}, [cursor, selectClosestThread]);
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
const useThreadDecorations = () => {
|
|
158
|
+
const { decorations, model } = useSheetContext();
|
|
159
|
+
const sheet = useMemo(() => model.sheet, [model.sheet]);
|
|
160
|
+
const sheetId = useMemo(() => fullyQualifiedId(sheet), [sheet]);
|
|
161
|
+
|
|
162
|
+
useEffect(() => {
|
|
163
|
+
const unsubscribe = effect(() => {
|
|
164
|
+
const activeThreadAnchors = new Set<string>();
|
|
165
|
+
if (!sheet.threads) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Process active threads
|
|
170
|
+
for (const thread of sheet.threads) {
|
|
171
|
+
if (!thread || thread.anchor === undefined || thread.status === 'resolved') {
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
activeThreadAnchors.add(thread.anchor);
|
|
176
|
+
const index = thread.anchor;
|
|
177
|
+
|
|
178
|
+
// Add decoration only if it doesn't already exist
|
|
179
|
+
const existingDecorations = decorations.getDecorationsForCell(index);
|
|
180
|
+
if (!existingDecorations || !existingDecorations.some((d) => d.type === 'comment')) {
|
|
181
|
+
decorations.addDecoration(index, createThreadDecoration(index, thread.id, sheetId));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Remove decorations for resolved or deleted threads
|
|
186
|
+
for (const decoration of decorations.getAllDecorations()) {
|
|
187
|
+
if (decoration.type !== 'comment') {
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (!activeThreadAnchors.has(decoration.cellIndex)) {
|
|
192
|
+
decorations.removeDecoration(decoration.cellIndex, 'comment');
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
return () => unsubscribe();
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export const useThreads = () => {
|
|
202
|
+
useUpdateCursorOnThreadSelection();
|
|
203
|
+
useSelectThreadOnCursorChange();
|
|
204
|
+
useThreadDecorations();
|
|
205
|
+
};
|
|
@@ -2,32 +2,84 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React from 'react';
|
|
5
|
+
import React, { useCallback } from 'react';
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
7
|
+
import { useIntentDispatcher } from '@dxos/app-framework';
|
|
8
|
+
import { fullyQualifiedId } from '@dxos/react-client/echo';
|
|
9
|
+
import { useIsDirectlyAttended } from '@dxos/react-ui-attention';
|
|
10
|
+
import { focusRing, mx } from '@dxos/react-ui-theme';
|
|
9
11
|
|
|
10
12
|
import { Sheet, type SheetRootProps } from './Sheet';
|
|
13
|
+
import { Toolbar, type ToolbarAction } from './Toolbar';
|
|
14
|
+
|
|
15
|
+
// TODO(Zan): Factor out, copied this from MarkdownPlugin.
|
|
16
|
+
const attentionFragment = mx(
|
|
17
|
+
'group-focus-within/editor:attention-surface group-[[aria-current]]/editor:attention-surface',
|
|
18
|
+
'group-focus-within/editor:border-separator',
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
// TODO(Zan): Factor out, copied this from MarkdownPlugin.
|
|
22
|
+
export const sectionToolbarLayout =
|
|
23
|
+
'bs-[--rail-action] bg-[--sticky-bg] sticky block-start-0 __-block-start-px transition-opacity';
|
|
24
|
+
|
|
25
|
+
const SheetContainer = ({ sheet, space, role }: SheetRootProps & { role?: string }) => {
|
|
26
|
+
const dispatch = useIntentDispatcher();
|
|
27
|
+
|
|
28
|
+
const id = fullyQualifiedId(sheet);
|
|
29
|
+
const isDirectlyAttended = useIsDirectlyAttended(id);
|
|
30
|
+
|
|
31
|
+
// TODO(Zan): Centralise the toolbar action handler. Current implementation in stories.
|
|
32
|
+
const handleAction = useCallback(
|
|
33
|
+
(action: ToolbarAction) => {
|
|
34
|
+
switch (action.type) {
|
|
35
|
+
case 'comment': {
|
|
36
|
+
// TODO(Zan): We shouldn't hardcode the action ID.
|
|
37
|
+
void dispatch({
|
|
38
|
+
action: 'dxos.org/plugin/thread/action/create',
|
|
39
|
+
data: {
|
|
40
|
+
cursor: action.anchor,
|
|
41
|
+
name: action.cellContent,
|
|
42
|
+
subject: sheet,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
[sheet, dispatch],
|
|
49
|
+
);
|
|
11
50
|
|
|
12
|
-
const SheetContainer = ({
|
|
13
|
-
sheet,
|
|
14
|
-
space,
|
|
15
|
-
role,
|
|
16
|
-
coordinate = { part: 'main', entryId: '' },
|
|
17
|
-
remoteFunctionUrl,
|
|
18
|
-
}: SheetRootProps & { role?: string; coordinate?: LayoutCoordinate }) => {
|
|
19
51
|
return (
|
|
20
|
-
<div
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
52
|
+
<div role='none' className={role === 'article' ? 'row-span-2 grid grid-rows-subgrid' : undefined}>
|
|
53
|
+
<Sheet.Root space={space} sheet={sheet}>
|
|
54
|
+
<div role='none' className={mx('flex flex-0 justify-center overflow-x-auto')}>
|
|
55
|
+
<Toolbar.Root
|
|
56
|
+
onAction={handleAction}
|
|
57
|
+
classNames={mx(
|
|
58
|
+
role === 'section'
|
|
59
|
+
? ['z-[2] group-focus-within/section:visible', !isDirectlyAttended && 'invisible', sectionToolbarLayout]
|
|
60
|
+
: 'group-focus-within/editor:border-separator group-[[aria-current]]/editor:border-separator',
|
|
61
|
+
)}
|
|
62
|
+
>
|
|
63
|
+
{/* TODO(Zan): Restore some of this functionality */}
|
|
64
|
+
{/* <Toolbar.Styles /> */}
|
|
65
|
+
{/* <Toolbar.Format /> */}
|
|
66
|
+
{/* <Toolbar.Alignment /> */}
|
|
67
|
+
<Toolbar.Separator />
|
|
68
|
+
<Toolbar.Actions />
|
|
69
|
+
</Toolbar.Root>
|
|
70
|
+
</div>
|
|
71
|
+
<div
|
|
72
|
+
role='none'
|
|
73
|
+
className={mx(
|
|
74
|
+
role === 'section' && 'aspect-square border-is border-bs border-be border-separator',
|
|
75
|
+
role === 'article' &&
|
|
76
|
+
'flex is-full overflow-hidden focus-visible:ring-inset row-span-1 data-[toolbar=disabled]:pbs-2 data-[toolbar=disabled]:row-span-2 border-bs border-separator',
|
|
77
|
+
focusRing,
|
|
78
|
+
attentionFragment,
|
|
79
|
+
)}
|
|
80
|
+
>
|
|
81
|
+
<Sheet.Main />
|
|
82
|
+
</div>
|
|
31
83
|
</Sheet.Root>
|
|
32
84
|
</div>
|
|
33
85
|
);
|
|
@@ -6,29 +6,24 @@ import '@dxos-theme';
|
|
|
6
6
|
|
|
7
7
|
import React from 'react';
|
|
8
8
|
|
|
9
|
-
import { Tooltip } from '@dxos/react-ui';
|
|
10
9
|
import { textBlockWidth } from '@dxos/react-ui-theme';
|
|
11
|
-
import { withTheme } from '@dxos/storybook-utils';
|
|
10
|
+
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
12
11
|
|
|
13
12
|
import { Toolbar } from './Toolbar';
|
|
14
13
|
import translations from '../../translations';
|
|
15
14
|
|
|
16
15
|
const Story = () => {
|
|
17
16
|
return (
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
<Toolbar.Alignment />
|
|
22
|
-
</Toolbar.Root>
|
|
23
|
-
</div>
|
|
24
|
-
</Tooltip.Provider>
|
|
17
|
+
<Toolbar.Root classNames={textBlockWidth}>
|
|
18
|
+
<Toolbar.Alignment />
|
|
19
|
+
</Toolbar.Root>
|
|
25
20
|
);
|
|
26
21
|
};
|
|
27
22
|
|
|
28
23
|
export default {
|
|
29
24
|
title: 'plugin-sheet/Toolbar',
|
|
30
25
|
component: Toolbar,
|
|
31
|
-
decorators: [withTheme],
|
|
26
|
+
decorators: [withTheme, withLayout({ tooltips: true })],
|
|
32
27
|
parameters: { translations, layout: 'fullscreen' },
|
|
33
28
|
render: (args: any) => <Story {...args} />,
|
|
34
29
|
};
|
|
@@ -23,22 +23,31 @@ import {
|
|
|
23
23
|
type ThemedClassName,
|
|
24
24
|
useTranslation,
|
|
25
25
|
} from '@dxos/react-ui';
|
|
26
|
+
import { nonNullable } from '@dxos/util';
|
|
26
27
|
|
|
27
28
|
import { ToolbarButton, ToolbarSeparator, ToolbarToggleButton } from './common';
|
|
29
|
+
import { addressToIndex } from '../../defs';
|
|
28
30
|
import { SHEET_PLUGIN } from '../../meta';
|
|
29
31
|
import { type Formatting } from '../../types';
|
|
32
|
+
import { useSheetContext } from '../Sheet/sheet-context';
|
|
30
33
|
|
|
31
34
|
//
|
|
32
35
|
// Root
|
|
33
36
|
//
|
|
34
37
|
|
|
35
|
-
export type
|
|
38
|
+
export type ToolbarAction =
|
|
39
|
+
| { type: 'clear' }
|
|
40
|
+
| { type: 'highlight' }
|
|
41
|
+
| { type: 'left' }
|
|
42
|
+
| { type: 'center' }
|
|
43
|
+
| { type: 'right' }
|
|
44
|
+
| { type: 'date' }
|
|
45
|
+
| { type: 'currency' }
|
|
46
|
+
| { type: 'comment'; anchor: string; cellContent?: string };
|
|
36
47
|
|
|
37
|
-
export type
|
|
38
|
-
type: ToolbarActionType;
|
|
39
|
-
};
|
|
48
|
+
export type ToolbarActionType = ToolbarAction['type'];
|
|
40
49
|
|
|
41
|
-
export type ToolbarActionHandler = (
|
|
50
|
+
export type ToolbarActionHandler = (action: ToolbarAction) => void;
|
|
42
51
|
|
|
43
52
|
export type ToolbarProps = ThemedClassName<
|
|
44
53
|
PropsWithChildren<{
|
|
@@ -96,7 +105,7 @@ const Format = () => {
|
|
|
96
105
|
Icon={Icon}
|
|
97
106
|
// disabled={state?.blockType === 'codeblock'}
|
|
98
107
|
// onClick={state ? () => onAction?.({ type, data: !getState(state) }) : undefined}
|
|
99
|
-
onClick={() => onAction?.({ type })}
|
|
108
|
+
onClick={() => onAction?.({ type: type as Exclude<typeof type, 'comment'> })}
|
|
100
109
|
>
|
|
101
110
|
{t(`toolbar ${type} label`)}
|
|
102
111
|
</ToolbarToggleButton>
|
|
@@ -127,7 +136,7 @@ const Alignment = () => {
|
|
|
127
136
|
Icon={Icon}
|
|
128
137
|
// disabled={state?.blockType === 'codeblock'}
|
|
129
138
|
// onClick={state ? () => onAction?.({ type, data: !getState(state) }) : undefined}
|
|
130
|
-
onClick={() => onAction?.({ type })}
|
|
139
|
+
onClick={() => onAction?.({ type: type as Exclude<typeof type, 'comment'> })}
|
|
131
140
|
>
|
|
132
141
|
{t(`toolbar ${type} label`)}
|
|
133
142
|
</ToolbarToggleButton>
|
|
@@ -157,7 +166,7 @@ const Styles = () => {
|
|
|
157
166
|
Icon={Icon}
|
|
158
167
|
// disabled={state?.blockType === 'codeblock'}
|
|
159
168
|
// onClick={state ? () => onAction?.({ type, data: !getState(state) }) : undefined}
|
|
160
|
-
onClick={() => onAction?.({ type })}
|
|
169
|
+
onClick={() => onAction?.({ type: type as Exclude<typeof type, 'comment'> })}
|
|
161
170
|
>
|
|
162
171
|
{t(`toolbar ${type} label`)}
|
|
163
172
|
</ToolbarToggleButton>
|
|
@@ -171,17 +180,49 @@ const Styles = () => {
|
|
|
171
180
|
//
|
|
172
181
|
|
|
173
182
|
const Actions = () => {
|
|
174
|
-
|
|
183
|
+
const { onAction } = useToolbarContext('Actions');
|
|
184
|
+
const { cursor, range, model } = useSheetContext();
|
|
175
185
|
const { t } = useTranslation(SHEET_PLUGIN);
|
|
186
|
+
|
|
187
|
+
const overlapsCommentAnchor = (model.sheet.threads ?? [])
|
|
188
|
+
.filter(nonNullable)
|
|
189
|
+
.filter((thread) => thread.status !== 'resolved')
|
|
190
|
+
.some((thread) => {
|
|
191
|
+
if (!cursor) {
|
|
192
|
+
return false;
|
|
193
|
+
}
|
|
194
|
+
return addressToIndex(model.sheet, cursor) === thread.anchor;
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
const hasCursor = !!cursor;
|
|
198
|
+
const cursorOnly = hasCursor && !range && !overlapsCommentAnchor;
|
|
199
|
+
|
|
200
|
+
const tooltipLabelKey = !hasCursor
|
|
201
|
+
? 'no cursor label'
|
|
202
|
+
: overlapsCommentAnchor
|
|
203
|
+
? 'selection overlaps existing comment label'
|
|
204
|
+
: range
|
|
205
|
+
? 'comment ranges not supported label'
|
|
206
|
+
: 'comment label';
|
|
207
|
+
|
|
176
208
|
return (
|
|
177
209
|
<ToolbarButton
|
|
178
210
|
value='comment'
|
|
179
211
|
Icon={ChatText}
|
|
180
212
|
data-testid='editor.toolbar.comment'
|
|
181
|
-
|
|
182
|
-
|
|
213
|
+
onClick={() => {
|
|
214
|
+
if (!cursor) {
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
return onAction?.({
|
|
218
|
+
type: 'comment',
|
|
219
|
+
anchor: addressToIndex(model.sheet, cursor),
|
|
220
|
+
cellContent: model.getCellText(cursor),
|
|
221
|
+
});
|
|
222
|
+
}}
|
|
223
|
+
disabled={!cursorOnly || overlapsCommentAnchor}
|
|
183
224
|
>
|
|
184
|
-
{t(
|
|
225
|
+
{t(tooltipLabelKey)}
|
|
185
226
|
</ToolbarButton>
|
|
186
227
|
);
|
|
187
228
|
};
|
package/src/components/index.ts
CHANGED
|
@@ -3,15 +3,14 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { getIndices, sortByIndex, getIndicesBelow, getIndicesAbove, getIndicesBetween } from '@tldraw/indices';
|
|
6
|
-
import { expect } from '
|
|
7
|
-
import { describe, test } from 'vitest';
|
|
6
|
+
import { describe, expect, test } from 'vitest';
|
|
8
7
|
|
|
9
8
|
import { inRange, addressFromA1Notation, addressToA1Notation, rangeFromA1Notation, rangeToA1Notation } from './types';
|
|
10
9
|
|
|
11
10
|
describe('cell', () => {
|
|
12
11
|
test('posToA1Notation', () => {
|
|
13
|
-
expect(addressToA1Notation({
|
|
14
|
-
expect(addressFromA1Notation('C2')).to.deep.eq({
|
|
12
|
+
expect(addressToA1Notation({ col: 0, row: 0 })).to.eq('A1');
|
|
13
|
+
expect(addressFromA1Notation('C2')).to.deep.eq({ col: 2, row: 1 });
|
|
15
14
|
});
|
|
16
15
|
|
|
17
16
|
test('rangeToA1Notation', () => {
|
|
@@ -56,19 +55,19 @@ describe('cell', () => {
|
|
|
56
55
|
// Values.
|
|
57
56
|
const cells: Record<string, any> = {};
|
|
58
57
|
const setCell = (cell: string, value: any) => {
|
|
59
|
-
const {
|
|
58
|
+
const { col, row } = addressFromA1Notation(cell);
|
|
60
59
|
// Reallocate if > current bounds.
|
|
61
|
-
if (
|
|
62
|
-
insertIndex(columns,
|
|
60
|
+
if (col >= columns.length) {
|
|
61
|
+
insertIndex(columns, col);
|
|
63
62
|
}
|
|
64
63
|
if (row >= rows.length) {
|
|
65
64
|
insertIndex(rows, row);
|
|
66
65
|
}
|
|
67
|
-
const index = `${columns[
|
|
66
|
+
const index = `${columns[col]}@${rows[row]}`;
|
|
68
67
|
cells[index] = value;
|
|
69
68
|
};
|
|
70
69
|
|
|
71
|
-
expect(addressFromA1Notation('A1')).to.deep.eq({
|
|
70
|
+
expect(addressFromA1Notation('A1')).to.deep.eq({ col: 0, row: 0 });
|
|
72
71
|
|
|
73
72
|
expect(columns).to.deep.eq(['a1', 'a2', 'a3', 'a4', 'a5']);
|
|
74
73
|
insertIndex(columns, 7);
|
|
@@ -4,25 +4,34 @@
|
|
|
4
4
|
|
|
5
5
|
import { invariant } from '@dxos/invariant';
|
|
6
6
|
|
|
7
|
-
export const
|
|
7
|
+
export const DEFAULT_ROWS = 50;
|
|
8
|
+
export const DEFAULT_COLUMNS = 26;
|
|
9
|
+
|
|
10
|
+
export const MAX_ROWS = 500;
|
|
11
|
+
export const MAX_COLUMNS = 26 * 2;
|
|
12
|
+
|
|
13
|
+
export type CellAddress = { col: number; row: number };
|
|
8
14
|
|
|
9
|
-
export type CellAddress = { column: number; row: number };
|
|
10
15
|
export type CellRange = { from: CellAddress; to?: CellAddress };
|
|
11
16
|
|
|
17
|
+
export type CellIndex = string;
|
|
18
|
+
|
|
19
|
+
export type CellContentValue = number | string | boolean | null;
|
|
20
|
+
|
|
12
21
|
export const posEquals = (a: CellAddress | undefined, b: CellAddress | undefined) => {
|
|
13
|
-
return a?.
|
|
22
|
+
return a?.col === b?.col && a?.row === b?.row;
|
|
14
23
|
};
|
|
15
24
|
|
|
16
|
-
export const columnLetter = (
|
|
17
|
-
invariant(
|
|
25
|
+
export const columnLetter = (col: number): string => {
|
|
26
|
+
invariant(col < MAX_COLUMNS, `Invalid column: ${col}`);
|
|
18
27
|
return (
|
|
19
|
-
(
|
|
20
|
-
String.fromCharCode('A'.charCodeAt(0) + (
|
|
28
|
+
(col >= 26 ? String.fromCharCode('A'.charCodeAt(0) + Math.floor(col / 26) - 1) : '') +
|
|
29
|
+
String.fromCharCode('A'.charCodeAt(0) + (col % 26))
|
|
21
30
|
);
|
|
22
31
|
};
|
|
23
32
|
|
|
24
|
-
export const addressToA1Notation = ({
|
|
25
|
-
return `${columnLetter(
|
|
33
|
+
export const addressToA1Notation = ({ col, row }: CellAddress): string => {
|
|
34
|
+
return `${columnLetter(col)}${row + 1}`;
|
|
26
35
|
};
|
|
27
36
|
|
|
28
37
|
export const addressFromA1Notation = (ref: string): CellAddress => {
|
|
@@ -30,7 +39,7 @@ export const addressFromA1Notation = (ref: string): CellAddress => {
|
|
|
30
39
|
invariant(match, `Invalid notation: ${ref}`);
|
|
31
40
|
return {
|
|
32
41
|
row: parseInt(match[2], 10) - 1,
|
|
33
|
-
|
|
42
|
+
col: match[1].split('').reduce((acc, c) => acc * 26 + c.charCodeAt(0) - 'A'.charCodeAt(0) + 1, 0) - 1,
|
|
34
43
|
};
|
|
35
44
|
};
|
|
36
45
|
|
|
@@ -59,13 +68,13 @@ export const inRange = (range: CellRange | undefined, cell: CellAddress): boolea
|
|
|
59
68
|
return false;
|
|
60
69
|
}
|
|
61
70
|
|
|
62
|
-
const {
|
|
63
|
-
const {
|
|
71
|
+
const { col: c1, row: r1 } = from;
|
|
72
|
+
const { col: c2, row: r2 } = to;
|
|
64
73
|
const cMin = Math.min(c1, c2);
|
|
65
74
|
const cMax = Math.max(c1, c2);
|
|
66
75
|
const rMin = Math.min(r1, r2);
|
|
67
76
|
const rMax = Math.max(r1, r2);
|
|
68
77
|
|
|
69
|
-
const {
|
|
70
|
-
return
|
|
78
|
+
const { col, row } = cell;
|
|
79
|
+
return col >= cMin && col <= cMax && row >= rMin && row <= rMax;
|
|
71
80
|
};
|