@dxos/plugin-sheet 0.6.10 → 0.6.11-staging.32b42e4
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-ISY6DUVE.mjs → SheetContainer-U4H5D34A.mjs} +64 -52
- package/dist/lib/browser/SheetContainer-U4H5D34A.mjs.map +7 -0
- package/dist/lib/browser/chunk-APHOLYUB.mjs +175 -0
- package/dist/lib/browser/chunk-APHOLYUB.mjs.map +7 -0
- package/dist/lib/browser/{chunk-CBRBNG3R.mjs → chunk-D5AGLXJP.mjs} +123 -202
- package/dist/lib/browser/chunk-D5AGLXJP.mjs.map +7 -0
- package/dist/lib/browser/{chunk-D3PUKBH6.mjs → chunk-FUAGSXA4.mjs} +1 -1
- package/dist/lib/browser/{chunk-D3PUKBH6.mjs.map → chunk-FUAGSXA4.mjs.map} +2 -2
- package/dist/lib/browser/chunk-NU4PBN33.mjs +8 -0
- package/dist/lib/browser/chunk-NU4PBN33.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +37 -80
- package/dist/lib/browser/index.mjs.map +4 -4
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/testing.mjs +92 -0
- package/dist/lib/browser/testing.mjs.map +7 -0
- package/dist/lib/browser/types.mjs +1 -1
- package/dist/lib/node/{SheetContainer-ESRTE7A5.cjs → SheetContainer-AXQV3ZT5.cjs} +83 -72
- package/dist/lib/node/SheetContainer-AXQV3ZT5.cjs.map +7 -0
- package/dist/lib/node/{chunk-4EGEA3KL.cjs → chunk-5KKJ4NPP.cjs} +135 -214
- package/dist/lib/node/chunk-5KKJ4NPP.cjs.map +7 -0
- package/dist/lib/node/chunk-CN3RPESU.cjs +202 -0
- package/dist/lib/node/chunk-CN3RPESU.cjs.map +7 -0
- package/dist/lib/node/{chunk-3R3J7IZR.cjs → chunk-DSYKOI4E.cjs} +4 -4
- package/dist/lib/node/{chunk-3R3J7IZR.cjs.map → chunk-DSYKOI4E.cjs.map} +2 -2
- package/dist/lib/node/chunk-PYXHNAAK.cjs +40 -0
- package/dist/lib/node/chunk-PYXHNAAK.cjs.map +7 -0
- package/dist/lib/node/index.cjs +38 -79
- package/dist/lib/node/index.cjs.map +4 -4
- package/dist/lib/node/meta.json +1 -1
- package/dist/lib/node/testing.cjs +111 -0
- package/dist/lib/node/testing.cjs.map +7 -0
- package/dist/lib/node/types.cjs +9 -9
- package/dist/lib/node/types.cjs.map +1 -1
- package/dist/types/src/SheetPlugin.d.ts.map +1 -1
- package/dist/types/src/components/CellEditor/extension.d.ts.map +1 -1
- package/dist/types/src/components/ComputeGraph/edge-function.d.ts.map +1 -1
- package/dist/types/src/components/ComputeGraph/graph-context.d.ts.map +1 -1
- package/dist/types/src/components/Sheet/Sheet.d.ts.map +1 -1
- package/dist/types/src/components/Sheet/Sheet.stories.d.ts.map +1 -1
- package/dist/types/src/components/SheetContainer.d.ts +1 -1
- package/dist/types/src/components/SheetContainer.d.ts.map +1 -1
- package/dist/types/src/components/Toolbar/Toolbar.stories.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/model/model.d.ts.map +1 -1
- package/dist/types/src/testing.d.ts +9 -0
- package/dist/types/src/testing.d.ts.map +1 -0
- package/dist/types/src/types.d.ts.map +1 -1
- package/package.json +38 -28
- package/src/SheetPlugin.tsx +36 -16
- package/src/components/CellEditor/extension.ts +16 -10
- package/src/components/ComputeGraph/edge-function.ts +6 -2
- package/src/components/ComputeGraph/graph-context.tsx +10 -1
- package/src/components/Sheet/Sheet.stories.tsx +9 -47
- package/src/components/Sheet/Sheet.tsx +24 -33
- package/src/components/Sheet/formatting.ts +1 -1
- package/src/components/SheetContainer.tsx +3 -4
- package/src/components/Toolbar/Toolbar.stories.tsx +5 -10
- package/src/model/model.ts +2 -3
- package/src/testing.ts +50 -0
- package/src/types.ts +2 -0
- package/dist/lib/browser/SheetContainer-ISY6DUVE.mjs.map +0 -7
- package/dist/lib/browser/chunk-CBRBNG3R.mjs.map +0 -7
- package/dist/lib/node/SheetContainer-ESRTE7A5.cjs.map +0 -7
- package/dist/lib/node/chunk-4EGEA3KL.cjs.map +0 -7
|
@@ -11,15 +11,15 @@ import { Client } from '@dxos/client';
|
|
|
11
11
|
import { type EchoReactiveObject } from '@dxos/echo-schema';
|
|
12
12
|
import { log } from '@dxos/log';
|
|
13
13
|
import { getSpace, type Space } from '@dxos/react-client/echo';
|
|
14
|
-
import { Button
|
|
14
|
+
import { Button } from '@dxos/react-ui';
|
|
15
15
|
import { mx } from '@dxos/react-ui-theme';
|
|
16
|
-
import { withTheme,
|
|
16
|
+
import { withTheme, withLayout } from '@dxos/storybook-utils';
|
|
17
17
|
|
|
18
18
|
import { Sheet } from './Sheet';
|
|
19
19
|
import { type SizeMap } from './grid';
|
|
20
20
|
import { useSheetContext } from './sheet-context';
|
|
21
|
-
import {
|
|
22
|
-
import { ValueTypeEnum,
|
|
21
|
+
import { createTestSheet, testSheetName } from '../../testing';
|
|
22
|
+
import { ValueTypeEnum, SheetType } from '../../types';
|
|
23
23
|
import { type ComputeGraph, createComputeGraph } from '../ComputeGraph';
|
|
24
24
|
// TODO(wittjosiah): Refactor. This is not exported from ./components due to depending on ECHO.
|
|
25
25
|
import { ComputeGraphContext, ComputeGraphContextProvider, useComputeGraph } from '../ComputeGraph/graph-context';
|
|
@@ -99,8 +99,6 @@ const SheetWithToolbar = ({ debug, space }: { debug?: boolean; space: Space }) =
|
|
|
99
99
|
);
|
|
100
100
|
};
|
|
101
101
|
|
|
102
|
-
const testSheetName = 'test';
|
|
103
|
-
|
|
104
102
|
const withGraphDecorator: Decorator = (Story) => {
|
|
105
103
|
const [graphs, setGraphs] = useState<Record<string, ComputeGraph>>({});
|
|
106
104
|
|
|
@@ -124,7 +122,7 @@ const withGraphDecorator: Decorator = (Story) => {
|
|
|
124
122
|
export default {
|
|
125
123
|
title: 'plugin-sheet/Sheet',
|
|
126
124
|
component: Sheet,
|
|
127
|
-
decorators: [
|
|
125
|
+
decorators: [withTheme, withLayout({ fullscreen: true, tooltips: true, classNames: 'inset-4' }), withGraphDecorator],
|
|
128
126
|
};
|
|
129
127
|
|
|
130
128
|
export const Default = () => {
|
|
@@ -136,11 +134,9 @@ export const Default = () => {
|
|
|
136
134
|
}
|
|
137
135
|
|
|
138
136
|
return (
|
|
139
|
-
<
|
|
140
|
-
<
|
|
141
|
-
|
|
142
|
-
</Sheet.Root>
|
|
143
|
-
</Tooltip.Provider>
|
|
137
|
+
<Sheet.Root sheet={sheet} space={space} onInfo={() => setDebug((debug) => !debug)}>
|
|
138
|
+
<SheetWithToolbar debug={debug} space={space} />
|
|
139
|
+
</Sheet.Root>
|
|
144
140
|
);
|
|
145
141
|
};
|
|
146
142
|
|
|
@@ -263,34 +259,6 @@ const Cell = ({ className, label }: { className?: string; label: string }) => (
|
|
|
263
259
|
<div className={mx('flex items-center justify-center border', className)}>{label}</div>
|
|
264
260
|
);
|
|
265
261
|
|
|
266
|
-
const createCells = (): Record<string, CellValue> => ({
|
|
267
|
-
B1: { value: 'Qty' },
|
|
268
|
-
B3: { value: 1 },
|
|
269
|
-
B4: { value: 2 },
|
|
270
|
-
B5: { value: 3 },
|
|
271
|
-
B7: { value: 'Total' },
|
|
272
|
-
|
|
273
|
-
C1: { value: 'Price' },
|
|
274
|
-
C3: { value: 2_000 },
|
|
275
|
-
C4: { value: 2_500 },
|
|
276
|
-
C5: { value: 3_000 },
|
|
277
|
-
C7: { value: '=SUMPRODUCT(B2:B6, C2:C6)' },
|
|
278
|
-
// C8: { value: '=C7*CRYPTO(D7)' },
|
|
279
|
-
C8: { value: '=C7*TEST()' },
|
|
280
|
-
|
|
281
|
-
D7: { value: 'USD' },
|
|
282
|
-
D8: { value: 'BTC' },
|
|
283
|
-
|
|
284
|
-
E3: { value: '=TODAY()' },
|
|
285
|
-
E4: { value: '=NOW()' },
|
|
286
|
-
|
|
287
|
-
F1: { value: `=${testSheetName}!A1` }, // Ref test sheet.
|
|
288
|
-
F3: { value: true },
|
|
289
|
-
F4: { value: false },
|
|
290
|
-
F5: { value: '8%' },
|
|
291
|
-
F6: { value: '$10000' },
|
|
292
|
-
});
|
|
293
|
-
|
|
294
262
|
const useTestSheet = () => {
|
|
295
263
|
const { graphs, setGraph } = useContext(ComputeGraphContext);
|
|
296
264
|
const [sheet, setSheet] = useState<EchoReactiveObject<SheetType>>();
|
|
@@ -307,13 +275,7 @@ const useTestSheet = () => {
|
|
|
307
275
|
setGraph(space.id, graph);
|
|
308
276
|
}
|
|
309
277
|
|
|
310
|
-
const sheet =
|
|
311
|
-
const model = new SheetModel(graph, sheet);
|
|
312
|
-
await model.initialize();
|
|
313
|
-
model.setValues(createCells());
|
|
314
|
-
model.sheet.columnMeta[model.sheet.columns[0]] = { size: 100 };
|
|
315
|
-
await model.destroy();
|
|
316
|
-
|
|
278
|
+
const sheet = await createTestSheet({ graph });
|
|
317
279
|
space.db.add(sheet);
|
|
318
280
|
setSheet(sheet);
|
|
319
281
|
});
|
|
@@ -40,7 +40,7 @@ import { debounce } from '@dxos/async';
|
|
|
40
40
|
import { fullyQualifiedId, createDocAccessor } from '@dxos/client/echo';
|
|
41
41
|
import { log } from '@dxos/log';
|
|
42
42
|
import { type ThemedClassName } from '@dxos/react-ui';
|
|
43
|
-
import { createAttendableAttributes } from '@dxos/react-ui-attention';
|
|
43
|
+
import { createAttendableAttributes, useHasAttention } from '@dxos/react-ui-attention';
|
|
44
44
|
import { mx } from '@dxos/react-ui-theme';
|
|
45
45
|
|
|
46
46
|
import {
|
|
@@ -112,13 +112,11 @@ import {
|
|
|
112
112
|
* - Update formula ranges by selection.
|
|
113
113
|
*/
|
|
114
114
|
|
|
115
|
-
// TODO(burdon): Factor out fragments.
|
|
116
115
|
const fragments = {
|
|
117
|
-
axis: 'bg-
|
|
118
|
-
axisSelected: 'bg-
|
|
119
|
-
cell: '
|
|
120
|
-
cellSelected: 'bg-
|
|
121
|
-
border: 'border-neutral-200 dark:border-neutral-700',
|
|
116
|
+
axis: 'bg-axisSurface text-axisText text-xs select-none',
|
|
117
|
+
axisSelected: 'bg-attention text-baseText',
|
|
118
|
+
cell: 'bg-gridCell',
|
|
119
|
+
cellSelected: 'bg-gridCellSelected text-baseText border !border-accentSurface',
|
|
122
120
|
};
|
|
123
121
|
|
|
124
122
|
//
|
|
@@ -244,7 +242,6 @@ const SheetMain = forwardRef<HTMLDivElement, SheetMainProps>(({ classNames, numR
|
|
|
244
242
|
role='none'
|
|
245
243
|
className={mx(
|
|
246
244
|
'grid grid-cols-[calc(var(--rail-size)-2px)_1fr] grid-rows-[32px_1fr_32px] bs-full is-full overflow-hidden',
|
|
247
|
-
fragments.border,
|
|
248
245
|
classNames,
|
|
249
246
|
)}
|
|
250
247
|
>
|
|
@@ -345,7 +342,7 @@ const GridCorner = (props: { className?: string } & Pick<DOMAttributes<HTMLDivEl
|
|
|
345
342
|
|
|
346
343
|
const MovingOverlay = ({ label }: { label: string }) => {
|
|
347
344
|
return (
|
|
348
|
-
<div className='flex w-full h-full justify-center items-center text-sm p-1 bg-
|
|
345
|
+
<div className='flex w-full h-full justify-center items-center text-sm p-1 bg-gridOverlay cursor-pointer'>
|
|
349
346
|
{label}
|
|
350
347
|
</div>
|
|
351
348
|
);
|
|
@@ -425,7 +422,7 @@ const SheetRows = forwardRef<HTMLDivElement, SheetRowsProps>(
|
|
|
425
422
|
<div className='relative flex grow overflow-hidden'>
|
|
426
423
|
{/* Fixed border. */}
|
|
427
424
|
<div
|
|
428
|
-
className={mx('z-20 absolute inset-0 border-y pointer-events-none'
|
|
425
|
+
className={mx('z-20 absolute inset-0 border-y border-gridLine pointer-events-none')}
|
|
429
426
|
style={{ width: axisWidth }}
|
|
430
427
|
/>
|
|
431
428
|
|
|
@@ -520,8 +517,7 @@ const GridRowCell = ({ idx, index, label, size, resize, selected, onSelect, onRe
|
|
|
520
517
|
{...listeners}
|
|
521
518
|
className={mx(
|
|
522
519
|
'flex h-full items-center justify-center cursor-pointer',
|
|
523
|
-
'border-t focus-visible:outline-none',
|
|
524
|
-
fragments.border,
|
|
520
|
+
'border-t border-gridLine focus-visible:outline-none',
|
|
525
521
|
fragments.axis,
|
|
526
522
|
selected && fragments.axisSelected,
|
|
527
523
|
isDragging && fragments.axisSelected,
|
|
@@ -532,11 +528,11 @@ const GridRowCell = ({ idx, index, label, size, resize, selected, onSelect, onRe
|
|
|
532
528
|
|
|
533
529
|
{/* Drop indicator. */}
|
|
534
530
|
{over?.id === idx && !isDragging && (
|
|
535
|
-
<div className='z-20 absolute top-0 w-full min-h-[4px] border-b-4 border-
|
|
531
|
+
<div className='z-20 absolute top-0 w-full min-h-[4px] border-b-4 border-accentSurface' />
|
|
536
532
|
)}
|
|
537
533
|
|
|
538
534
|
{/* Resize indicator. */}
|
|
539
|
-
{resizing && <div className='z-20 absolute bottom-0 w-full min-h-[4px] border-b-4 border-
|
|
535
|
+
{resizing && <div className='z-20 absolute bottom-0 w-full min-h-[4px] border-b-4 border-accentSurface' />}
|
|
540
536
|
</div>
|
|
541
537
|
</Resizable>
|
|
542
538
|
);
|
|
@@ -588,7 +584,7 @@ const SheetColumns = forwardRef<HTMLDivElement, SheetColumnsProps>(
|
|
|
588
584
|
<div className='relative flex grow overflow-hidden'>
|
|
589
585
|
{/* Fixed border. */}
|
|
590
586
|
<div
|
|
591
|
-
className={mx('z-20 absolute inset-0 border-x pointer-events-none'
|
|
587
|
+
className={mx('z-20 absolute inset-0 border-x border-gridLine pointer-events-none')}
|
|
592
588
|
style={{ height: axisHeight }}
|
|
593
589
|
/>
|
|
594
590
|
|
|
@@ -684,8 +680,7 @@ const GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, o
|
|
|
684
680
|
{...listeners}
|
|
685
681
|
className={mx(
|
|
686
682
|
'flex h-full items-center justify-center cursor-pointer',
|
|
687
|
-
'border-l focus-visible:outline-none',
|
|
688
|
-
fragments.border,
|
|
683
|
+
'border-l border-gridLine focus-visible:outline-none',
|
|
689
684
|
fragments.axis,
|
|
690
685
|
selected && fragments.axisSelected,
|
|
691
686
|
isDragging && fragments.axisSelected,
|
|
@@ -696,11 +691,11 @@ const GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, o
|
|
|
696
691
|
|
|
697
692
|
{/* Drop indicator. */}
|
|
698
693
|
{over?.id === idx && !isDragging && (
|
|
699
|
-
<div className='z-20 absolute left-0 h-full min-w-[4px] border-l-4 border-
|
|
694
|
+
<div className='z-20 absolute left-0 h-full min-w-[4px] border-l-4 border-accentSurface' />
|
|
700
695
|
)}
|
|
701
696
|
|
|
702
697
|
{/* Resize indicator. */}
|
|
703
|
-
{resizing && <div className='z-20 absolute right-0 h-full min-h-[4px] border-l-4 border-
|
|
698
|
+
{resizing && <div className='z-20 absolute right-0 h-full min-h-[4px] border-l-4 border-accentSurface' />}
|
|
704
699
|
</div>
|
|
705
700
|
</Resizable>
|
|
706
701
|
);
|
|
@@ -860,18 +855,17 @@ const SheetGrid = forwardRef<HTMLDivElement, SheetGridProps>(
|
|
|
860
855
|
});
|
|
861
856
|
|
|
862
857
|
// TODO(burdon): Prevent scroll if not attended.
|
|
863
|
-
const
|
|
864
|
-
const attendableAttrs = createAttendableAttributes(
|
|
865
|
-
|
|
866
|
-
const attended = true;
|
|
858
|
+
const id = fullyQualifiedId(model.sheet);
|
|
859
|
+
const attendableAttrs = createAttendableAttributes(id);
|
|
860
|
+
const hasAttention = useHasAttention(id);
|
|
867
861
|
|
|
868
862
|
return (
|
|
869
863
|
<div ref={containerRef} role='grid' className='relative flex grow overflow-hidden'>
|
|
870
864
|
{/* Fixed border. */}
|
|
871
|
-
<div className={mx('z-20 absolute inset-0 border pointer-events-none'
|
|
865
|
+
<div className={mx('z-20 absolute inset-0 border border-gridLine pointer-events-none')} />
|
|
872
866
|
|
|
873
867
|
{/* Grid scroll container. */}
|
|
874
|
-
<div ref={scrollerRef} className={mx('grow',
|
|
868
|
+
<div ref={scrollerRef} className={mx('grow', hasAttention && 'overflow-auto scrollbar-thin')}>
|
|
875
869
|
{/* Scroll content. */}
|
|
876
870
|
<div
|
|
877
871
|
className='relative select-none'
|
|
@@ -991,7 +985,7 @@ const SelectionOverlay = ({ root }: { root: HTMLDivElement }) => {
|
|
|
991
985
|
<div
|
|
992
986
|
role='none'
|
|
993
987
|
style={bounds}
|
|
994
|
-
className='z-10 absolute pointer-events-none bg-
|
|
988
|
+
className='z-10 absolute pointer-events-none bg-gridSelectionOverlay border border-gridOverlay'
|
|
995
989
|
/>
|
|
996
990
|
);
|
|
997
991
|
};
|
|
@@ -1018,10 +1012,8 @@ const SheetCell = ({ id, cell, style, active, onSelect }: SheetCellProps) => {
|
|
|
1018
1012
|
role='cell'
|
|
1019
1013
|
style={style}
|
|
1020
1014
|
className={mx(
|
|
1021
|
-
'flex w-full h-full truncate items-center border cursor-pointer',
|
|
1022
|
-
'px-2 py-1',
|
|
1015
|
+
'flex w-full h-full px-2 py-1 truncate items-center border border-gridLine cursor-pointer',
|
|
1023
1016
|
fragments.cell,
|
|
1024
|
-
fragments.border,
|
|
1025
1017
|
active && ['z-20', fragments.cellSelected],
|
|
1026
1018
|
classNames,
|
|
1027
1019
|
)}
|
|
@@ -1093,13 +1085,13 @@ const SheetStatusBar = () => {
|
|
|
1093
1085
|
}
|
|
1094
1086
|
|
|
1095
1087
|
return (
|
|
1096
|
-
<div className={mx('flex shrink-0 justify-between items-center px-4 py-1 text-sm border-x
|
|
1088
|
+
<div className={mx('flex shrink-0 justify-between items-center px-4 py-1 text-sm border-x border-gridLine')}>
|
|
1097
1089
|
<div className='flex gap-4 items-center'>
|
|
1098
1090
|
<div className='flex w-16 items-center font-mono'>
|
|
1099
1091
|
{(range && rangeToA1Notation(range)) || (cursor && addressToA1Notation(cursor))}
|
|
1100
1092
|
</div>
|
|
1101
1093
|
<div className='flex gap-2 items-center'>
|
|
1102
|
-
<FunctionIcon className={mx('text-
|
|
1094
|
+
<FunctionIcon className={mx('text-greenText', isFormula ? 'visible' : 'invisible')} />
|
|
1103
1095
|
<span className='font-mono'>{value}</span>
|
|
1104
1096
|
</div>
|
|
1105
1097
|
</div>
|
|
@@ -1129,8 +1121,7 @@ const SheetDebug = () => {
|
|
|
1129
1121
|
<div
|
|
1130
1122
|
className={mx(
|
|
1131
1123
|
'z-20 absolute right-0 top-20 bottom-20 w-[30rem] overflow-auto scrollbar-thin',
|
|
1132
|
-
'border text-xs bg-neutral-50 dark:bg-black text-cyan-500 font-mono p-1 opacity-80',
|
|
1133
|
-
fragments.border,
|
|
1124
|
+
'border border-gridLine text-xs bg-neutral-50 dark:bg-black text-cyan-500 font-mono p-1 opacity-80',
|
|
1134
1125
|
)}
|
|
1135
1126
|
>
|
|
1136
1127
|
<pre className='whitespace-pre-wrap'>
|
|
@@ -51,7 +51,7 @@ export class FormattingModel {
|
|
|
51
51
|
case ValueTypeEnum.Boolean: {
|
|
52
52
|
return {
|
|
53
53
|
value: (value as boolean).toLocaleString().toUpperCase(),
|
|
54
|
-
classNames: [...classNames, value ? '!text-
|
|
54
|
+
classNames: [...classNames, value ? '!text-greenText' : '!text-orangeText'],
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
57
|
|
|
@@ -13,19 +13,18 @@ const SheetContainer = ({
|
|
|
13
13
|
sheet,
|
|
14
14
|
space,
|
|
15
15
|
role,
|
|
16
|
-
|
|
16
|
+
remoteFunctionUrl,
|
|
17
17
|
}: SheetRootProps & { role?: string; coordinate?: LayoutCoordinate }) => {
|
|
18
18
|
return (
|
|
19
19
|
<div
|
|
20
20
|
role='none'
|
|
21
21
|
className={mx(
|
|
22
22
|
'flex',
|
|
23
|
-
role === 'article' && 'row-span-2',
|
|
23
|
+
role === 'article' && 'row-span-2',
|
|
24
24
|
role === 'section' && 'aspect-square border-y border-is border-separator',
|
|
25
|
-
coordinate.part !== 'solo' && 'border-is border-separator',
|
|
26
25
|
)}
|
|
27
26
|
>
|
|
28
|
-
<Sheet.Root sheet={sheet} space={space}>
|
|
27
|
+
<Sheet.Root sheet={sheet} space={space} remoteFunctionUrl={remoteFunctionUrl}>
|
|
29
28
|
<Sheet.Main />
|
|
30
29
|
</Sheet.Root>
|
|
31
30
|
</div>
|
|
@@ -6,29 +6,24 @@ import '@dxos-theme';
|
|
|
6
6
|
|
|
7
7
|
import React from 'react';
|
|
8
8
|
|
|
9
|
-
import { Tooltip } from '@dxos/react-ui';
|
|
10
9
|
import { textBlockWidth } from '@dxos/react-ui-theme';
|
|
11
|
-
import { withTheme } from '@dxos/storybook-utils';
|
|
10
|
+
import { withLayout, withTheme } from '@dxos/storybook-utils';
|
|
12
11
|
|
|
13
12
|
import { Toolbar } from './Toolbar';
|
|
14
13
|
import translations from '../../translations';
|
|
15
14
|
|
|
16
15
|
const Story = () => {
|
|
17
16
|
return (
|
|
18
|
-
<
|
|
19
|
-
<
|
|
20
|
-
|
|
21
|
-
<Toolbar.Alignment />
|
|
22
|
-
</Toolbar.Root>
|
|
23
|
-
</div>
|
|
24
|
-
</Tooltip.Provider>
|
|
17
|
+
<Toolbar.Root classNames={textBlockWidth}>
|
|
18
|
+
<Toolbar.Alignment />
|
|
19
|
+
</Toolbar.Root>
|
|
25
20
|
);
|
|
26
21
|
};
|
|
27
22
|
|
|
28
23
|
export default {
|
|
29
24
|
title: 'plugin-sheet/Toolbar',
|
|
30
25
|
component: Toolbar,
|
|
31
|
-
decorators: [withTheme],
|
|
26
|
+
decorators: [withTheme, withLayout({ tooltips: true })],
|
|
32
27
|
parameters: { translations, layout: 'fullscreen' },
|
|
33
28
|
render: (args: any) => <Story {...args} />,
|
|
34
29
|
};
|
package/src/model/model.ts
CHANGED
|
@@ -21,9 +21,8 @@ import { createIndices, RangeException, ReadonlyException } from './util';
|
|
|
21
21
|
import { type ComputeGraph } from '../components';
|
|
22
22
|
import { type CellScalarValue, type CellValue, type SheetType, ValueTypeEnum } from '../types';
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
const DEFAULT_COLUMNS = 26 * 2;
|
|
24
|
+
const DEFAULT_ROWS = 100;
|
|
25
|
+
const DEFAULT_COLUMNS = 26;
|
|
27
26
|
|
|
28
27
|
export type CellIndex = string;
|
|
29
28
|
|
package/src/testing.ts
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
//
|
|
2
|
+
// Copyright 2024 DXOS.org
|
|
3
|
+
//
|
|
4
|
+
|
|
5
|
+
import { type ComputeGraph, createComputeGraph } from './components';
|
|
6
|
+
import { SheetModel } from './model';
|
|
7
|
+
import { createSheet, type CellValue } from './types';
|
|
8
|
+
|
|
9
|
+
export const testSheetName = 'test';
|
|
10
|
+
|
|
11
|
+
export const createCells = (): Record<string, CellValue> => ({
|
|
12
|
+
B1: { value: 'Qty' },
|
|
13
|
+
B3: { value: 1 },
|
|
14
|
+
B4: { value: 2 },
|
|
15
|
+
B5: { value: 3 },
|
|
16
|
+
B7: { value: 'Total' },
|
|
17
|
+
|
|
18
|
+
C1: { value: 'Price' },
|
|
19
|
+
C3: { value: 2_000 },
|
|
20
|
+
C4: { value: 2_500 },
|
|
21
|
+
C5: { value: 3_000 },
|
|
22
|
+
C7: { value: '=SUMPRODUCT(B2:B6, C2:C6)' },
|
|
23
|
+
// C8: { value: '=C7*CRYPTO(D7)' },
|
|
24
|
+
C8: { value: '=C7*TEST()' },
|
|
25
|
+
|
|
26
|
+
D7: { value: 'USD' },
|
|
27
|
+
D8: { value: 'BTC' },
|
|
28
|
+
|
|
29
|
+
E3: { value: '=TODAY()' },
|
|
30
|
+
E4: { value: '=NOW()' },
|
|
31
|
+
|
|
32
|
+
F1: { value: `=${testSheetName}!A1` }, // Ref test sheet.
|
|
33
|
+
F3: { value: true },
|
|
34
|
+
F4: { value: false },
|
|
35
|
+
F5: { value: '8%' },
|
|
36
|
+
F6: { value: '$10000' },
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
export const createTestSheet = async ({
|
|
40
|
+
name,
|
|
41
|
+
graph = createComputeGraph(),
|
|
42
|
+
}: { name?: string; graph?: ComputeGraph } = {}) => {
|
|
43
|
+
const sheet = createSheet(name);
|
|
44
|
+
const model = new SheetModel(graph, sheet);
|
|
45
|
+
await model.initialize();
|
|
46
|
+
model.setValues(createCells());
|
|
47
|
+
model.sheet.columnMeta[model.sheet.columns[0]] = { size: 100 };
|
|
48
|
+
await model.destroy();
|
|
49
|
+
return sheet;
|
|
50
|
+
};
|
package/src/types.ts
CHANGED
|
@@ -83,6 +83,8 @@ export const RowColumnMeta = S.Struct({
|
|
|
83
83
|
});
|
|
84
84
|
|
|
85
85
|
// TODO(burdon): Index to all updates when rows/columns are inserted/deleted.
|
|
86
|
+
// TODO(wittjosiah): Migrate typename to remove `Type` suffix.
|
|
87
|
+
// TODO(wittjosiah): Rename title to name to align with other schemas.
|
|
86
88
|
export class SheetType extends TypedObject({ typename: 'dxos.org/type/SheetType', version: '0.1.0' })({
|
|
87
89
|
title: S.optional(S.String),
|
|
88
90
|
|