@dxos/plugin-sheet 0.6.14-main.7bd9c89 → 0.6.14-staging.54a8bab
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-JZEKRM4Z.mjs} +83 -76
- package/dist/lib/browser/SheetContainer-JZEKRM4Z.mjs.map +7 -0
- package/dist/lib/browser/{chunk-BWN5DZWZ.mjs → chunk-BVUN7SHF.mjs} +6 -13
- package/dist/lib/browser/chunk-BVUN7SHF.mjs.map +7 -0
- package/dist/lib/browser/{chunk-FGMFOW6U.mjs → chunk-G2FUL6PK.mjs} +791 -690
- package/dist/lib/browser/chunk-G2FUL6PK.mjs.map +7 -0
- package/dist/lib/browser/{chunk-D3QTX46O.mjs → chunk-RABELMEQ.mjs} +3 -2
- package/dist/lib/browser/{chunk-D3QTX46O.mjs.map → chunk-RABELMEQ.mjs.map} +3 -3
- package/dist/lib/browser/{chunk-GSV5QNLD.mjs → chunk-VMSX6Z4X.mjs} +297 -44
- package/dist/lib/browser/chunk-VMSX6Z4X.mjs.map +7 -0
- package/dist/lib/browser/{graph-M4IQ76QX.mjs → compute-graph-GGWUX644.mjs} +4 -2
- package/dist/lib/browser/index.mjs +91 -21
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/meta.mjs +1 -1
- package/dist/lib/browser/types.mjs +2 -2
- package/dist/lib/node/{SheetContainer-N5IQGEFL.cjs → SheetContainer-PJE74VO4.cjs} +81 -81
- package/dist/lib/node/SheetContainer-PJE74VO4.cjs.map +7 -0
- package/dist/lib/node/{chunk-QIFIGEKV.cjs → chunk-2ZVZI2KJ.cjs} +6 -5
- package/dist/lib/node/{chunk-QIFIGEKV.cjs.map → chunk-2ZVZI2KJ.cjs.map} +3 -3
- package/dist/lib/node/{chunk-NZARD7UP.cjs → chunk-AWKOWDMI.cjs} +10 -17
- package/dist/lib/node/chunk-AWKOWDMI.cjs.map +7 -0
- package/dist/lib/node/{chunk-5XPK2V4A.cjs → chunk-O7XR4R7Y.cjs} +306 -42
- package/dist/lib/node/chunk-O7XR4R7Y.cjs.map +7 -0
- package/dist/lib/node/{chunk-53BMSUIK.cjs → chunk-STZ7S7RF.cjs} +755 -668
- package/dist/lib/node/chunk-STZ7S7RF.cjs.map +7 -0
- package/dist/lib/node/{graph-Q3N2X26H.cjs → compute-graph-KGWA2QLE.cjs} +21 -19
- package/dist/lib/node/compute-graph-KGWA2QLE.cjs.map +7 -0
- package/dist/lib/node/index.cjs +109 -42
- package/dist/lib/node/index.cjs.map +4 -4
- 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 +7 -7
- package/dist/lib/node/types.cjs.map +1 -1
- package/dist/lib/node-esm/{SheetContainer-46PBMF2E.mjs → SheetContainer-R73XEXHU.mjs} +83 -76
- package/dist/lib/node-esm/SheetContainer-R73XEXHU.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-VCYJWE3O.mjs → chunk-BM2Q3FFC.mjs} +3 -2
- package/dist/lib/node-esm/{chunk-VCYJWE3O.mjs.map → chunk-BM2Q3FFC.mjs.map} +3 -3
- package/dist/lib/node-esm/{chunk-5WPZCXNS.mjs → chunk-CR4K75EL.mjs} +296 -44
- package/dist/lib/node-esm/chunk-CR4K75EL.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-WFDTY3IC.mjs → chunk-UIBWRHW7.mjs} +6 -13
- package/dist/lib/node-esm/chunk-UIBWRHW7.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-T3PRH7QS.mjs → chunk-V5N3Y2O5.mjs} +791 -690
- package/dist/lib/node-esm/chunk-V5N3Y2O5.mjs.map +7 -0
- package/dist/lib/node-esm/{graph-SMPUMOV2.mjs → compute-graph-2SCZT7N5.mjs} +4 -2
- package/dist/lib/node-esm/index.mjs +91 -21
- package/dist/lib/node-esm/index.mjs.map +4 -4
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/meta.mjs +1 -1
- package/dist/lib/node-esm/types.mjs +2 -2
- 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/SheetContainer/SheetContainer.stories.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 +6 -3
- 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 +3 -3
- 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 +2 -2
- 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 +3 -7
- 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/meta.d.ts +1 -0
- package/dist/types/src/meta.d.ts.map +1 -1
- 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 +13 -6
- 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 +18 -3
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types.d.ts +37 -33
- package/dist/types/src/types.d.ts.map +1 -1
- package/package.json +43 -50
- package/src/SheetPlugin.tsx +45 -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 +181 -24
- package/src/components/GridSheet/SheetCellEditor.stories.tsx +1 -1
- package/src/components/GridSheet/util.ts +34 -18
- package/src/components/RangeList/RangeList.tsx +53 -0
- package/src/components/RangeList/index.ts +5 -0
- package/src/components/SheetContainer/SheetContainer.stories.tsx +5 -3
- package/src/components/SheetContainer/SheetContainer.tsx +10 -4
- package/src/components/SheetContext/SheetContext.tsx +43 -20
- package/src/components/Toolbar/Toolbar.tsx +98 -74
- 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 +27 -9
- package/src/{graph → compute-graph}/compute-node.ts +2 -3
- package/src/{graph → compute-graph}/functions/async-function.ts +1 -0
- package/src/{graph → compute-graph}/functions/edge-function.ts +5 -3
- package/src/defs/index.ts +1 -1
- package/src/defs/sheet-range-types.ts +9 -6
- package/src/defs/types.ts +6 -1
- package/src/defs/util.ts +4 -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/meta.ts +1 -0
- package/src/model/index.ts +1 -1
- package/src/model/sheet-model.test.ts +6 -4
- package/src/model/sheet-model.ts +103 -26
- 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 +18 -3
- package/src/types.ts +24 -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-GGWUX644.mjs.map} +0 -0
- /package/dist/lib/node-esm/{graph-SMPUMOV2.mjs.map → compute-graph-2SCZT7N5.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/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,9 +2,9 @@
|
|
|
2
2
|
// Copyright 2024 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { useEffect, useState } from 'react';
|
|
6
6
|
|
|
7
|
-
import { createDocAccessor } from '@dxos/react-client/echo';
|
|
7
|
+
import { createDocAccessor, fullyQualifiedId } from '@dxos/react-client/echo';
|
|
8
8
|
import { parseValue, cellClassesForFieldType } from '@dxos/react-ui-data';
|
|
9
9
|
import {
|
|
10
10
|
type GridContentProps,
|
|
@@ -16,10 +16,12 @@ import {
|
|
|
16
16
|
type DxGridCellValue,
|
|
17
17
|
colToA1Notation,
|
|
18
18
|
rowToA1Notation,
|
|
19
|
+
commentedClassName,
|
|
19
20
|
} from '@dxos/react-ui-grid';
|
|
20
21
|
import { mx } from '@dxos/react-ui-theme';
|
|
21
22
|
|
|
22
|
-
import { type CellAddress, inRange, cellClassNameForRange } from '../../defs';
|
|
23
|
+
import { type CellAddress, inRange, cellClassNameForRange, rangeFromIndex } from '../../defs';
|
|
24
|
+
import { parseThreadAnchorAsCellRange } from '../../integrations';
|
|
23
25
|
import { type SheetModel } from '../../model';
|
|
24
26
|
|
|
25
27
|
export const dxGridCellIndexToSheetCellAddress = (index: string): CellAddress => {
|
|
@@ -57,16 +59,26 @@ const createDxGridRows = (model: SheetModel): DxGridAxisMeta => {
|
|
|
57
59
|
const projectCellProps = (model: SheetModel, col: number, row: number): DxGridCellValue => {
|
|
58
60
|
const address = { col, row };
|
|
59
61
|
const rawValue = model.getValue(address);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
const ranges = model.sheet.ranges?.filter(({ range }) => inRange(rangeFromIndex(model.sheet, range), address));
|
|
63
|
+
const threadRefs = model.sheet.threads
|
|
64
|
+
?.filter((thread) => {
|
|
65
|
+
const range = thread?.anchor && parseThreadAnchorAsCellRange(thread!.anchor);
|
|
66
|
+
return thread && range ? inRange(range, address) : false;
|
|
67
|
+
})
|
|
68
|
+
.map((thread) => fullyQualifiedId(thread!))
|
|
69
|
+
.join(' ');
|
|
70
|
+
|
|
71
|
+
const description = model.getValueDescription(address);
|
|
72
|
+
const type = description?.type;
|
|
73
|
+
const format = description?.format;
|
|
65
74
|
const classNames = ranges?.map(cellClassNameForRange).reverse();
|
|
66
75
|
|
|
67
|
-
return {
|
|
76
|
+
return {
|
|
77
|
+
value: parseValue({ type, format, value: rawValue }),
|
|
78
|
+
className: mx(cellClassesForFieldType({ type, format }), threadRefs && commentedClassName, classNames),
|
|
79
|
+
dataRefs: threadRefs,
|
|
80
|
+
};
|
|
68
81
|
};
|
|
69
|
-
|
|
70
82
|
const gridCellGetter = (model: SheetModel) => {
|
|
71
83
|
// TODO(thure): Actually use the cache.
|
|
72
84
|
const cachedGridCells: DxGridPlaneCells = {};
|
|
@@ -115,23 +127,27 @@ const cellGetter = (model: SheetModel) => {
|
|
|
115
127
|
};
|
|
116
128
|
|
|
117
129
|
export const useSheetModelDxGridProps = (
|
|
118
|
-
|
|
130
|
+
dxGrid: DxGridElement | null,
|
|
119
131
|
model: SheetModel,
|
|
120
132
|
): Pick<GridContentProps, 'columns' | 'rows'> => {
|
|
121
133
|
const [columns, setColumns] = useState<DxGridAxisMeta>(createDxGridColumns(model));
|
|
122
134
|
const [rows, setRows] = useState<DxGridAxisMeta>(createDxGridColumns(model));
|
|
123
135
|
|
|
124
|
-
|
|
136
|
+
useEffect(() => {
|
|
125
137
|
const cellsAccessor = createDocAccessor(model.sheet, ['cells']);
|
|
126
|
-
if (
|
|
127
|
-
|
|
138
|
+
if (dxGrid) {
|
|
139
|
+
dxGrid.getCells = cellGetter(model);
|
|
128
140
|
}
|
|
129
141
|
const handleCellsUpdate = () => {
|
|
130
|
-
|
|
142
|
+
dxGrid?.requestUpdate('initialCells');
|
|
131
143
|
};
|
|
132
144
|
cellsAccessor.handle.addListener('change', handleCellsUpdate);
|
|
133
|
-
|
|
134
|
-
|
|
145
|
+
const unsubscribe = model.graph.update.on(handleCellsUpdate);
|
|
146
|
+
return () => {
|
|
147
|
+
cellsAccessor.handle.removeListener('change', handleCellsUpdate);
|
|
148
|
+
unsubscribe();
|
|
149
|
+
};
|
|
150
|
+
}, [model, dxGrid]);
|
|
135
151
|
|
|
136
152
|
useEffect(() => {
|
|
137
153
|
const columnMetaAccessor = createDocAccessor(model.sheet, ['columnMeta']);
|
|
@@ -148,7 +164,7 @@ export const useSheetModelDxGridProps = (
|
|
|
148
164
|
columnMetaAccessor.handle.removeListener('change', handleColumnMetaUpdate);
|
|
149
165
|
rowMetaAccessor.handle.removeListener('change', handleRowMetaUpdate);
|
|
150
166
|
};
|
|
151
|
-
}, [model]);
|
|
167
|
+
}, [model, dxGrid]);
|
|
152
168
|
|
|
153
169
|
return { columns, rows };
|
|
154
170
|
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import React, { useCallback } from 'react';
|
|
6
|
+
|
|
7
|
+
import { S } from '@dxos/echo-schema';
|
|
8
|
+
import { useTranslation } from '@dxos/react-ui';
|
|
9
|
+
import { List } from '@dxos/react-ui-list';
|
|
10
|
+
import { ghostHover } from '@dxos/react-ui-theme';
|
|
11
|
+
|
|
12
|
+
import { rangeFromIndex, rangeToA1Notation } from '../../defs';
|
|
13
|
+
import { SHEET_PLUGIN } from '../../meta';
|
|
14
|
+
import { Range, type SheetType } from '../../types';
|
|
15
|
+
|
|
16
|
+
export type RangeListProps = {
|
|
17
|
+
sheet: SheetType;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const RangeList = ({ sheet }: RangeListProps) => {
|
|
21
|
+
const { t } = useTranslation(SHEET_PLUGIN);
|
|
22
|
+
// TODO(thure): Implement similar to comments, #8121
|
|
23
|
+
const handleSelectRange = (range: Range) => {};
|
|
24
|
+
const handleDeleteRange = useCallback(
|
|
25
|
+
(range: Range) => {
|
|
26
|
+
const index = sheet.ranges.findIndex((sheetRange) => sheetRange === range);
|
|
27
|
+
sheet.ranges.splice(index, 1);
|
|
28
|
+
},
|
|
29
|
+
[sheet],
|
|
30
|
+
);
|
|
31
|
+
return (
|
|
32
|
+
<>
|
|
33
|
+
<h2 className='p-2 text-sm font-semibold'>{t('range list heading')}</h2>
|
|
34
|
+
<List.Root<Range> items={sheet.ranges} isItem={S.is(Range)}>
|
|
35
|
+
{({ items: ranges }) =>
|
|
36
|
+
ranges.map((range, i) => (
|
|
37
|
+
<List.Item key={i} item={range} classNames={['p-2', ghostHover]}>
|
|
38
|
+
<List.ItemDragHandle />
|
|
39
|
+
<List.ItemTitle onClick={() => handleSelectRange(range)}>
|
|
40
|
+
{t('range title', {
|
|
41
|
+
position: rangeToA1Notation(rangeFromIndex(sheet, range.range)),
|
|
42
|
+
key: t(`range key ${range.key} label`),
|
|
43
|
+
value: t(`range value ${range.value} label`),
|
|
44
|
+
})}
|
|
45
|
+
</List.ItemTitle>
|
|
46
|
+
<List.ItemDeleteButton onClick={() => handleDeleteRange(range)} />
|
|
47
|
+
</List.Item>
|
|
48
|
+
))
|
|
49
|
+
}
|
|
50
|
+
</List.Root>
|
|
51
|
+
</>
|
|
52
|
+
);
|
|
53
|
+
};
|
|
@@ -10,19 +10,20 @@ import { withClientProvider } from '@dxos/react-client/testing';
|
|
|
10
10
|
import { withTheme, withLayout } from '@dxos/storybook-utils';
|
|
11
11
|
|
|
12
12
|
import { SheetContainer } from './SheetContainer';
|
|
13
|
-
import { useComputeGraph } from '../../hooks';
|
|
14
13
|
import { createTestCells, useTestSheet, withComputeGraphDecorator } from '../../testing';
|
|
14
|
+
import translations from '../../translations';
|
|
15
15
|
import { SheetType } from '../../types';
|
|
16
|
+
import { useComputeGraph } from '../ComputeGraph';
|
|
16
17
|
|
|
17
18
|
export const Basic = () => {
|
|
18
19
|
const space = useSpace();
|
|
19
20
|
const graph = useComputeGraph(space);
|
|
20
21
|
const sheet = useTestSheet(space, graph, { cells: createTestCells() });
|
|
21
|
-
if (!sheet || !
|
|
22
|
+
if (!sheet || !space) {
|
|
22
23
|
return null;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
|
-
return <SheetContainer
|
|
26
|
+
return <SheetContainer space={space} sheet={sheet} role='article' />;
|
|
26
27
|
};
|
|
27
28
|
|
|
28
29
|
const meta: Meta = {
|
|
@@ -38,6 +39,7 @@ const meta: Meta = {
|
|
|
38
39
|
classNames: 'grid grid-cols-1 grid-rows-[min-content_minmax(0,1fr)_min-content]',
|
|
39
40
|
}),
|
|
40
41
|
],
|
|
42
|
+
parameters: { translations },
|
|
41
43
|
};
|
|
42
44
|
|
|
43
45
|
export default meta;
|
|
@@ -4,13 +4,19 @@
|
|
|
4
4
|
|
|
5
5
|
import React from 'react';
|
|
6
6
|
|
|
7
|
+
import { type Space } from '@dxos/react-client/echo';
|
|
8
|
+
|
|
9
|
+
import { type SheetType } from '../../types';
|
|
10
|
+
import { useComputeGraph } from '../ComputeGraph';
|
|
7
11
|
import { FunctionEditor } from '../FunctionEditor';
|
|
8
12
|
import { GridSheet } from '../GridSheet';
|
|
9
|
-
import { SheetProvider
|
|
13
|
+
import { SheetProvider } from '../SheetContext';
|
|
10
14
|
import { Toolbar } from '../Toolbar';
|
|
11
15
|
|
|
12
|
-
export const SheetContainer = ({
|
|
13
|
-
|
|
16
|
+
export const SheetContainer = ({ space, sheet, role }: { space: Space; sheet: SheetType; role?: string }) => {
|
|
17
|
+
const graph = useComputeGraph(space);
|
|
18
|
+
|
|
19
|
+
return graph ? (
|
|
14
20
|
<SheetProvider sheet={sheet} graph={graph}>
|
|
15
21
|
<Toolbar.Root role={role}>
|
|
16
22
|
<Toolbar.Styles />
|
|
@@ -23,5 +29,5 @@ export const SheetContainer = ({ graph, sheet, role }: SheetProviderProps & { ro
|
|
|
23
29
|
<FunctionEditor />
|
|
24
30
|
</div>
|
|
25
31
|
</SheetProvider>
|
|
26
|
-
);
|
|
32
|
+
) : null;
|
|
27
33
|
};
|
|
@@ -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}
|
|
@@ -3,32 +3,36 @@
|
|
|
3
3
|
//
|
|
4
4
|
|
|
5
5
|
import { createContext } from '@radix-ui/react-context';
|
|
6
|
-
import React, { type PropsWithChildren, useCallback
|
|
6
|
+
import React, { type PropsWithChildren, useCallback } from 'react';
|
|
7
7
|
|
|
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,
|
|
31
|
+
styleKey,
|
|
29
32
|
type StyleKey,
|
|
30
33
|
type StyleValue,
|
|
31
34
|
} from '../../defs';
|
|
35
|
+
import { completeCellRangeToThreadCursor } from '../../integrations';
|
|
32
36
|
import { SHEET_PLUGIN } from '../../meta';
|
|
33
37
|
import { type SheetType } from '../../types';
|
|
34
38
|
import { useSheetContext } from '../SheetContext';
|
|
@@ -86,10 +90,11 @@ type CommentAction = { key: CommentKey; value: CommentValue; cellContent?: strin
|
|
|
86
90
|
type StyleAction = { key: StyleKey; value: StyleValue };
|
|
87
91
|
|
|
88
92
|
export type ToolbarAction = StyleAction | AlignAction | CommentAction;
|
|
93
|
+
export type ToolbarActionAnnotated = ToolbarAction & { unset?: boolean };
|
|
89
94
|
|
|
90
95
|
export type ToolbarActionType = ToolbarAction['key'];
|
|
91
96
|
|
|
92
|
-
export type ToolbarActionHandler = (action:
|
|
97
|
+
export type ToolbarActionHandler = (action: ToolbarActionAnnotated) => void;
|
|
93
98
|
|
|
94
99
|
export type ToolbarProps = ThemedClassName<
|
|
95
100
|
PropsWithChildren<{
|
|
@@ -97,9 +102,9 @@ export type ToolbarProps = ThemedClassName<
|
|
|
97
102
|
}>
|
|
98
103
|
>;
|
|
99
104
|
|
|
100
|
-
const [ToolbarContextProvider, useToolbarContext] = createContext<{
|
|
101
|
-
|
|
102
|
-
);
|
|
105
|
+
const [ToolbarContextProvider, useToolbarContext] = createContext<{
|
|
106
|
+
onAction: (action: ToolbarActionAnnotated) => void;
|
|
107
|
+
}>('Toolbar');
|
|
103
108
|
|
|
104
109
|
// TODO(Zan): Factor out, copied this from MarkdownPlugin.
|
|
105
110
|
const sectionToolbarLayout =
|
|
@@ -108,42 +113,50 @@ const sectionToolbarLayout =
|
|
|
108
113
|
type Range = SheetType['ranges'][number];
|
|
109
114
|
|
|
110
115
|
const ToolbarRoot = ({ children, role, classNames }: ToolbarProps) => {
|
|
111
|
-
const { id, model,
|
|
116
|
+
const { id, model, cursorFallbackRange, cursor } = useSheetContext();
|
|
112
117
|
const { hasAttention } = useAttention(id);
|
|
113
118
|
const dispatch = useIntentDispatcher();
|
|
114
119
|
|
|
115
|
-
// TODO(Zan):
|
|
120
|
+
// TODO(Zan): Externalize the toolbar action handler. E.g., Toolbar/keys should both fire events.
|
|
116
121
|
const handleAction = useCallback(
|
|
117
|
-
(action:
|
|
122
|
+
(action: ToolbarActionAnnotated) => {
|
|
118
123
|
switch (action.key) {
|
|
119
|
-
case '
|
|
120
|
-
if (
|
|
121
|
-
const index =
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
124
|
+
case 'alignment':
|
|
125
|
+
if (cursorFallbackRange) {
|
|
126
|
+
const index =
|
|
127
|
+
model.sheet.ranges?.findIndex(
|
|
128
|
+
(range) =>
|
|
129
|
+
range.key === action.key &&
|
|
130
|
+
inRange(rangeFromIndex(model.sheet, range.range), cursorFallbackRange.from),
|
|
131
|
+
) ?? -1;
|
|
125
132
|
const nextRangeEntity = {
|
|
126
|
-
range:
|
|
133
|
+
range: rangeToIndex(model.sheet, cursorFallbackRange),
|
|
127
134
|
key: action.key,
|
|
128
135
|
value: action.value,
|
|
129
136
|
};
|
|
130
137
|
if (index < 0) {
|
|
131
138
|
model.sheet.ranges?.push(nextRangeEntity);
|
|
139
|
+
} else if (model.sheet.ranges![index].value === action.value) {
|
|
140
|
+
model.sheet.ranges?.splice(index, 1);
|
|
132
141
|
} else {
|
|
133
142
|
model.sheet.ranges?.splice(index, 1, nextRangeEntity);
|
|
134
143
|
}
|
|
135
144
|
}
|
|
136
145
|
break;
|
|
137
146
|
case 'style':
|
|
138
|
-
if (action.
|
|
139
|
-
const index = model.sheet.ranges?.findIndex(
|
|
147
|
+
if (action.unset) {
|
|
148
|
+
const index = model.sheet.ranges?.findIndex(
|
|
149
|
+
(range) =>
|
|
150
|
+
range.key === action.key &&
|
|
151
|
+
cursorFallbackRange &&
|
|
152
|
+
inRange(rangeFromIndex(model.sheet, range.range), cursorFallbackRange.from),
|
|
153
|
+
);
|
|
140
154
|
if (index >= 0) {
|
|
141
155
|
model.sheet.ranges?.splice(index, 1);
|
|
142
156
|
}
|
|
143
|
-
} else if (
|
|
144
|
-
const nextRange = range ? { from: range.from, to: range.to ?? range.from } : { from: cursor, to: cursor };
|
|
157
|
+
} else if (cursorFallbackRange) {
|
|
145
158
|
model.sheet.ranges?.push({
|
|
146
|
-
range:
|
|
159
|
+
range: rangeToIndex(model.sheet, cursorFallbackRange),
|
|
147
160
|
key: action.key,
|
|
148
161
|
value: action.value,
|
|
149
162
|
});
|
|
@@ -151,24 +164,27 @@ const ToolbarRoot = ({ children, role, classNames }: ToolbarProps) => {
|
|
|
151
164
|
break;
|
|
152
165
|
case 'comment': {
|
|
153
166
|
// TODO(Zan): We shouldn't hardcode the action ID.
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
167
|
+
if (cursorFallbackRange) {
|
|
168
|
+
void dispatch({
|
|
169
|
+
action: 'dxos.org/plugin/thread/action/create',
|
|
170
|
+
data: {
|
|
171
|
+
cursor: completeCellRangeToThreadCursor(cursorFallbackRange),
|
|
172
|
+
name: action.cellContent,
|
|
173
|
+
subject: model.sheet,
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
}
|
|
162
177
|
}
|
|
163
178
|
}
|
|
164
179
|
},
|
|
165
|
-
[model.sheet,
|
|
180
|
+
[model.sheet, cursorFallbackRange, cursor, dispatch],
|
|
166
181
|
);
|
|
167
182
|
|
|
168
183
|
return (
|
|
169
184
|
<ToolbarContextProvider onAction={handleAction}>
|
|
170
185
|
<NaturalToolbar.Root
|
|
171
186
|
classNames={[
|
|
187
|
+
'pli-0.5',
|
|
172
188
|
...(role === 'section'
|
|
173
189
|
? ['z-[2] group-focus-within/section:visible', !hasAttention && 'invisible', sectionToolbarLayout]
|
|
174
190
|
: ['attention-surface']),
|
|
@@ -204,48 +220,55 @@ const Alignment = () => {
|
|
|
204
220
|
const { onAction } = useToolbarContext('Alignment');
|
|
205
221
|
const { t } = useTranslation(SHEET_PLUGIN);
|
|
206
222
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
);
|
|
223
|
+
// TODO(thure): Can this O(n) call be memoized?
|
|
224
|
+
const value = cursor
|
|
225
|
+
? model.sheet.ranges?.findLast(
|
|
226
|
+
({ range, key }) => key === alignKey && inRange(rangeFromIndex(model.sheet, range), cursor),
|
|
227
|
+
)?.value
|
|
228
|
+
: undefined;
|
|
214
229
|
|
|
215
230
|
return (
|
|
216
231
|
<NaturalToolbar.ToggleGroup
|
|
217
232
|
type='single'
|
|
218
|
-
value={
|
|
219
|
-
|
|
233
|
+
value={
|
|
234
|
+
// TODO(thure): providing `undefined` leaves the last item active which was active rather than showing none.
|
|
235
|
+
value ?? 'never'
|
|
236
|
+
}
|
|
237
|
+
onValueChange={(value: AlignValue) => onAction?.({ key: alignKey, value })}
|
|
220
238
|
>
|
|
221
239
|
{alignmentOptions.map(({ value, icon }) => (
|
|
222
240
|
<ToolbarItem itemType='toggleGroupItem' key={value} value={value} icon={icon}>
|
|
223
|
-
{t(
|
|
241
|
+
{t('toolbar action label', {
|
|
242
|
+
key: t(`range key ${alignKey} label`),
|
|
243
|
+
value: t(`range value ${value} label`),
|
|
244
|
+
})}
|
|
224
245
|
</ToolbarItem>
|
|
225
246
|
))}
|
|
226
247
|
</NaturalToolbar.ToggleGroup>
|
|
227
248
|
);
|
|
228
249
|
};
|
|
229
250
|
|
|
230
|
-
const styleOptions: ButtonProps<StyleValue>[] = [
|
|
251
|
+
const styleOptions: ButtonProps<StyleValue>[] = [
|
|
252
|
+
{ value: 'highlight', icon: 'ph--highlighter--regular' },
|
|
253
|
+
{ value: 'softwrap', icon: 'ph--paragraph--regular' },
|
|
254
|
+
];
|
|
231
255
|
|
|
232
256
|
const Styles = () => {
|
|
233
|
-
const {
|
|
257
|
+
const { cursorFallbackRange, model } = useSheetContext();
|
|
234
258
|
const { onAction } = useToolbarContext('Styles');
|
|
235
259
|
const { t } = useTranslation(SHEET_PLUGIN);
|
|
236
260
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
);
|
|
261
|
+
// TODO(thure): Can this O(n) call be memoized?
|
|
262
|
+
const activeValues = cursorFallbackRange
|
|
263
|
+
? model.sheet.ranges
|
|
264
|
+
?.filter(
|
|
265
|
+
({ range, key }) => key === 'style' && inRange(rangeFromIndex(model.sheet, range), cursorFallbackRange.from),
|
|
266
|
+
)
|
|
267
|
+
.reduce((acc, { value }) => {
|
|
268
|
+
acc.add(value);
|
|
269
|
+
return acc;
|
|
270
|
+
}, new Set())
|
|
271
|
+
: undefined;
|
|
249
272
|
|
|
250
273
|
return (
|
|
251
274
|
<>
|
|
@@ -254,10 +277,15 @@ const Styles = () => {
|
|
|
254
277
|
itemType='toggle'
|
|
255
278
|
key={value}
|
|
256
279
|
pressed={activeValues?.has(value)}
|
|
257
|
-
onPressedChange={(nextPressed: boolean) =>
|
|
280
|
+
onPressedChange={(nextPressed: boolean) => {
|
|
281
|
+
onAction?.({ key: 'style', value, unset: !nextPressed });
|
|
282
|
+
}}
|
|
258
283
|
icon={icon}
|
|
259
284
|
>
|
|
260
|
-
{t(
|
|
285
|
+
{t('toolbar action label', {
|
|
286
|
+
key: t(`range key ${styleKey} label`),
|
|
287
|
+
value: t(`range value ${value} label`),
|
|
288
|
+
})}
|
|
261
289
|
</ToolbarItem>
|
|
262
290
|
))}
|
|
263
291
|
</>
|
|
@@ -270,29 +298,25 @@ const Styles = () => {
|
|
|
270
298
|
|
|
271
299
|
const Actions = () => {
|
|
272
300
|
const { onAction } = useToolbarContext('Actions');
|
|
273
|
-
const {
|
|
301
|
+
const { cursorFallbackRange, cursor, model } = useSheetContext();
|
|
274
302
|
const { t } = useTranslation(SHEET_PLUGIN);
|
|
275
303
|
|
|
304
|
+
// TODO(thure): Can this O(n) call be memoized?
|
|
276
305
|
const overlapsCommentAnchor = (model.sheet.threads ?? [])
|
|
277
306
|
.filter(nonNullable)
|
|
278
307
|
.filter((thread) => thread.status !== 'resolved')
|
|
279
308
|
.some((thread) => {
|
|
280
|
-
if (!
|
|
309
|
+
if (!cursorFallbackRange) {
|
|
281
310
|
return false;
|
|
282
311
|
}
|
|
283
|
-
return
|
|
312
|
+
return rangeToIndex(model.sheet, cursorFallbackRange) === thread.anchor;
|
|
284
313
|
});
|
|
285
314
|
|
|
286
|
-
const
|
|
287
|
-
const cursorOnly = hasCursor && !range && !overlapsCommentAnchor;
|
|
288
|
-
|
|
289
|
-
const tooltipLabelKey = !hasCursor
|
|
315
|
+
const tooltipLabelKey = !cursor
|
|
290
316
|
? 'no cursor label'
|
|
291
317
|
: overlapsCommentAnchor
|
|
292
318
|
? 'selection overlaps existing comment label'
|
|
293
|
-
:
|
|
294
|
-
? 'comment ranges not supported label'
|
|
295
|
-
: 'comment label';
|
|
319
|
+
: 'comment label';
|
|
296
320
|
|
|
297
321
|
return (
|
|
298
322
|
<ToolbarItem
|
|
@@ -301,16 +325,16 @@ const Actions = () => {
|
|
|
301
325
|
icon='ph--chat-text--regular'
|
|
302
326
|
data-testid='editor.toolbar.comment'
|
|
303
327
|
onClick={() => {
|
|
304
|
-
if (!
|
|
328
|
+
if (!cursorFallbackRange) {
|
|
305
329
|
return;
|
|
306
330
|
}
|
|
307
331
|
return onAction?.({
|
|
308
332
|
key: 'comment',
|
|
309
|
-
value:
|
|
310
|
-
cellContent: model.getCellText(
|
|
333
|
+
value: rangeToIndex(model.sheet, cursorFallbackRange),
|
|
334
|
+
cellContent: model.getCellText(cursorFallbackRange.from),
|
|
311
335
|
});
|
|
312
336
|
}}
|
|
313
|
-
disabled={!
|
|
337
|
+
disabled={!cursorFallbackRange || overlapsCommentAnchor}
|
|
314
338
|
>
|
|
315
339
|
{t(tooltipLabelKey)}
|
|
316
340
|
</ToolbarItem>
|
package/src/components/index.ts
CHANGED