@dxos/plugin-sheet 0.8.4-main.7ace549 → 0.8.4-main.937b3ca
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-ESCXPI7Y.mjs +397 -0
- package/dist/lib/browser/SheetContainer-ESCXPI7Y.mjs.map +7 -0
- package/dist/lib/browser/{anchor-sort-OWOAGQM6.mjs → anchor-sort-JBRMW6OY.mjs} +7 -7
- package/dist/lib/browser/anchor-sort-JBRMW6OY.mjs.map +7 -0
- package/dist/lib/browser/chunk-2SAGT3BB.mjs +397 -0
- package/dist/lib/browser/chunk-2SAGT3BB.mjs.map +7 -0
- package/dist/lib/browser/{chunk-7VEWYJJN.mjs → chunk-IFLWVS2V.mjs} +5 -5
- package/dist/lib/browser/chunk-IFLWVS2V.mjs.map +7 -0
- package/dist/lib/browser/chunk-W6N44ONZ.mjs +1470 -0
- package/dist/lib/browser/chunk-W6N44ONZ.mjs.map +7 -0
- package/dist/lib/browser/compute-graph-registry-DL2PX7TF.mjs +21 -0
- package/dist/lib/browser/compute-graph-registry-DL2PX7TF.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +66 -76
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/markdown-BC4KBDUO.mjs +29 -0
- package/dist/lib/browser/markdown-BC4KBDUO.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/operation-resolver-FJ4UWZUM.mjs +79 -0
- package/dist/lib/browser/operation-resolver-FJ4UWZUM.mjs.map +7 -0
- package/dist/lib/browser/{react-surface-VPLFBQSV.mjs → react-surface-5BXM6TJ3.mjs} +16 -19
- package/dist/lib/browser/react-surface-5BXM6TJ3.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +5 -2
- package/dist/lib/node-esm/SheetContainer-YVIDJKP4.mjs +398 -0
- package/dist/lib/node-esm/SheetContainer-YVIDJKP4.mjs.map +7 -0
- package/dist/lib/node-esm/{anchor-sort-FG3DS4HM.mjs → anchor-sort-C3XFPI6S.mjs} +7 -7
- package/dist/lib/node-esm/anchor-sort-C3XFPI6S.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-IMWGSIDG.mjs +398 -0
- package/dist/lib/node-esm/chunk-IMWGSIDG.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-4QV4AGWK.mjs → chunk-PPOYR7DK.mjs} +5 -5
- package/dist/lib/node-esm/chunk-PPOYR7DK.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-S7RYX7DG.mjs +1471 -0
- package/dist/lib/node-esm/chunk-S7RYX7DG.mjs.map +7 -0
- package/dist/lib/node-esm/compute-graph-registry-VXH55GDI.mjs +22 -0
- package/dist/lib/node-esm/compute-graph-registry-VXH55GDI.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +66 -76
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/markdown-6DGZCJRM.mjs +30 -0
- package/dist/lib/node-esm/markdown-6DGZCJRM.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/operation-resolver-OGXEUWHA.mjs +80 -0
- package/dist/lib/node-esm/operation-resolver-OGXEUWHA.mjs.map +7 -0
- package/dist/lib/node-esm/{react-surface-YLTZQVNL.mjs → react-surface-RLHC6B77.mjs} +16 -19
- package/dist/lib/node-esm/react-surface-RLHC6B77.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +5 -2
- package/dist/types/src/SheetPlugin.d.ts +2 -1
- package/dist/types/src/SheetPlugin.d.ts.map +1 -1
- package/dist/types/src/capabilities/anchor-sort/anchor-sort.d.ts +5 -0
- package/dist/types/src/capabilities/anchor-sort/anchor-sort.d.ts.map +1 -0
- package/dist/types/src/capabilities/anchor-sort/index.d.ts +3 -0
- package/dist/types/src/capabilities/anchor-sort/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/compute-graph-registry/compute-graph-registry.d.ts +5 -0
- package/dist/types/src/capabilities/compute-graph-registry/compute-graph-registry.d.ts.map +1 -0
- package/dist/types/src/capabilities/compute-graph-registry/index.d.ts +3 -0
- package/dist/types/src/capabilities/compute-graph-registry/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts +5 -6
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/markdown/index.d.ts +3 -0
- package/dist/types/src/capabilities/markdown/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/markdown/markdown.d.ts +5 -0
- package/dist/types/src/capabilities/markdown/markdown.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-resolver/index.d.ts +3 -0
- package/dist/types/src/capabilities/operation-resolver/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts +5 -0
- package/dist/types/src/capabilities/operation-resolver/operation-resolver.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface/index.d.ts +3 -0
- package/dist/types/src/capabilities/react-surface/index.d.ts.map +1 -0
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts +5 -0
- package/dist/types/src/capabilities/react-surface/react-surface.d.ts.map +1 -0
- 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/SheetCellEditor.stories.d.ts +1 -1
- package/dist/types/src/components/GridSheet/SheetCellEditor.stories.d.ts.map +1 -1
- package/dist/types/src/components/RangeList/RangeList.d.ts.map +1 -1
- package/dist/types/src/components/SheetContainer/SheetContainer.d.ts +4 -5
- package/dist/types/src/components/SheetContainer/SheetContainer.d.ts.map +1 -1
- package/dist/types/src/components/SheetContainer/SheetContainer.stories.d.ts +2 -1
- package/dist/types/src/components/SheetContainer/SheetContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/SheetToolbar/SheetToolbar.d.ts.map +1 -1
- package/dist/types/src/components/SheetToolbar/align.d.ts +12 -19
- package/dist/types/src/components/SheetToolbar/align.d.ts.map +1 -1
- package/dist/types/src/components/SheetToolbar/style.d.ts +12 -18
- package/dist/types/src/components/SheetToolbar/style.d.ts.map +1 -1
- package/dist/types/src/components/SheetToolbar/useToolbarState.d.ts +14 -1
- package/dist/types/src/components/SheetToolbar/useToolbarState.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/extensions/compute.stories.d.ts.map +1 -1
- package/dist/types/src/extensions/editor/sheet-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/thread-ranges.d.ts.map +1 -1
- package/dist/types/src/meta.d.ts +2 -2
- package/dist/types/src/meta.d.ts.map +1 -1
- package/dist/types/src/model/sheet-model.d.ts.map +1 -1
- package/dist/types/src/testing/testing.d.ts +7 -7
- package/dist/types/src/types/Sheet.d.ts +32 -26
- package/dist/types/src/types/Sheet.d.ts.map +1 -1
- package/dist/types/src/types/capabilities.d.ts +6 -0
- package/dist/types/src/types/capabilities.d.ts.map +1 -0
- package/dist/types/src/types/index.d.ts +1 -0
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +91 -65
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +75 -70
- package/src/SheetPlugin.tsx +42 -58
- package/src/capabilities/anchor-sort/anchor-sort.ts +26 -0
- package/src/capabilities/anchor-sort/index.ts +7 -0
- package/src/capabilities/compute-graph-registry/compute-graph-registry.ts +27 -0
- package/src/capabilities/compute-graph-registry/index.ts +7 -0
- package/src/capabilities/index.ts +5 -9
- package/src/capabilities/markdown/index.ts +7 -0
- package/src/capabilities/markdown/markdown.ts +30 -0
- package/src/capabilities/operation-resolver/index.ts +7 -0
- package/src/capabilities/operation-resolver/operation-resolver.ts +77 -0
- package/src/capabilities/react-surface/index.ts +7 -0
- package/src/capabilities/react-surface/react-surface.tsx +43 -0
- package/src/components/ComputeGraph/compute-graph.stories.tsx +1 -1
- package/src/components/GridSheet/GridSheet.stories.tsx +2 -2
- package/src/components/GridSheet/GridSheet.tsx +14 -19
- package/src/components/GridSheet/SheetCellEditor.stories.tsx +6 -3
- package/src/components/GridSheet/util.ts +1 -1
- package/src/components/RangeList/RangeList.tsx +5 -2
- package/src/components/SheetContainer/SheetContainer.stories.tsx +41 -21
- package/src/components/SheetContainer/SheetContainer.tsx +27 -20
- package/src/components/SheetContext/SheetContext.tsx +4 -4
- package/src/components/SheetToolbar/SheetToolbar.tsx +29 -18
- package/src/components/SheetToolbar/align.ts +41 -16
- package/src/components/SheetToolbar/style.ts +45 -15
- package/src/components/SheetToolbar/useToolbarState.ts +22 -5
- package/src/extensions/compute.stories.tsx +15 -6
- package/src/extensions/compute.ts +1 -1
- package/src/extensions/editor/sheet-extension.ts +7 -4
- package/src/index.ts +1 -1
- package/src/integrations/thread-ranges.ts +36 -40
- package/src/meta.ts +2 -2
- package/src/model/sheet-model.ts +67 -37
- package/src/playwright/playwright.config.ts +1 -1
- package/src/playwright/sheet.spec.ts +1 -0
- package/src/sanity.test.ts +1 -1
- package/src/types/Sheet.ts +16 -13
- package/src/{capabilities → types}/capabilities.ts +2 -2
- package/src/types/index.ts +1 -0
- package/src/types/types.ts +81 -37
- package/dist/lib/browser/SheetContainer-WDKJPYCB.mjs +0 -349
- package/dist/lib/browser/SheetContainer-WDKJPYCB.mjs.map +0 -7
- package/dist/lib/browser/anchor-sort-OWOAGQM6.mjs.map +0 -7
- package/dist/lib/browser/chunk-6ILNTWSF.mjs +0 -852
- package/dist/lib/browser/chunk-6ILNTWSF.mjs.map +0 -7
- package/dist/lib/browser/chunk-73AV3NH6.mjs +0 -15
- package/dist/lib/browser/chunk-73AV3NH6.mjs.map +0 -7
- package/dist/lib/browser/chunk-7VEWYJJN.mjs.map +0 -7
- package/dist/lib/browser/chunk-FWFAAGXL.mjs +0 -28
- package/dist/lib/browser/chunk-FWFAAGXL.mjs.map +0 -7
- package/dist/lib/browser/chunk-GBK6OLCY.mjs +0 -907
- package/dist/lib/browser/chunk-GBK6OLCY.mjs.map +0 -7
- package/dist/lib/browser/compute-graph-registry-AP5RA7W3.mjs +0 -21
- package/dist/lib/browser/compute-graph-registry-AP5RA7W3.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-OMHQGXFL.mjs +0 -56
- package/dist/lib/browser/intent-resolver-OMHQGXFL.mjs.map +0 -7
- package/dist/lib/browser/markdown-B6VKYY2S.mjs +0 -26
- package/dist/lib/browser/markdown-B6VKYY2S.mjs.map +0 -7
- package/dist/lib/browser/react-surface-VPLFBQSV.mjs.map +0 -7
- package/dist/lib/node-esm/SheetContainer-62MZAU6Q.mjs +0 -350
- package/dist/lib/node-esm/SheetContainer-62MZAU6Q.mjs.map +0 -7
- package/dist/lib/node-esm/anchor-sort-FG3DS4HM.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-44YTKTMP.mjs +0 -16
- package/dist/lib/node-esm/chunk-44YTKTMP.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-4QV4AGWK.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-HILDMVPL.mjs +0 -29
- package/dist/lib/node-esm/chunk-HILDMVPL.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-KSHCRK5J.mjs +0 -908
- package/dist/lib/node-esm/chunk-KSHCRK5J.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-QI3PNRCD.mjs +0 -853
- package/dist/lib/node-esm/chunk-QI3PNRCD.mjs.map +0 -7
- package/dist/lib/node-esm/compute-graph-registry-UMQ5UYCL.mjs +0 -22
- package/dist/lib/node-esm/compute-graph-registry-UMQ5UYCL.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-DHEHYV3B.mjs +0 -57
- package/dist/lib/node-esm/intent-resolver-DHEHYV3B.mjs.map +0 -7
- package/dist/lib/node-esm/markdown-VKY7HXU2.mjs +0 -27
- package/dist/lib/node-esm/markdown-VKY7HXU2.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-YLTZQVNL.mjs.map +0 -7
- package/dist/types/src/capabilities/anchor-sort.d.ts +0 -4
- package/dist/types/src/capabilities/anchor-sort.d.ts.map +0 -1
- package/dist/types/src/capabilities/capabilities.d.ts +0 -5
- package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
- package/dist/types/src/capabilities/compute-graph-registry.d.ts +0 -4
- package/dist/types/src/capabilities/compute-graph-registry.d.ts.map +0 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
- package/dist/types/src/capabilities/markdown.d.ts +0 -4
- package/dist/types/src/capabilities/markdown.d.ts.map +0 -1
- package/dist/types/src/capabilities/react-surface.d.ts +0 -4
- package/dist/types/src/capabilities/react-surface.d.ts.map +0 -1
- package/src/capabilities/anchor-sort.ts +0 -21
- package/src/capabilities/compute-graph-registry.ts +0 -23
- package/src/capabilities/intent-resolver.ts +0 -38
- package/src/capabilities/markdown.ts +0 -23
- package/src/capabilities/react-surface.tsx +0 -41
|
@@ -2,15 +2,32 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
import { live } from '@dxos/live-object';
|
|
5
|
+
import { Atom, type Registry, RegistryContext, useAtomValue } from '@effect-atom/atom-react';
|
|
6
|
+
import { useContext, useMemo } from 'react';
|
|
8
7
|
|
|
9
8
|
import { type AlignState } from './align';
|
|
10
9
|
import { type StyleState } from './style';
|
|
11
10
|
|
|
12
11
|
export type ToolbarState = Partial<StyleState & AlignState>;
|
|
12
|
+
export type ToolbarStateAtom = Atom.Writable<ToolbarState>;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Creates a reactive toolbar state Atom.
|
|
16
|
+
*/
|
|
17
|
+
export const useToolbarState = (initialState: ToolbarState = {}): ToolbarStateAtom => {
|
|
18
|
+
return useMemo(() => Atom.make<ToolbarState>(initialState).pipe(Atom.keepAlive), []);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Hook to read the current toolbar state value.
|
|
23
|
+
*/
|
|
24
|
+
export const useToolbarStateValue = (stateAtom: ToolbarStateAtom): ToolbarState => {
|
|
25
|
+
return useAtomValue(stateAtom);
|
|
26
|
+
};
|
|
13
27
|
|
|
14
|
-
|
|
15
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Hook to get the registry for updating toolbar state.
|
|
30
|
+
*/
|
|
31
|
+
export const useToolbarStateRegistry = (): Registry.Registry => {
|
|
32
|
+
return useContext(RegistryContext);
|
|
16
33
|
};
|
|
@@ -5,21 +5,21 @@
|
|
|
5
5
|
import { type Meta, type StoryObj } from '@storybook/react-vite';
|
|
6
6
|
import React, { useEffect, useMemo } from 'react';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { OperationPlugin, RuntimePlugin } from '@dxos/app-framework';
|
|
9
9
|
import { withPluginManager } from '@dxos/app-framework/testing';
|
|
10
10
|
import { PublicKey } from '@dxos/keys';
|
|
11
11
|
import { useSpace } from '@dxos/react-client/echo';
|
|
12
12
|
import { withClientProvider } from '@dxos/react-client/testing';
|
|
13
13
|
import { useThemeContext } from '@dxos/react-ui';
|
|
14
14
|
import { withTheme } from '@dxos/react-ui/testing';
|
|
15
|
+
import { useTextEditor } from '@dxos/react-ui-editor';
|
|
15
16
|
import {
|
|
16
17
|
createBasicExtensions,
|
|
17
18
|
createMarkdownExtensions,
|
|
18
19
|
createThemeExtensions,
|
|
19
20
|
decorateMarkdown,
|
|
20
21
|
documentId,
|
|
21
|
-
|
|
22
|
-
} from '@dxos/react-ui-editor';
|
|
22
|
+
} from '@dxos/ui-editor';
|
|
23
23
|
import { isNonNullable } from '@dxos/util';
|
|
24
24
|
|
|
25
25
|
import { GridSheet, SheetProvider, useComputeGraph } from '../components';
|
|
@@ -73,7 +73,12 @@ const Grid = () => {
|
|
|
73
73
|
const model = useSheetModel(graph, sheet);
|
|
74
74
|
useEffect(() => {
|
|
75
75
|
if (model) {
|
|
76
|
-
model.setValues({
|
|
76
|
+
model.setValues({
|
|
77
|
+
A1: { value: 100 },
|
|
78
|
+
A2: { value: 200 },
|
|
79
|
+
A3: { value: 300 },
|
|
80
|
+
A5: { value: '=SUM(A1:A3)' },
|
|
81
|
+
});
|
|
77
82
|
}
|
|
78
83
|
}, [model]);
|
|
79
84
|
|
|
@@ -103,9 +108,13 @@ const meta = {
|
|
|
103
108
|
title: 'plugins/plugin-sheet/extensions',
|
|
104
109
|
decorators: [
|
|
105
110
|
withTheme,
|
|
106
|
-
withClientProvider({
|
|
111
|
+
withClientProvider({
|
|
112
|
+
types: [Sheet.Sheet],
|
|
113
|
+
createIdentity: true,
|
|
114
|
+
createSpace: true,
|
|
115
|
+
}),
|
|
107
116
|
// TODO(wittjosiah): Try to write story which does not depend on plugin manager.
|
|
108
|
-
withPluginManager({ plugins: [
|
|
117
|
+
withPluginManager({ plugins: [OperationPlugin(), RuntimePlugin()] }),
|
|
109
118
|
withComputeGraphDecorator(),
|
|
110
119
|
],
|
|
111
120
|
parameters: {
|
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
createSheetName,
|
|
24
24
|
} from '@dxos/compute';
|
|
25
25
|
import { invariant } from '@dxos/invariant';
|
|
26
|
-
import { documentId, singleValueFacet } from '@dxos/
|
|
26
|
+
import { documentId, singleValueFacet } from '@dxos/ui-editor';
|
|
27
27
|
|
|
28
28
|
const LANGUAGE_TAG = 'dx';
|
|
29
29
|
|
|
@@ -20,8 +20,8 @@ import { spreadsheet } from 'codemirror-lang-spreadsheet';
|
|
|
20
20
|
|
|
21
21
|
import { type FunctionDefinition } from '@dxos/compute';
|
|
22
22
|
import { RANGE_NOTATION } from '@dxos/compute';
|
|
23
|
-
import { singleValueFacet } from '@dxos/
|
|
24
|
-
import { mx } from '@dxos/
|
|
23
|
+
import { singleValueFacet } from '@dxos/ui-editor';
|
|
24
|
+
import { mx } from '@dxos/ui-theme';
|
|
25
25
|
|
|
26
26
|
/**
|
|
27
27
|
* https://codemirror.net/examples/styling
|
|
@@ -75,7 +75,10 @@ export type SheetExtensionOptions = {
|
|
|
75
75
|
* https://hyperformula.handsontable.com/guide/key-concepts.html#grammar
|
|
76
76
|
*/
|
|
77
77
|
export const sheetExtension = ({ debug, functions = [] }: SheetExtensionOptions): Extension => {
|
|
78
|
-
const { extension, language } = spreadsheet({
|
|
78
|
+
const { extension, language } = spreadsheet({
|
|
79
|
+
idiom: 'en-US',
|
|
80
|
+
decimalSeparator: '.',
|
|
81
|
+
});
|
|
79
82
|
|
|
80
83
|
const createCompletion = (name: string) => {
|
|
81
84
|
const { section = 'Custom', description, syntax } = functions.find((value) => value.name === name) ?? {};
|
|
@@ -166,7 +169,7 @@ export const sheetExtension = ({ debug, functions = [] }: SheetExtensionOptions)
|
|
|
166
169
|
icons: false,
|
|
167
170
|
tooltipClass: () =>
|
|
168
171
|
mx(
|
|
169
|
-
'!-left-[1px] !top-[33px] !-m-0 border !border-
|
|
172
|
+
'!-left-[1px] !top-[33px] !-m-0 border !border-bs-0 [&>ul]:!min-w-[198px]',
|
|
170
173
|
'[&>ul>li[aria-selected]]:!bg-accentSurface',
|
|
171
174
|
'border-separator',
|
|
172
175
|
),
|
package/src/index.ts
CHANGED
|
@@ -2,18 +2,18 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import * as
|
|
6
|
-
import * as Schema from 'effect/Schema';
|
|
5
|
+
import * as Effect from 'effect/Effect';
|
|
7
6
|
import { useCallback, useEffect, useMemo } from 'react';
|
|
8
7
|
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
8
|
+
import { Common } from '@dxos/app-framework';
|
|
9
|
+
import { useOperationInvoker, useOperationResolver } from '@dxos/app-framework/react';
|
|
11
10
|
import { debounce } from '@dxos/async';
|
|
12
11
|
import { type CellAddress, type CompleteCellRange, inRange } from '@dxos/compute';
|
|
13
12
|
import { Obj, Relation } from '@dxos/echo';
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
13
|
+
import { OperationResolver } from '@dxos/operation';
|
|
14
|
+
import { ATTENDABLE_PATH_SEPARATOR, DeckOperation } from '@dxos/plugin-deck/types';
|
|
15
|
+
import { ThreadOperation } from '@dxos/plugin-thread/types';
|
|
16
|
+
import { Filter, Query, useQuery } from '@dxos/react-client/echo';
|
|
17
17
|
import { type DxGridElement, type GridContentProps } from '@dxos/react-ui-grid';
|
|
18
18
|
import { AnchoredTo, Thread } from '@dxos/types';
|
|
19
19
|
|
|
@@ -39,43 +39,37 @@ export const parseThreadAnchorAsCellRange = (cursor: string): CompleteCellRange
|
|
|
39
39
|
|
|
40
40
|
export const useUpdateFocusedCellOnThreadSelection = (grid: DxGridElement | null) => {
|
|
41
41
|
const { model, setActiveRefs } = useSheetContext();
|
|
42
|
-
const
|
|
42
|
+
const sheetId = Obj.getDXN(model.sheet).toString();
|
|
43
|
+
|
|
44
|
+
const scrollIntoViewHandler = useMemo(
|
|
43
45
|
() =>
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
OperationResolver.make({
|
|
47
|
+
operation: Common.LayoutOperation.ScrollIntoView,
|
|
46
48
|
position: 'hoist',
|
|
47
|
-
filter: (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return data.subject === Obj.getDXN(model.sheet).toString() && !!data.options?.cursor;
|
|
59
|
-
},
|
|
60
|
-
resolve: ({ options: { cursor, ref } }) => {
|
|
61
|
-
setActiveRefs(ref);
|
|
62
|
-
// TODO(Zan): Everywhere we refer to the cursor in a thread context should change to `anchor`.
|
|
63
|
-
const range = parseThreadAnchorAsCellRange(cursor!);
|
|
64
|
-
range && grid?.setFocus({ ...range.to, plane: 'grid' }, true);
|
|
65
|
-
},
|
|
49
|
+
filter: (input) => input.subject === sheetId && !!input.cursor,
|
|
50
|
+
handler: (input) =>
|
|
51
|
+
Effect.sync(() => {
|
|
52
|
+
const { cursor, ref } = input;
|
|
53
|
+
if (cursor) {
|
|
54
|
+
setActiveRefs(ref as GridContentProps['activeRefs']);
|
|
55
|
+
// TODO(Zan): Everywhere we refer to the cursor in a thread context should change to `anchor`.
|
|
56
|
+
const range = parseThreadAnchorAsCellRange(cursor);
|
|
57
|
+
range && grid?.setFocus({ ...range.to, plane: 'grid' }, true);
|
|
58
|
+
}
|
|
59
|
+
}),
|
|
66
60
|
}),
|
|
67
|
-
[
|
|
61
|
+
[sheetId, setActiveRefs, grid],
|
|
68
62
|
);
|
|
69
63
|
|
|
70
|
-
|
|
64
|
+
useOperationResolver(meta.id, scrollIntoViewHandler);
|
|
71
65
|
};
|
|
72
66
|
|
|
73
67
|
export const useSelectThreadOnCellFocus = () => {
|
|
74
68
|
const { model, cursor } = useSheetContext();
|
|
75
|
-
const {
|
|
69
|
+
const { invokePromise } = useOperationInvoker();
|
|
76
70
|
|
|
77
|
-
const
|
|
78
|
-
const anchors = useQuery(
|
|
71
|
+
const db = Obj.getDatabase(model.sheet);
|
|
72
|
+
const anchors = useQuery(db, Query.select(Filter.id(model.sheet.id)).targetOf(AnchoredTo.AnchoredTo));
|
|
79
73
|
|
|
80
74
|
const selectClosestThread = useCallback(
|
|
81
75
|
(cellAddress: CellAddress) => {
|
|
@@ -95,14 +89,16 @@ export const useSelectThreadOnCellFocus = () => {
|
|
|
95
89
|
|
|
96
90
|
if (closestThread) {
|
|
97
91
|
const primary = Obj.getDXN(model.sheet).toString();
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
92
|
+
void (async () => {
|
|
93
|
+
await invokePromise(ThreadOperation.Select, { current: Relation.getDXN(closestThread).toString() });
|
|
94
|
+
await invokePromise(DeckOperation.ChangeCompanion, {
|
|
95
|
+
primary,
|
|
96
|
+
companion: `${primary}${ATTENDABLE_PATH_SEPARATOR}comments`,
|
|
97
|
+
});
|
|
98
|
+
})();
|
|
103
99
|
}
|
|
104
100
|
},
|
|
105
|
-
[
|
|
101
|
+
[invokePromise, anchors],
|
|
106
102
|
);
|
|
107
103
|
|
|
108
104
|
const debounced = useMemo(() => {
|
package/src/meta.ts
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { type
|
|
5
|
+
import { type Plugin } from '@dxos/app-framework';
|
|
6
6
|
import { trim } from '@dxos/util';
|
|
7
7
|
|
|
8
|
-
export const meta:
|
|
8
|
+
export const meta: Plugin.Meta = {
|
|
9
9
|
id: 'dxos.org/plugin/sheet',
|
|
10
10
|
name: 'Sheet',
|
|
11
11
|
description: trim`
|
package/src/model/sheet-model.ts
CHANGED
|
@@ -122,7 +122,9 @@ export class SheetModel extends Resource {
|
|
|
122
122
|
*/
|
|
123
123
|
protected override async _open(): Promise<void> {
|
|
124
124
|
log('initialize', { id: this.id });
|
|
125
|
-
|
|
125
|
+
Obj.change(this._sheet, (s) => {
|
|
126
|
+
initialize(s);
|
|
127
|
+
});
|
|
126
128
|
|
|
127
129
|
this._graph.update.on((event) => {
|
|
128
130
|
if (event.type === 'functionsUpdated') {
|
|
@@ -181,13 +183,19 @@ export class SheetModel extends Resource {
|
|
|
181
183
|
}
|
|
182
184
|
|
|
183
185
|
insertRows(i: number, n = 1): string[] {
|
|
184
|
-
|
|
186
|
+
let idx: string[] = [];
|
|
187
|
+
Obj.change(this._sheet, (s) => {
|
|
188
|
+
idx = insertIndices(s.rows, i, n, MAX_ROWS);
|
|
189
|
+
});
|
|
185
190
|
this.reset();
|
|
186
191
|
return idx;
|
|
187
192
|
}
|
|
188
193
|
|
|
189
194
|
insertColumns(i: number, n = 1): string[] {
|
|
190
|
-
|
|
195
|
+
let idx: string[] = [];
|
|
196
|
+
Obj.change(this._sheet, (s) => {
|
|
197
|
+
idx = insertIndices(s.columns, i, n, MAX_COLS);
|
|
198
|
+
});
|
|
191
199
|
this.reset();
|
|
192
200
|
return idx;
|
|
193
201
|
}
|
|
@@ -200,8 +208,10 @@ export class SheetModel extends Resource {
|
|
|
200
208
|
const values = this.getCellValues(range).flat();
|
|
201
209
|
const index = this._sheet.rows.indexOf(rowIndex);
|
|
202
210
|
this.clear(range);
|
|
203
|
-
this._sheet
|
|
204
|
-
|
|
211
|
+
Obj.change(this._sheet, (s) => {
|
|
212
|
+
s.rows.splice(index, 1);
|
|
213
|
+
delete s.rowMeta[rowIndex];
|
|
214
|
+
});
|
|
205
215
|
this.reset();
|
|
206
216
|
return { axis: 'row', index, axisIndex: rowIndex, axisMeta: this._sheet.rowMeta[rowIndex], values };
|
|
207
217
|
}
|
|
@@ -214,35 +224,41 @@ export class SheetModel extends Resource {
|
|
|
214
224
|
const values = this.getCellValues(range).flat();
|
|
215
225
|
const index = this._sheet.columns.indexOf(colIndex);
|
|
216
226
|
this.clear(range);
|
|
217
|
-
this._sheet
|
|
218
|
-
|
|
227
|
+
Obj.change(this._sheet, (s) => {
|
|
228
|
+
s.columns.splice(index, 1);
|
|
229
|
+
delete s.columnMeta[colIndex];
|
|
230
|
+
});
|
|
219
231
|
this.reset();
|
|
220
232
|
return { axis: 'col', index, axisIndex: colIndex, axisMeta: this._sheet.rowMeta[colIndex], values };
|
|
221
233
|
}
|
|
222
234
|
|
|
223
235
|
restoreRow({ index, axisIndex, axisMeta, values }: SheetAction.RestoreAxis): void {
|
|
224
|
-
this._sheet
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
236
|
+
Obj.change(this._sheet, (s) => {
|
|
237
|
+
s.rows.splice(index, 0, axisIndex);
|
|
238
|
+
values.forEach((value, col) => {
|
|
239
|
+
if (value) {
|
|
240
|
+
s.cells[`${s.columns[col]}@${axisIndex}`] = { value };
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
if (axisMeta) {
|
|
244
|
+
s.rowMeta[axisIndex] = axisMeta;
|
|
228
245
|
}
|
|
229
246
|
});
|
|
230
|
-
if (axisMeta) {
|
|
231
|
-
this._sheet.rowMeta[axisIndex] = axisMeta;
|
|
232
|
-
}
|
|
233
247
|
this.reset();
|
|
234
248
|
}
|
|
235
249
|
|
|
236
250
|
restoreColumn({ index, axisIndex, axisMeta, values }: SheetAction.RestoreAxis): void {
|
|
237
|
-
this._sheet
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
251
|
+
Obj.change(this._sheet, (s) => {
|
|
252
|
+
s.columns.splice(index, 0, axisIndex);
|
|
253
|
+
values.forEach((value, row) => {
|
|
254
|
+
if (value) {
|
|
255
|
+
s.cells[`${axisIndex}@${s.rows[row]}`] = { value };
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
if (axisMeta) {
|
|
259
|
+
s.columnMeta[axisIndex] = axisMeta;
|
|
241
260
|
}
|
|
242
261
|
});
|
|
243
|
-
if (axisMeta) {
|
|
244
|
-
this._sheet.columnMeta[axisIndex] = axisMeta;
|
|
245
|
-
}
|
|
246
262
|
this.reset();
|
|
247
263
|
}
|
|
248
264
|
|
|
@@ -259,18 +275,22 @@ export class SheetModel extends Resource {
|
|
|
259
275
|
const topLeft = getTopLeft(range);
|
|
260
276
|
const values = this._iterRange(range, () => null);
|
|
261
277
|
this._node.graph.hf.setCellContents(toSimpleCellAddress(this._node.sheetId, topLeft), values);
|
|
262
|
-
this.
|
|
263
|
-
|
|
264
|
-
|
|
278
|
+
Obj.change(this._sheet, (s) => {
|
|
279
|
+
this._iterRange(range, (cell) => {
|
|
280
|
+
const idx = addressToIndex(this._sheet, cell);
|
|
281
|
+
delete s.cells[idx];
|
|
282
|
+
});
|
|
265
283
|
});
|
|
266
284
|
}
|
|
267
285
|
|
|
268
286
|
cut(range: CellRange): void {
|
|
269
287
|
invariant(this._node);
|
|
270
288
|
this._node.graph.hf.cut(toModelRange(this._node.sheetId, range));
|
|
271
|
-
this.
|
|
272
|
-
|
|
273
|
-
|
|
289
|
+
Obj.change(this._sheet, (s) => {
|
|
290
|
+
this._iterRange(range, (cell) => {
|
|
291
|
+
const idx = addressToIndex(this._sheet, cell);
|
|
292
|
+
delete s.cells[idx];
|
|
293
|
+
});
|
|
274
294
|
});
|
|
275
295
|
}
|
|
276
296
|
|
|
@@ -283,13 +303,15 @@ export class SheetModel extends Resource {
|
|
|
283
303
|
invariant(this._node);
|
|
284
304
|
if (!this._node.graph.hf.isClipboardEmpty()) {
|
|
285
305
|
const changes = this._node.graph.hf.paste(toSimpleCellAddress(this._node.sheetId, cell));
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
306
|
+
Obj.change(this._sheet, (s) => {
|
|
307
|
+
for (const change of changes) {
|
|
308
|
+
if (change instanceof ExportedCellChange) {
|
|
309
|
+
const { address, newValue } = change;
|
|
310
|
+
const idx = addressToIndex(this._sheet, { row: address.row, col: address.col });
|
|
311
|
+
s.cells[idx] = { value: newValue };
|
|
312
|
+
}
|
|
291
313
|
}
|
|
292
|
-
}
|
|
314
|
+
});
|
|
293
315
|
}
|
|
294
316
|
}
|
|
295
317
|
|
|
@@ -380,11 +402,15 @@ export class SheetModel extends Resource {
|
|
|
380
402
|
// Reallocate if > current bounds.
|
|
381
403
|
let refresh = false;
|
|
382
404
|
if (cell.row >= this._sheet.rows.length) {
|
|
383
|
-
|
|
405
|
+
Obj.change(this._sheet, (s) => {
|
|
406
|
+
insertIndices(s.rows, cell.row, 1, MAX_ROWS);
|
|
407
|
+
});
|
|
384
408
|
refresh = true;
|
|
385
409
|
}
|
|
386
410
|
if (cell.col >= this._sheet.columns.length) {
|
|
387
|
-
|
|
411
|
+
Obj.change(this._sheet, (s) => {
|
|
412
|
+
insertIndices(s.columns, cell.col, 1, MAX_COLS);
|
|
413
|
+
});
|
|
388
414
|
refresh = true;
|
|
389
415
|
}
|
|
390
416
|
|
|
@@ -401,13 +427,17 @@ export class SheetModel extends Resource {
|
|
|
401
427
|
// Insert into sheet.
|
|
402
428
|
const idx = addressToIndex(this._sheet, cell);
|
|
403
429
|
if (value === undefined || value === null) {
|
|
404
|
-
|
|
430
|
+
Obj.change(this._sheet, (s) => {
|
|
431
|
+
delete s.cells[idx];
|
|
432
|
+
});
|
|
405
433
|
} else {
|
|
406
434
|
if (isFormula(value)) {
|
|
407
435
|
value = this._graph.mapFunctionBindingToId(mapFormulaRefsToIndices(this._sheet, value));
|
|
408
436
|
}
|
|
409
437
|
|
|
410
|
-
this._sheet
|
|
438
|
+
Obj.change(this._sheet, (s) => {
|
|
439
|
+
s.cells[idx] = { value };
|
|
440
|
+
});
|
|
411
441
|
}
|
|
412
442
|
}
|
|
413
443
|
|
|
@@ -10,7 +10,7 @@ export default defineConfig({
|
|
|
10
10
|
...e2ePreset(import.meta.dirname),
|
|
11
11
|
// TODO(wittjosiah): Avoid hard-coding ports.
|
|
12
12
|
webServer: {
|
|
13
|
-
command: 'moon run storybook:serve-e2e -- --port=9005',
|
|
13
|
+
command: 'moon run storybook-react:serve-e2e -- --port=9005',
|
|
14
14
|
port: 9005,
|
|
15
15
|
reuseExistingServer: false,
|
|
16
16
|
},
|
|
@@ -16,6 +16,7 @@ test.describe('plugin-sheet', () => {
|
|
|
16
16
|
test.beforeEach(async ({ browser }) => {
|
|
17
17
|
const setup = await setupPage(browser, {
|
|
18
18
|
url: storybookUrl('plugins-plugin-sheet-sheetcontainer--spec', 9005),
|
|
19
|
+
viewportSize: { width: 1280, height: 720 },
|
|
19
20
|
});
|
|
20
21
|
page = setup.page;
|
|
21
22
|
sheet = new SheetManager(page);
|
package/src/sanity.test.ts
CHANGED
|
@@ -22,7 +22,7 @@ import { Function } from '@dxos/functions';
|
|
|
22
22
|
describe('test', () => {
|
|
23
23
|
test('test', async () => {
|
|
24
24
|
const client = new Client();
|
|
25
|
-
client.addTypes([Function.Function]);
|
|
25
|
+
await client.addTypes([Function.Function]);
|
|
26
26
|
await client.initialize();
|
|
27
27
|
await client.halo.createIdentity();
|
|
28
28
|
|
package/src/types/Sheet.ts
CHANGED
|
@@ -70,7 +70,7 @@ export const Sheet = Schema.Struct({
|
|
|
70
70
|
// Cell formatting referenced by indexed range.
|
|
71
71
|
ranges: Schema.Array(Range).pipe(Schema.mutable, FormInputAnnotation.set(false)),
|
|
72
72
|
}).pipe(
|
|
73
|
-
Type.
|
|
73
|
+
Type.object({
|
|
74
74
|
typename: 'dxos.org/type/Sheet',
|
|
75
75
|
version: '0.1.0',
|
|
76
76
|
}),
|
|
@@ -86,18 +86,21 @@ export type SheetProps = {
|
|
|
86
86
|
export const make = ({ name, cells = {}, ...size }: SheetProps = {}) => {
|
|
87
87
|
const sheet = Obj.make(Sheet, { name, cells: {}, rows: [], columns: [], rowMeta: {}, columnMeta: {}, ranges: [] });
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
89
|
+
// Initialize and set cells within Obj.change to satisfy change context requirements.
|
|
90
|
+
Obj.change(sheet, () => {
|
|
91
|
+
initialize(sheet, size);
|
|
92
|
+
|
|
93
|
+
if (cells) {
|
|
94
|
+
Object.entries(cells).forEach(([key, { value }]) => {
|
|
95
|
+
const idx = addressToIndex(sheet, addressFromA1Notation(key));
|
|
96
|
+
if (isFormula(value)) {
|
|
97
|
+
value = mapFormulaRefsToIndices(sheet, value);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
sheet.cells[idx] = { value };
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
});
|
|
101
104
|
|
|
102
105
|
return sheet;
|
|
103
106
|
};
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
// Copyright 2025 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { Capability } from '@dxos/app-framework';
|
|
6
6
|
import { type ComputeGraphRegistry } from '@dxos/compute';
|
|
7
7
|
|
|
8
8
|
import { meta } from '../meta';
|
|
9
9
|
|
|
10
10
|
export namespace SheetCapabilities {
|
|
11
|
-
export const ComputeGraphRegistry =
|
|
11
|
+
export const ComputeGraphRegistry = Capability.make<ComputeGraphRegistry>(
|
|
12
12
|
`${meta.id}/capability/compute-graph-registry`,
|
|
13
13
|
);
|
|
14
14
|
}
|