@dxos/plugin-sheet 0.6.14-main.7bd9c89 → 0.6.14-main.8b352a0
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-AKWROARP.mjs → SheetContainer-R65IDJHN.mjs} +54 -58
- package/dist/lib/browser/SheetContainer-R65IDJHN.mjs.map +7 -0
- package/dist/lib/browser/{chunk-BWN5DZWZ.mjs → chunk-5KVQ5IPW.mjs} +3 -12
- package/dist/lib/browser/chunk-5KVQ5IPW.mjs.map +7 -0
- package/dist/lib/browser/{chunk-FGMFOW6U.mjs → chunk-I2DKJ72A.mjs} +570 -669
- package/dist/lib/browser/chunk-I2DKJ72A.mjs.map +7 -0
- package/dist/lib/browser/{chunk-GSV5QNLD.mjs → chunk-KCYJSOFB.mjs} +252 -33
- package/dist/lib/browser/chunk-KCYJSOFB.mjs.map +7 -0
- package/dist/lib/browser/{graph-M4IQ76QX.mjs → compute-graph-SJT67236.mjs} +4 -2
- package/dist/lib/browser/index.mjs +62 -20
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/types.mjs +1 -1
- package/dist/lib/node/{SheetContainer-N5IQGEFL.cjs → SheetContainer-6BO4C5X2.cjs} +52 -62
- package/dist/lib/node/SheetContainer-6BO4C5X2.cjs.map +7 -0
- package/dist/lib/node/{chunk-NZARD7UP.cjs → chunk-2XJ5I4UF.cjs} +6 -15
- package/dist/lib/node/chunk-2XJ5I4UF.cjs.map +7 -0
- package/dist/lib/node/{chunk-53BMSUIK.cjs → chunk-DEPJHN47.cjs} +534 -646
- package/dist/lib/node/chunk-DEPJHN47.cjs.map +7 -0
- package/dist/lib/node/{chunk-5XPK2V4A.cjs → chunk-JF5XNTF3.cjs} +257 -28
- package/dist/lib/node/chunk-JF5XNTF3.cjs.map +7 -0
- package/dist/lib/node/{graph-Q3N2X26H.cjs → compute-graph-AQBDL7HO.cjs} +21 -19
- package/dist/lib/node/compute-graph-AQBDL7HO.cjs.map +7 -0
- package/dist/lib/node/index.cjs +70 -31
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/types.cjs +6 -6
- package/dist/lib/node/types.cjs.map +1 -1
- package/dist/lib/node-esm/{SheetContainer-46PBMF2E.mjs → SheetContainer-MJXC5E3P.mjs} +54 -58
- package/dist/lib/node-esm/SheetContainer-MJXC5E3P.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-T3PRH7QS.mjs → chunk-25V7WY4R.mjs} +570 -669
- package/dist/lib/node-esm/chunk-25V7WY4R.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-WFDTY3IC.mjs → chunk-5TXLF6PL.mjs} +3 -12
- package/dist/lib/node-esm/chunk-5TXLF6PL.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-5WPZCXNS.mjs → chunk-XBEHKYO7.mjs} +251 -33
- package/dist/lib/node-esm/chunk-XBEHKYO7.mjs.map +7 -0
- package/dist/lib/node-esm/{graph-SMPUMOV2.mjs → compute-graph-FRCKXEYK.mjs} +4 -2
- package/dist/lib/node-esm/index.mjs +62 -20
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/types.mjs +1 -1
- package/dist/types/src/SheetPlugin.d.ts.map +1 -1
- package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts +3 -1
- package/dist/types/src/components/ComputeGraph/ComputeGraphContextProvider.d.ts.map +1 -1
- package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +1 -1
- package/dist/types/src/components/GridSheet/GridSheet.stories.d.ts.map +1 -1
- package/dist/types/src/components/GridSheet/util.d.ts +1 -2
- package/dist/types/src/components/GridSheet/util.d.ts.map +1 -1
- package/dist/types/src/components/RangeList/RangeList.d.ts +7 -0
- package/dist/types/src/components/RangeList/RangeList.d.ts.map +1 -0
- package/dist/types/src/components/RangeList/index.d.ts +2 -0
- package/dist/types/src/components/RangeList/index.d.ts.map +1 -0
- package/dist/types/src/components/SheetContainer/SheetContainer.d.ts +6 -3
- package/dist/types/src/components/SheetContainer/SheetContainer.d.ts.map +1 -1
- package/dist/types/src/components/SheetContext/SheetContext.d.ts +7 -5
- package/dist/types/src/components/SheetContext/SheetContext.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +5 -2
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/compute-graph/compute-graph-registry.d.ts.map +1 -0
- package/dist/types/src/{graph → compute-graph}/compute-graph.d.ts +1 -1
- package/dist/types/src/compute-graph/compute-graph.d.ts.map +1 -0
- package/dist/types/src/compute-graph/compute-graph.stories.d.ts.map +1 -0
- package/dist/types/src/compute-graph/compute-graph.test.d.ts.map +1 -0
- package/dist/types/src/compute-graph/compute-node.d.ts.map +1 -0
- package/dist/types/src/compute-graph/functions/async-function.d.ts.map +1 -0
- package/dist/types/src/compute-graph/functions/edge-function.d.ts.map +1 -0
- package/dist/types/src/compute-graph/functions/function-defs.d.ts.map +1 -0
- package/dist/types/src/compute-graph/functions/index.d.ts.map +1 -0
- package/dist/types/src/compute-graph/hyperformula.test.d.ts.map +1 -0
- package/dist/types/src/compute-graph/index.d.ts.map +1 -0
- package/dist/types/src/compute-graph/testing/index.d.ts.map +1 -0
- package/dist/types/src/compute-graph/testing/test-builder.d.ts.map +1 -0
- package/dist/types/src/compute-graph/testing/test-plugin.d.ts.map +1 -0
- package/dist/types/src/compute-graph/util.d.ts.map +1 -0
- package/dist/types/src/defs/index.d.ts +1 -1
- package/dist/types/src/defs/index.d.ts.map +1 -1
- package/dist/types/src/defs/sheet-range-types.d.ts +1 -1
- package/dist/types/src/defs/sheet-range-types.d.ts.map +1 -1
- package/dist/types/src/defs/types.d.ts +6 -0
- package/dist/types/src/defs/types.d.ts.map +1 -1
- package/dist/types/src/defs/util.d.ts +2 -6
- package/dist/types/src/defs/util.d.ts.map +1 -1
- package/dist/types/src/extensions/compute.d.ts +1 -1
- package/dist/types/src/extensions/compute.d.ts.map +1 -1
- package/dist/types/src/extensions/editor/extension.d.ts +23 -3
- package/dist/types/src/extensions/editor/extension.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -1
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/integrations/index.d.ts +2 -0
- package/dist/types/src/integrations/index.d.ts.map +1 -0
- package/dist/types/src/integrations/thread-ranges.d.ts +7 -0
- package/dist/types/src/integrations/thread-ranges.d.ts.map +1 -0
- package/dist/types/src/model/index.d.ts +1 -1
- package/dist/types/src/model/index.d.ts.map +1 -1
- package/dist/types/src/model/sheet-model.d.ts +1 -1
- package/dist/types/src/model/sheet-model.d.ts.map +1 -1
- package/dist/types/src/{hooks → model}/useSheetModel.d.ts +1 -1
- package/dist/types/src/model/useSheetModel.d.ts.map +1 -0
- package/dist/types/src/serializer.d.ts +4 -0
- package/dist/types/src/serializer.d.ts.map +1 -0
- package/dist/types/src/testing/testing.d.ts +1 -1
- package/dist/types/src/testing/testing.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +13 -3
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +4 -30
- package/dist/types/src/types.d.ts.map +1 -1
- package/package.json +43 -50
- package/src/SheetPlugin.tsx +25 -12
- package/src/components/ComputeGraph/ComputeGraphContextProvider.tsx +19 -2
- package/src/components/FunctionEditor/FunctionEditor.tsx +5 -5
- package/src/components/GridSheet/GridSheet.stories.tsx +3 -1
- package/src/components/GridSheet/GridSheet.tsx +118 -22
- package/src/components/GridSheet/SheetCellEditor.stories.tsx +1 -1
- package/src/components/GridSheet/util.ts +24 -14
- package/src/components/RangeList/RangeList.tsx +53 -0
- package/src/components/RangeList/index.ts +5 -0
- package/src/components/SheetContainer/SheetContainer.stories.tsx +3 -3
- package/src/components/SheetContainer/SheetContainer.tsx +10 -4
- package/src/components/SheetContext/SheetContext.tsx +43 -20
- package/src/components/Toolbar/Toolbar.tsx +44 -41
- package/src/components/index.ts +1 -0
- package/src/{graph → compute-graph}/compute-graph.stories.tsx +2 -1
- package/src/{graph → compute-graph}/compute-graph.ts +5 -2
- package/src/{graph → compute-graph}/compute-node.ts +2 -3
- package/src/defs/index.ts +1 -1
- package/src/defs/sheet-range-types.ts +5 -4
- package/src/defs/types.ts +6 -1
- package/src/defs/util.ts +3 -19
- package/src/extensions/compute.stories.tsx +2 -2
- package/src/extensions/compute.ts +2 -2
- package/src/extensions/editor/extension.test.ts +1 -1
- package/src/extensions/editor/extension.ts +48 -23
- package/src/index.ts +2 -2
- package/src/integrations/index.ts +5 -0
- package/src/integrations/thread-ranges.ts +101 -0
- package/src/model/index.ts +1 -1
- package/src/model/sheet-model.test.ts +1 -1
- package/src/model/sheet-model.ts +13 -8
- package/src/{hooks → model}/useSheetModel.ts +1 -1
- package/src/serializer.ts +27 -0
- package/src/testing/testing.tsx +1 -1
- package/src/translations.ts +13 -3
- package/src/types.ts +4 -2
- package/dist/lib/browser/SheetContainer-AKWROARP.mjs.map +0 -7
- package/dist/lib/browser/chunk-BWN5DZWZ.mjs.map +0 -7
- package/dist/lib/browser/chunk-FGMFOW6U.mjs.map +0 -7
- package/dist/lib/browser/chunk-GSV5QNLD.mjs.map +0 -7
- package/dist/lib/node/SheetContainer-N5IQGEFL.cjs.map +0 -7
- package/dist/lib/node/chunk-53BMSUIK.cjs.map +0 -7
- package/dist/lib/node/chunk-5XPK2V4A.cjs.map +0 -7
- package/dist/lib/node/chunk-NZARD7UP.cjs.map +0 -7
- package/dist/lib/node/graph-Q3N2X26H.cjs.map +0 -7
- package/dist/lib/node-esm/SheetContainer-46PBMF2E.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-5WPZCXNS.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-T3PRH7QS.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-WFDTY3IC.mjs.map +0 -7
- package/dist/types/src/graph/compute-graph-registry.d.ts.map +0 -1
- package/dist/types/src/graph/compute-graph.d.ts.map +0 -1
- package/dist/types/src/graph/compute-graph.stories.d.ts.map +0 -1
- package/dist/types/src/graph/compute-graph.test.d.ts.map +0 -1
- package/dist/types/src/graph/compute-node.d.ts.map +0 -1
- package/dist/types/src/graph/functions/async-function.d.ts.map +0 -1
- package/dist/types/src/graph/functions/edge-function.d.ts.map +0 -1
- package/dist/types/src/graph/functions/function-defs.d.ts.map +0 -1
- package/dist/types/src/graph/functions/index.d.ts.map +0 -1
- package/dist/types/src/graph/hyperformula.test.d.ts.map +0 -1
- package/dist/types/src/graph/index.d.ts.map +0 -1
- package/dist/types/src/graph/testing/index.d.ts.map +0 -1
- package/dist/types/src/graph/testing/test-builder.d.ts.map +0 -1
- package/dist/types/src/graph/testing/test-plugin.d.ts.map +0 -1
- package/dist/types/src/graph/util.d.ts.map +0 -1
- package/dist/types/src/hooks/hooks.stories.d.ts +0 -6
- package/dist/types/src/hooks/hooks.stories.d.ts.map +0 -1
- package/dist/types/src/hooks/index.d.ts +0 -4
- package/dist/types/src/hooks/index.d.ts.map +0 -1
- package/dist/types/src/hooks/threads.d.ts +0 -8
- package/dist/types/src/hooks/threads.d.ts.map +0 -1
- package/dist/types/src/hooks/useComputeGraph.d.ts +0 -7
- package/dist/types/src/hooks/useComputeGraph.d.ts.map +0 -1
- package/dist/types/src/hooks/useSheetModel.d.ts.map +0 -1
- package/dist/types/src/model/decorations.d.ts +0 -26
- package/dist/types/src/model/decorations.d.ts.map +0 -1
- package/src/hooks/hooks.stories.tsx +0 -53
- package/src/hooks/index.ts +0 -7
- package/src/hooks/threads.ts +0 -147
- package/src/hooks/useComputeGraph.ts +0 -28
- package/src/model/decorations.ts +0 -66
- /package/dist/lib/browser/{graph-M4IQ76QX.mjs.map → compute-graph-SJT67236.mjs.map} +0 -0
- /package/dist/lib/node-esm/{graph-SMPUMOV2.mjs.map → compute-graph-FRCKXEYK.mjs.map} +0 -0
- /package/dist/types/src/{graph → compute-graph}/compute-graph-registry.d.ts +0 -0
- /package/dist/types/src/{graph → compute-graph}/compute-graph.stories.d.ts +0 -0
- /package/dist/types/src/{graph → compute-graph}/compute-graph.test.d.ts +0 -0
- /package/dist/types/src/{graph → compute-graph}/compute-node.d.ts +0 -0
- /package/dist/types/src/{graph → compute-graph}/functions/async-function.d.ts +0 -0
- /package/dist/types/src/{graph → compute-graph}/functions/edge-function.d.ts +0 -0
- /package/dist/types/src/{graph → compute-graph}/functions/function-defs.d.ts +0 -0
- /package/dist/types/src/{graph → compute-graph}/functions/index.d.ts +0 -0
- /package/dist/types/src/{graph → compute-graph}/hyperformula.test.d.ts +0 -0
- /package/dist/types/src/{graph → compute-graph}/index.d.ts +0 -0
- /package/dist/types/src/{graph → compute-graph}/testing/index.d.ts +0 -0
- /package/dist/types/src/{graph → compute-graph}/testing/test-builder.d.ts +0 -0
- /package/dist/types/src/{graph → compute-graph}/testing/test-plugin.d.ts +0 -0
- /package/dist/types/src/{graph → compute-graph}/util.d.ts +0 -0
- /package/src/{graph → compute-graph}/compute-graph-registry.ts +0 -0
- /package/src/{graph → compute-graph}/compute-graph.test.ts +0 -0
- /package/src/{graph → compute-graph}/functions/async-function.ts +0 -0
- /package/src/{graph → compute-graph}/functions/edge-function.ts +0 -0
- /package/src/{graph → compute-graph}/functions/function-defs.ts +0 -0
- /package/src/{graph → compute-graph}/functions/index.ts +0 -0
- /package/src/{graph → compute-graph}/hyperformula.test.ts +0 -0
- /package/src/{graph → compute-graph}/index.ts +0 -0
- /package/src/{graph → compute-graph}/testing/index.ts +0 -0
- /package/src/{graph → compute-graph}/testing/test-builder.ts +0 -0
- /package/src/{graph → compute-graph}/testing/test-plugin.ts +0 -0
- /package/src/{graph → compute-graph}/util.ts +0 -0
|
@@ -2,16 +2,21 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import React, { type PropsWithChildren, createContext,
|
|
5
|
+
import React, { type PropsWithChildren, createContext, useCallback, useContext, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
import { invariant } from '@dxos/invariant';
|
|
8
8
|
import { fullyQualifiedId } from '@dxos/react-client/echo';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
import {
|
|
10
|
+
Grid,
|
|
11
|
+
type GridContentProps,
|
|
12
|
+
type GridEditing,
|
|
13
|
+
type GridScopedProps,
|
|
14
|
+
useGridContext,
|
|
15
|
+
} from '@dxos/react-ui-grid';
|
|
16
|
+
|
|
17
|
+
import { type ComputeGraph } from '../../compute-graph';
|
|
18
|
+
import { type CellAddress, type CellRange, type CompleteCellRange } from '../../defs';
|
|
19
|
+
import { type SheetModel, useSheetModel } from '../../model';
|
|
15
20
|
import { type SheetType } from '../../types';
|
|
16
21
|
|
|
17
22
|
export type SheetContextValue = {
|
|
@@ -25,17 +30,19 @@ export type SheetContextValue = {
|
|
|
25
30
|
setCursor: (cell: CellAddress | undefined) => void;
|
|
26
31
|
range?: CellRange;
|
|
27
32
|
setRange: (range: CellRange | undefined) => void;
|
|
33
|
+
cursorFallbackRange?: CompleteCellRange;
|
|
28
34
|
|
|
29
35
|
// Editing state (undefined if not editing).
|
|
30
36
|
editing: GridEditing;
|
|
31
37
|
setEditing: (editing: GridEditing) => void;
|
|
32
38
|
|
|
39
|
+
// Active refs
|
|
40
|
+
activeRefs: GridContentProps['activeRefs'];
|
|
41
|
+
setActiveRefs: (activeRefs: GridContentProps['activeRefs']) => void;
|
|
42
|
+
|
|
33
43
|
// Events.
|
|
34
44
|
// TODO(burdon): Generalize.
|
|
35
45
|
onInfo?: () => void;
|
|
36
|
-
|
|
37
|
-
// Decorations.
|
|
38
|
-
decorations: ReturnType<typeof createDecorations>;
|
|
39
46
|
};
|
|
40
47
|
|
|
41
48
|
const SheetContext = createContext<SheetContextValue | undefined>(undefined);
|
|
@@ -54,15 +61,29 @@ const SheetProviderImpl = ({
|
|
|
54
61
|
}: GridScopedProps<PropsWithChildren<Pick<SheetContextValue, 'onInfo' | 'model'>>>) => {
|
|
55
62
|
const { id, editing, setEditing } = useGridContext('SheetProvider', __gridScope);
|
|
56
63
|
|
|
57
|
-
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
const [cursor, setCursorInternal] = useState<CellAddress>();
|
|
65
|
+
const [range, setRangeInternal] = useState<CellRange>();
|
|
66
|
+
const [cursorFallbackRange, setCursorFallbackRange] = useState<CompleteCellRange>();
|
|
67
|
+
const [activeRefs, setActiveRefs] = useState<GridContentProps['activeRefs']>('');
|
|
68
|
+
|
|
69
|
+
const setCursor = useCallback(
|
|
70
|
+
(nextCursor?: CellAddress) => {
|
|
71
|
+
setCursorInternal(nextCursor);
|
|
72
|
+
setCursorFallbackRange(
|
|
73
|
+
range?.to ? (range as CompleteCellRange) : nextCursor ? { from: nextCursor!, to: nextCursor! } : undefined,
|
|
74
|
+
);
|
|
75
|
+
},
|
|
76
|
+
[range],
|
|
77
|
+
);
|
|
78
|
+
const setRange = useCallback(
|
|
79
|
+
(nextRange?: CellRange) => {
|
|
80
|
+
setRangeInternal(nextRange);
|
|
81
|
+
setCursorFallbackRange(
|
|
82
|
+
nextRange?.to ? (nextRange as CompleteCellRange) : cursor ? { from: cursor!, to: cursor! } : undefined,
|
|
83
|
+
);
|
|
84
|
+
},
|
|
85
|
+
[cursor],
|
|
86
|
+
);
|
|
66
87
|
|
|
67
88
|
return (
|
|
68
89
|
<SheetContext.Provider
|
|
@@ -75,9 +96,11 @@ const SheetProviderImpl = ({
|
|
|
75
96
|
setCursor,
|
|
76
97
|
range,
|
|
77
98
|
setRange,
|
|
99
|
+
cursorFallbackRange,
|
|
100
|
+
activeRefs,
|
|
101
|
+
setActiveRefs,
|
|
78
102
|
// TODO(burdon): Change to event.
|
|
79
103
|
onInfo,
|
|
80
|
-
decorations,
|
|
81
104
|
}}
|
|
82
105
|
>
|
|
83
106
|
{children}
|
|
@@ -8,27 +8,30 @@ import React, { type PropsWithChildren, useCallback, useMemo } from 'react';
|
|
|
8
8
|
import { useIntentDispatcher } from '@dxos/app-framework';
|
|
9
9
|
import {
|
|
10
10
|
Icon,
|
|
11
|
+
type ThemedClassName,
|
|
11
12
|
Toolbar as NaturalToolbar,
|
|
12
|
-
useTranslation,
|
|
13
|
-
Tooltip,
|
|
14
|
-
type ToolbarToggleGroupItemProps as NaturalToolbarToggleGroupItemProps,
|
|
15
13
|
type ToolbarButtonProps as NaturalToolbarButtonProps,
|
|
14
|
+
type ToolbarToggleGroupItemProps as NaturalToolbarToggleGroupItemProps,
|
|
16
15
|
type ToolbarToggleProps as NaturalToolbarToggleProps,
|
|
17
|
-
|
|
16
|
+
Tooltip,
|
|
17
|
+
useTranslation,
|
|
18
18
|
} from '@dxos/react-ui';
|
|
19
19
|
import { useAttention } from '@dxos/react-ui-attention';
|
|
20
20
|
import { nonNullable } from '@dxos/util';
|
|
21
21
|
|
|
22
22
|
import {
|
|
23
|
-
|
|
23
|
+
alignKey,
|
|
24
24
|
type AlignKey,
|
|
25
25
|
type AlignValue,
|
|
26
26
|
type CommentKey,
|
|
27
27
|
type CommentValue,
|
|
28
28
|
inRange,
|
|
29
|
+
rangeFromIndex,
|
|
30
|
+
rangeToIndex,
|
|
29
31
|
type StyleKey,
|
|
30
32
|
type StyleValue,
|
|
31
33
|
} from '../../defs';
|
|
34
|
+
import { completeCellRangeToThreadCursor } from '../../integrations';
|
|
32
35
|
import { SHEET_PLUGIN } from '../../meta';
|
|
33
36
|
import { type SheetType } from '../../types';
|
|
34
37
|
import { useSheetContext } from '../SheetContext';
|
|
@@ -108,22 +111,21 @@ const sectionToolbarLayout =
|
|
|
108
111
|
type Range = SheetType['ranges'][number];
|
|
109
112
|
|
|
110
113
|
const ToolbarRoot = ({ children, role, classNames }: ToolbarProps) => {
|
|
111
|
-
const { id, model,
|
|
114
|
+
const { id, model, cursorFallbackRange, cursor } = useSheetContext();
|
|
112
115
|
const { hasAttention } = useAttention(id);
|
|
113
116
|
const dispatch = useIntentDispatcher();
|
|
114
117
|
|
|
115
|
-
// TODO(Zan):
|
|
118
|
+
// TODO(Zan): Externalize the toolbar action handler. E.g., Toolbar/keys should both fire events.
|
|
116
119
|
const handleAction = useCallback(
|
|
117
120
|
(action: ToolbarAction) => {
|
|
118
121
|
switch (action.key) {
|
|
119
|
-
case '
|
|
120
|
-
if (cursor) {
|
|
122
|
+
case 'alignment':
|
|
123
|
+
if (cursor && cursorFallbackRange) {
|
|
121
124
|
const index = model.sheet.ranges?.findIndex(
|
|
122
|
-
(range) => range.key === action.key && inRange(range.range, cursor),
|
|
125
|
+
(range) => range.key === action.key && inRange(rangeFromIndex(model.sheet, range.range), cursor),
|
|
123
126
|
);
|
|
124
|
-
const nextRange = range ? { from: range.from, to: range.to ?? range.from } : { from: cursor, to: cursor };
|
|
125
127
|
const nextRangeEntity = {
|
|
126
|
-
range:
|
|
128
|
+
range: rangeToIndex(model.sheet, cursorFallbackRange),
|
|
127
129
|
key: action.key,
|
|
128
130
|
value: action.value,
|
|
129
131
|
};
|
|
@@ -140,10 +142,9 @@ const ToolbarRoot = ({ children, role, classNames }: ToolbarProps) => {
|
|
|
140
142
|
if (index >= 0) {
|
|
141
143
|
model.sheet.ranges?.splice(index, 1);
|
|
142
144
|
}
|
|
143
|
-
} else if (
|
|
144
|
-
const nextRange = range ? { from: range.from, to: range.to ?? range.from } : { from: cursor, to: cursor };
|
|
145
|
+
} else if (cursorFallbackRange) {
|
|
145
146
|
model.sheet.ranges?.push({
|
|
146
|
-
range:
|
|
147
|
+
range: rangeToIndex(model.sheet, cursorFallbackRange),
|
|
147
148
|
key: action.key,
|
|
148
149
|
value: action.value,
|
|
149
150
|
});
|
|
@@ -151,18 +152,20 @@ const ToolbarRoot = ({ children, role, classNames }: ToolbarProps) => {
|
|
|
151
152
|
break;
|
|
152
153
|
case 'comment': {
|
|
153
154
|
// TODO(Zan): We shouldn't hardcode the action ID.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
155
|
+
if (cursorFallbackRange) {
|
|
156
|
+
void dispatch({
|
|
157
|
+
action: 'dxos.org/plugin/thread/action/create',
|
|
158
|
+
data: {
|
|
159
|
+
cursor: completeCellRangeToThreadCursor(cursorFallbackRange),
|
|
160
|
+
name: action.cellContent,
|
|
161
|
+
subject: model.sheet,
|
|
162
|
+
},
|
|
163
|
+
});
|
|
164
|
+
}
|
|
162
165
|
}
|
|
163
166
|
}
|
|
164
167
|
},
|
|
165
|
-
[model.sheet,
|
|
168
|
+
[model.sheet, cursorFallbackRange, cursor, dispatch],
|
|
166
169
|
);
|
|
167
170
|
|
|
168
171
|
return (
|
|
@@ -207,7 +210,9 @@ const Alignment = () => {
|
|
|
207
210
|
const value = useMemo(
|
|
208
211
|
() =>
|
|
209
212
|
cursor
|
|
210
|
-
? model.sheet.ranges?.find(
|
|
213
|
+
? model.sheet.ranges?.find(
|
|
214
|
+
({ range, key }) => key === alignKey && inRange(rangeFromIndex(model.sheet, range), cursor),
|
|
215
|
+
)?.value
|
|
211
216
|
: undefined,
|
|
212
217
|
[cursor, model.sheet.ranges],
|
|
213
218
|
);
|
|
@@ -216,11 +221,14 @@ const Alignment = () => {
|
|
|
216
221
|
<NaturalToolbar.ToggleGroup
|
|
217
222
|
type='single'
|
|
218
223
|
value={value}
|
|
219
|
-
onValueChange={(value: AlignValue) => onAction?.({ key:
|
|
224
|
+
onValueChange={(value: AlignValue) => onAction?.({ key: alignKey, value })}
|
|
220
225
|
>
|
|
221
226
|
{alignmentOptions.map(({ value, icon }) => (
|
|
222
227
|
<ToolbarItem itemType='toggleGroupItem' key={value} value={value} icon={icon}>
|
|
223
|
-
{t(
|
|
228
|
+
{t('toolbar action label', {
|
|
229
|
+
key: t(`range key ${alignKey} label`),
|
|
230
|
+
value: t(`range value ${value} label`),
|
|
231
|
+
})}
|
|
224
232
|
</ToolbarItem>
|
|
225
233
|
))}
|
|
226
234
|
</NaturalToolbar.ToggleGroup>
|
|
@@ -238,7 +246,7 @@ const Styles = () => {
|
|
|
238
246
|
() =>
|
|
239
247
|
cursor
|
|
240
248
|
? model.sheet.ranges
|
|
241
|
-
?.filter(({ range, key }) => key === 'style' && inRange(range, cursor))
|
|
249
|
+
?.filter(({ range, key }) => key === 'style' && inRange(rangeFromIndex(model.sheet, range), cursor))
|
|
242
250
|
.reduce((acc, { value }) => {
|
|
243
251
|
acc.add(value);
|
|
244
252
|
return acc;
|
|
@@ -270,29 +278,24 @@ const Styles = () => {
|
|
|
270
278
|
|
|
271
279
|
const Actions = () => {
|
|
272
280
|
const { onAction } = useToolbarContext('Actions');
|
|
273
|
-
const {
|
|
281
|
+
const { cursorFallbackRange, cursor, model } = useSheetContext();
|
|
274
282
|
const { t } = useTranslation(SHEET_PLUGIN);
|
|
275
283
|
|
|
276
284
|
const overlapsCommentAnchor = (model.sheet.threads ?? [])
|
|
277
285
|
.filter(nonNullable)
|
|
278
286
|
.filter((thread) => thread.status !== 'resolved')
|
|
279
287
|
.some((thread) => {
|
|
280
|
-
if (!
|
|
288
|
+
if (!cursorFallbackRange) {
|
|
281
289
|
return false;
|
|
282
290
|
}
|
|
283
|
-
return
|
|
291
|
+
return rangeToIndex(model.sheet, cursorFallbackRange) === thread.anchor;
|
|
284
292
|
});
|
|
285
293
|
|
|
286
|
-
const
|
|
287
|
-
const cursorOnly = hasCursor && !range && !overlapsCommentAnchor;
|
|
288
|
-
|
|
289
|
-
const tooltipLabelKey = !hasCursor
|
|
294
|
+
const tooltipLabelKey = !cursor
|
|
290
295
|
? 'no cursor label'
|
|
291
296
|
: overlapsCommentAnchor
|
|
292
297
|
? 'selection overlaps existing comment label'
|
|
293
|
-
:
|
|
294
|
-
? 'comment ranges not supported label'
|
|
295
|
-
: 'comment label';
|
|
298
|
+
: 'comment label';
|
|
296
299
|
|
|
297
300
|
return (
|
|
298
301
|
<ToolbarItem
|
|
@@ -301,16 +304,16 @@ const Actions = () => {
|
|
|
301
304
|
icon='ph--chat-text--regular'
|
|
302
305
|
data-testid='editor.toolbar.comment'
|
|
303
306
|
onClick={() => {
|
|
304
|
-
if (!cursor) {
|
|
307
|
+
if (!(cursorFallbackRange && cursor)) {
|
|
305
308
|
return;
|
|
306
309
|
}
|
|
307
310
|
return onAction?.({
|
|
308
311
|
key: 'comment',
|
|
309
|
-
value:
|
|
312
|
+
value: rangeToIndex(model.sheet, cursorFallbackRange),
|
|
310
313
|
cellContent: model.getCellText(cursor),
|
|
311
314
|
});
|
|
312
315
|
}}
|
|
313
|
-
disabled={!
|
|
316
|
+
disabled={!cursor || overlapsCommentAnchor}
|
|
314
317
|
>
|
|
315
318
|
{t(tooltipLabelKey)}
|
|
316
319
|
</ToolbarItem>
|
package/src/components/index.ts
CHANGED
|
@@ -15,8 +15,9 @@ import { SyntaxHighlighter } from '@dxos/react-ui-syntax-highlighter';
|
|
|
15
15
|
import { withTheme } from '@dxos/storybook-utils';
|
|
16
16
|
|
|
17
17
|
import { testFunctionPlugins } from './testing';
|
|
18
|
+
import { useComputeGraph } from '../components';
|
|
18
19
|
import { createSheet } from '../defs';
|
|
19
|
-
import {
|
|
20
|
+
import { useSheetModel } from '../model';
|
|
20
21
|
import { withComputeGraphDecorator } from '../testing';
|
|
21
22
|
import { SheetType } from '../types';
|
|
22
23
|
|
|
@@ -24,6 +24,8 @@ import {
|
|
|
24
24
|
EDGE_FUNCTION_NAME,
|
|
25
25
|
} from './functions';
|
|
26
26
|
|
|
27
|
+
// TODO(burdon): Factor out compute-graph.
|
|
28
|
+
|
|
27
29
|
// TODO(wittjosiah): Factor out.
|
|
28
30
|
const OBJECT_ID_LENGTH = 60; // 33 (space id) + 1 (separator) + 26 (object id).
|
|
29
31
|
|
|
@@ -71,6 +73,7 @@ export class ComputeGraph extends Resource {
|
|
|
71
73
|
) {
|
|
72
74
|
super();
|
|
73
75
|
this._hf.updateConfig({ context: this.context });
|
|
76
|
+
|
|
74
77
|
// TODO(burdon): If debounce then aggregate changes.
|
|
75
78
|
const onValuesUpdate: Listeners['valuesUpdated'] = (changes) => {
|
|
76
79
|
for (const change of changes) {
|
|
@@ -116,7 +119,7 @@ export class ComputeGraph extends Resource {
|
|
|
116
119
|
getOrCreateNode(name: string): ComputeNode {
|
|
117
120
|
invariant(name.length);
|
|
118
121
|
if (!this._hf.doesSheetExist(name)) {
|
|
119
|
-
log
|
|
122
|
+
log('created node', { space: this._space?.id, sheet: name });
|
|
120
123
|
this._hf.addSheet(name);
|
|
121
124
|
}
|
|
122
125
|
|
|
@@ -130,7 +133,7 @@ export class ComputeGraph extends Resource {
|
|
|
130
133
|
|
|
131
134
|
/**
|
|
132
135
|
* Map bound value to custom function invocation.
|
|
133
|
-
* E.g., "HELLO(...args)" => "
|
|
136
|
+
* E.g., "HELLO(...args)" => "DX("HELLO", ...args)".
|
|
134
137
|
*/
|
|
135
138
|
mapFormulaToNative(formula: string): string {
|
|
136
139
|
return (
|
|
@@ -10,7 +10,7 @@ import { Resource } from '@dxos/context';
|
|
|
10
10
|
|
|
11
11
|
import { DetailedCellError } from '#hyperformula';
|
|
12
12
|
import { type ComputeGraph } from './compute-graph';
|
|
13
|
-
import { type CellAddress } from '../defs';
|
|
13
|
+
import { type CellAddress, isFormula } from '../defs';
|
|
14
14
|
import { type CellScalarValue } from '../types';
|
|
15
15
|
|
|
16
16
|
export type ComputeNodeEvent = {
|
|
@@ -50,8 +50,7 @@ export class ComputeNode extends Resource {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
setValue(cell: CellAddress, value: CellScalarValue) {
|
|
53
|
-
const mappedValue =
|
|
54
|
-
typeof value === 'string' && value.charAt(0) === '=' ? this._graph.mapFormulaToNative(value) : value;
|
|
53
|
+
const mappedValue = isFormula(value) ? this._graph.mapFormulaToNative(value) : value;
|
|
55
54
|
this._graph.hf.setCellContents({ sheet: this.sheetId, row: cell.row, col: cell.col }, [[mappedValue]]);
|
|
56
55
|
}
|
|
57
56
|
|
package/src/defs/index.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { type ClassNameValue } from '@dxos/react-ui';
|
|
|
6
6
|
|
|
7
7
|
import { type SheetType } from '../types';
|
|
8
8
|
|
|
9
|
-
export const alignKey = '
|
|
9
|
+
export const alignKey = 'alignment';
|
|
10
10
|
export type AlignKey = typeof alignKey;
|
|
11
11
|
export type AlignValue = 'start' | 'center' | 'end' | 'unset';
|
|
12
12
|
|
|
@@ -18,9 +18,10 @@ export const styleKey = 'style';
|
|
|
18
18
|
export type StyleKey = typeof styleKey;
|
|
19
19
|
export type StyleValue = 'highlight' | 'unset';
|
|
20
20
|
|
|
21
|
+
// TODO(burdon): Reconcile with plugin-table.
|
|
21
22
|
export const cellClassNameForRange = ({ key, value }: SheetType['ranges'][number]): ClassNameValue => {
|
|
22
23
|
switch (key) {
|
|
23
|
-
case
|
|
24
|
+
case alignKey:
|
|
24
25
|
switch (value) {
|
|
25
26
|
case 'start':
|
|
26
27
|
return 'text-start';
|
|
@@ -31,9 +32,9 @@ export const cellClassNameForRange = ({ key, value }: SheetType['ranges'][number
|
|
|
31
32
|
default:
|
|
32
33
|
return undefined;
|
|
33
34
|
}
|
|
34
|
-
case
|
|
35
|
+
case commentKey:
|
|
35
36
|
return 'bg-gridComment';
|
|
36
|
-
case
|
|
37
|
+
case styleKey:
|
|
37
38
|
switch (value) {
|
|
38
39
|
case 'highlight':
|
|
39
40
|
return 'bg-gridHighlight';
|
package/src/defs/types.ts
CHANGED
|
@@ -13,11 +13,16 @@ export const MAX_COLUMNS = 26 * 2;
|
|
|
13
13
|
export type CellAddress = { col: number; row: number };
|
|
14
14
|
|
|
15
15
|
export type CellRange = { from: CellAddress; to?: CellAddress };
|
|
16
|
+
export type CompleteCellRange = { from: CellAddress; to: CellAddress };
|
|
16
17
|
|
|
17
18
|
export type CellIndex = string;
|
|
18
19
|
|
|
19
20
|
export type CellContentValue = number | string | boolean | null;
|
|
20
21
|
|
|
22
|
+
export const RANGE_NOTATION = /^[A-Z]+[0-9]+(:[A-Z]+[0-9]+)?$/;
|
|
23
|
+
|
|
24
|
+
export const isFormula = (value: any): value is string => typeof value === 'string' && value.charAt(0) === '=';
|
|
25
|
+
|
|
21
26
|
export const posEquals = (a: CellAddress | undefined, b: CellAddress | undefined) => {
|
|
22
27
|
return a?.col === b?.col && a?.row === b?.row;
|
|
23
28
|
};
|
|
@@ -34,7 +39,7 @@ export const addressToA1Notation = ({ col, row }: CellAddress): string => {
|
|
|
34
39
|
return `${columnLetter(col)}${row + 1}`;
|
|
35
40
|
};
|
|
36
41
|
|
|
37
|
-
// TODO(burdon): See simpleCellAddressFromString
|
|
42
|
+
// TODO(burdon): See (HF) simpleCellAddressFromString.
|
|
38
43
|
export const addressFromA1Notation = (ref: string): CellAddress => {
|
|
39
44
|
const match = ref.match(/([A-Z]+)(\d+)/);
|
|
40
45
|
invariant(match, `Invalid notation: ${ref}`);
|
package/src/defs/util.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
addressFromA1Notation,
|
|
10
10
|
type CellAddress,
|
|
11
11
|
type CellRange,
|
|
12
|
+
type CompleteCellRange,
|
|
12
13
|
DEFAULT_COLUMNS,
|
|
13
14
|
DEFAULT_ROWS,
|
|
14
15
|
MAX_COLUMNS,
|
|
@@ -69,6 +70,7 @@ export const createSheet = ({ name, cells, ...size }: CreateSheetOptions = {}):
|
|
|
69
70
|
rowMeta: {},
|
|
70
71
|
columnMeta: {},
|
|
71
72
|
ranges: [],
|
|
73
|
+
threads: [],
|
|
72
74
|
});
|
|
73
75
|
|
|
74
76
|
initialize(sheet, size);
|
|
@@ -111,29 +113,11 @@ export const rangeToIndex = (sheet: SheetType, range: CellRange): string => {
|
|
|
111
113
|
/**
|
|
112
114
|
* E.g., "CA2@CB3:CC4@CD5" => "A1:B2".
|
|
113
115
|
*/
|
|
114
|
-
export const rangeFromIndex = (sheet: SheetType, idx: string):
|
|
116
|
+
export const rangeFromIndex = (sheet: SheetType, idx: string): CompleteCellRange => {
|
|
115
117
|
const [from, to] = idx.split(':').map((index) => addressFromIndex(sheet, index));
|
|
116
118
|
return { from, to };
|
|
117
119
|
};
|
|
118
120
|
|
|
119
|
-
/**
|
|
120
|
-
* Find closest cell to cursor.
|
|
121
|
-
*/
|
|
122
|
-
export const closest = (cursor: CellAddress, cells: CellAddress[]): CellAddress | undefined => {
|
|
123
|
-
let closestCell: CellAddress | undefined;
|
|
124
|
-
let closestDistance = Number.MAX_SAFE_INTEGER;
|
|
125
|
-
|
|
126
|
-
for (const cell of cells) {
|
|
127
|
-
const distance = Math.abs(cell.row - cursor.row) + Math.abs(cell.col - cursor.col);
|
|
128
|
-
if (distance < closestDistance) {
|
|
129
|
-
closestCell = cell;
|
|
130
|
-
closestDistance = distance;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
return closestCell;
|
|
135
|
-
};
|
|
136
|
-
|
|
137
121
|
/**
|
|
138
122
|
* Compares the positions of two cell indexes in a sheet.
|
|
139
123
|
* Sorts primarily by row, then by column if rows are equal.
|
|
@@ -23,8 +23,8 @@ import { withTheme, withLayout } from '@dxos/storybook-utils';
|
|
|
23
23
|
import { nonNullable } from '@dxos/util';
|
|
24
24
|
|
|
25
25
|
import { compute, computeGraphFacet } from './compute';
|
|
26
|
-
import { GridSheet, SheetProvider } from '../components';
|
|
27
|
-
import {
|
|
26
|
+
import { GridSheet, SheetProvider, useComputeGraph } from '../components';
|
|
27
|
+
import { useSheetModel } from '../model';
|
|
28
28
|
import { useTestSheet, withComputeGraphDecorator } from '../testing';
|
|
29
29
|
import { SheetType } from '../types';
|
|
30
30
|
|
|
@@ -16,10 +16,10 @@ import { Decoration, EditorView, ViewPlugin, WidgetType } from '@codemirror/view
|
|
|
16
16
|
|
|
17
17
|
import { type UnsubscribeCallback, debounce } from '@dxos/async';
|
|
18
18
|
import { invariant } from '@dxos/invariant';
|
|
19
|
-
import { documentId, singleValueFacet } from '@dxos/react-ui-editor
|
|
19
|
+
import { documentId, singleValueFacet } from '@dxos/react-ui-editor';
|
|
20
20
|
|
|
21
|
+
import { type ComputeGraph, type ComputeNode, createSheetName } from '../compute-graph';
|
|
21
22
|
import { type CellAddress } from '../defs';
|
|
22
|
-
import { type ComputeGraph, type ComputeNode, createSheetName } from '../graph';
|
|
23
23
|
import { type CellScalarValue } from '../types';
|
|
24
24
|
|
|
25
25
|
const LANGUAGE_TAG = 'dx';
|
|
@@ -9,7 +9,7 @@ import { spreadsheet } from 'codemirror-lang-spreadsheet';
|
|
|
9
9
|
import { describe, expect, test } from 'vitest';
|
|
10
10
|
|
|
11
11
|
import { sheetExtension } from './extension';
|
|
12
|
-
import { defaultFunctions } from '../../graph';
|
|
12
|
+
import { defaultFunctions } from '../../compute-graph';
|
|
13
13
|
|
|
14
14
|
describe('formula parser', () => {
|
|
15
15
|
const {
|
|
@@ -18,10 +18,11 @@ import { type SyntaxNode } from '@lezer/common';
|
|
|
18
18
|
import { tags } from '@lezer/highlight';
|
|
19
19
|
import { spreadsheet } from 'codemirror-lang-spreadsheet';
|
|
20
20
|
|
|
21
|
-
import { singleValueFacet } from '@dxos/react-ui-editor
|
|
21
|
+
import { singleValueFacet } from '@dxos/react-ui-editor';
|
|
22
22
|
import { mx } from '@dxos/react-ui-theme';
|
|
23
23
|
|
|
24
|
-
import { type FunctionDefinition } from '../../graph';
|
|
24
|
+
import { type FunctionDefinition } from '../../compute-graph';
|
|
25
|
+
import { RANGE_NOTATION } from '../../defs';
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* https://codemirror.net/examples/styling
|
|
@@ -195,34 +196,53 @@ export const sheetExtension = ({ functions = [] }: SheetExtensionOptions): Exten
|
|
|
195
196
|
];
|
|
196
197
|
};
|
|
197
198
|
|
|
198
|
-
export type
|
|
199
|
-
|
|
200
|
-
|
|
199
|
+
export type SelectionRange = { from: number; to: number };
|
|
200
|
+
|
|
201
|
+
export interface RangeController {
|
|
202
|
+
setRange(range: string): void;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export type RangeExtensionOptions = {
|
|
206
|
+
/**
|
|
207
|
+
* Provides controller callback when extension is initialized.
|
|
208
|
+
*/
|
|
209
|
+
onInit?: (controller: RangeController) => void;
|
|
210
|
+
/**
|
|
211
|
+
* Called when the active range changes.
|
|
212
|
+
* @param state The current state.
|
|
213
|
+
* @param state.activeRange undefined if no range is active, otherwise a possibly partially defined range.
|
|
214
|
+
*/
|
|
215
|
+
onStateChange?: (state: { activeRange: string | undefined }) => void;
|
|
216
|
+
};
|
|
201
217
|
|
|
202
218
|
/**
|
|
203
219
|
* Tracks the currently active cell within a formula and provides a callback to modify it.
|
|
204
220
|
*/
|
|
205
|
-
export const rangeExtension = (onInit
|
|
221
|
+
export const rangeExtension = ({ onInit, onStateChange }: RangeExtensionOptions): Extension => {
|
|
206
222
|
let view: EditorView;
|
|
207
|
-
let activeRange:
|
|
208
|
-
const provider: CellRangeNotifier = (range: string) => {
|
|
209
|
-
if (activeRange) {
|
|
210
|
-
view.dispatch(
|
|
211
|
-
view.state.update({
|
|
212
|
-
changes: { ...activeRange, insert: range.toString() },
|
|
213
|
-
selection: { anchor: activeRange.from + range.length },
|
|
214
|
-
}),
|
|
215
|
-
);
|
|
216
|
-
}
|
|
223
|
+
let activeRange: SelectionRange | undefined;
|
|
217
224
|
|
|
218
|
-
|
|
225
|
+
// Called externally to provide current range.
|
|
226
|
+
const notifier: RangeController = {
|
|
227
|
+
setRange: (range: string) => {
|
|
228
|
+
if (activeRange) {
|
|
229
|
+
view.dispatch(
|
|
230
|
+
view.state.update({
|
|
231
|
+
changes: { ...activeRange, insert: range.toString() },
|
|
232
|
+
selection: { anchor: activeRange.from + range.length },
|
|
233
|
+
}),
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
view.focus();
|
|
238
|
+
},
|
|
219
239
|
};
|
|
220
240
|
|
|
221
241
|
return ViewPlugin.fromClass(
|
|
222
242
|
class {
|
|
223
243
|
constructor(_view: EditorView) {
|
|
224
244
|
view = _view;
|
|
225
|
-
onInit(
|
|
245
|
+
onInit?.(notifier);
|
|
226
246
|
}
|
|
227
247
|
|
|
228
248
|
update(view: ViewUpdate) {
|
|
@@ -235,17 +255,15 @@ export const rangeExtension = (onInit: (notifier: CellRangeNotifier) => void): E
|
|
|
235
255
|
visitTree(topNode, ({ type, from, to }) => {
|
|
236
256
|
if (from <= anchor && to >= anchor) {
|
|
237
257
|
switch (type.name) {
|
|
238
|
-
case 'Function':
|
|
258
|
+
case 'Function':
|
|
239
259
|
// Mark but keep looking.
|
|
240
260
|
activeRange = { from: to, to };
|
|
241
261
|
break;
|
|
242
|
-
}
|
|
243
262
|
|
|
244
|
-
case 'CloseParen':
|
|
263
|
+
case 'CloseParen':
|
|
245
264
|
// Mark but keep looking.
|
|
246
265
|
activeRange = { from, to: from };
|
|
247
266
|
break;
|
|
248
|
-
}
|
|
249
267
|
|
|
250
268
|
case 'RangeToken':
|
|
251
269
|
case 'CellToken':
|
|
@@ -259,8 +277,15 @@ export const rangeExtension = (onInit: (notifier: CellRangeNotifier) => void): E
|
|
|
259
277
|
|
|
260
278
|
// Allow start of formula.
|
|
261
279
|
if (!activeRange && view.state.doc.toString()[0] === '=') {
|
|
262
|
-
|
|
280
|
+
const str = view.state.doc.sliceString(1);
|
|
281
|
+
if (RANGE_NOTATION.test(str)) {
|
|
282
|
+
activeRange = { from: 1, to: str.length + 1 };
|
|
283
|
+
}
|
|
263
284
|
}
|
|
285
|
+
|
|
286
|
+
onStateChange?.({
|
|
287
|
+
activeRange: activeRange ? view.state.doc.sliceString(activeRange.from, activeRange.to) : undefined,
|
|
288
|
+
});
|
|
264
289
|
}
|
|
265
290
|
},
|
|
266
291
|
);
|
package/src/index.ts
CHANGED