@dxos/plugin-sheet 0.6.11 → 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 (106) hide show
  1. package/dist/lib/browser/{SheetContainer-U4H5D34A.mjs → SheetContainer-Y7ZMFBAP.mjs} +568 -109
  2. package/dist/lib/browser/SheetContainer-Y7ZMFBAP.mjs.map +7 -0
  3. package/dist/lib/browser/{chunk-D5AGLXJP.mjs → chunk-GNNVBNCX.mjs} +55 -47
  4. package/dist/lib/browser/chunk-GNNVBNCX.mjs.map +7 -0
  5. package/dist/lib/browser/{chunk-APHOLYUB.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 +15 -6
  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-AXQV3ZT5.cjs → SheetContainer-KEOKUKAQ.cjs} +509 -62
  15. package/dist/lib/node/SheetContainer-KEOKUKAQ.cjs.map +7 -0
  16. package/dist/lib/node/{chunk-PYXHNAAK.cjs → chunk-57PB2HPY.cjs} +5 -5
  17. package/dist/lib/node/{chunk-CN3RPESU.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-5KKJ4NPP.cjs → chunk-ZRQZFV5T.cjs} +70 -57
  21. package/dist/lib/node/chunk-ZRQZFV5T.cjs.map +7 -0
  22. package/dist/lib/node/index.cjs +31 -23
  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 +8 -15
  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 +5 -1
  82. package/src/components/Sheet/Sheet.tsx +45 -8
  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 -18
  88. package/src/components/Toolbar/Toolbar.tsx +54 -12
  89. package/src/model/index.ts +1 -0
  90. package/src/model/model.browser.test.ts +1 -2
  91. package/src/model/model.ts +9 -43
  92. package/src/model/types.test.ts +1 -2
  93. package/src/model/util.ts +67 -0
  94. package/src/translations.ts +6 -1
  95. package/src/types.ts +26 -3
  96. package/dist/lib/browser/SheetContainer-U4H5D34A.mjs.map +0 -7
  97. package/dist/lib/browser/chunk-D5AGLXJP.mjs.map +0 -7
  98. package/dist/lib/browser/chunk-FUAGSXA4.mjs.map +0 -7
  99. package/dist/lib/browser/chunk-NU4PBN33.mjs +0 -8
  100. package/dist/lib/node/SheetContainer-AXQV3ZT5.cjs.map +0 -7
  101. package/dist/lib/node/chunk-5KKJ4NPP.cjs.map +0 -7
  102. package/dist/lib/node/chunk-DSYKOI4E.cjs.map +0 -7
  103. /package/dist/lib/browser/{chunk-APHOLYUB.mjs.map → chunk-PGKZPKUD.mjs.map} +0 -0
  104. /package/dist/lib/browser/{chunk-NU4PBN33.mjs.map → chunk-VBF7YENS.mjs.map} +0 -0
  105. /package/dist/lib/node/{chunk-PYXHNAAK.cjs.map → chunk-57PB2HPY.cjs.map} +0 -0
  106. /package/dist/lib/node/{chunk-CN3RPESU.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_AXQV3ZT5_exports = {};
30
- __export(SheetContainer_AXQV3ZT5_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_AXQV3ZT5_exports);
34
- var import_chunk_CN3RPESU = require("./chunk-CN3RPESU.cjs");
35
- var import_chunk_5KKJ4NPP = require("./chunk-5KKJ4NPP.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_5KKJ4NPP.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_5KKJ4NPP.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_5KKJ4NPP.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_5KKJ4NPP.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_5KKJ4NPP.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: [
@@ -395,7 +451,7 @@ var FormattingModel = class {
395
451
  //
396
452
  // Numbers.
397
453
  //
398
- case import_chunk_DSYKOI4E.ValueTypeEnum.Number: {
454
+ case import_chunk_VJU3NPUJ.ValueTypeEnum.Number: {
399
455
  return {
400
456
  value: value.toLocaleString(locales),
401
457
  classNames: [
@@ -404,7 +460,7 @@ var FormattingModel = class {
404
460
  ]
405
461
  };
406
462
  }
407
- case import_chunk_DSYKOI4E.ValueTypeEnum.Percent: {
463
+ case import_chunk_VJU3NPUJ.ValueTypeEnum.Percent: {
408
464
  return {
409
465
  value: value * 100 + "%",
410
466
  classNames: [
@@ -413,7 +469,7 @@ var FormattingModel = class {
413
469
  ]
414
470
  };
415
471
  }
416
- case import_chunk_DSYKOI4E.ValueTypeEnum.Currency: {
472
+ case import_chunk_VJU3NPUJ.ValueTypeEnum.Currency: {
417
473
  return {
418
474
  value: value.toLocaleString(locales, {
419
475
  style: "currency",
@@ -430,21 +486,21 @@ var FormattingModel = class {
430
486
  //
431
487
  // Dates.
432
488
  //
433
- case import_chunk_DSYKOI4E.ValueTypeEnum.DateTime: {
489
+ case import_chunk_VJU3NPUJ.ValueTypeEnum.DateTime: {
434
490
  const date = this.model.toLocalDate(value);
435
491
  return {
436
492
  value: date.toLocaleString(locales),
437
493
  classNames
438
494
  };
439
495
  }
440
- case import_chunk_DSYKOI4E.ValueTypeEnum.Date: {
496
+ case import_chunk_VJU3NPUJ.ValueTypeEnum.Date: {
441
497
  const date = this.model.toLocalDate(value);
442
498
  return {
443
499
  value: date.toLocaleDateString(locales),
444
500
  classNames
445
501
  };
446
502
  }
447
- case import_chunk_DSYKOI4E.ValueTypeEnum.Time: {
503
+ case import_chunk_VJU3NPUJ.ValueTypeEnum.Time: {
448
504
  const date = this.model.toLocalDate(value);
449
505
  return {
450
506
  value: date.toLocaleTimeString(locales),
@@ -467,7 +523,7 @@ var useSheetContext = () => {
467
523
  const context = (0, import_react6.useContext)(SheetContext);
468
524
  (0, import_invariant.invariant)(context, void 0, {
469
525
  F: __dxlog_file,
470
- L: 45,
526
+ L: 49,
471
527
  S: void 0,
472
528
  A: [
473
529
  "context",
@@ -478,12 +534,12 @@ var useSheetContext = () => {
478
534
  };
479
535
  var mapFormulaBindingToId = (functions) => (formula) => {
480
536
  return formula.replace(/([a-zA-Z0-9]+)\((.*)\)/g, (match, binding, args) => {
481
- if (import_chunk_5KKJ4NPP.defaultFunctions.find((fn2) => fn2.name === binding) || binding === "EDGE") {
537
+ if (import_chunk_ZRQZFV5T.defaultFunctions.find((fn2) => fn2.name === binding) || binding === "EDGE") {
482
538
  return match;
483
539
  }
484
540
  const fn = functions.find((fn2) => fn2.binding === binding);
485
541
  if (fn) {
486
- return `${(0, import_echo2.fullyQualifiedId)(fn)}(${args})`;
542
+ return `${(0, import_echo3.fullyQualifiedId)(fn)}(${args})`;
487
543
  } else {
488
544
  return match;
489
545
  }
@@ -495,7 +551,7 @@ var mapFormulaBindingFromId = (functions) => (formula) => {
495
551
  if (id.length !== OBJECT_ID_LENGTH) {
496
552
  return match;
497
553
  }
498
- const fn = functions.find((fn2) => (0, import_echo2.fullyQualifiedId)(fn2) === id);
554
+ const fn = functions.find((fn2) => (0, import_echo3.fullyQualifiedId)(fn2) === id);
499
555
  if (fn?.binding) {
500
556
  return `${fn.binding}(${args})`;
501
557
  } else {
@@ -504,16 +560,17 @@ var mapFormulaBindingFromId = (functions) => (formula) => {
504
560
  });
505
561
  };
506
562
  var SheetContextProvider = ({ children, sheet, space, readonly, onInfo, ...options }) => {
507
- const graph = (0, import_chunk_CN3RPESU.useComputeGraph)(space, options);
563
+ const graph = (0, import_chunk_6LWBQAQZ.useComputeGraph)(space, options);
508
564
  const [cursor, setCursor] = (0, import_react6.useState)();
509
565
  const [range, setRange] = (0, import_react6.useState)();
510
566
  const [editing, setEditing] = (0, import_react6.useState)(false);
567
+ const decorations = (0, import_react6.useMemo)(() => createDecorations(), []);
511
568
  const [[model, formatting] = [], setModels] = (0, import_react6.useState)(void 0);
512
569
  (0, import_react6.useEffect)(() => {
513
570
  let model2;
514
571
  let formatting2;
515
572
  const t = setTimeout(async () => {
516
- model2 = new import_chunk_5KKJ4NPP.SheetModel(graph, sheet, space, {
573
+ model2 = new import_chunk_ZRQZFV5T.SheetModel(graph, sheet, space, {
517
574
  readonly,
518
575
  mapFormulaBindingToId,
519
576
  mapFormulaBindingFromId
@@ -547,10 +604,168 @@ var SheetContextProvider = ({ children, sheet, space, readonly, onInfo, ...optio
547
604
  editing,
548
605
  setEditing,
549
606
  // TODO(burdon): Change to event.
550
- onInfo
607
+ onInfo,
608
+ decorations
551
609
  }
552
610
  }, children);
553
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
+ };
554
769
  var getRelativeClientRect = (root, element) => {
555
770
  const rootRect = root.getBoundingClientRect();
556
771
  const elementRect = element.getBoundingClientRect();
@@ -641,7 +856,7 @@ var editorKeys = ({ onNav, onClose }) => {
641
856
  ]);
642
857
  };
643
858
  var CellEditor = ({ value, extension, autoFocus, onBlur }) => {
644
- const { themeMode } = (0, import_react_ui.useThemeContext)();
859
+ const { themeMode } = (0, import_react_ui2.useThemeContext)();
645
860
  const { parentRef } = (0, import_react_ui_editor.useTextEditor)(() => {
646
861
  return {
647
862
  autoFocus,
@@ -679,7 +894,7 @@ var CellEditor = ({ value, extension, autoFocus, onBlur }) => {
679
894
  }, [
680
895
  extension
681
896
  ]);
682
- return /* @__PURE__ */ import_react7.default.createElement("div", {
897
+ return /* @__PURE__ */ import_react8.default.createElement("div", {
683
898
  ref: parentRef,
684
899
  className: "flex w-full"
685
900
  });
@@ -794,7 +1009,7 @@ var sheetExtension = ({ functions = [] }) => {
794
1009
  // NOTE: Useful for debugging.
795
1010
  closeOnBlur: false,
796
1011
  icons: false,
797
- tooltipClass: () => (0, import_react_ui_theme3.mx)(
1012
+ tooltipClass: () => (0, import_react_ui_theme4.mx)(
798
1013
  // TODO(burdon): Factor out fragments.
799
1014
  // TODO(burdon): Size to make width same as column.
800
1015
  "!-left-[1px] !top-[33px] !-m-0 border !border-t-0 [&>ul]:!min-w-[198px]",
@@ -900,6 +1115,7 @@ var SheetRoot = ({ children, ...props }) => {
900
1115
  var SheetMain = /* @__PURE__ */ (0, import_react3.forwardRef)(({ classNames, numRows, numColumns }, forwardRef2) => {
901
1116
  const { model, cursor, setCursor, setRange, setEditing } = useSheetContext();
902
1117
  const { rowsRef, columnsRef, contentRef } = useScrollHandlers();
1118
+ useThreads();
903
1119
  const [rows, setRows] = (0, import_react3.useState)([
904
1120
  ...model.sheet.rows
905
1121
  ]);
@@ -907,10 +1123,10 @@ var SheetMain = /* @__PURE__ */ (0, import_react3.forwardRef)(({ classNames, num
907
1123
  ...model.sheet.columns
908
1124
  ]);
909
1125
  (0, import_react3.useEffect)(() => {
910
- const rowsAccessor = (0, import_echo.createDocAccessor)(model.sheet, [
1126
+ const rowsAccessor = (0, import_echo2.createDocAccessor)(model.sheet, [
911
1127
  "rows"
912
1128
  ]);
913
- const columnsAccessor = (0, import_echo.createDocAccessor)(model.sheet, [
1129
+ const columnsAccessor = (0, import_echo2.createDocAccessor)(model.sheet, [
914
1130
  "columns"
915
1131
  ]);
916
1132
  const handleUpdate = (0, import_async.debounce)(() => {
@@ -938,22 +1154,22 @@ var SheetMain = /* @__PURE__ */ (0, import_react3.forwardRef)(({ classNames, num
938
1154
  columns
939
1155
  ]);
940
1156
  const handleMoveRows = (from, to, num = 1) => {
941
- const cursorIdx = cursor ? model.addressToIndex(cursor) : void 0;
1157
+ const cursorIdx = cursor ? (0, import_chunk_ZRQZFV5T.addressToIndex)(model.sheet, cursor) : void 0;
942
1158
  const [rows2] = model.sheet.rows.splice(from, num);
943
1159
  model.sheet.rows.splice(to, 0, rows2);
944
1160
  if (cursorIdx) {
945
- setCursor(model.addressFromIndex(cursorIdx));
1161
+ setCursor((0, import_chunk_ZRQZFV5T.addressFromIndex)(model.sheet, cursorIdx));
946
1162
  }
947
1163
  setRows([
948
1164
  ...model.sheet.rows
949
1165
  ]);
950
1166
  };
951
1167
  const handleMoveColumns = (from, to, num = 1) => {
952
- const cursorIdx = cursor ? model.addressToIndex(cursor) : void 0;
1168
+ const cursorIdx = cursor ? (0, import_chunk_ZRQZFV5T.addressToIndex)(model.sheet, cursor) : void 0;
953
1169
  const columns2 = model.sheet.columns.splice(from, num);
954
1170
  model.sheet.columns.splice(to, 0, ...columns2);
955
1171
  if (cursorIdx) {
956
- setCursor(model.addressFromIndex(cursorIdx));
1172
+ setCursor((0, import_chunk_ZRQZFV5T.addressFromIndex)(model.sheet, cursorIdx));
957
1173
  }
958
1174
  setColumns([
959
1175
  ...model.sheet.columns
@@ -962,10 +1178,10 @@ var SheetMain = /* @__PURE__ */ (0, import_react3.forwardRef)(({ classNames, num
962
1178
  const [rowSizes, setRowSizes] = (0, import_react3.useState)();
963
1179
  const [columnSizes, setColumnSizes] = (0, import_react3.useState)();
964
1180
  (0, import_react3.useEffect)(() => {
965
- const rowAccessor = (0, import_echo.createDocAccessor)(model.sheet, [
1181
+ const rowAccessor = (0, import_echo2.createDocAccessor)(model.sheet, [
966
1182
  "rowMeta"
967
1183
  ]);
968
- const columnAccessor = (0, import_echo.createDocAccessor)(model.sheet, [
1184
+ const columnAccessor = (0, import_echo2.createDocAccessor)(model.sheet, [
969
1185
  "columnMeta"
970
1186
  ]);
971
1187
  const handleUpdate = (0, import_async.debounce)(() => {
@@ -1309,14 +1525,14 @@ var SheetColumns = /* @__PURE__ */ (0, import_react3.forwardRef)(({ columns, siz
1309
1525
  key: idx,
1310
1526
  idx,
1311
1527
  index,
1312
- label: (0, import_chunk_5KKJ4NPP.columnLetter)(index),
1528
+ label: (0, import_chunk_ZRQZFV5T.columnLetter)(index),
1313
1529
  size: sizes?.[idx] ?? defaultWidth,
1314
1530
  resize: index < columns.length - 1,
1315
1531
  selected: selected === index,
1316
1532
  onResize,
1317
1533
  onSelect
1318
1534
  }))), /* @__PURE__ */ (0, import_react_dom.createPortal)(/* @__PURE__ */ import_react3.default.createElement(import_core.DragOverlay, null, active && /* @__PURE__ */ import_react3.default.createElement(MovingOverlay, {
1319
- label: (0, import_chunk_5KKJ4NPP.columnLetter)(active.data.current.index)
1535
+ label: (0, import_chunk_ZRQZFV5T.columnLetter)(active.data.current.index)
1320
1536
  })), document.body))));
1321
1537
  });
1322
1538
  var GridColumnCell = ({ idx, index, label, size, resize, selected, onSelect, onResize }) => {
@@ -1398,7 +1614,7 @@ var SheetGrid = /* @__PURE__ */ (0, import_react3.forwardRef)(({ size, rows, col
1398
1614
  id: model.id
1399
1615
  }, {
1400
1616
  F: __dxlog_file2,
1401
- L: 730,
1617
+ L: 737,
1402
1618
  S: void 0,
1403
1619
  C: (f, a) => f(...a)
1404
1620
  });
@@ -1515,9 +1731,9 @@ var SheetGrid = /* @__PURE__ */ (0, import_react3.forwardRef)(({ size, rows, col
1515
1731
  rowSizes,
1516
1732
  columnSizes
1517
1733
  });
1518
- const id = (0, import_echo.fullyQualifiedId)(model.sheet);
1519
- const attendableAttrs = (0, import_react_ui_attention.createAttendableAttributes)(id);
1520
- const hasAttention = (0, import_react_ui_attention.useHasAttention)(id);
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);
1521
1737
  return /* @__PURE__ */ import_react3.default.createElement("div", {
1522
1738
  ref: containerRef,
1523
1739
  role: "grid",
@@ -1550,9 +1766,9 @@ var SheetGrid = /* @__PURE__ */ (0, import_react3.forwardRef)(({ size, rows, col
1550
1766
  row,
1551
1767
  column
1552
1768
  };
1553
- const id2 = (0, import_chunk_5KKJ4NPP.addressToA1Notation)(cell);
1554
- const idx = model.addressToIndex(cell);
1555
- const active = (0, import_chunk_5KKJ4NPP.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);
1556
1772
  if (active && editing) {
1557
1773
  const value = initialText.current ?? model.getCellText(cell) ?? "";
1558
1774
  const handleClose = (value2) => {
@@ -1632,13 +1848,27 @@ var SelectionOverlay = ({ root }) => {
1632
1848
  });
1633
1849
  };
1634
1850
  var SheetCell = ({ id, cell, style, active, onSelect }) => {
1635
- const { formatting, editing, setRange } = useSheetContext();
1851
+ const { formatting, editing, setRange, decorations, model: { sheet } } = useSheetContext();
1636
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));
1637
1867
  return /* @__PURE__ */ import_react3.default.createElement("div", {
1638
1868
  [`data-${CELL_DATA_KEY}`]: id,
1639
1869
  role: "cell",
1640
1870
  style,
1641
- className: (0, import_react_ui_theme2.mx)("flex w-full h-full px-2 py-1 truncate items-center border border-gridLine cursor-pointer", fragments.cell, active && [
1871
+ className: (0, import_react_ui_theme2.mx)("border border-gridLine cursor-pointer", fragments.cell, active && [
1642
1872
  "z-20",
1643
1873
  fragments.cellSelected
1644
1874
  ], classNames),
@@ -1652,14 +1882,14 @@ var SheetCell = ({ id, cell, style, active, onSelect }) => {
1652
1882
  }
1653
1883
  },
1654
1884
  onDoubleClick: () => onSelect?.(cell, true)
1655
- }, value);
1885
+ }, decoratedContent);
1656
1886
  };
1657
1887
  var GridCellEditor = ({ style, value, onNav, onClose }) => {
1658
1888
  const { model, range } = useSheetContext();
1659
1889
  const notifier = (0, import_react3.useRef)();
1660
1890
  (0, import_react3.useEffect)(() => {
1661
1891
  if (range) {
1662
- notifier.current?.((0, import_chunk_5KKJ4NPP.rangeToA1Notation)(range));
1892
+ notifier.current?.((0, import_chunk_ZRQZFV5T.rangeToA1Notation)(range));
1663
1893
  }
1664
1894
  }, [
1665
1895
  range
@@ -1706,7 +1936,7 @@ var SheetStatusBar = () => {
1706
1936
  className: "flex gap-4 items-center"
1707
1937
  }, /* @__PURE__ */ import_react3.default.createElement("div", {
1708
1938
  className: "flex w-16 items-center font-mono"
1709
- }, range && (0, import_chunk_5KKJ4NPP.rangeToA1Notation)(range) || cursor && (0, import_chunk_5KKJ4NPP.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", {
1710
1940
  className: "flex gap-2 items-center"
1711
1941
  }, /* @__PURE__ */ import_react3.default.createElement(import_react2.Function, {
1712
1942
  className: (0, import_react_ui_theme2.mx)("text-greenText", isFormula ? "visible" : "invisible")
@@ -1718,7 +1948,7 @@ var SheetDebug = () => {
1718
1948
  const { model, cursor, range } = useSheetContext();
1719
1949
  const [, forceUpdate] = (0, import_react3.useState)({});
1720
1950
  (0, import_react3.useEffect)(() => {
1721
- const accessor = (0, import_echo.createDocAccessor)(model.sheet, []);
1951
+ const accessor = (0, import_echo2.createDocAccessor)(model.sheet, []);
1722
1952
  const handleUpdate = () => forceUpdate({});
1723
1953
  accessor.handle.addListener("change", handleUpdate);
1724
1954
  handleUpdate();
@@ -1751,15 +1981,232 @@ var Sheet = {
1751
1981
  StatusBar: SheetStatusBar,
1752
1982
  Debug: SheetDebug
1753
1983
  };
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";
1754
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
+ ]);
1755
2185
  return /* @__PURE__ */ import_react.default.createElement("div", {
1756
2186
  role: "none",
1757
- className: (0, import_react_ui_theme.mx)("flex", role === "article" && "row-span-2", role === "section" && "aspect-square border-y border-is border-separator")
2187
+ className: role === "article" ? "row-span-2 grid grid-rows-subgrid" : void 0
1758
2188
  }, /* @__PURE__ */ import_react.default.createElement(Sheet.Root, {
1759
2189
  sheet,
1760
2190
  space,
1761
2191
  remoteFunctionUrl
1762
- }, /* @__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))));
1763
2206
  };
1764
2207
  var SheetContainer_default = SheetContainer;
1765
- //# sourceMappingURL=SheetContainer-AXQV3ZT5.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