@dxos/plugin-sheet 0.6.11-staging.e6894a4 → 0.6.12-main.5cc132e

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 (107) hide show
  1. package/dist/lib/browser/{SheetContainer-4XOKHKKZ.mjs → SheetContainer-Y7ZMFBAP.mjs} +582 -121
  2. package/dist/lib/browser/SheetContainer-Y7ZMFBAP.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-P7SSL3EG.mjs → chunk-GNNVBNCX.mjs} +61 -53
  4. package/dist/lib/browser/chunk-GNNVBNCX.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-FWGRE3EG.mjs → chunk-PGKZPKUD.mjs} +2 -2
  6. package/dist/lib/browser/chunk-VBF7YENS.mjs +8 -0
  7. package/dist/lib/browser/{chunk-FUAGSXA4.mjs → chunk-WUPTZUTX.mjs} +6 -3
  8. package/dist/lib/browser/chunk-WUPTZUTX.mjs.map +7 -0
  9. package/dist/lib/browser/index.mjs +29 -18
  10. package/dist/lib/browser/index.mjs.map +3 -3
  11. package/dist/lib/browser/meta.json +1 -1
  12. package/dist/lib/browser/testing.mjs +3 -3
  13. package/dist/lib/browser/types.mjs +1 -1
  14. package/dist/lib/node/{SheetContainer-IQT6TR4Z.cjs → SheetContainer-KEOKUKAQ.cjs} +528 -79
  15. package/dist/lib/node/SheetContainer-KEOKUKAQ.cjs.map +7 -0
  16. package/dist/lib/node/{chunk-5EPCDAZC.cjs → chunk-57PB2HPY.cjs} +5 -5
  17. package/dist/lib/node/{chunk-727C6YNP.cjs → chunk-6LWBQAQZ.cjs} +9 -9
  18. package/dist/lib/node/{chunk-DSYKOI4E.cjs → chunk-VJU3NPUJ.cjs} +8 -5
  19. package/dist/lib/node/chunk-VJU3NPUJ.cjs.map +7 -0
  20. package/dist/lib/node/{chunk-SVAIIXWQ.cjs → chunk-ZRQZFV5T.cjs} +76 -63
  21. package/dist/lib/node/chunk-ZRQZFV5T.cjs.map +7 -0
  22. package/dist/lib/node/index.cjs +43 -33
  23. package/dist/lib/node/index.cjs.map +3 -3
  24. package/dist/lib/node/meta.json +1 -1
  25. package/dist/lib/node/testing.cjs +6 -6
  26. package/dist/lib/node/types.cjs +9 -9
  27. package/dist/lib/node/types.cjs.map +1 -1
  28. package/dist/lib/node-esm/SheetContainer-Y7ZMFBAP.mjs +2231 -0
  29. package/dist/lib/node-esm/SheetContainer-Y7ZMFBAP.mjs.map +7 -0
  30. package/dist/lib/node-esm/chunk-GNNVBNCX.mjs +3243 -0
  31. package/dist/lib/node-esm/chunk-GNNVBNCX.mjs.map +7 -0
  32. package/dist/lib/node-esm/chunk-JRL5LGCE.mjs +18 -0
  33. package/dist/lib/node-esm/chunk-JRL5LGCE.mjs.map +7 -0
  34. package/dist/lib/node-esm/chunk-PGKZPKUD.mjs +175 -0
  35. package/dist/lib/node-esm/chunk-PGKZPKUD.mjs.map +7 -0
  36. package/dist/lib/node-esm/chunk-VBF7YENS.mjs +8 -0
  37. package/dist/lib/node-esm/chunk-VBF7YENS.mjs.map +7 -0
  38. package/dist/lib/node-esm/chunk-WUPTZUTX.mjs +85 -0
  39. package/dist/lib/node-esm/chunk-WUPTZUTX.mjs.map +7 -0
  40. package/dist/lib/node-esm/index.mjs +257 -0
  41. package/dist/lib/node-esm/index.mjs.map +7 -0
  42. package/dist/lib/node-esm/meta.json +1 -0
  43. package/dist/lib/node-esm/meta.mjs +9 -0
  44. package/dist/lib/node-esm/meta.mjs.map +7 -0
  45. package/dist/lib/node-esm/testing.mjs +92 -0
  46. package/dist/lib/node-esm/testing.mjs.map +7 -0
  47. package/dist/lib/node-esm/types.mjs +22 -0
  48. package/dist/lib/node-esm/types.mjs.map +7 -0
  49. package/dist/types/src/SheetPlugin.d.ts.map +1 -1
  50. package/dist/types/src/components/Sheet/Sheet.d.ts.map +1 -1
  51. package/dist/types/src/components/Sheet/Sheet.stories.d.ts.map +1 -1
  52. package/dist/types/src/components/Sheet/decorations.d.ts +24 -0
  53. package/dist/types/src/components/Sheet/decorations.d.ts.map +1 -0
  54. package/dist/types/src/components/Sheet/formatting.d.ts.map +1 -1
  55. package/dist/types/src/components/Sheet/sheet-context.d.ts +2 -0
  56. package/dist/types/src/components/Sheet/sheet-context.d.ts.map +1 -1
  57. package/dist/types/src/components/Sheet/threads.d.ts +2 -0
  58. package/dist/types/src/components/Sheet/threads.d.ts.map +1 -0
  59. package/dist/types/src/components/SheetContainer.d.ts +2 -3
  60. package/dist/types/src/components/SheetContainer.d.ts.map +1 -1
  61. package/dist/types/src/components/Toolbar/Toolbar.d.ts +19 -3
  62. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  63. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts +17 -12
  64. package/dist/types/src/components/Toolbar/Toolbar.stories.d.ts.map +1 -1
  65. package/dist/types/src/components/index.d.ts +1 -2
  66. package/dist/types/src/components/index.d.ts.map +1 -1
  67. package/dist/types/src/model/index.d.ts +1 -0
  68. package/dist/types/src/model/index.d.ts.map +1 -1
  69. package/dist/types/src/model/model.d.ts +0 -16
  70. package/dist/types/src/model/model.d.ts.map +1 -1
  71. package/dist/types/src/model/util.d.ts +24 -0
  72. package/dist/types/src/model/util.d.ts.map +1 -1
  73. package/dist/types/src/translations.d.ts +17 -12
  74. package/dist/types/src/translations.d.ts.map +1 -1
  75. package/dist/types/src/types.d.ts +72 -2
  76. package/dist/types/src/types.d.ts.map +1 -1
  77. package/package.json +36 -32
  78. package/src/SheetPlugin.tsx +19 -20
  79. package/src/components/CellEditor/extension.test.ts +1 -2
  80. package/src/components/ComputeGraph/graph.browser.test.ts +1 -2
  81. package/src/components/Sheet/Sheet.stories.tsx +11 -9
  82. package/src/components/Sheet/Sheet.tsx +57 -29
  83. package/src/components/Sheet/decorations.ts +62 -0
  84. package/src/components/Sheet/formatting.ts +3 -3
  85. package/src/components/Sheet/sheet-context.tsx +9 -1
  86. package/src/components/Sheet/threads.tsx +201 -0
  87. package/src/components/SheetContainer.tsx +72 -20
  88. package/src/components/Toolbar/Toolbar.stories.tsx +5 -10
  89. package/src/components/Toolbar/Toolbar.tsx +54 -12
  90. package/src/model/index.ts +1 -0
  91. package/src/model/model.browser.test.ts +1 -2
  92. package/src/model/model.ts +11 -46
  93. package/src/model/types.test.ts +1 -2
  94. package/src/model/util.ts +67 -0
  95. package/src/translations.ts +6 -1
  96. package/src/types.ts +26 -3
  97. package/dist/lib/browser/SheetContainer-4XOKHKKZ.mjs.map +0 -7
  98. package/dist/lib/browser/chunk-FUAGSXA4.mjs.map +0 -7
  99. package/dist/lib/browser/chunk-P7SSL3EG.mjs.map +0 -7
  100. package/dist/lib/browser/chunk-YPU3R7FA.mjs +0 -8
  101. package/dist/lib/node/SheetContainer-IQT6TR4Z.cjs.map +0 -7
  102. package/dist/lib/node/chunk-DSYKOI4E.cjs.map +0 -7
  103. package/dist/lib/node/chunk-SVAIIXWQ.cjs.map +0 -7
  104. /package/dist/lib/browser/{chunk-FWGRE3EG.mjs.map → chunk-PGKZPKUD.mjs.map} +0 -0
  105. /package/dist/lib/browser/{chunk-YPU3R7FA.mjs.map → chunk-VBF7YENS.mjs.map} +0 -0
  106. /package/dist/lib/node/{chunk-5EPCDAZC.cjs.map → chunk-57PB2HPY.cjs.map} +0 -0
  107. /package/dist/lib/node/{chunk-727C6YNP.cjs.map → chunk-6LWBQAQZ.cjs.map} +0 -0
@@ -26,16 +26,20 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
- var SheetContainer_IQT6TR4Z_exports = {};
30
- __export(SheetContainer_IQT6TR4Z_exports, {
31
- default: () => SheetContainer_default
29
+ var SheetContainer_KEOKUKAQ_exports = {};
30
+ __export(SheetContainer_KEOKUKAQ_exports, {
31
+ default: () => SheetContainer_default,
32
+ sectionToolbarLayout: () => sectionToolbarLayout
32
33
  });
33
- module.exports = __toCommonJS(SheetContainer_IQT6TR4Z_exports);
34
- var import_chunk_727C6YNP = require("./chunk-727C6YNP.cjs");
35
- var import_chunk_SVAIIXWQ = require("./chunk-SVAIIXWQ.cjs");
36
- var import_chunk_DSYKOI4E = require("./chunk-DSYKOI4E.cjs");
34
+ module.exports = __toCommonJS(SheetContainer_KEOKUKAQ_exports);
35
+ var import_chunk_6LWBQAQZ = require("./chunk-6LWBQAQZ.cjs");
36
+ var import_chunk_ZRQZFV5T = require("./chunk-ZRQZFV5T.cjs");
37
+ var import_chunk_VJU3NPUJ = require("./chunk-VJU3NPUJ.cjs");
37
38
  var import_chunk_BJ6ZD7MN = require("./chunk-BJ6ZD7MN.cjs");
38
39
  var import_react = __toESM(require("react"));
40
+ var import_app_framework = require("@dxos/app-framework");
41
+ var import_echo = require("@dxos/react-client/echo");
42
+ var import_react_ui_attention = require("@dxos/react-ui-attention");
39
43
  var import_react_ui_theme = require("@dxos/react-ui-theme");
40
44
  var import_core = require("@dnd-kit/core");
41
45
  var import_modifiers = require("@dnd-kit/modifiers");
@@ -46,18 +50,26 @@ var import_react3 = __toESM(require("react"));
46
50
  var import_react_dom = require("react-dom");
47
51
  var import_react_resize_detector = require("react-resize-detector");
48
52
  var import_async = require("@dxos/async");
49
- var import_echo = require("@dxos/client/echo");
53
+ var import_echo2 = require("@dxos/client/echo");
50
54
  var import_log = require("@dxos/log");
51
- var import_react_ui_attention = require("@dxos/react-ui-attention");
55
+ var import_react_ui_attention2 = require("@dxos/react-ui-attention");
52
56
  var import_react_ui_theme2 = require("@dxos/react-ui-theme");
53
57
  var import_react4 = require("react");
54
58
  var import_react5 = require("react");
55
59
  var import_react6 = __toESM(require("react"));
56
60
  var import_invariant = require("@dxos/invariant");
57
- var import_echo2 = require("@dxos/react-client/echo");
58
- var import_view = require("@codemirror/view");
61
+ var import_echo3 = require("@dxos/react-client/echo");
62
+ var import_echo_schema = require("@dxos/echo-schema");
63
+ var import_signals_core = require("@preact/signals-core");
59
64
  var import_react7 = __toESM(require("react"));
65
+ var import_app_framework2 = require("@dxos/app-framework");
66
+ var import_async2 = require("@dxos/async");
67
+ var import_echo4 = require("@dxos/react-client/echo");
60
68
  var import_react_ui = require("@dxos/react-ui");
69
+ var import_react_ui_theme3 = require("@dxos/react-ui-theme");
70
+ var import_view = require("@codemirror/view");
71
+ var import_react8 = __toESM(require("react"));
72
+ var import_react_ui2 = require("@dxos/react-ui");
61
73
  var import_react_ui_editor = require("@dxos/react-ui-editor");
62
74
  var import_autocomplete = require("@codemirror/autocomplete");
63
75
  var import_language = require("@codemirror/language");
@@ -65,7 +77,15 @@ var import_state = require("@codemirror/state");
65
77
  var import_view2 = require("@codemirror/view");
66
78
  var import_highlight = require("@lezer/highlight");
67
79
  var import_codemirror_lang_spreadsheet = require("codemirror-lang-spreadsheet");
68
- var import_react_ui_theme3 = require("@dxos/react-ui-theme");
80
+ var import_react_ui_theme4 = require("@dxos/react-ui-theme");
81
+ var import_react9 = require("@phosphor-icons/react");
82
+ var import_react_context = require("@radix-ui/react-context");
83
+ var import_react10 = __toESM(require("react"));
84
+ var import_react_ui3 = require("@dxos/react-ui");
85
+ var import_util = require("@dxos/util");
86
+ var import_react11 = __toESM(require("react"));
87
+ var import_react_ui4 = require("@dxos/react-ui");
88
+ var import_react_ui_theme5 = require("@dxos/react-ui-theme");
69
89
  var axisWidth = "calc(var(--rail-size)-2px)";
70
90
  var axisHeight = 34;
71
91
  var minWidth = 40;
@@ -182,12 +202,12 @@ var getCellAtPointer = (event) => {
182
202
  if (root) {
183
203
  const value = root.dataset[CELL_DATA_KEY];
184
204
  if (value) {
185
- return (0, import_chunk_SVAIIXWQ.addressFromA1Notation)(value);
205
+ return (0, import_chunk_ZRQZFV5T.addressFromA1Notation)(value);
186
206
  }
187
207
  }
188
208
  };
189
209
  var getCellElement = (root, cell) => {
190
- const pos = (0, import_chunk_SVAIIXWQ.addressToA1Notation)(cell);
210
+ const pos = (0, import_chunk_ZRQZFV5T.addressToA1Notation)(cell);
191
211
  return root.querySelector(`[data-${CELL_DATA_KEY}="${pos}"]`);
192
212
  };
193
213
  var handleNav = (ev, cursor, range, size) => {
@@ -315,7 +335,7 @@ var useRangeSelect = (cb) => {
315
335
  const onMouseMove = (ev) => {
316
336
  if (from) {
317
337
  let current = getCellAtPointer(ev);
318
- if ((0, import_chunk_SVAIIXWQ.posEquals)(current, from)) {
338
+ if ((0, import_chunk_ZRQZFV5T.posEquals)(current, from)) {
319
339
  current = void 0;
320
340
  }
321
341
  setTo(current);
@@ -328,7 +348,7 @@ var useRangeSelect = (cb) => {
328
348
  const onMouseUp = (ev) => {
329
349
  if (from) {
330
350
  let current = getCellAtPointer(ev);
331
- if ((0, import_chunk_SVAIIXWQ.posEquals)(current, from)) {
351
+ if ((0, import_chunk_ZRQZFV5T.posEquals)(current, from)) {
332
352
  current = void 0;
333
353
  }
334
354
  setFrom(void 0);
@@ -351,6 +371,42 @@ var useRangeSelect = (cb) => {
351
371
  }
352
372
  };
353
373
  };
374
+ var createDecorations = () => {
375
+ const { decorations } = (0, import_echo_schema.create)({
376
+ decorations: {}
377
+ });
378
+ const addDecoration = (cellIndex, decorator) => {
379
+ decorations[cellIndex] = [
380
+ ...decorations[cellIndex] || [],
381
+ decorator
382
+ ];
383
+ };
384
+ const removeDecoration = (cellIndex, type) => {
385
+ if (type) {
386
+ decorations[cellIndex] = (decorations[cellIndex] || []).filter((d) => d.type !== type);
387
+ } else {
388
+ delete decorations[cellIndex];
389
+ }
390
+ };
391
+ const getDecorationsForCell = (cellIndex) => {
392
+ return decorations[cellIndex];
393
+ };
394
+ const getAllDecorations = () => {
395
+ const result = [];
396
+ for (const decoratorArray of Object.values(decorations)) {
397
+ for (const decorator of decoratorArray) {
398
+ result.push(decorator);
399
+ }
400
+ }
401
+ return result;
402
+ };
403
+ return {
404
+ addDecoration,
405
+ removeDecoration,
406
+ getDecorationsForCell,
407
+ getAllDecorations
408
+ };
409
+ };
354
410
  var FormattingModel = class {
355
411
  constructor(model) {
356
412
  this.model = model;
@@ -364,14 +420,14 @@ var FormattingModel = class {
364
420
  return {};
365
421
  }
366
422
  const locales = void 0;
367
- const idx = this.model.addressToIndex(cell);
423
+ const idx = (0, import_chunk_ZRQZFV5T.addressToIndex)(this.model.sheet, cell);
368
424
  let formatting = this.model.sheet.formatting?.[idx] ?? {};
369
425
  const classNames = [
370
426
  ...formatting?.classNames ?? []
371
427
  ];
372
428
  for (const [idx2, _formatting] of Object.entries(this.model.sheet.formatting)) {
373
- const range = this.model.rangeFromIndex(idx2);
374
- if ((0, import_chunk_SVAIIXWQ.inRange)(range, cell)) {
429
+ const range = (0, import_chunk_ZRQZFV5T.rangeFromIndex)(this.model.sheet, idx2);
430
+ if ((0, import_chunk_ZRQZFV5T.inRange)(range, cell)) {
375
431
  if (_formatting.classNames) {
376
432
  classNames.push(..._formatting.classNames);
377
433
  }
@@ -383,7 +439,7 @@ var FormattingModel = class {
383
439
  const defaultNumber = "justify-end font-mono";
384
440
  const type = formatting?.type ?? this.model.getValueType(cell);
385
441
  switch (type) {
386
- case import_chunk_DSYKOI4E.ValueTypeEnum.Boolean: {
442
+ case import_chunk_VJU3NPUJ.ValueTypeEnum.Boolean: {
387
443
  return {
388
444
  value: value.toLocaleString().toUpperCase(),
389
445
  classNames: [
@@ -392,7 +448,10 @@ var FormattingModel = class {
392
448
  ]
393
449
  };
394
450
  }
395
- case import_chunk_DSYKOI4E.ValueTypeEnum.Number: {
451
+ //
452
+ // Numbers.
453
+ //
454
+ case import_chunk_VJU3NPUJ.ValueTypeEnum.Number: {
396
455
  return {
397
456
  value: value.toLocaleString(locales),
398
457
  classNames: [
@@ -401,7 +460,7 @@ var FormattingModel = class {
401
460
  ]
402
461
  };
403
462
  }
404
- case import_chunk_DSYKOI4E.ValueTypeEnum.Percent: {
463
+ case import_chunk_VJU3NPUJ.ValueTypeEnum.Percent: {
405
464
  return {
406
465
  value: value * 100 + "%",
407
466
  classNames: [
@@ -410,7 +469,7 @@ var FormattingModel = class {
410
469
  ]
411
470
  };
412
471
  }
413
- case import_chunk_DSYKOI4E.ValueTypeEnum.Currency: {
472
+ case import_chunk_VJU3NPUJ.ValueTypeEnum.Currency: {
414
473
  return {
415
474
  value: value.toLocaleString(locales, {
416
475
  style: "currency",
@@ -424,21 +483,24 @@ var FormattingModel = class {
424
483
  ]
425
484
  };
426
485
  }
427
- case import_chunk_DSYKOI4E.ValueTypeEnum.DateTime: {
486
+ //
487
+ // Dates.
488
+ //
489
+ case import_chunk_VJU3NPUJ.ValueTypeEnum.DateTime: {
428
490
  const date = this.model.toLocalDate(value);
429
491
  return {
430
492
  value: date.toLocaleString(locales),
431
493
  classNames
432
494
  };
433
495
  }
434
- case import_chunk_DSYKOI4E.ValueTypeEnum.Date: {
496
+ case import_chunk_VJU3NPUJ.ValueTypeEnum.Date: {
435
497
  const date = this.model.toLocalDate(value);
436
498
  return {
437
499
  value: date.toLocaleDateString(locales),
438
500
  classNames
439
501
  };
440
502
  }
441
- case import_chunk_DSYKOI4E.ValueTypeEnum.Time: {
503
+ case import_chunk_VJU3NPUJ.ValueTypeEnum.Time: {
442
504
  const date = this.model.toLocalDate(value);
443
505
  return {
444
506
  value: date.toLocaleTimeString(locales),
@@ -461,7 +523,7 @@ var useSheetContext = () => {
461
523
  const context = (0, import_react6.useContext)(SheetContext);
462
524
  (0, import_invariant.invariant)(context, void 0, {
463
525
  F: __dxlog_file,
464
- L: 45,
526
+ L: 49,
465
527
  S: void 0,
466
528
  A: [
467
529
  "context",
@@ -472,12 +534,12 @@ var useSheetContext = () => {
472
534
  };
473
535
  var mapFormulaBindingToId = (functions) => (formula) => {
474
536
  return formula.replace(/([a-zA-Z0-9]+)\((.*)\)/g, (match, binding, args) => {
475
- if (import_chunk_SVAIIXWQ.defaultFunctions.find((fn2) => fn2.name === binding) || binding === "EDGE") {
537
+ if (import_chunk_ZRQZFV5T.defaultFunctions.find((fn2) => fn2.name === binding) || binding === "EDGE") {
476
538
  return match;
477
539
  }
478
540
  const fn = functions.find((fn2) => fn2.binding === binding);
479
541
  if (fn) {
480
- return `${(0, import_echo2.fullyQualifiedId)(fn)}(${args})`;
542
+ return `${(0, import_echo3.fullyQualifiedId)(fn)}(${args})`;
481
543
  } else {
482
544
  return match;
483
545
  }
@@ -489,7 +551,7 @@ var mapFormulaBindingFromId = (functions) => (formula) => {
489
551
  if (id.length !== OBJECT_ID_LENGTH) {
490
552
  return match;
491
553
  }
492
- const fn = functions.find((fn2) => (0, import_echo2.fullyQualifiedId)(fn2) === id);
554
+ const fn = functions.find((fn2) => (0, import_echo3.fullyQualifiedId)(fn2) === id);
493
555
  if (fn?.binding) {
494
556
  return `${fn.binding}(${args})`;
495
557
  } else {
@@ -498,16 +560,17 @@ var mapFormulaBindingFromId = (functions) => (formula) => {
498
560
  });
499
561
  };
500
562
  var SheetContextProvider = ({ children, sheet, space, readonly, onInfo, ...options }) => {
501
- const graph = (0, import_chunk_727C6YNP.useComputeGraph)(space, options);
563
+ const graph = (0, import_chunk_6LWBQAQZ.useComputeGraph)(space, options);
502
564
  const [cursor, setCursor] = (0, import_react6.useState)();
503
565
  const [range, setRange] = (0, import_react6.useState)();
504
566
  const [editing, setEditing] = (0, import_react6.useState)(false);
567
+ const decorations = (0, import_react6.useMemo)(() => createDecorations(), []);
505
568
  const [[model, formatting] = [], setModels] = (0, import_react6.useState)(void 0);
506
569
  (0, import_react6.useEffect)(() => {
507
570
  let model2;
508
571
  let formatting2;
509
572
  const t = setTimeout(async () => {
510
- model2 = new import_chunk_SVAIIXWQ.SheetModel(graph, sheet, space, {
573
+ model2 = new import_chunk_ZRQZFV5T.SheetModel(graph, sheet, space, {
511
574
  readonly,
512
575
  mapFormulaBindingToId,
513
576
  mapFormulaBindingFromId
@@ -541,10 +604,168 @@ var SheetContextProvider = ({ children, sheet, space, readonly, onInfo, ...optio
541
604
  editing,
542
605
  setEditing,
543
606
  // TODO(burdon): Change to event.
544
- onInfo
607
+ onInfo,
608
+ decorations
545
609
  }
546
610
  }, children);
547
611
  };
612
+ var CommentIndicator = () => {
613
+ return /* @__PURE__ */ import_react7.default.createElement("div", {
614
+ role: "none",
615
+ className: "absolute top-0 right-0 w-0 h-0 border-t-8 border-l-8 border-t-cmCommentSurface border-l-transparent"
616
+ });
617
+ };
618
+ var ThreadedCellWrapper = ({ children }) => {
619
+ const dispatch = (0, import_app_framework2.useIntentDispatcher)();
620
+ const [isHovered, setIsHovered] = import_react7.default.useState(true);
621
+ const { t } = (0, import_react_ui.useTranslation)(import_chunk_BJ6ZD7MN.SHEET_PLUGIN);
622
+ const handleClick = import_react7.default.useCallback((_event) => {
623
+ void dispatch({
624
+ action: import_app_framework2.LayoutAction.SET_LAYOUT,
625
+ data: {
626
+ element: "complementary",
627
+ state: true
628
+ }
629
+ });
630
+ }, [
631
+ dispatch
632
+ ]);
633
+ return /* @__PURE__ */ import_react7.default.createElement("div", {
634
+ role: "none",
635
+ className: (0, import_react_ui_theme3.mx)("relative h-full is-full"),
636
+ onMouseEnter: () => {
637
+ setIsHovered(true);
638
+ },
639
+ onMouseLeave: () => {
640
+ setIsHovered(false);
641
+ }
642
+ }, /* @__PURE__ */ import_react7.default.createElement(CommentIndicator, null), isHovered && /* @__PURE__ */ import_react7.default.createElement("div", {
643
+ className: "absolute inset-0 flex items-center justify-end pr-1"
644
+ }, /* @__PURE__ */ import_react7.default.createElement("button", {
645
+ className: "ch-button text-xs min-bs-0 p-1",
646
+ onClick: handleClick,
647
+ "aria-label": t("open comment for sheet cell")
648
+ }, /* @__PURE__ */ import_react7.default.createElement(import_react_ui.Icon, {
649
+ icon: "ph--chat--regular",
650
+ "aria-hidden": true
651
+ }))), children);
652
+ };
653
+ var createThreadDecoration = (cellIndex, threadId, sheetId) => {
654
+ return {
655
+ type: "comment",
656
+ cellIndex,
657
+ decorate: (props) => /* @__PURE__ */ import_react7.default.createElement(ThreadedCellWrapper, props)
658
+ };
659
+ };
660
+ var useUpdateCursorOnThreadSelection = () => {
661
+ const { setCursor, model } = useSheetContext();
662
+ const handleScrollIntoView = (0, import_react7.useCallback)(({ action, data }) => {
663
+ switch (action) {
664
+ case import_app_framework2.LayoutAction.SCROLL_INTO_VIEW: {
665
+ if (!data?.id || data?.cursor === void 0 || data?.id !== (0, import_echo4.fullyQualifiedId)(model.sheet)) {
666
+ return;
667
+ }
668
+ const cellAddress = (0, import_chunk_ZRQZFV5T.addressFromIndex)(model.sheet, data.cursor);
669
+ setCursor(cellAddress);
670
+ }
671
+ }
672
+ }, [
673
+ model.sheet,
674
+ setCursor
675
+ ]);
676
+ (0, import_app_framework2.useIntentResolver)(import_chunk_BJ6ZD7MN.SHEET_PLUGIN, handleScrollIntoView);
677
+ };
678
+ var useSelectThreadOnCursorChange = () => {
679
+ const { cursor, model } = useSheetContext();
680
+ const dispatch = (0, import_app_framework2.useIntentDispatcher)();
681
+ const activeThreads = (0, import_react7.useMemo)(() => model.sheet.threads?.filter((thread) => !!thread && thread.status === "active") ?? [], [
682
+ JSON.stringify(model.sheet.threads)
683
+ ]);
684
+ const activeThreadAddresses = (0, import_react7.useMemo)(() => activeThreads.map((thread) => thread.anchor).filter((anchor) => anchor !== void 0).map((anchor) => (0, import_chunk_ZRQZFV5T.addressFromIndex)(model.sheet, anchor)), [
685
+ activeThreads,
686
+ model.sheet
687
+ ]);
688
+ const selectClosestThread = (0, import_react7.useCallback)((cellAddress) => {
689
+ if (!cellAddress || !activeThreads) {
690
+ return;
691
+ }
692
+ const closestThreadAnchor = (0, import_chunk_ZRQZFV5T.closest)(cellAddress, activeThreadAddresses);
693
+ if (closestThreadAnchor) {
694
+ const closestThread = activeThreads.find((thread) => thread && thread.anchor === (0, import_chunk_ZRQZFV5T.addressToIndex)(model.sheet, closestThreadAnchor));
695
+ if (closestThread) {
696
+ void dispatch([
697
+ {
698
+ action: "dxos.org/plugin/thread/action/select",
699
+ data: {
700
+ current: (0, import_echo4.fullyQualifiedId)(closestThread)
701
+ }
702
+ }
703
+ ]);
704
+ }
705
+ }
706
+ }, [
707
+ dispatch,
708
+ activeThreads,
709
+ activeThreadAddresses,
710
+ model.sheet
711
+ ]);
712
+ const debounced = (0, import_react7.useMemo)(() => {
713
+ return (0, import_async2.debounce)((cursor2) => requestAnimationFrame(() => selectClosestThread(cursor2)), 50);
714
+ }, [
715
+ selectClosestThread
716
+ ]);
717
+ (0, import_react7.useEffect)(() => {
718
+ if (!cursor) {
719
+ return;
720
+ }
721
+ debounced(cursor);
722
+ }, [
723
+ cursor,
724
+ selectClosestThread
725
+ ]);
726
+ };
727
+ var useThreadDecorations = () => {
728
+ const { decorations, model } = useSheetContext();
729
+ const sheet = (0, import_react7.useMemo)(() => model.sheet, [
730
+ model.sheet
731
+ ]);
732
+ const sheetId = (0, import_react7.useMemo)(() => (0, import_echo4.fullyQualifiedId)(sheet), [
733
+ sheet
734
+ ]);
735
+ (0, import_react7.useEffect)(() => {
736
+ const unsubscribe = (0, import_signals_core.effect)(() => {
737
+ const activeThreadAnchors = /* @__PURE__ */ new Set();
738
+ if (!sheet.threads) {
739
+ return;
740
+ }
741
+ for (const thread of sheet.threads) {
742
+ if (!thread || thread.anchor === void 0 || thread.status === "resolved") {
743
+ continue;
744
+ }
745
+ activeThreadAnchors.add(thread.anchor);
746
+ const index = thread.anchor;
747
+ const existingDecorations = decorations.getDecorationsForCell(index);
748
+ if (!existingDecorations || !existingDecorations.some((d) => d.type === "comment")) {
749
+ decorations.addDecoration(index, createThreadDecoration(index, thread.id, sheetId));
750
+ }
751
+ }
752
+ for (const decoration of decorations.getAllDecorations()) {
753
+ if (decoration.type !== "comment") {
754
+ continue;
755
+ }
756
+ if (!activeThreadAnchors.has(decoration.cellIndex)) {
757
+ decorations.removeDecoration(decoration.cellIndex, "comment");
758
+ }
759
+ }
760
+ });
761
+ return () => unsubscribe();
762
+ });
763
+ };
764
+ var useThreads = () => {
765
+ useUpdateCursorOnThreadSelection();
766
+ useSelectThreadOnCursorChange();
767
+ useThreadDecorations();
768
+ };
548
769
  var getRelativeClientRect = (root, element) => {
549
770
  const rootRect = root.getBoundingClientRect();
550
771
  const elementRect = element.getBoundingClientRect();
@@ -635,7 +856,7 @@ var editorKeys = ({ onNav, onClose }) => {
635
856
  ]);
636
857
  };
637
858
  var CellEditor = ({ value, extension, autoFocus, onBlur }) => {
638
- const { themeMode } = (0, import_react_ui.useThemeContext)();
859
+ const { themeMode } = (0, import_react_ui2.useThemeContext)();
639
860
  const { parentRef } = (0, import_react_ui_editor.useTextEditor)(() => {
640
861
  return {
641
862
  autoFocus,
@@ -673,7 +894,7 @@ var CellEditor = ({ value, extension, autoFocus, onBlur }) => {
673
894
  }, [
674
895
  extension
675
896
  ]);
676
- return /* @__PURE__ */ import_react7.default.createElement("div", {
897
+ return /* @__PURE__ */ import_react8.default.createElement("div", {
677
898
  ref: parentRef,
678
899
  className: "flex w-full"
679
900
  });
@@ -788,7 +1009,7 @@ var sheetExtension = ({ functions = [] }) => {
788
1009
  // NOTE: Useful for debugging.
789
1010
  closeOnBlur: false,
790
1011
  icons: false,
791
- tooltipClass: () => (0, import_react_ui_theme3.mx)(
1012
+ tooltipClass: () => (0, import_react_ui_theme4.mx)(
792
1013
  // TODO(burdon): Factor out fragments.
793
1014
  // TODO(burdon): Size to make width same as column.
794
1015
  "!-left-[1px] !top-[33px] !-m-0 border !border-t-0 [&>ul]:!min-w-[198px]",
@@ -886,8 +1107,7 @@ var fragments = {
886
1107
  axis: "bg-axisSurface text-axisText text-xs select-none",
887
1108
  axisSelected: "bg-attention text-baseText",
888
1109
  cell: "bg-gridCell",
889
- cellSelected: "bg-gridCellSelected text-baseText border !border-accentSurface",
890
- border: "border-gridLine"
1110
+ cellSelected: "bg-gridCellSelected text-baseText border !border-accentSurface"
891
1111
  };
892
1112
  var SheetRoot = ({ children, ...props }) => {
893
1113
  return /* @__PURE__ */ import_react3.default.createElement(SheetContextProvider, props, children);
@@ -895,6 +1115,7 @@ var SheetRoot = ({ children, ...props }) => {
895
1115
  var SheetMain = /* @__PURE__ */ (0, import_react3.forwardRef)(({ classNames, numRows, numColumns }, forwardRef2) => {
896
1116
  const { model, cursor, setCursor, setRange, setEditing } = useSheetContext();
897
1117
  const { rowsRef, columnsRef, contentRef } = useScrollHandlers();
1118
+ useThreads();
898
1119
  const [rows, setRows] = (0, import_react3.useState)([
899
1120
  ...model.sheet.rows
900
1121
  ]);
@@ -902,10 +1123,10 @@ var SheetMain = /* @__PURE__ */ (0, import_react3.forwardRef)(({ classNames, num
902
1123
  ...model.sheet.columns
903
1124
  ]);
904
1125
  (0, import_react3.useEffect)(() => {
905
- const rowsAccessor = (0, import_echo.createDocAccessor)(model.sheet, [
1126
+ const rowsAccessor = (0, import_echo2.createDocAccessor)(model.sheet, [
906
1127
  "rows"
907
1128
  ]);
908
- const columnsAccessor = (0, import_echo.createDocAccessor)(model.sheet, [
1129
+ const columnsAccessor = (0, import_echo2.createDocAccessor)(model.sheet, [
909
1130
  "columns"
910
1131
  ]);
911
1132
  const handleUpdate = (0, import_async.debounce)(() => {
@@ -933,22 +1154,22 @@ var SheetMain = /* @__PURE__ */ (0, import_react3.forwardRef)(({ classNames, num
933
1154
  columns
934
1155
  ]);
935
1156
  const handleMoveRows = (from, to, num = 1) => {
936
- const cursorIdx = cursor ? model.addressToIndex(cursor) : void 0;
1157
+ const cursorIdx = cursor ? (0, import_chunk_ZRQZFV5T.addressToIndex)(model.sheet, cursor) : void 0;
937
1158
  const [rows2] = model.sheet.rows.splice(from, num);
938
1159
  model.sheet.rows.splice(to, 0, rows2);
939
1160
  if (cursorIdx) {
940
- setCursor(model.addressFromIndex(cursorIdx));
1161
+ setCursor((0, import_chunk_ZRQZFV5T.addressFromIndex)(model.sheet, cursorIdx));
941
1162
  }
942
1163
  setRows([
943
1164
  ...model.sheet.rows
944
1165
  ]);
945
1166
  };
946
1167
  const handleMoveColumns = (from, to, num = 1) => {
947
- const cursorIdx = cursor ? model.addressToIndex(cursor) : void 0;
1168
+ const cursorIdx = cursor ? (0, import_chunk_ZRQZFV5T.addressToIndex)(model.sheet, cursor) : void 0;
948
1169
  const columns2 = model.sheet.columns.splice(from, num);
949
1170
  model.sheet.columns.splice(to, 0, ...columns2);
950
1171
  if (cursorIdx) {
951
- setCursor(model.addressFromIndex(cursorIdx));
1172
+ setCursor((0, import_chunk_ZRQZFV5T.addressFromIndex)(model.sheet, cursorIdx));
952
1173
  }
953
1174
  setColumns([
954
1175
  ...model.sheet.columns
@@ -957,10 +1178,10 @@ var SheetMain = /* @__PURE__ */ (0, import_react3.forwardRef)(({ classNames, num
957
1178
  const [rowSizes, setRowSizes] = (0, import_react3.useState)();
958
1179
  const [columnSizes, setColumnSizes] = (0, import_react3.useState)();
959
1180
  (0, import_react3.useEffect)(() => {
960
- const rowAccessor = (0, import_echo.createDocAccessor)(model.sheet, [
1181
+ const rowAccessor = (0, import_echo2.createDocAccessor)(model.sheet, [
961
1182
  "rowMeta"
962
1183
  ]);
963
- const columnAccessor = (0, import_echo.createDocAccessor)(model.sheet, [
1184
+ const columnAccessor = (0, import_echo2.createDocAccessor)(model.sheet, [
964
1185
  "columnMeta"
965
1186
  ]);
966
1187
  const handleUpdate = (0, import_async.debounce)(() => {
@@ -1007,7 +1228,7 @@ var SheetMain = /* @__PURE__ */ (0, import_react3.forwardRef)(({ classNames, num
1007
1228
  };
1008
1229
  return /* @__PURE__ */ import_react3.default.createElement("div", {
1009
1230
  role: "none",
1010
- className: (0, import_react_ui_theme2.mx)("grid grid-cols-[calc(var(--rail-size)-2px)_1fr] grid-rows-[32px_1fr_32px] bs-full is-full overflow-hidden", fragments.border, classNames)
1231
+ className: (0, import_react_ui_theme2.mx)("grid grid-cols-[calc(var(--rail-size)-2px)_1fr] grid-rows-[32px_1fr_32px] bs-full is-full overflow-hidden", classNames)
1011
1232
  }, /* @__PURE__ */ import_react3.default.createElement(GridCorner, {
1012
1233
  onClick: () => {
1013
1234
  setCursor(void 0);
@@ -1142,7 +1363,7 @@ var SheetRows = /* @__PURE__ */ (0, import_react3.forwardRef)(({ rows, sizes, se
1142
1363
  return /* @__PURE__ */ import_react3.default.createElement("div", {
1143
1364
  className: "relative flex grow overflow-hidden"
1144
1365
  }, /* @__PURE__ */ import_react3.default.createElement("div", {
1145
- className: (0, import_react_ui_theme2.mx)("z-20 absolute inset-0 border-y pointer-events-none", fragments.border),
1366
+ className: (0, import_react_ui_theme2.mx)("z-20 absolute inset-0 border-y border-gridLine pointer-events-none"),
1146
1367
  style: {
1147
1368
  width: axisWidth
1148
1369
  }
@@ -1230,7 +1451,7 @@ var GridRowCell = ({ idx, index, label, size, resize, selected, onSelect, onResi
1230
1451
  ref: setNodeRef,
1231
1452
  ...attributes,
1232
1453
  ...listeners,
1233
- className: (0, import_react_ui_theme2.mx)("flex h-full items-center justify-center cursor-pointer", "border-t focus-visible:outline-none", fragments.border, fragments.axis, selected && fragments.axisSelected, isDragging && fragments.axisSelected),
1454
+ className: (0, import_react_ui_theme2.mx)("flex h-full items-center justify-center cursor-pointer", "border-t border-gridLine focus-visible:outline-none", fragments.axis, selected && fragments.axisSelected, isDragging && fragments.axisSelected),
1234
1455
  onClick: () => onSelect?.(index)
1235
1456
  }, /* @__PURE__ */ import_react3.default.createElement("span", {
1236
1457
  className: "flex w-full justify-center"
@@ -1276,7 +1497,7 @@ var SheetColumns = /* @__PURE__ */ (0, import_react3.forwardRef)(({ columns, siz
1276
1497
  return /* @__PURE__ */ import_react3.default.createElement("div", {
1277
1498
  className: "relative flex grow overflow-hidden"
1278
1499
  }, /* @__PURE__ */ import_react3.default.createElement("div", {
1279
- className: (0, import_react_ui_theme2.mx)("z-20 absolute inset-0 border-x pointer-events-none", fragments.border),
1500
+ className: (0, import_react_ui_theme2.mx)("z-20 absolute inset-0 border-x border-gridLine pointer-events-none"),
1280
1501
  style: {
1281
1502
  height: axisHeight
1282
1503
  }
@@ -1304,14 +1525,14 @@ var SheetColumns = /* @__PURE__ */ (0, import_react3.forwardRef)(({ columns, siz
1304
1525
  key: idx,
1305
1526
  idx,
1306
1527
  index,
1307
- label: (0, import_chunk_SVAIIXWQ.columnLetter)(index),
1528
+ label: (0, import_chunk_ZRQZFV5T.columnLetter)(index),
1308
1529
  size: sizes?.[idx] ?? defaultWidth,
1309
1530
  resize: index < columns.length - 1,
1310
1531
  selected: selected === index,
1311
1532
  onResize,
1312
1533
  onSelect
1313
1534
  }))), /* @__PURE__ */ (0, import_react_dom.createPortal)(/* @__PURE__ */ import_react3.default.createElement(import_core.DragOverlay, null, active && /* @__PURE__ */ import_react3.default.createElement(MovingOverlay, {
1314
- label: (0, import_chunk_SVAIIXWQ.columnLetter)(active.data.current.index)
1535
+ label: (0, import_chunk_ZRQZFV5T.columnLetter)(active.data.current.index)
1315
1536
  })), document.body))));
1316
1537
  });
1317
1538
  var GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, onResize }) => {
@@ -1367,7 +1588,7 @@ var GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, onR
1367
1588
  ref: setNodeRef,
1368
1589
  ...attributes,
1369
1590
  ...listeners,
1370
- className: (0, import_react_ui_theme2.mx)("flex h-full items-center justify-center cursor-pointer", "border-l focus-visible:outline-none", fragments.border, fragments.axis, selected && fragments.axisSelected, isDragging && fragments.axisSelected),
1591
+ className: (0, import_react_ui_theme2.mx)("flex h-full items-center justify-center cursor-pointer", "border-l border-gridLine focus-visible:outline-none", fragments.axis, selected && fragments.axisSelected, isDragging && fragments.axisSelected),
1371
1592
  onClick: () => onSelect?.(index)
1372
1593
  }, /* @__PURE__ */ import_react3.default.createElement("span", {
1373
1594
  className: "flex w-full justify-center"
@@ -1393,7 +1614,7 @@ var SheetGrid = /* @__PURE__ */ (0, import_react3.forwardRef)(({ size, rows, col
1393
1614
  id: model.id
1394
1615
  }, {
1395
1616
  F: __dxlog_file2,
1396
- L: 735,
1617
+ L: 737,
1397
1618
  S: void 0,
1398
1619
  C: (f, a) => f(...a)
1399
1620
  });
@@ -1510,18 +1731,18 @@ var SheetGrid = /* @__PURE__ */ (0, import_react3.forwardRef)(({ size, rows, col
1510
1731
  rowSizes,
1511
1732
  columnSizes
1512
1733
  });
1513
- const qualifiedSubjectId = (0, import_echo.fullyQualifiedId)(model.sheet);
1514
- const attendableAttrs = (0, import_react_ui_attention.createAttendableAttributes)(qualifiedSubjectId);
1515
- const attended = true;
1734
+ const id = (0, import_echo2.fullyQualifiedId)(model.sheet);
1735
+ const attendableAttrs = (0, import_react_ui_attention2.createAttendableAttributes)(id);
1736
+ const hasAttention = (0, import_react_ui_attention2.useHasAttention)(id);
1516
1737
  return /* @__PURE__ */ import_react3.default.createElement("div", {
1517
1738
  ref: containerRef,
1518
1739
  role: "grid",
1519
1740
  className: "relative flex grow overflow-hidden"
1520
1741
  }, /* @__PURE__ */ import_react3.default.createElement("div", {
1521
- className: (0, import_react_ui_theme2.mx)("z-20 absolute inset-0 border pointer-events-none", fragments.border)
1742
+ className: (0, import_react_ui_theme2.mx)("z-20 absolute inset-0 border border-gridLine pointer-events-none")
1522
1743
  }), /* @__PURE__ */ import_react3.default.createElement("div", {
1523
1744
  ref: scrollerRef,
1524
- className: (0, import_react_ui_theme2.mx)("grow", attended && "overflow-auto scrollbar-thin")
1745
+ className: (0, import_react_ui_theme2.mx)("grow", hasAttention && "overflow-auto scrollbar-thin")
1525
1746
  }, /* @__PURE__ */ import_react3.default.createElement("div", {
1526
1747
  className: "relative select-none",
1527
1748
  style: {
@@ -1545,9 +1766,9 @@ var SheetGrid = /* @__PURE__ */ (0, import_react3.forwardRef)(({ size, rows, col
1545
1766
  row,
1546
1767
  column
1547
1768
  };
1548
- const id = (0, import_chunk_SVAIIXWQ.addressToA1Notation)(cell);
1549
- const idx = model.addressToIndex(cell);
1550
- const active = (0, import_chunk_SVAIIXWQ.posEquals)(cursor, cell);
1769
+ const id2 = (0, import_chunk_ZRQZFV5T.addressToA1Notation)(cell);
1770
+ const idx = (0, import_chunk_ZRQZFV5T.addressToIndex)(model.sheet, cell);
1771
+ const active = (0, import_chunk_ZRQZFV5T.posEquals)(cursor, cell);
1551
1772
  if (active && editing) {
1552
1773
  const value = initialText.current ?? model.getCellText(cell) ?? "";
1553
1774
  const handleClose = (value2) => {
@@ -1588,8 +1809,8 @@ var SheetGrid = /* @__PURE__ */ (0, import_react3.forwardRef)(({ size, rows, col
1588
1809
  });
1589
1810
  }
1590
1811
  return /* @__PURE__ */ import_react3.default.createElement(SheetCell, {
1591
- key: id,
1592
- id,
1812
+ key: id2,
1813
+ id: id2,
1593
1814
  cell,
1594
1815
  active,
1595
1816
  style,
@@ -1627,13 +1848,27 @@ var SelectionOverlay = ({ root }) => {
1627
1848
  });
1628
1849
  };
1629
1850
  var SheetCell = ({ id, cell, style, active, onSelect }) => {
1630
- const { formatting, editing, setRange } = useSheetContext();
1851
+ const { formatting, editing, setRange, decorations, model: { sheet } } = useSheetContext();
1631
1852
  const { value, classNames } = formatting.getFormatting(cell);
1853
+ const decorationsForCell = decorations.getDecorationsForCell((0, import_chunk_ZRQZFV5T.addressToIndex)(sheet, cell)) ?? [];
1854
+ const decorationAddedClasses = (0, import_react3.useMemo)(() => decorationsForCell.flatMap((d) => d.classNames ?? []), [
1855
+ decorationsForCell
1856
+ ]);
1857
+ const decoratedContent = decorationsForCell.reduce((children, { decorate }) => {
1858
+ if (!decorate) {
1859
+ return children;
1860
+ }
1861
+ const DecoratorComponent = decorate;
1862
+ return /* @__PURE__ */ import_react3.default.createElement(DecoratorComponent, null, children);
1863
+ }, /* @__PURE__ */ import_react3.default.createElement("div", {
1864
+ role: "none",
1865
+ className: (0, import_react_ui_theme2.mx)("flex flex-grow bs-full is-full px-2 items-center truncate cursor-pointer", ...decorationAddedClasses)
1866
+ }, value));
1632
1867
  return /* @__PURE__ */ import_react3.default.createElement("div", {
1633
1868
  [`data-${CELL_DATA_KEY}`]: id,
1634
1869
  role: "cell",
1635
1870
  style,
1636
- className: (0, import_react_ui_theme2.mx)("flex w-full h-full truncate items-center border cursor-pointer", "px-2 py-1", fragments.cell, fragments.border, active && [
1871
+ className: (0, import_react_ui_theme2.mx)("border border-gridLine cursor-pointer", fragments.cell, active && [
1637
1872
  "z-20",
1638
1873
  fragments.cellSelected
1639
1874
  ], classNames),
@@ -1647,14 +1882,14 @@ var SheetCell = ({ id, cell, style, active, onSelect }) => {
1647
1882
  }
1648
1883
  },
1649
1884
  onDoubleClick: () => onSelect?.(cell, true)
1650
- }, value);
1885
+ }, decoratedContent);
1651
1886
  };
1652
1887
  var GridCellEditor = ({ style, value, onNav, onClose }) => {
1653
1888
  const { model, range } = useSheetContext();
1654
1889
  const notifier = (0, import_react3.useRef)();
1655
1890
  (0, import_react3.useEffect)(() => {
1656
1891
  if (range) {
1657
- notifier.current?.((0, import_chunk_SVAIIXWQ.rangeToA1Notation)(range));
1892
+ notifier.current?.((0, import_chunk_ZRQZFV5T.rangeToA1Notation)(range));
1658
1893
  }
1659
1894
  }, [
1660
1895
  range
@@ -1696,12 +1931,12 @@ var SheetStatusBar = () => {
1696
1931
  }
1697
1932
  }
1698
1933
  return /* @__PURE__ */ import_react3.default.createElement("div", {
1699
- className: (0, import_react_ui_theme2.mx)("flex shrink-0 justify-between items-center px-4 py-1 text-sm border-x", fragments.border)
1934
+ className: (0, import_react_ui_theme2.mx)("flex shrink-0 justify-between items-center px-4 py-1 text-sm border-x border-gridLine")
1700
1935
  }, /* @__PURE__ */ import_react3.default.createElement("div", {
1701
1936
  className: "flex gap-4 items-center"
1702
1937
  }, /* @__PURE__ */ import_react3.default.createElement("div", {
1703
1938
  className: "flex w-16 items-center font-mono"
1704
- }, range && (0, import_chunk_SVAIIXWQ.rangeToA1Notation)(range) || cursor && (0, import_chunk_SVAIIXWQ.addressToA1Notation)(cursor)), /* @__PURE__ */ import_react3.default.createElement("div", {
1939
+ }, range && (0, import_chunk_ZRQZFV5T.rangeToA1Notation)(range) || cursor && (0, import_chunk_ZRQZFV5T.addressToA1Notation)(cursor)), /* @__PURE__ */ import_react3.default.createElement("div", {
1705
1940
  className: "flex gap-2 items-center"
1706
1941
  }, /* @__PURE__ */ import_react3.default.createElement(import_react2.Function, {
1707
1942
  className: (0, import_react_ui_theme2.mx)("text-greenText", isFormula ? "visible" : "invisible")
@@ -1713,7 +1948,7 @@ var SheetDebug = () => {
1713
1948
  const { model, cursor, range } = useSheetContext();
1714
1949
  const [, forceUpdate] = (0, import_react3.useState)({});
1715
1950
  (0, import_react3.useEffect)(() => {
1716
- const accessor = (0, import_echo.createDocAccessor)(model.sheet, []);
1951
+ const accessor = (0, import_echo2.createDocAccessor)(model.sheet, []);
1717
1952
  const handleUpdate = () => forceUpdate({});
1718
1953
  accessor.handle.addListener("change", handleUpdate);
1719
1954
  handleUpdate();
@@ -1724,7 +1959,7 @@ var SheetDebug = () => {
1724
1959
  model
1725
1960
  ]);
1726
1961
  return /* @__PURE__ */ import_react3.default.createElement("div", {
1727
- className: (0, import_react_ui_theme2.mx)("z-20 absolute right-0 top-20 bottom-20 w-[30rem] overflow-auto scrollbar-thin", "border text-xs bg-neutral-50 dark:bg-black text-cyan-500 font-mono p-1 opacity-80", fragments.border)
1962
+ className: (0, import_react_ui_theme2.mx)("z-20 absolute right-0 top-20 bottom-20 w-[30rem] overflow-auto scrollbar-thin", "border border-gridLine text-xs bg-neutral-50 dark:bg-black text-cyan-500 font-mono p-1 opacity-80")
1728
1963
  }, /* @__PURE__ */ import_react3.default.createElement("pre", {
1729
1964
  className: "whitespace-pre-wrap"
1730
1965
  }, JSON.stringify({
@@ -1746,18 +1981,232 @@ var Sheet = {
1746
1981
  StatusBar: SheetStatusBar,
1747
1982
  Debug: SheetDebug
1748
1983
  };
1749
- var SheetContainer = ({ sheet, space, role, coordinate = {
1750
- part: "main",
1751
- entryId: ""
1752
- }, remoteFunctionUrl }) => {
1984
+ var iconStyles = (0, import_react_ui_theme5.getSize)(5);
1985
+ var buttonStyles = "min-bs-0 p-2";
1986
+ var tooltipProps = {
1987
+ side: "top",
1988
+ classNames: "z-10"
1989
+ };
1990
+ var ToolbarSeparator = () => /* @__PURE__ */ import_react11.default.createElement("div", {
1991
+ role: "separator",
1992
+ className: "grow"
1993
+ });
1994
+ var ToolbarButton = ({ Icon: Icon2, children, ...props }) => {
1995
+ return /* @__PURE__ */ import_react11.default.createElement(import_react_ui4.Tooltip.Root, null, /* @__PURE__ */ import_react11.default.createElement(import_react_ui4.Tooltip.Trigger, {
1996
+ asChild: true
1997
+ }, /* @__PURE__ */ import_react11.default.createElement(import_react_ui4.Toolbar.Button, {
1998
+ variant: "ghost",
1999
+ ...props,
2000
+ classNames: buttonStyles
2001
+ }, /* @__PURE__ */ import_react11.default.createElement(Icon2, {
2002
+ className: iconStyles
2003
+ }), /* @__PURE__ */ import_react11.default.createElement("span", {
2004
+ className: "sr-only"
2005
+ }, children))), /* @__PURE__ */ import_react11.default.createElement(import_react_ui4.Tooltip.Portal, null, /* @__PURE__ */ import_react11.default.createElement(import_react_ui4.Tooltip.Content, tooltipProps, children, /* @__PURE__ */ import_react11.default.createElement(import_react_ui4.Tooltip.Arrow, null))));
2006
+ };
2007
+ var ToolbarToggleButton = ({ Icon: Icon2, children, ...props }) => {
2008
+ return /* @__PURE__ */ import_react11.default.createElement(import_react_ui4.Tooltip.Root, null, /* @__PURE__ */ import_react11.default.createElement(import_react_ui4.Tooltip.Trigger, {
2009
+ asChild: true
2010
+ }, /* @__PURE__ */ import_react11.default.createElement(import_react_ui4.Toolbar.ToggleGroupItem, {
2011
+ variant: "ghost",
2012
+ ...props,
2013
+ classNames: buttonStyles
2014
+ }, /* @__PURE__ */ import_react11.default.createElement(Icon2, {
2015
+ className: iconStyles
2016
+ }), /* @__PURE__ */ import_react11.default.createElement("span", {
2017
+ className: "sr-only"
2018
+ }, children))), /* @__PURE__ */ import_react11.default.createElement(import_react_ui4.Tooltip.Portal, null, /* @__PURE__ */ import_react11.default.createElement(import_react_ui4.Tooltip.Content, tooltipProps, children, /* @__PURE__ */ import_react11.default.createElement(import_react_ui4.Tooltip.Arrow, null))));
2019
+ };
2020
+ var [ToolbarContextProvider, useToolbarContext] = (0, import_react_context.createContext)("Toolbar");
2021
+ var ToolbarRoot = ({ children, onAction, classNames }) => {
2022
+ return /* @__PURE__ */ import_react10.default.createElement(ToolbarContextProvider, {
2023
+ onAction
2024
+ }, /* @__PURE__ */ import_react10.default.createElement(import_react_ui3.DensityProvider, {
2025
+ density: "fine"
2026
+ }, /* @__PURE__ */ import_react10.default.createElement(import_react_ui3.ElevationProvider, {
2027
+ elevation: "chrome"
2028
+ }, /* @__PURE__ */ import_react10.default.createElement(import_react_ui3.Toolbar.Root, {
2029
+ classNames: [
2030
+ "is-full shrink-0 overflow-x-auto overflow-y-hidden p-1",
2031
+ classNames
2032
+ ]
2033
+ }, children))));
2034
+ };
2035
+ var formatOptions = [
2036
+ {
2037
+ type: "date",
2038
+ Icon: import_react9.Calendar,
2039
+ getState: (state) => false
2040
+ },
2041
+ {
2042
+ type: "currency",
2043
+ Icon: import_react9.CurrencyDollar,
2044
+ getState: (state) => false
2045
+ }
2046
+ ];
2047
+ var Format = () => {
2048
+ const { onAction } = useToolbarContext("Format");
2049
+ const { t } = (0, import_react_ui3.useTranslation)(import_chunk_BJ6ZD7MN.SHEET_PLUGIN);
2050
+ return /* @__PURE__ */ import_react10.default.createElement(import_react_ui3.Toolbar.ToggleGroup, {
2051
+ type: "single"
2052
+ }, formatOptions.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ import_react10.default.createElement(ToolbarToggleButton, {
2053
+ key: type,
2054
+ value: type,
2055
+ Icon: Icon2,
2056
+ // disabled={state?.blockType === 'codeblock'}
2057
+ // onClick={state ? () => onAction?.({ type, data: !getState(state) }) : undefined}
2058
+ onClick: () => onAction?.({
2059
+ type
2060
+ })
2061
+ }, t(`toolbar ${type} label`))));
2062
+ };
2063
+ var alignmentOptions = [
2064
+ {
2065
+ type: "left",
2066
+ Icon: import_react9.TextAlignLeft,
2067
+ getState: (state) => false
2068
+ },
2069
+ {
2070
+ type: "center",
2071
+ Icon: import_react9.TextAlignCenter,
2072
+ getState: (state) => false
2073
+ },
2074
+ {
2075
+ type: "right",
2076
+ Icon: import_react9.TextAlignRight,
2077
+ getState: (state) => false
2078
+ }
2079
+ ];
2080
+ var Alignment = () => {
2081
+ const { onAction } = useToolbarContext("Alignment");
2082
+ const { t } = (0, import_react_ui3.useTranslation)(import_chunk_BJ6ZD7MN.SHEET_PLUGIN);
2083
+ return /* @__PURE__ */ import_react10.default.createElement(import_react_ui3.Toolbar.ToggleGroup, {
2084
+ type: "single"
2085
+ }, alignmentOptions.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ import_react10.default.createElement(ToolbarToggleButton, {
2086
+ key: type,
2087
+ value: type,
2088
+ Icon: Icon2,
2089
+ // disabled={state?.blockType === 'codeblock'}
2090
+ // onClick={state ? () => onAction?.({ type, data: !getState(state) }) : undefined}
2091
+ onClick: () => onAction?.({
2092
+ type
2093
+ })
2094
+ }, t(`toolbar ${type} label`))));
2095
+ };
2096
+ var styleOptions = [
2097
+ {
2098
+ type: "clear",
2099
+ Icon: import_react9.Eraser,
2100
+ getState: (state) => false
2101
+ },
2102
+ {
2103
+ type: "highlight",
2104
+ Icon: import_react9.HighlighterCircle,
2105
+ getState: (state) => false
2106
+ }
2107
+ ];
2108
+ var Styles = () => {
2109
+ const { onAction } = useToolbarContext("Alignment");
2110
+ const { t } = (0, import_react_ui3.useTranslation)(import_chunk_BJ6ZD7MN.SHEET_PLUGIN);
2111
+ return /* @__PURE__ */ import_react10.default.createElement(import_react_ui3.Toolbar.ToggleGroup, {
2112
+ type: "single"
2113
+ }, styleOptions.map(({ type, getState, Icon: Icon2 }) => /* @__PURE__ */ import_react10.default.createElement(ToolbarToggleButton, {
2114
+ key: type,
2115
+ value: type,
2116
+ Icon: Icon2,
2117
+ // disabled={state?.blockType === 'codeblock'}
2118
+ // onClick={state ? () => onAction?.({ type, data: !getState(state) }) : undefined}
2119
+ onClick: () => onAction?.({
2120
+ type
2121
+ })
2122
+ }, t(`toolbar ${type} label`))));
2123
+ };
2124
+ var Actions = () => {
2125
+ const { onAction } = useToolbarContext("Actions");
2126
+ const { cursor, range, model } = useSheetContext();
2127
+ const { t } = (0, import_react_ui3.useTranslation)(import_chunk_BJ6ZD7MN.SHEET_PLUGIN);
2128
+ const overlapsCommentAnchor = (model.sheet.threads ?? []).filter(import_util.nonNullable).filter((thread) => thread.status !== "resolved").some((thread) => {
2129
+ if (!cursor) {
2130
+ return false;
2131
+ }
2132
+ return (0, import_chunk_ZRQZFV5T.addressToIndex)(model.sheet, cursor) === thread.anchor;
2133
+ });
2134
+ const hasCursor = !!cursor;
2135
+ const cursorOnly = hasCursor && !range && !overlapsCommentAnchor;
2136
+ const tooltipLabelKey = !hasCursor ? "no cursor label" : overlapsCommentAnchor ? "selection overlaps existing comment label" : range ? "comment ranges not supported label" : "comment label";
2137
+ return /* @__PURE__ */ import_react10.default.createElement(ToolbarButton, {
2138
+ value: "comment",
2139
+ Icon: import_react9.ChatText,
2140
+ "data-testid": "editor.toolbar.comment",
2141
+ onClick: () => {
2142
+ if (!cursor) {
2143
+ return;
2144
+ }
2145
+ return onAction?.({
2146
+ type: "comment",
2147
+ anchor: (0, import_chunk_ZRQZFV5T.addressToIndex)(model.sheet, cursor),
2148
+ cellContent: model.getCellText(cursor)
2149
+ });
2150
+ },
2151
+ disabled: !cursorOnly || overlapsCommentAnchor
2152
+ }, t(tooltipLabelKey));
2153
+ };
2154
+ var Toolbar = {
2155
+ Root: ToolbarRoot,
2156
+ Separator: ToolbarSeparator,
2157
+ Alignment,
2158
+ Format,
2159
+ Styles,
2160
+ Actions
2161
+ };
2162
+ var attentionFragment = (0, import_react_ui_theme.mx)("group-focus-within/editor:attention-surface group-[[aria-current]]/editor:attention-surface", "group-focus-within/editor:border-separator");
2163
+ var sectionToolbarLayout = "bs-[--rail-action] bg-[--sticky-bg] sticky block-start-0 __-block-start-px transition-opacity";
2164
+ var SheetContainer = ({ sheet, space, role, remoteFunctionUrl }) => {
2165
+ const dispatch = (0, import_app_framework.useIntentDispatcher)();
2166
+ const id = (0, import_echo.fullyQualifiedId)(sheet);
2167
+ const isDirectlyAttended = (0, import_react_ui_attention.useIsDirectlyAttended)(id);
2168
+ const handleAction = (0, import_react.useCallback)((action) => {
2169
+ switch (action.type) {
2170
+ case "comment": {
2171
+ void dispatch({
2172
+ action: "dxos.org/plugin/thread/action/create",
2173
+ data: {
2174
+ cursor: action.anchor,
2175
+ name: action.cellContent,
2176
+ subject: sheet
2177
+ }
2178
+ });
2179
+ }
2180
+ }
2181
+ }, [
2182
+ sheet,
2183
+ dispatch
2184
+ ]);
1753
2185
  return /* @__PURE__ */ import_react.default.createElement("div", {
1754
2186
  role: "none",
1755
- className: (0, import_react_ui_theme.mx)("flex", role === "article" && "row-span-2", role === "section" && "aspect-square border-y border-is border-separator", coordinate.part !== "solo" && "border-is border-separator")
2187
+ className: role === "article" ? "row-span-2 grid grid-rows-subgrid" : void 0
1756
2188
  }, /* @__PURE__ */ import_react.default.createElement(Sheet.Root, {
1757
2189
  sheet,
1758
2190
  space,
1759
2191
  remoteFunctionUrl
1760
- }, /* @__PURE__ */ import_react.default.createElement(Sheet.Main, null)));
2192
+ }, /* @__PURE__ */ import_react.default.createElement("div", {
2193
+ role: "none",
2194
+ className: (0, import_react_ui_theme.mx)("flex flex-0 justify-center overflow-x-auto")
2195
+ }, /* @__PURE__ */ import_react.default.createElement(Toolbar.Root, {
2196
+ onAction: handleAction,
2197
+ classNames: (0, import_react_ui_theme.mx)(role === "section" ? [
2198
+ "z-[2] group-focus-within/section:visible",
2199
+ !isDirectlyAttended && "invisible",
2200
+ sectionToolbarLayout
2201
+ ] : "group-focus-within/editor:border-separator group-[[aria-current]]/editor:border-separator")
2202
+ }, /* @__PURE__ */ import_react.default.createElement(Toolbar.Separator, null), /* @__PURE__ */ import_react.default.createElement(Toolbar.Actions, null))), /* @__PURE__ */ import_react.default.createElement("div", {
2203
+ role: "none",
2204
+ className: (0, import_react_ui_theme.mx)(role === "section" && "aspect-square border-is border-bs border-be border-separator", role === "article" && "flex is-full overflow-hidden focus-visible:ring-inset row-span-1 data-[toolbar=disabled]:pbs-2 data-[toolbar=disabled]:row-span-2 border-bs border-separator", import_react_ui_theme.focusRing, attentionFragment)
2205
+ }, /* @__PURE__ */ import_react.default.createElement(Sheet.Main, null))));
1761
2206
  };
1762
2207
  var SheetContainer_default = SheetContainer;
1763
- //# sourceMappingURL=SheetContainer-IQT6TR4Z.cjs.map
2208
+ // Annotate the CommonJS export names for ESM import in node:
2209
+ 0 && (module.exports = {
2210
+ sectionToolbarLayout
2211
+ });
2212
+ //# sourceMappingURL=SheetContainer-KEOKUKAQ.cjs.map