@dxos/plugin-sheet 0.6.13-main.548ca8d → 0.6.13-main.ed424a1

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.
Files changed (79) hide show
  1. package/dist/lib/browser/{SheetContainer-NDNIS44E.mjs → SheetContainer-RVRACGCZ.mjs} +107 -82
  2. package/dist/lib/browser/SheetContainer-RVRACGCZ.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-GKI67SEF.mjs → chunk-BWN5DZWZ.mjs} +16 -11
  4. package/dist/lib/browser/chunk-BWN5DZWZ.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-AQSGDA4X.mjs → chunk-HOG37RYS.mjs} +92 -178
  6. package/dist/lib/browser/chunk-HOG37RYS.mjs.map +7 -0
  7. package/dist/lib/browser/index.mjs +2 -2
  8. package/dist/lib/browser/meta.json +1 -1
  9. package/dist/lib/browser/types.mjs +3 -3
  10. package/dist/lib/node/{SheetContainer-YSQGJD7K.cjs → SheetContainer-J7XROAMN.cjs} +113 -89
  11. package/dist/lib/node/SheetContainer-J7XROAMN.cjs.map +7 -0
  12. package/dist/lib/node/{chunk-6F43RV45.cjs → chunk-AXQZA2YS.cjs} +103 -186
  13. package/dist/lib/node/chunk-AXQZA2YS.cjs.map +7 -0
  14. package/dist/lib/node/{chunk-ER3PM7GD.cjs → chunk-NZARD7UP.cjs} +20 -15
  15. package/dist/lib/node/chunk-NZARD7UP.cjs.map +7 -0
  16. package/dist/lib/node/index.cjs +18 -18
  17. package/dist/lib/node/meta.json +1 -1
  18. package/dist/lib/node/types.cjs +7 -7
  19. package/dist/lib/node/types.cjs.map +1 -1
  20. package/dist/lib/node-esm/{SheetContainer-M7WRMZDU.mjs → SheetContainer-YWQVKHQB.mjs} +107 -82
  21. package/dist/lib/node-esm/SheetContainer-YWQVKHQB.mjs.map +7 -0
  22. package/dist/lib/node-esm/{chunk-ELTFPX5B.mjs → chunk-BPXXIAOQ.mjs} +92 -178
  23. package/dist/lib/node-esm/chunk-BPXXIAOQ.mjs.map +7 -0
  24. package/dist/lib/node-esm/{chunk-ZVLLQ2PJ.mjs → chunk-WFDTY3IC.mjs} +16 -11
  25. package/dist/lib/node-esm/chunk-WFDTY3IC.mjs.map +7 -0
  26. package/dist/lib/node-esm/index.mjs +2 -2
  27. package/dist/lib/node-esm/meta.json +1 -1
  28. package/dist/lib/node-esm/types.mjs +3 -3
  29. package/dist/types/src/components/GridSheet/GridSheet.d.ts.map +1 -1
  30. package/dist/types/src/components/GridSheet/util.d.ts +2 -2
  31. package/dist/types/src/components/GridSheet/util.d.ts.map +1 -1
  32. package/dist/types/src/components/SheetContainer/SheetContainer.d.ts.map +1 -1
  33. package/dist/types/src/components/SheetContainer/SheetContainer.stories.d.ts.map +1 -1
  34. package/dist/types/src/components/SheetContext/SheetContext.d.ts +1 -2
  35. package/dist/types/src/components/SheetContext/SheetContext.d.ts.map +1 -1
  36. package/dist/types/src/components/Toolbar/Toolbar.d.ts +11 -17
  37. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  38. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +1 -2
  39. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  40. package/dist/types/src/components/index.d.ts.map +1 -1
  41. package/dist/types/src/defs/index.d.ts +1 -0
  42. package/dist/types/src/defs/index.d.ts.map +1 -1
  43. package/dist/types/src/defs/sheet-range-types.d.ts +13 -0
  44. package/dist/types/src/defs/sheet-range-types.d.ts.map +1 -0
  45. package/dist/types/src/hooks/index.d.ts +0 -1
  46. package/dist/types/src/hooks/index.d.ts.map +1 -1
  47. package/dist/types/src/model/index.d.ts +0 -1
  48. package/dist/types/src/model/index.d.ts.map +1 -1
  49. package/dist/types/src/types.d.ts +39 -20
  50. package/dist/types/src/types.d.ts.map +1 -1
  51. package/package.json +35 -34
  52. package/src/components/GridSheet/GridSheet.stories.tsx +2 -2
  53. package/src/components/GridSheet/GridSheet.tsx +5 -3
  54. package/src/components/GridSheet/util.ts +24 -10
  55. package/src/components/SheetContainer/SheetContainer.stories.tsx +2 -2
  56. package/src/components/SheetContainer/SheetContainer.tsx +3 -28
  57. package/src/components/SheetContext/SheetContext.tsx +5 -9
  58. package/src/components/Toolbar/Toolbar.tsx +116 -68
  59. package/src/defs/index.ts +1 -0
  60. package/src/defs/sheet-range-types.ts +46 -0
  61. package/src/defs/util.ts +1 -1
  62. package/src/hooks/index.ts +0 -1
  63. package/src/model/index.ts +0 -1
  64. package/src/types.ts +5 -11
  65. package/dist/lib/browser/SheetContainer-NDNIS44E.mjs.map +0 -7
  66. package/dist/lib/browser/chunk-AQSGDA4X.mjs.map +0 -7
  67. package/dist/lib/browser/chunk-GKI67SEF.mjs.map +0 -7
  68. package/dist/lib/node/SheetContainer-YSQGJD7K.cjs.map +0 -7
  69. package/dist/lib/node/chunk-6F43RV45.cjs.map +0 -7
  70. package/dist/lib/node/chunk-ER3PM7GD.cjs.map +0 -7
  71. package/dist/lib/node-esm/SheetContainer-M7WRMZDU.mjs.map +0 -7
  72. package/dist/lib/node-esm/chunk-ELTFPX5B.mjs.map +0 -7
  73. package/dist/lib/node-esm/chunk-ZVLLQ2PJ.mjs.map +0 -7
  74. package/dist/types/src/hooks/useFormattingModel.d.ts +0 -3
  75. package/dist/types/src/hooks/useFormattingModel.d.ts.map +0 -1
  76. package/dist/types/src/model/formatting-model.d.ts +0 -19
  77. package/dist/types/src/model/formatting-model.d.ts.map +0 -1
  78. package/src/hooks/useFormattingModel.ts +0 -11
  79. package/src/model/formatting-model.ts +0 -116
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,eAAe,EACf,oBAAoB,EACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,CAAC,EAAe,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAM9C,oBAAY,WAAW;IACrB,MAAM,wCAA2B;CAClC;AAKD,KAAK,cAAc,CAAC,CAAC,IAAI;IACvB,MAAM,EAAE;QACN,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC;QAClC,UAAU,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,MAAM,CAAC;KAC9F,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,eAAe,GAC/C,sBAAsB,GACtB,oBAAoB,GACpB,yBAAyB,GACzB,uBAAuB,GACvB,oBAAoB,GACpB,cAAc,GACd,iBAAiB,GACjB,aAAa,GACb,cAAc,CAAC,SAAS,CAAC,CAAC;AAE5B,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAE/D,eAAO,MAAM,SAAS;;EAKpB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,SAAS,CAAC,CAAC;AAGxD,eAAO,MAAM,UAAU;;;;;;EAMrB,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,UAAU,CAAC,CAAC;AAG1D,eAAO,MAAM,aAAa;;EAExB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAsCuC,CAAC;;oBAA8D,CAAC;uBAAyC,CAAC;wBAAwD,CAAC;;;;;;;;2BAAsP,CAAC;qBAAuC,CAAC;;iBAA8C,CAAC;sBAA4E,CAAC;;;mBAAwE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAvoB,CAAC;;oBAA8D,CAAC;uBAAyC,CAAC;wBAAwD,CAAC;;;;;;;;2BAAsP,CAAC;qBAAuC,CAAC;;iBAA8C,CAAC;sBAA4E,CAAC;;;mBAAwE,CAAC;;;;;;;;AAnCjrB,qBAAa,SAAU,SAAQ,cAwB7B;CAAG;AAEL,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/types.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,eAAe,EACf,oBAAoB,EACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,GAAG,EAAE,CAAC,EAAe,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EAAE,KAAK,yBAAyB,EAAE,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMxD,oBAAY,WAAW;IACrB,MAAM,wCAA2B;CAClC;AAKD,KAAK,cAAc,CAAC,CAAC,IAAI;IACvB,MAAM,EAAE;QACN,SAAS,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,GAAG,IAAI,CAAC,CAAC;QAClC,UAAU,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,KAAK,MAAM,CAAC;KAC9F,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,eAAe,GAC/C,sBAAsB,GACtB,oBAAoB,GACpB,yBAAyB,GACzB,uBAAuB,GACvB,oBAAoB,GACpB,cAAc,GACd,iBAAiB,GACjB,aAAa,GACb,cAAc,CAAC,SAAS,CAAC,CAAC;AAE5B,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAE/D,eAAO,MAAM,SAAS;;EAKpB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,SAAS,CAAC,CAAC;AAGxD,eAAO,MAAM,KAAK;;;;;;;;;;;;;EAIhB,CAAC;AAGH,eAAO,MAAM,aAAa;;EAExB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAqCwN,CAAC;;oBAA8D,CAAC;uBAAyC,CAAC;wBAAwD,CAAC;;;;;;;;2BAAsP,CAAC;qBAAuC,CAAC;;iBAA8C,CAAC;sBAA4E,CAAC;;;mBAAwE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAAvoB,CAAC;;oBAA8D,CAAC;uBAAyC,CAAC;wBAAwD,CAAC;;;;;;;;2BAAsP,CAAC;qBAAuC,CAAC;;iBAA8C,CAAC;sBAA4E,CAAC;;;mBAAwE,CAAC;;;;;;;;AAlCl2B,qBAAa,SAAU,SAAQ,cAuB7B;CAAG;AAEL,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CACnC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-sheet",
3
- "version": "0.6.13-main.548ca8d",
3
+ "version": "0.6.13-main.ed424a1",
4
4
  "description": "Braneframe sketch plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -77,30 +77,31 @@
77
77
  "re-resizable": "^6.9.17",
78
78
  "react-markdown": "^8.0.5",
79
79
  "react-resize-detector": "^11.0.1",
80
- "@dxos/app-framework": "0.6.13-main.548ca8d",
81
- "@dxos/async": "0.6.13-main.548ca8d",
82
- "@dxos/context": "0.6.13-main.548ca8d",
83
- "@dxos/client": "0.6.13-main.548ca8d",
84
- "@dxos/crypto": "0.6.13-main.548ca8d",
85
- "@dxos/debug": "0.6.13-main.548ca8d",
86
- "@dxos/invariant": "0.6.13-main.548ca8d",
87
- "@dxos/keys": "0.6.13-main.548ca8d",
88
- "@dxos/echo-schema": "0.6.13-main.548ca8d",
89
- "@dxos/log": "0.6.13-main.548ca8d",
90
- "@dxos/plugin-client": "0.6.13-main.548ca8d",
91
- "@dxos/plugin-attention": "0.6.13-main.548ca8d",
92
- "@dxos/plugin-graph": "0.6.13-main.548ca8d",
93
- "@dxos/plugin-markdown": "0.6.13-main.548ca8d",
94
- "@dxos/plugin-space": "0.6.13-main.548ca8d",
95
- "@dxos/plugin-script": "0.6.13-main.548ca8d",
96
- "@dxos/plugin-stack": "0.6.13-main.548ca8d",
97
- "@dxos/react-client": "0.6.13-main.548ca8d",
98
- "@dxos/react-hooks": "0.6.13-main.548ca8d",
99
- "@dxos/react-ui-attention": "0.6.13-main.548ca8d",
100
- "@dxos/react-ui-editor": "0.6.13-main.548ca8d",
101
- "@dxos/react-ui-grid": "0.6.13-main.548ca8d",
102
- "@dxos/schema": "0.6.13-main.548ca8d",
103
- "@dxos/util": "0.6.13-main.548ca8d"
80
+ "@dxos/async": "0.6.13-main.ed424a1",
81
+ "@dxos/app-framework": "0.6.13-main.ed424a1",
82
+ "@dxos/client": "0.6.13-main.ed424a1",
83
+ "@dxos/crypto": "0.6.13-main.ed424a1",
84
+ "@dxos/context": "0.6.13-main.ed424a1",
85
+ "@dxos/debug": "0.6.13-main.ed424a1",
86
+ "@dxos/echo-schema": "0.6.13-main.ed424a1",
87
+ "@dxos/invariant": "0.6.13-main.ed424a1",
88
+ "@dxos/keys": "0.6.13-main.ed424a1",
89
+ "@dxos/log": "0.6.13-main.ed424a1",
90
+ "@dxos/plugin-client": "0.6.13-main.ed424a1",
91
+ "@dxos/plugin-attention": "0.6.13-main.ed424a1",
92
+ "@dxos/plugin-graph": "0.6.13-main.ed424a1",
93
+ "@dxos/plugin-script": "0.6.13-main.ed424a1",
94
+ "@dxos/plugin-markdown": "0.6.13-main.ed424a1",
95
+ "@dxos/plugin-stack": "0.6.13-main.ed424a1",
96
+ "@dxos/plugin-space": "0.6.13-main.ed424a1",
97
+ "@dxos/react-client": "0.6.13-main.ed424a1",
98
+ "@dxos/react-hooks": "0.6.13-main.ed424a1",
99
+ "@dxos/react-ui-attention": "0.6.13-main.ed424a1",
100
+ "@dxos/react-ui-data": "0.6.13-main.ed424a1",
101
+ "@dxos/schema": "0.6.13-main.ed424a1",
102
+ "@dxos/react-ui-grid": "0.6.13-main.ed424a1",
103
+ "@dxos/react-ui-editor": "0.6.13-main.ed424a1",
104
+ "@dxos/util": "0.6.13-main.ed424a1"
104
105
  },
105
106
  "devDependencies": {
106
107
  "@lezer/generator": "^1.7.1",
@@ -112,19 +113,19 @@
112
113
  "react": "~18.2.0",
113
114
  "react-dom": "~18.2.0",
114
115
  "vite": "5.4.7",
115
- "@dxos/echo-generator": "0.6.13-main.548ca8d",
116
- "@dxos/random": "0.6.13-main.548ca8d",
117
- "@dxos/react-ui": "0.6.13-main.548ca8d",
118
- "@dxos/react-ui-theme": "0.6.13-main.548ca8d",
119
- "@dxos/react-ui-types": "0.6.13-main.548ca8d",
120
- "@dxos/storybook-utils": "0.6.13-main.548ca8d",
121
- "@dxos/react-ui-syntax-highlighter": "0.6.13-main.548ca8d"
116
+ "@dxos/random": "0.6.13-main.ed424a1",
117
+ "@dxos/echo-generator": "0.6.13-main.ed424a1",
118
+ "@dxos/react-ui-syntax-highlighter": "0.6.13-main.ed424a1",
119
+ "@dxos/react-ui": "0.6.13-main.ed424a1",
120
+ "@dxos/react-ui-theme": "0.6.13-main.ed424a1",
121
+ "@dxos/react-ui-types": "0.6.13-main.ed424a1",
122
+ "@dxos/storybook-utils": "0.6.13-main.ed424a1"
122
123
  },
123
124
  "peerDependencies": {
124
125
  "react": "~18.2.0",
125
126
  "react-dom": "~18.2.0",
126
- "@dxos/react-ui": "0.6.13-main.548ca8d",
127
- "@dxos/react-ui-theme": "0.6.13-main.548ca8d"
127
+ "@dxos/react-ui-theme": "0.6.13-main.ed424a1",
128
+ "@dxos/react-ui": "0.6.13-main.ed424a1"
128
129
  },
129
130
  "publishConfig": {
130
131
  "access": "public"
@@ -10,7 +10,7 @@ import { withTheme, withLayout } from '@dxos/storybook-utils';
10
10
 
11
11
  import { GridSheet } from './GridSheet';
12
12
  import { useComputeGraph } from '../../hooks';
13
- import { useTestSheet, withComputeGraphDecorator } from '../../testing';
13
+ import { createTestCells, useTestSheet, withComputeGraphDecorator } from '../../testing';
14
14
  import { SheetType } from '../../types';
15
15
  import { SheetProvider } from '../SheetContext';
16
16
 
@@ -28,7 +28,7 @@ export default {
28
28
  export const Basic = () => {
29
29
  const space = useSpace();
30
30
  const graph = useComputeGraph(space);
31
- const sheet = useTestSheet(space, graph);
31
+ const sheet = useTestSheet(space, graph, { cells: createTestCells() });
32
32
  if (!sheet || !graph) {
33
33
  return null;
34
34
  }
@@ -42,7 +42,7 @@ const sheetRowDefault = { grid: { size: 32, resizeable: true } };
42
42
  const sheetColDefault = { frozenColsStart: { size: 48 }, grid: { size: 180, resizeable: true } };
43
43
 
44
44
  export const GridSheet = () => {
45
- const { id, model, formatting, editing, setEditing, setCursor, setRange } = useSheetContext();
45
+ const { id, model, editing, setEditing, setCursor, setRange } = useSheetContext();
46
46
  const dxGrid = useRef<DxGridElement | null>(null);
47
47
  const rangeNotifier = useRef<CellRangeNotifier>();
48
48
  const { hasAttention } = useAttention(id);
@@ -51,7 +51,9 @@ export const GridSheet = () => {
51
51
  (event: FocusEvent) => {
52
52
  if (!editing) {
53
53
  const cell = closestCell(event.target);
54
- setCursor(cell && cell.plane === 'grid' ? { col: cell.col, row: cell.row } : undefined);
54
+ if (cell && cell.plane === 'grid') {
55
+ setCursor({ col: cell.col, row: cell.row });
56
+ }
55
57
  }
56
58
  },
57
59
  [editing],
@@ -116,7 +118,7 @@ export const GridSheet = () => {
116
118
  [hasAttention],
117
119
  );
118
120
 
119
- const { columns, rows } = useSheetModelDxGridProps(dxGrid, model, formatting);
121
+ const { columns, rows } = useSheetModelDxGridProps(dxGrid, model);
120
122
 
121
123
  const extension = useMemo(
122
124
  () => [
@@ -5,6 +5,7 @@
5
5
  import { type MutableRefObject, useEffect, useLayoutEffect, useState } from 'react';
6
6
 
7
7
  import { createDocAccessor } from '@dxos/react-client/echo';
8
+ import { parseValue, cellClassesForFieldType } from '@dxos/react-ui-data';
8
9
  import {
9
10
  type GridContentProps,
10
11
  type DxGridElement,
@@ -12,13 +13,14 @@ import {
12
13
  type DxGridPlane,
13
14
  type DxGridPlaneRange,
14
15
  type DxGridPlaneCells,
16
+ type DxGridCellValue,
15
17
  colToA1Notation,
16
18
  rowToA1Notation,
17
19
  } from '@dxos/react-ui-grid';
18
20
  import { mx } from '@dxos/react-ui-theme';
19
21
 
20
- import { type CellAddress } from '../../defs';
21
- import { type SheetModel, type FormattingModel } from '../../model';
22
+ import { type CellAddress, inRange, cellClassNameForRange } from '../../defs';
23
+ import { type SheetModel } from '../../model';
22
24
 
23
25
  export const dxGridCellIndexToSheetCellAddress = (index: string): CellAddress => {
24
26
  const [colStr, rowStr] = index.split(',');
@@ -52,7 +54,20 @@ const createDxGridRows = (model: SheetModel): DxGridAxisMeta => {
52
54
  );
53
55
  };
54
56
 
55
- const gridCellGetter = (model: SheetModel, formatting: FormattingModel) => {
57
+ const projectCellProps = (model: SheetModel, col: number, row: number): DxGridCellValue => {
58
+ const address = { col, row };
59
+ const rawValue = model.getValue(address);
60
+ if (rawValue === undefined || rawValue === null) {
61
+ return { value: '' };
62
+ }
63
+ const ranges = model.sheet.ranges?.filter(({ range }) => inRange(range, address));
64
+ const type = model.getValueType(address);
65
+ const classNames = ranges?.map(cellClassNameForRange).reverse();
66
+
67
+ return { value: parseValue(type, rawValue), className: mx(cellClassesForFieldType(type), classNames) };
68
+ };
69
+
70
+ const gridCellGetter = (model: SheetModel) => {
56
71
  // TODO(thure): Actually use the cache.
57
72
  const cachedGridCells: DxGridPlaneCells = {};
58
73
  return (nextBounds: DxGridPlaneRange): DxGridPlaneCells => {
@@ -60,10 +75,10 @@ const gridCellGetter = (model: SheetModel, formatting: FormattingModel) => {
60
75
  return [...Array(nextBounds.end.row - nextBounds.start.row)].forEach((_, r0) => {
61
76
  const col = nextBounds.start.col + c0;
62
77
  const row = nextBounds.start.row + r0;
63
- const cell = formatting.getFormatting({ col, row });
78
+ const cell = projectCellProps(model, col, row);
64
79
  if (cell.value) {
65
80
  cachedGridCells;
66
- cachedGridCells[`${col},${row}`] = { value: cell.value, className: mx(cell.classNames) };
81
+ cachedGridCells[`${col},${row}`] = cell;
67
82
  }
68
83
  });
69
84
  });
@@ -79,8 +94,8 @@ export const rowLabelCell = (row: number) => ({
79
94
 
80
95
  export const colLabelCell = (col: number) => ({ value: colToA1Notation(col), resizeHandle: 'col' });
81
96
 
82
- const cellGetter = (model: SheetModel, formatting: FormattingModel) => {
83
- const getGridCells = gridCellGetter(model, formatting);
97
+ const cellGetter = (model: SheetModel) => {
98
+ const getGridCells = gridCellGetter(model);
84
99
  return (nextBounds: DxGridPlaneRange, plane: DxGridPlane): DxGridPlaneCells => {
85
100
  switch (plane) {
86
101
  case 'grid':
@@ -106,7 +121,6 @@ const cellGetter = (model: SheetModel, formatting: FormattingModel) => {
106
121
  export const useSheetModelDxGridProps = (
107
122
  dxGridRef: MutableRefObject<DxGridElement | null>,
108
123
  model: SheetModel,
109
- formatting: FormattingModel,
110
124
  ): Pick<GridContentProps, 'columns' | 'rows'> => {
111
125
  const [columns, setColumns] = useState<DxGridAxisMeta>(createDxGridColumns(model));
112
126
  const [rows, setRows] = useState<DxGridAxisMeta>(createDxGridColumns(model));
@@ -114,14 +128,14 @@ export const useSheetModelDxGridProps = (
114
128
  useLayoutEffect(() => {
115
129
  const cellsAccessor = createDocAccessor(model.sheet, ['cells']);
116
130
  if (dxGridRef.current) {
117
- dxGridRef.current.getCells = cellGetter(model, formatting);
131
+ dxGridRef.current.getCells = cellGetter(model);
118
132
  }
119
133
  const handleCellsUpdate = () => {
120
134
  dxGridRef.current?.requestUpdate('initialCells');
121
135
  };
122
136
  cellsAccessor.handle.addListener('change', handleCellsUpdate);
123
137
  return () => cellsAccessor.handle.removeListener('change', handleCellsUpdate);
124
- }, [model, formatting]);
138
+ }, [model]);
125
139
 
126
140
  useEffect(() => {
127
141
  const columnMetaAccessor = createDocAccessor(model.sheet, ['columnMeta']);
@@ -10,7 +10,7 @@ import { withTheme, withLayout } from '@dxos/storybook-utils';
10
10
 
11
11
  import { SheetContainer } from './SheetContainer';
12
12
  import { useComputeGraph } from '../../hooks';
13
- import { useTestSheet, withComputeGraphDecorator } from '../../testing';
13
+ import { createTestCells, useTestSheet, withComputeGraphDecorator } from '../../testing';
14
14
  import { SheetType } from '../../types';
15
15
 
16
16
  export default {
@@ -31,7 +31,7 @@ export default {
31
31
  export const Basic = () => {
32
32
  const space = useSpace();
33
33
  const graph = useComputeGraph(space);
34
- const sheet = useTestSheet(space, graph);
34
+ const sheet = useTestSheet(space, graph, { cells: createTestCells() });
35
35
  if (!sheet || !graph) {
36
36
  return null;
37
37
  }
@@ -2,43 +2,18 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import React, { useCallback } from 'react';
6
-
7
- import { useIntentDispatcher } from '@dxos/app-framework';
5
+ import React from 'react';
8
6
 
9
7
  import { FunctionEditor } from '../FunctionEditor';
10
8
  import { GridSheet } from '../GridSheet';
11
9
  import { SheetProvider, type SheetProviderProps } from '../SheetContext';
12
- import { Toolbar, type ToolbarAction } from '../Toolbar';
10
+ import { Toolbar } from '../Toolbar';
13
11
 
14
12
  export const SheetContainer = ({ graph, sheet, role }: SheetProviderProps & { role?: string }) => {
15
- const dispatch = useIntentDispatcher();
16
-
17
- // TODO(Zan): Centralise the toolbar action handler. Current implementation in stories.
18
- const handleAction = useCallback(
19
- (action: ToolbarAction) => {
20
- switch (action.type) {
21
- case 'comment': {
22
- // TODO(Zan): We shouldn't hardcode the action ID.
23
- void dispatch({
24
- action: 'dxos.org/plugin/thread/action/create',
25
- data: {
26
- cursor: action.anchor,
27
- name: action.cellContent,
28
- subject: sheet,
29
- },
30
- });
31
- }
32
- }
33
- },
34
- [sheet, dispatch],
35
- );
36
-
37
13
  return (
38
14
  <SheetProvider sheet={sheet} graph={graph}>
39
- <Toolbar.Root onAction={handleAction} role={role}>
15
+ <Toolbar.Root role={role}>
40
16
  <Toolbar.Styles />
41
- <Toolbar.Format />
42
17
  <Toolbar.Alignment />
43
18
  <Toolbar.Separator />
44
19
  <Toolbar.Actions />
@@ -10,15 +10,14 @@ import { Grid, useGridContext, type GridScopedProps, type GridEditing } from '@d
10
10
 
11
11
  import { type CellAddress, type CellRange } from '../../defs';
12
12
  import { type ComputeGraph } from '../../graph';
13
- import { useSheetModel, useFormattingModel, useSelectThreadOnCellFocus, useThreadDecorations } from '../../hooks';
14
- import { type FormattingModel, type SheetModel, createDecorations } from '../../model';
13
+ import { useSheetModel, useSelectThreadOnCellFocus, useThreadDecorations } from '../../hooks';
14
+ import { type SheetModel, createDecorations } from '../../model';
15
15
  import { type SheetType } from '../../types';
16
16
 
17
17
  export type SheetContextValue = {
18
18
  id: string;
19
19
 
20
20
  model: SheetModel;
21
- formatting: FormattingModel;
22
21
 
23
22
  // Cursor state.
24
23
  // TODO(burdon): Cursor and range should use indices.
@@ -49,11 +48,10 @@ export const useSheetContext = (): SheetContextValue => {
49
48
 
50
49
  const SheetProviderImpl = ({
51
50
  model,
52
- formatting,
53
51
  onInfo,
54
52
  children,
55
53
  __gridScope,
56
- }: GridScopedProps<PropsWithChildren<Pick<SheetContextValue, 'onInfo' | 'model' | 'formatting'>>>) => {
54
+ }: GridScopedProps<PropsWithChildren<Pick<SheetContextValue, 'onInfo' | 'model'>>>) => {
57
55
  const { id, editing, setEditing } = useGridContext('SheetProvider', __gridScope);
58
56
 
59
57
  // TODO(Zan): Impl. set range and set cursor that scrolls to that cell or range if it is not visible.
@@ -71,7 +69,6 @@ const SheetProviderImpl = ({
71
69
  value={{
72
70
  id,
73
71
  model,
74
- formatting,
75
72
  editing,
76
73
  setEditing,
77
74
  cursor,
@@ -96,11 +93,10 @@ export type SheetProviderProps = {
96
93
 
97
94
  export const SheetProvider = ({ children, graph, sheet, readonly, onInfo }: PropsWithChildren<SheetProviderProps>) => {
98
95
  const model = useSheetModel(graph, sheet, { readonly });
99
- const formatting = useFormattingModel(model);
100
96
 
101
- return !model || !formatting ? null : (
97
+ return !model ? null : (
102
98
  <Grid.Root id={fullyQualifiedId(sheet)}>
103
- <SheetProviderImpl model={model} formatting={formatting} onInfo={onInfo}>
99
+ <SheetProviderImpl model={model} onInfo={onInfo}>
104
100
  {children}
105
101
  </SheetProviderImpl>
106
102
  </Grid.Root>
@@ -3,8 +3,9 @@
3
3
  //
4
4
 
5
5
  import { createContext } from '@radix-ui/react-context';
6
- import React, { type PropsWithChildren } from 'react';
6
+ import React, { type PropsWithChildren, useCallback, useMemo } from 'react';
7
7
 
8
+ import { useIntentDispatcher } from '@dxos/app-framework';
8
9
  import {
9
10
  Icon,
10
11
  Toolbar as NaturalToolbar,
@@ -18,9 +19,18 @@ import {
18
19
  import { useAttention } from '@dxos/react-ui-attention';
19
20
  import { nonNullable } from '@dxos/util';
20
21
 
21
- import { addressToIndex } from '../../defs';
22
+ import {
23
+ addressToIndex,
24
+ type AlignKey,
25
+ type AlignValue,
26
+ type CommentKey,
27
+ type CommentValue,
28
+ inRange,
29
+ type StyleKey,
30
+ type StyleValue,
31
+ } from '../../defs';
22
32
  import { SHEET_PLUGIN } from '../../meta';
23
- import { type Formatting } from '../../types';
33
+ import { type SheetType } from '../../types';
24
34
  import { useSheetContext } from '../SheetContext';
25
35
 
26
36
  //
@@ -71,42 +81,92 @@ export const ToolbarItem = ({ itemType, icon, children, ...props }: ToolbarItemP
71
81
  // Root
72
82
  //
73
83
 
74
- type AlignValue = 'left' | 'center' | 'right' | 'unset';
75
- type AlignAction = { type: 'align'; value: AlignValue };
76
-
77
- type CommentAction = { type: 'comment'; anchor: string; cellContent?: string };
78
-
79
- type FormatValue = 'date' | 'currency' | 'unset';
80
- type FormatAction = { type: 'format'; value: FormatValue };
84
+ type AlignAction = { key: AlignKey; value: AlignValue };
85
+ type CommentAction = { key: CommentKey; value: CommentValue; cellContent?: string };
86
+ type StyleAction = { key: StyleKey; value: StyleValue };
81
87
 
82
- type StyleValue = 'highlight' | 'unset';
83
- type StyleAction = { type: 'style'; value: StyleValue };
88
+ export type ToolbarAction = StyleAction | AlignAction | CommentAction;
84
89
 
85
- export type ToolbarAction = StyleAction | AlignAction | FormatAction | CommentAction;
86
-
87
- export type ToolbarActionType = ToolbarAction['type'];
90
+ export type ToolbarActionType = ToolbarAction['key'];
88
91
 
89
92
  export type ToolbarActionHandler = (action: ToolbarAction) => void;
90
93
 
91
94
  export type ToolbarProps = ThemedClassName<
92
95
  PropsWithChildren<{
93
- onAction?: ToolbarActionHandler;
94
96
  role?: string;
95
97
  }>
96
98
  >;
97
99
 
98
- const [ToolbarContextProvider, useToolbarContext] = createContext<ToolbarProps>('Toolbar');
100
+ const [ToolbarContextProvider, useToolbarContext] = createContext<{ onAction: (action: ToolbarAction) => void }>(
101
+ 'Toolbar',
102
+ );
99
103
 
100
104
  // TODO(Zan): Factor out, copied this from MarkdownPlugin.
101
105
  const sectionToolbarLayout =
102
106
  'bs-[--rail-action] bg-[--sticky-bg] sticky block-start-0 __-block-start-px transition-opacity';
103
107
 
104
- const ToolbarRoot = ({ children, onAction, role, classNames }: ToolbarProps) => {
105
- const { id } = useSheetContext();
108
+ type Range = SheetType['ranges'][number];
109
+
110
+ const ToolbarRoot = ({ children, role, classNames }: ToolbarProps) => {
111
+ const { id, model, range, cursor } = useSheetContext();
106
112
  const { hasAttention } = useAttention(id);
113
+ const dispatch = useIntentDispatcher();
114
+
115
+ // TODO(Zan): Centralise the toolbar action handler. Current implementation in stories.
116
+ const handleAction = useCallback(
117
+ (action: ToolbarAction) => {
118
+ switch (action.key) {
119
+ case 'align':
120
+ if (cursor) {
121
+ const index = model.sheet.ranges?.findIndex(
122
+ (range) => range.key === action.key && inRange(range.range, cursor),
123
+ );
124
+ const nextRange = range ? { from: range.from, to: range.to ?? range.from } : { from: cursor, to: cursor };
125
+ const nextRangeEntity = {
126
+ range: nextRange as Range['range'],
127
+ key: action.key,
128
+ value: action.value,
129
+ };
130
+ if (index < 0) {
131
+ model.sheet.ranges?.push(nextRangeEntity);
132
+ } else {
133
+ model.sheet.ranges?.splice(index, 1, nextRangeEntity);
134
+ }
135
+ }
136
+ break;
137
+ case 'style':
138
+ if (action.value === 'unset') {
139
+ const index = model.sheet.ranges?.findIndex((range) => range.key === action.key);
140
+ if (index >= 0) {
141
+ model.sheet.ranges?.splice(index, 1);
142
+ }
143
+ } else if (range || cursor) {
144
+ const nextRange = range ? { from: range.from, to: range.to ?? range.from } : { from: cursor, to: cursor };
145
+ model.sheet.ranges?.push({
146
+ range: nextRange as Range['range'],
147
+ key: action.key,
148
+ value: action.value,
149
+ });
150
+ }
151
+ break;
152
+ case 'comment': {
153
+ // TODO(Zan): We shouldn't hardcode the action ID.
154
+ void dispatch({
155
+ action: 'dxos.org/plugin/thread/action/create',
156
+ data: {
157
+ cursor: action.value,
158
+ name: action.cellContent,
159
+ subject: model.sheet,
160
+ },
161
+ });
162
+ }
163
+ }
164
+ },
165
+ [model.sheet, range, cursor, dispatch],
166
+ );
107
167
 
108
168
  return (
109
- <ToolbarContextProvider onAction={onAction}>
169
+ <ToolbarContextProvider onAction={handleAction}>
110
170
  <NaturalToolbar.Root
111
171
  classNames={[
112
172
  ...(role === 'section'
@@ -126,61 +186,39 @@ const ToolbarRoot = ({ children, onAction, role, classNames }: ToolbarProps) =>
126
186
  type ButtonProps<T> = {
127
187
  value: T;
128
188
  icon: string;
129
- getState: (state: Formatting) => boolean;
130
- disabled?: (state: Formatting) => boolean;
189
+ disabled?: (state: Range) => boolean;
131
190
  };
132
191
 
133
192
  //
134
193
  // Alignment
135
194
  //
136
195
 
137
- const formatOptions: ButtonProps<FormatValue>[] = [
138
- { value: 'date', icon: 'ph--calendar--regular', getState: (state) => false },
139
- { value: 'currency', icon: 'ph--currency-dollar--regular', getState: (state) => false },
140
- ];
141
-
142
- const Format = () => {
143
- const { onAction } = useToolbarContext('Format');
144
- const { t } = useTranslation(SHEET_PLUGIN);
145
-
146
- return (
147
- <NaturalToolbar.ToggleGroup
148
- type='single'
149
- // value={cellStyles.filter(({ getState }) => state && getState(state)).map(({ type }) => type)}
150
- >
151
- {formatOptions.map(({ value, getState, icon }) => (
152
- <ToolbarItem
153
- itemType='toggleGroupItem'
154
- key={value}
155
- value={value}
156
- icon={icon}
157
- onClick={() => onAction?.({ type: 'format', value })}
158
- >
159
- {t(`toolbar ${value} label`)}
160
- </ToolbarItem>
161
- ))}
162
- </NaturalToolbar.ToggleGroup>
163
- );
164
- };
165
-
166
196
  const alignmentOptions: ButtonProps<AlignValue>[] = [
167
- { value: 'left', icon: 'ph--text-align-left--regular', getState: (state) => false },
168
- { value: 'center', icon: 'ph--text-align-center--regular', getState: (state) => false },
169
- { value: 'right', icon: 'ph--text-align-right--regular', getState: (state) => false },
197
+ { value: 'start', icon: 'ph--text-align-left--regular' },
198
+ { value: 'center', icon: 'ph--text-align-center--regular' },
199
+ { value: 'end', icon: 'ph--text-align-right--regular' },
170
200
  ];
171
201
 
172
202
  const Alignment = () => {
203
+ const { cursor, model } = useSheetContext();
173
204
  const { onAction } = useToolbarContext('Alignment');
174
205
  const { t } = useTranslation(SHEET_PLUGIN);
175
206
 
207
+ const value = useMemo(
208
+ () =>
209
+ cursor
210
+ ? model.sheet.ranges?.find(({ range, key }) => key === 'alignment' && inRange(range, cursor))?.value
211
+ : undefined,
212
+ [cursor, model.sheet.ranges],
213
+ );
214
+
176
215
  return (
177
216
  <NaturalToolbar.ToggleGroup
178
217
  type='single'
179
- // value={cellStyles.filter(({ getState }) => state && getState(state)).map(({ type }) => type)}
180
- // disabled={state?.blockType === 'codeblock'}
181
- onValueChange={(value: AlignValue) => onAction?.({ type: 'align', value })}
218
+ value={value}
219
+ onValueChange={(value: AlignValue) => onAction?.({ key: 'align', value })}
182
220
  >
183
- {alignmentOptions.map(({ value, getState, icon }) => (
221
+ {alignmentOptions.map(({ value, icon }) => (
184
222
  <ToolbarItem itemType='toggleGroupItem' key={value} value={value} icon={icon}>
185
223
  {t(`toolbar ${value} label`)}
186
224
  </ToolbarItem>
@@ -189,23 +227,34 @@ const Alignment = () => {
189
227
  );
190
228
  };
191
229
 
192
- const styleOptions: ButtonProps<StyleValue>[] = [
193
- { value: 'highlight', icon: 'ph--highlighter--regular', getState: (state) => false },
194
- ];
230
+ const styleOptions: ButtonProps<StyleValue>[] = [{ value: 'highlight', icon: 'ph--highlighter--regular' }];
195
231
 
196
232
  const Styles = () => {
233
+ const { cursor, model } = useSheetContext();
197
234
  const { onAction } = useToolbarContext('Styles');
198
235
  const { t } = useTranslation(SHEET_PLUGIN);
199
236
 
237
+ const activeValues = useMemo(
238
+ () =>
239
+ cursor
240
+ ? model.sheet.ranges
241
+ ?.filter(({ range, key }) => key === 'style' && inRange(range, cursor))
242
+ .reduce((acc, { value }) => {
243
+ acc.add(value);
244
+ return acc;
245
+ }, new Set())
246
+ : undefined,
247
+ [cursor, model.sheet.ranges],
248
+ );
249
+
200
250
  return (
201
251
  <>
202
- {styleOptions.map(({ value, getState, icon }) => (
252
+ {styleOptions.map(({ value, icon }) => (
203
253
  <ToolbarItem
204
254
  itemType='toggle'
205
255
  key={value}
206
- onPressedChange={(nextPressed: boolean) =>
207
- onAction?.({ type: 'style', value: nextPressed ? 'highlight' : 'unset' })
208
- }
256
+ pressed={activeValues?.has(value)}
257
+ onPressedChange={(nextPressed: boolean) => onAction?.({ key: 'style', value: nextPressed ? value : 'unset' })}
209
258
  icon={icon}
210
259
  >
211
260
  {t(`toolbar ${value} label`)}
@@ -256,8 +305,8 @@ const Actions = () => {
256
305
  return;
257
306
  }
258
307
  return onAction?.({
259
- type: 'comment',
260
- anchor: addressToIndex(model.sheet, cursor),
308
+ key: 'comment',
309
+ value: addressToIndex(model.sheet, cursor),
261
310
  cellContent: model.getCellText(cursor),
262
311
  });
263
312
  }}
@@ -272,7 +321,6 @@ export const Toolbar = {
272
321
  Root: ToolbarRoot,
273
322
  Separator: ToolbarSeparator,
274
323
  Alignment,
275
- Format,
276
324
  Styles,
277
325
  Actions,
278
326
  };
package/src/defs/index.ts CHANGED
@@ -4,3 +4,4 @@
4
4
 
5
5
  export * from './types';
6
6
  export * from './util';
7
+ export * from './sheet-range-types';