@dxos/react-ui-editor 0.3.10-main.8fd45da → 0.3.10-main.92d1f2c

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 (87) hide show
  1. package/dist/lib/browser/index.mjs +986 -296
  2. package/dist/lib/browser/index.mjs.map +4 -4
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +19 -1
  5. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
  6. package/dist/types/src/components/TextEditor/TextEditor.d.ts +2 -1
  7. package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
  8. package/dist/types/src/components/TextEditor/extensions/autocomplete.d.ts.map +1 -1
  9. package/dist/types/src/components/TextEditor/extensions/basic.d.ts +2 -1
  10. package/dist/types/src/components/TextEditor/extensions/basic.d.ts.map +1 -1
  11. package/dist/types/src/components/TextEditor/extensions/blast.d.ts +25 -0
  12. package/dist/types/src/components/TextEditor/extensions/blast.d.ts.map +1 -0
  13. package/dist/types/src/components/TextEditor/extensions/comments.d.ts +10 -6
  14. package/dist/types/src/components/TextEditor/extensions/comments.d.ts.map +1 -1
  15. package/dist/types/src/components/TextEditor/extensions/demo.d.ts +11 -0
  16. package/dist/types/src/components/TextEditor/extensions/demo.d.ts.map +1 -0
  17. package/dist/types/src/components/TextEditor/extensions/experimental.d.ts +1 -1
  18. package/dist/types/src/components/TextEditor/extensions/experimental.d.ts.map +1 -1
  19. package/dist/types/src/components/TextEditor/extensions/image.d.ts +4 -0
  20. package/dist/types/src/components/TextEditor/extensions/image.d.ts.map +1 -0
  21. package/dist/types/src/components/TextEditor/extensions/index.d.ts +5 -0
  22. package/dist/types/src/components/TextEditor/extensions/index.d.ts.map +1 -1
  23. package/dist/types/src/components/TextEditor/extensions/link.d.ts.map +1 -1
  24. package/dist/types/src/components/TextEditor/extensions/listener.d.ts +4 -2
  25. package/dist/types/src/components/TextEditor/extensions/listener.d.ts.map +1 -1
  26. package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts +2 -1
  27. package/dist/types/src/components/TextEditor/extensions/markdown/bundle.d.ts.map +1 -1
  28. package/dist/types/src/components/TextEditor/extensions/markdown/highlight.d.ts +9 -3
  29. package/dist/types/src/components/TextEditor/extensions/markdown/highlight.d.ts.map +1 -1
  30. package/dist/types/src/components/TextEditor/extensions/mention.d.ts +6 -0
  31. package/dist/types/src/components/TextEditor/extensions/mention.d.ts.map +1 -0
  32. package/dist/types/src/components/TextEditor/extensions/table.d.ts +8 -0
  33. package/dist/types/src/components/TextEditor/extensions/table.d.ts.map +1 -0
  34. package/dist/types/src/components/TextEditor/extensions/tasklist.d.ts +2 -1
  35. package/dist/types/src/components/TextEditor/extensions/tasklist.d.ts.map +1 -1
  36. package/dist/types/src/components/TextEditor/themes/default.d.ts +5 -0
  37. package/dist/types/src/components/TextEditor/themes/default.d.ts.map +1 -1
  38. package/dist/types/src/hooks/automerge/PatchSemaphore.d.ts +3 -0
  39. package/dist/types/src/hooks/automerge/PatchSemaphore.d.ts.map +1 -1
  40. package/dist/types/src/hooks/automerge/automerge.stories.d.ts +8 -1
  41. package/dist/types/src/hooks/automerge/automerge.stories.d.ts.map +1 -1
  42. package/dist/types/src/hooks/automerge/index.d.ts +1 -1
  43. package/dist/types/src/hooks/automerge/index.d.ts.map +1 -1
  44. package/dist/types/src/hooks/automerge/plugin.d.ts.map +1 -1
  45. package/dist/types/src/hooks/automerge/translation/automerge-to-codemirror.d.ts +5 -0
  46. package/dist/types/src/hooks/automerge/translation/automerge-to-codemirror.d.ts.map +1 -0
  47. package/dist/types/src/hooks/automerge/translation/codemirror-to-automerge.d.ts +6 -0
  48. package/dist/types/src/hooks/automerge/translation/codemirror-to-automerge.d.ts.map +1 -0
  49. package/dist/types/src/hooks/automerge/translation/index.d.ts +3 -0
  50. package/dist/types/src/hooks/automerge/translation/index.d.ts.map +1 -0
  51. package/dist/types/src/{components/TextEditor → hooks/yjs}/yjs.stories.d.ts +1 -1
  52. package/dist/types/src/hooks/yjs/yjs.stories.d.ts.map +1 -0
  53. package/dist/types/src/styles/markdown.d.ts +3 -2
  54. package/dist/types/src/styles/markdown.d.ts.map +1 -1
  55. package/package.json +20 -19
  56. package/src/components/TextEditor/MarkdownEditor.stories.tsx +106 -29
  57. package/src/components/TextEditor/TextEditor.tsx +12 -8
  58. package/src/components/TextEditor/extensions/autocomplete.ts +5 -20
  59. package/src/components/TextEditor/extensions/basic.ts +2 -1
  60. package/src/components/TextEditor/extensions/blast.ts +387 -0
  61. package/src/components/TextEditor/extensions/comments.ts +59 -60
  62. package/src/components/TextEditor/extensions/demo.ts +69 -0
  63. package/src/components/TextEditor/extensions/experimental.tsx +14 -35
  64. package/src/components/TextEditor/extensions/image.ts +67 -0
  65. package/src/components/TextEditor/extensions/index.ts +5 -0
  66. package/src/components/TextEditor/extensions/link.ts +17 -25
  67. package/src/components/TextEditor/extensions/listener.ts +4 -4
  68. package/src/components/TextEditor/extensions/markdown/bundle.ts +30 -19
  69. package/src/components/TextEditor/extensions/markdown/highlight.ts +147 -108
  70. package/src/components/TextEditor/extensions/mention.ts +31 -0
  71. package/src/components/TextEditor/extensions/table.ts +122 -0
  72. package/src/components/TextEditor/extensions/tasklist.ts +41 -27
  73. package/src/components/TextEditor/themes/default.ts +54 -2
  74. package/src/hooks/automerge/PatchSemaphore.ts +12 -9
  75. package/src/hooks/automerge/automerge.stories.tsx +3 -2
  76. package/src/hooks/automerge/index.ts +1 -1
  77. package/src/hooks/automerge/plugin.ts +1 -0
  78. package/src/hooks/automerge/{amToCodemirror.ts → translation/automerge-to-codemirror.ts} +10 -2
  79. package/src/hooks/automerge/{codeMirrorToAm.ts → translation/codemirror-to-automerge.ts} +7 -4
  80. package/src/hooks/automerge/translation/index.ts +6 -0
  81. package/src/{components/TextEditor → hooks/yjs}/yjs.stories.tsx +1 -1
  82. package/src/styles/markdown.ts +14 -8
  83. package/dist/types/src/components/TextEditor/yjs.stories.d.ts.map +0 -1
  84. package/dist/types/src/hooks/automerge/amToCodemirror.d.ts +0 -6
  85. package/dist/types/src/hooks/automerge/amToCodemirror.d.ts.map +0 -1
  86. package/dist/types/src/hooks/automerge/codeMirrorToAm.d.ts +0 -7
  87. package/dist/types/src/hooks/automerge/codeMirrorToAm.d.ts.map +0 -1
@@ -24,13 +24,13 @@ var autocomplete = ({ onSearch }) => {
24
24
  // TODO(burdon): Optional decoration via addToOptions
25
25
  override: [
26
26
  (context) => {
27
- const word = context.matchBefore(/\w*/);
28
- if (!word || word.from === word.to && !context.explicit) {
27
+ const match = context.matchBefore(/\w*/);
28
+ if (!match || match.from === match.to && !context.explicit) {
29
29
  return null;
30
30
  }
31
31
  return {
32
- from: word.from,
33
- options: onSearch(word.text.toLowerCase())
32
+ from: match.from,
33
+ options: onSearch(match.text.toLowerCase())
34
34
  };
35
35
  }
36
36
  ]
@@ -43,7 +43,7 @@ import { closeBrackets } from "@codemirror/autocomplete";
43
43
  import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@codemirror/language";
44
44
  import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
45
45
  import { EditorView, placeholder } from "@codemirror/view";
46
- var basicBundle = ({ themeMode, placeholder: _placeholder }) => [
46
+ var basicBundle = ({ readonly, themeMode, placeholder: _placeholder }) => [
47
47
  // TODO(burdon): Compare with minimalSetup.
48
48
  // https://codemirror.net/docs/ref/#codemirror.minimalSetup
49
49
  bracketMatching(),
@@ -54,18 +54,413 @@ var basicBundle = ({ themeMode, placeholder: _placeholder }) => [
54
54
  themeMode === "dark" ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle)
55
55
  ].filter(Boolean);
56
56
 
57
- // packages/ui/react-ui-editor/src/components/TextEditor/extensions/comments.ts
58
- import { Decoration, EditorView as EditorView2, keymap as keymap2, MatchDecorator, ViewPlugin, WidgetType } from "@codemirror/view";
57
+ // packages/ui/react-ui-editor/src/components/TextEditor/extensions/blast.ts
58
+ import { StateField } from "@codemirror/state";
59
+ import { EditorView as EditorView2, keymap as keymap2 } from "@codemirror/view";
60
+ import defaultsDeep from "lodash.defaultsdeep";
59
61
  import { invariant } from "@dxos/invariant";
60
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/extensions/comments.ts";
62
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/extensions/blast.ts";
63
+ var defaultOptions = {
64
+ effect: 2,
65
+ maxParticles: 200,
66
+ particleGravity: 0.08,
67
+ particleAlphaFadeout: 0.996,
68
+ particleSize: {
69
+ min: 2,
70
+ max: 8
71
+ },
72
+ particleNumRange: {
73
+ min: 5,
74
+ max: 10
75
+ },
76
+ particleVelocityRange: {
77
+ x: [
78
+ -1,
79
+ 1
80
+ ],
81
+ y: [
82
+ -3.5,
83
+ -1.5
84
+ ]
85
+ },
86
+ particleShrinkRate: 0.95,
87
+ shakeIntensity: 5
88
+ };
89
+ var blast = (options) => {
90
+ let blaster;
91
+ let last = 0;
92
+ const getPoint = (view, pos) => {
93
+ const { left: x = 0, top: y = 0 } = view.coordsForChar(pos) ?? {};
94
+ const element = document.elementFromPoint(x, y);
95
+ const { offsetLeft: left = 0, offsetTop: top = 0 } = view.scrollDOM.parentElement ?? {};
96
+ const point = {
97
+ x: x - left,
98
+ y: y - top
99
+ };
100
+ return {
101
+ element,
102
+ point
103
+ };
104
+ };
105
+ return [
106
+ // Cursor moved.
107
+ EditorView2.updateListener.of((update4) => {
108
+ if (blaster?.node !== update4.view.scrollDOM) {
109
+ if (blaster) {
110
+ blaster.destroy();
111
+ }
112
+ blaster = new Blaster(update4.view.scrollDOM, defaultsDeep({
113
+ particleGravity: 0.2,
114
+ particleShrinkRate: 0.995,
115
+ color: () => [
116
+ 100 + Math.random() * 100,
117
+ 0,
118
+ 0
119
+ ]
120
+ }, options, defaultOptions));
121
+ blaster.initialize();
122
+ blaster.start();
123
+ } else {
124
+ blaster.resize();
125
+ }
126
+ const current = update4.view.state.selection.main.head;
127
+ if (current !== last) {
128
+ last = current;
129
+ const { element, point } = getPoint(update4.view, current);
130
+ if (element && point) {
131
+ blaster.spawn({
132
+ element,
133
+ point
134
+ });
135
+ }
136
+ }
137
+ }),
138
+ // Document changed.
139
+ StateField.define({
140
+ create: () => null,
141
+ update: (_value, transaction) => {
142
+ if (blaster && transaction.docChanged) {
143
+ const view = EditorView2.findFromDOM(blaster.node);
144
+ const { element, point } = getPoint(view, transaction.selection.main.head);
145
+ if (element && point) {
146
+ blaster.spawn({
147
+ element,
148
+ point
149
+ });
150
+ }
151
+ }
152
+ return null;
153
+ }
154
+ }),
155
+ keymap2.of([
156
+ {
157
+ any: (view, event) => {
158
+ if (blaster && event.key === "Enter" && event.shiftKey) {
159
+ blaster.shake({
160
+ time: 0.4
161
+ });
162
+ }
163
+ return false;
164
+ }
165
+ }
166
+ ])
167
+ ];
168
+ };
169
+ var Blaster = class {
170
+ constructor(_node, _options) {
171
+ this._node = _node;
172
+ this._options = _options;
173
+ this._running = false;
174
+ this._shakeTime = 0;
175
+ this._shakeTimeMax = 0;
176
+ this._particles = [];
177
+ this._particlePointer = 0;
178
+ this._lastPoint = {
179
+ x: 0,
180
+ y: 0
181
+ };
182
+ this.shake = throttle(({ time }) => {
183
+ this._shakeTime = this._shakeTimeMax;
184
+ this._shakeTimeMax = time;
185
+ }, 100);
186
+ this.spawn = throttle(({ element, point }) => {
187
+ const color = getRGBComponents(element, this._options.color);
188
+ const numParticles = random(this._options.particleNumRange.min, this._options.particleNumRange.max);
189
+ const dir = this._lastPoint.x === point.x ? 0 : this._lastPoint.x < point.x ? 1 : -1;
190
+ this._lastPoint = point;
191
+ for (let i = numParticles; i--; i > 0) {
192
+ this._particles[this._particlePointer] = this._effect.create(point.x - dir * 16, point.y, color);
193
+ this._particlePointer = (this._particlePointer + 1) % this._options.maxParticles;
194
+ }
195
+ }, 100);
196
+ this._effect = this._options.effect === 1 ? new Effect1(_options) : new Effect2(_options);
197
+ }
198
+ get node() {
199
+ return this._node;
200
+ }
201
+ initialize() {
202
+ invariant(!this._canvas && !this._ctx, void 0, {
203
+ F: __dxlog_file,
204
+ L: 152,
205
+ S: this,
206
+ A: [
207
+ "!this._canvas && !this._ctx",
208
+ ""
209
+ ]
210
+ });
211
+ this._canvas = document.createElement("canvas");
212
+ this._canvas.id = "code-blast-canvas";
213
+ this._canvas.style.position = "absolute";
214
+ this._canvas.style.zIndex = "0";
215
+ this._canvas.style.pointerEvents = "none";
216
+ this._ctx = this._canvas.getContext("2d");
217
+ const parent = this._node.parentElement?.parentElement;
218
+ parent?.appendChild(this._canvas);
219
+ this.resize();
220
+ }
221
+ destroy() {
222
+ this.stop();
223
+ if (this._canvas) {
224
+ this._canvas.remove();
225
+ this._canvas = void 0;
226
+ this._ctx = void 0;
227
+ }
228
+ }
229
+ resize() {
230
+ if (this._node.parentElement && this._canvas) {
231
+ const { offsetLeft: x, offsetTop: y, offsetWidth: width, offsetHeight: height } = this._node.parentElement;
232
+ this._canvas.style.top = `${y}px`;
233
+ this._canvas.style.left = `${x}px`;
234
+ this._canvas.width = width;
235
+ this._canvas.height = height;
236
+ }
237
+ }
238
+ start() {
239
+ invariant(this._canvas && this._ctx, void 0, {
240
+ F: __dxlog_file,
241
+ L: 191,
242
+ S: this,
243
+ A: [
244
+ "this._canvas && this._ctx",
245
+ ""
246
+ ]
247
+ });
248
+ this._running = true;
249
+ this.loop();
250
+ }
251
+ stop() {
252
+ this._running = false;
253
+ this._node.style.transform = "translate(0px, 0px)";
254
+ }
255
+ loop() {
256
+ if (!this._running || !this._canvas || !this._ctx) {
257
+ return;
258
+ }
259
+ this._ctx.clearRect(0, 0, this._canvas.width ?? 0, this._canvas.height ?? 0);
260
+ const now = (/* @__PURE__ */ new Date()).getTime();
261
+ this._lastTime ??= now;
262
+ const dt = (now - this._lastTime) / 1e3;
263
+ this._lastTime = now;
264
+ if (this._shakeTime > 0) {
265
+ this._shakeTime -= dt;
266
+ const magnitude = this._shakeTime / this._shakeTimeMax * this._options.shakeIntensity;
267
+ const shakeX = random(-magnitude, magnitude);
268
+ const shakeY = random(-magnitude, magnitude);
269
+ this._node.style.transform = `translate(${shakeX}px,${shakeY}px)`;
270
+ }
271
+ this.drawParticles();
272
+ requestAnimationFrame(this.loop.bind(this));
273
+ }
274
+ drawParticles() {
275
+ for (let i = this._particles.length; i--; i > 0) {
276
+ const particle = this._particles[i];
277
+ if (!particle) {
278
+ continue;
279
+ }
280
+ if (particle.alpha < 0.01 || particle.size <= 0.5) {
281
+ continue;
282
+ }
283
+ this._effect.update(this._ctx, particle);
284
+ }
285
+ }
286
+ };
287
+ var Effect = class {
288
+ constructor(_options) {
289
+ this._options = _options;
290
+ }
291
+ };
292
+ var Effect1 = class extends Effect {
293
+ create(x, y, color) {
294
+ return {
295
+ x,
296
+ y: y + 10,
297
+ vx: random(this._options.particleVelocityRange.x[0], this._options.particleVelocityRange.x[1]),
298
+ vy: random(this._options.particleVelocityRange.y[0], this._options.particleVelocityRange.y[1]),
299
+ size: random(this._options.particleSize.min, this._options.particleSize.max),
300
+ color,
301
+ alpha: 1
302
+ };
303
+ }
304
+ update(ctx, particle) {
305
+ particle.vy += this._options.particleGravity;
306
+ particle.x += particle.vx;
307
+ particle.y += particle.vy;
308
+ particle.alpha *= this._options.particleAlphaFadeout;
309
+ ctx.fillStyle = `rgba(${particle.color[0]},${particle.color[1]},${particle.color[2]},${particle.alpha})`;
310
+ ctx.fillRect(Math.round(particle.x - 1), Math.round(particle.y - 1), particle.size, particle.size);
311
+ }
312
+ };
313
+ var Effect2 = class extends Effect {
314
+ create(x, y, color) {
315
+ return {
316
+ x,
317
+ y: y + 10,
318
+ vx: random(this._options.particleVelocityRange.x[0], this._options.particleVelocityRange.x[1]),
319
+ vy: random(this._options.particleVelocityRange.y[0], this._options.particleVelocityRange.y[1]),
320
+ size: random(this._options.particleSize.min, this._options.particleSize.max),
321
+ color,
322
+ alpha: 1,
323
+ theta: random(0, 360) * Math.PI / 180,
324
+ drag: 0.92,
325
+ wander: 0.15
326
+ };
327
+ }
328
+ update(ctx, particle) {
329
+ particle.vy += this._options.particleGravity;
330
+ particle.x += particle.vx;
331
+ particle.y += particle.vy;
332
+ particle.vx *= particle.drag;
333
+ particle.vy *= particle.drag;
334
+ particle.theta += random(-0.5, 0.5);
335
+ particle.vx += Math.sin(particle.theta) * 0.1;
336
+ particle.vy += Math.cos(particle.theta) * 0.1;
337
+ particle.size *= this._options.particleShrinkRate;
338
+ particle.alpha *= this._options.particleAlphaFadeout;
339
+ ctx.fillStyle = `rgba(${particle.color[0]},${particle.color[1]},${particle.color[2]},${particle.alpha})`;
340
+ ctx.beginPath();
341
+ ctx.arc(Math.round(particle.x - 1), Math.round(particle.y - 1), particle.size, 0, 2 * Math.PI);
342
+ ctx.fill();
343
+ }
344
+ };
345
+ function throttle(callback, limit) {
346
+ let wait = false;
347
+ return function(...args) {
348
+ if (!wait) {
349
+ callback.apply(this, args);
350
+ wait = true;
351
+ setTimeout(() => {
352
+ wait = false;
353
+ }, limit);
354
+ }
355
+ };
356
+ }
357
+ var getRGBComponents = (node, color) => {
358
+ if (typeof color === "function") {
359
+ return color();
360
+ }
361
+ const bgColor = getComputedStyle(node).color;
362
+ if (bgColor) {
363
+ const x = bgColor.match(/(\d+), (\d+), (\d+)/)?.slice(1);
364
+ if (x) {
365
+ return x;
366
+ }
367
+ }
368
+ return [
369
+ 50,
370
+ 50,
371
+ 50
372
+ ];
373
+ };
374
+ var random = (min, max) => {
375
+ if (!max) {
376
+ max = min;
377
+ min = 0;
378
+ }
379
+ return min + ~~(Math.random() * (max - min + 1));
380
+ };
381
+
382
+ // packages/ui/react-ui-editor/src/components/TextEditor/extensions/demo.ts
383
+ import { keymap as keymap3 } from "@codemirror/view";
384
+ var defaultItems = [
385
+ "hello world!",
386
+ "this is a test.",
387
+ "this is [DXOS](https://dxos.org)"
388
+ ];
389
+ var demo = ({ delay = 75, items = defaultItems } = {}) => {
390
+ let t;
391
+ let idx = 0;
392
+ return [
393
+ keymap3.of([
394
+ {
395
+ // Reset.
396
+ key: "alt-meta-'",
397
+ run: (view) => {
398
+ clearTimeout(t);
399
+ idx = 0;
400
+ return true;
401
+ }
402
+ },
403
+ {
404
+ // Next prompt.
405
+ // TODO(burdon): Press 1-9 to select prompt?
406
+ key: "shift-meta-'",
407
+ run: (view) => {
408
+ clearTimeout(t);
409
+ const text = items[idx++];
410
+ if (idx === items?.length) {
411
+ idx = 0;
412
+ }
413
+ let i = 0;
414
+ const insert = (d = 0) => {
415
+ t = setTimeout(() => {
416
+ const pos = view.state.selection.main.head;
417
+ view.dispatch({
418
+ changes: {
419
+ from: pos,
420
+ insert: text[i++]
421
+ },
422
+ selection: {
423
+ anchor: pos + 1
424
+ }
425
+ });
426
+ if (i < text.length) {
427
+ insert(Math.random() * delay * (text[i] === " " ? 2 : 1));
428
+ }
429
+ }, d);
430
+ };
431
+ insert();
432
+ return true;
433
+ }
434
+ }
435
+ ])
436
+ ];
437
+ };
438
+
439
+ // packages/ui/react-ui-editor/src/components/TextEditor/extensions/comments.ts
440
+ import { keymap as keymap4, Decoration, EditorView as EditorView3, MatchDecorator, ViewPlugin, WidgetType } from "@codemirror/view";
441
+ import { debounce } from "@dxos/async";
442
+ import { invariant as invariant2 } from "@dxos/invariant";
443
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/extensions/comments.ts";
444
+ var styles = EditorView3.baseTheme({
445
+ "& .cm-bookmark": {
446
+ cursor: "pointer",
447
+ margin: "4px",
448
+ padding: "4px",
449
+ backgroundColor: "yellow"
450
+ },
451
+ "& .cm-bookmark-selected": {
452
+ backgroundColor: "orange"
453
+ }
454
+ });
61
455
  var BookmarkWidget = class extends WidgetType {
62
- constructor(_pos, _id) {
456
+ constructor(_pos, _id, _handleClick) {
63
457
  super();
64
458
  this._pos = _pos;
65
459
  this._id = _id;
66
- invariant(this._id, void 0, {
67
- F: __dxlog_file,
68
- L: 40,
460
+ this._handleClick = _handleClick;
461
+ invariant2(this._id, void 0, {
462
+ F: __dxlog_file2,
463
+ L: 37,
69
464
  S: this,
70
465
  A: [
71
466
  "this._id",
@@ -76,30 +471,25 @@ var BookmarkWidget = class extends WidgetType {
76
471
  eq(other) {
77
472
  return this._id === other._id;
78
473
  }
79
- // TODO(burdon): Click to select.
80
474
  toDOM() {
81
475
  const span = document.createElement("span");
82
476
  span.className = "cm-bookmark";
83
- span.textContent = "\u{1F4AC}";
477
+ span.textContent = "\xA7";
478
+ span.onclick = () => this._handleClick();
84
479
  return span;
85
480
  }
86
481
  };
87
- var styles = EditorView2.baseTheme({
88
- "& .cm-bookmark": {
89
- cursor: "pointer",
90
- margin: "4px",
91
- padding: "4px",
92
- backgroundColor: "yellow"
93
- }
94
- });
95
482
  var comments = (options = {}) => {
483
+ let active;
96
484
  const bookmarkMatcher = new MatchDecorator({
97
485
  regexp: /\[\^(\w+)\]/g,
98
486
  decoration: (match, view, pos) => {
99
487
  const id = match[1];
100
488
  return Decoration.replace({
101
489
  id,
102
- widget: new BookmarkWidget(pos, id)
490
+ widget: new BookmarkWidget(pos, id, () => handleUpdate({
491
+ active: id
492
+ }))
103
493
  });
104
494
  }
105
495
  });
@@ -107,19 +497,22 @@ var comments = (options = {}) => {
107
497
  constructor(view) {
108
498
  this.bookmarks = bookmarkMatcher.createDeco(view);
109
499
  }
110
- update(update2) {
111
- this.bookmarks = bookmarkMatcher.updateDeco(update2, this.bookmarks);
500
+ update(update4) {
501
+ this.bookmarks = bookmarkMatcher.updateDeco(update4, this.bookmarks);
112
502
  }
113
503
  }, {
114
504
  decorations: (instance) => instance.bookmarks,
115
- provide: (plugin) => EditorView2.atomicRanges.of((view) => {
505
+ provide: (plugin) => EditorView3.atomicRanges.of((view) => {
116
506
  return view.plugin(plugin)?.bookmarks || Decoration.none;
117
507
  })
118
508
  });
509
+ const handleUpdate = debounce((data) => {
510
+ options.onUpdate?.(data);
511
+ }, 200);
119
512
  return [
120
- keymap2.of([
513
+ keymap4.of([
121
514
  {
122
- key: options?.key ?? "alt-meta-c",
515
+ key: options?.key ?? "shift-meta-c",
123
516
  run: (view) => {
124
517
  const id = options.onCreate?.();
125
518
  if (id) {
@@ -142,42 +535,108 @@ var comments = (options = {}) => {
142
535
  ]),
143
536
  bookmarks,
144
537
  // Monitor cursor movement.
145
- EditorView2.updateListener.of((update2) => {
146
- const view = update2.view;
538
+ EditorView3.updateListener.of((update4) => {
539
+ active = void 0;
540
+ if (!options.onUpdate) {
541
+ return;
542
+ }
543
+ const view = update4.view;
147
544
  const pos = view.state.selection.main.head;
148
545
  const decorations = [];
149
546
  const rangeSet = view.plugin(bookmarks)?.bookmarks;
150
- rangeSet?.between(pos, pos + 1, (from, to, value) => {
151
- if (value.spec.widget) {
152
- decorations.push({
153
- from,
154
- to,
155
- value
156
- });
547
+ let closest = Infinity;
548
+ const { from, to } = (
549
+ /* view.visibleRanges?.[0] ?? */
550
+ {
551
+ from: 0,
552
+ to: view.state.doc.length
553
+ }
554
+ );
555
+ rangeSet?.between(from, to, (from2, to2, value) => {
556
+ decorations.push({
557
+ from: from2,
558
+ to: to2,
559
+ value
560
+ });
561
+ const d = Math.min(Math.abs(pos - from2), Math.abs(pos - to2));
562
+ if (d < closest) {
563
+ active = value.spec.id;
564
+ closest = d;
157
565
  }
158
566
  });
159
567
  if (decorations.length) {
160
- const { from, value: { spec: { id } } } = decorations[0];
161
- const location = view.coordsAtPos(from);
162
- if (location) {
163
- options.onUpdate?.({
164
- items: decorations.map(({ value: { spec: { id: id2 } } }) => id2),
165
- active: id,
166
- pos,
167
- location
168
- });
169
- }
568
+ handleUpdate({
569
+ active,
570
+ items: decorations.map(({ from: from2, value: { spec: { id } } }) => ({
571
+ id,
572
+ pos: from2,
573
+ location: view.coordsAtPos(from2)
574
+ }))
575
+ });
170
576
  }
171
577
  }),
172
578
  styles
173
579
  ];
174
580
  };
175
581
 
176
- // packages/ui/react-ui-editor/src/components/TextEditor/extensions/link.ts
582
+ // packages/ui/react-ui-editor/src/components/TextEditor/extensions/image.ts
177
583
  import { syntaxTree } from "@codemirror/language";
178
- import { RangeSetBuilder, StateField } from "@codemirror/state";
179
- import { Decoration as Decoration2, EditorView as EditorView3, WidgetType as WidgetType2 } from "@codemirror/view";
180
- var LinkButton = class extends WidgetType2 {
584
+ import { RangeSetBuilder, StateField as StateField2 } from "@codemirror/state";
585
+ import { Decoration as Decoration2, EditorView as EditorView4, WidgetType as WidgetType2 } from "@codemirror/view";
586
+ var image = (options = {}) => {
587
+ return StateField2.define({
588
+ create: (state) => update(state, options),
589
+ update: (_, tr) => update(tr.state, options),
590
+ provide: (field) => EditorView4.decorations.from(field)
591
+ });
592
+ };
593
+ var update = (state, options) => {
594
+ const builder = new RangeSetBuilder();
595
+ const cursor = state.selection.main.head;
596
+ syntaxTree(state).iterate({
597
+ enter: (node) => {
598
+ if (node.name === "Image") {
599
+ const urlNode = node.node.getChild("URL");
600
+ if (urlNode) {
601
+ const hide = state.readOnly || cursor < node.from || cursor > node.to;
602
+ const url = state.sliceDoc(urlNode.from, urlNode.to);
603
+ builder.add(hide ? node.from : node.to, node.to, Decoration2.replace({
604
+ widget: new ImageWidget(url)
605
+ }));
606
+ }
607
+ }
608
+ }
609
+ });
610
+ return builder.finish();
611
+ };
612
+ var ImageWidget = class extends WidgetType2 {
613
+ constructor(_url) {
614
+ super();
615
+ this._url = _url;
616
+ }
617
+ eq(other) {
618
+ return this._url === other?._url;
619
+ }
620
+ toDOM(view) {
621
+ const img = document.createElement("img");
622
+ img.setAttribute("src", this._url);
623
+ img.setAttribute("class", "cm-image");
624
+ return img;
625
+ }
626
+ };
627
+
628
+ // packages/ui/react-ui-editor/src/components/TextEditor/extensions/link.ts
629
+ import { syntaxTree as syntaxTree2 } from "@codemirror/language";
630
+ import { RangeSetBuilder as RangeSetBuilder2, StateField as StateField3 } from "@codemirror/state";
631
+ import { Decoration as Decoration3, EditorView as EditorView5, WidgetType as WidgetType3 } from "@codemirror/view";
632
+ var link = (options = {}) => {
633
+ return StateField3.define({
634
+ create: (state) => update2(state, options),
635
+ update: (_, tr) => update2(tr.state, options),
636
+ provide: (field) => EditorView5.decorations.from(field)
637
+ });
638
+ };
639
+ var LinkButton = class extends WidgetType3 {
181
640
  constructor(_pos, _url, _onAttach) {
182
641
  super();
183
642
  this._pos = _pos;
@@ -193,7 +652,7 @@ var LinkButton = class extends WidgetType2 {
193
652
  return el;
194
653
  }
195
654
  };
196
- var LinkText = class extends WidgetType2 {
655
+ var LinkText = class extends WidgetType3 {
197
656
  constructor(_pos, _text, _url) {
198
657
  super();
199
658
  this._pos = _pos;
@@ -223,10 +682,10 @@ var LinkText = class extends WidgetType2 {
223
682
  return link2;
224
683
  }
225
684
  };
226
- var update = (state, options) => {
227
- const builder = new RangeSetBuilder();
685
+ var update2 = (state, options) => {
686
+ const builder = new RangeSetBuilder2();
228
687
  const cursor = state.selection.main.head;
229
- syntaxTree(state).iterate({
688
+ syntaxTree2(state).iterate({
230
689
  enter: (node) => {
231
690
  if (node.name === "Link") {
232
691
  const marks = node.node.getChildren("LinkMark");
@@ -236,13 +695,13 @@ var update = (state, options) => {
236
695
  if (!url) {
237
696
  return false;
238
697
  }
239
- if (cursor < node.from || cursor > node.to) {
240
- builder.add(node.from, node.to, Decoration2.replace({
698
+ if (state.readOnly || cursor < node.from || cursor > node.to) {
699
+ builder.add(node.from, node.to, Decoration3.replace({
241
700
  widget: new LinkText(node.from, text, options.link ? url : void 0)
242
701
  }));
243
702
  }
244
703
  if (options.onRender) {
245
- builder.add(node.to, node.to, Decoration2.replace({
704
+ builder.add(node.to, node.to, Decoration3.replace({
246
705
  widget: new LinkButton(node.from, url, options.onRender)
247
706
  }));
248
707
  }
@@ -252,52 +711,71 @@ var update = (state, options) => {
252
711
  });
253
712
  return builder.finish();
254
713
  };
255
- var link = (options = {}) => {
256
- return StateField.define({
257
- create: (state) => update(state, options),
258
- update: (_, tr) => update(tr.state, options),
259
- provide: (field) => EditorView3.decorations.from(field)
260
- });
261
- };
262
714
 
263
715
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/listener.ts
264
- import { StateField as StateField2 } from "@codemirror/state";
265
- var listener = (onChange) => StateField2.define({
266
- create: () => null,
267
- update: (_value, transaction) => {
268
- if (transaction.docChanged && onChange) {
269
- onChange(transaction.newDoc.toString());
716
+ import { StateField as StateField4 } from "@codemirror/state";
717
+ var listener = ({ onChange }) => {
718
+ return StateField4.define({
719
+ create: () => null,
720
+ update: (_value, transaction) => {
721
+ if (transaction.docChanged && onChange) {
722
+ onChange(transaction.newDoc.toString());
723
+ }
724
+ return null;
270
725
  }
271
- return null;
272
- }
273
- });
726
+ });
727
+ };
274
728
 
275
729
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/bundle.ts
276
730
  import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
277
- import { defaultKeymap, history, indentWithTab } from "@codemirror/commands";
731
+ import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
278
732
  import { markdownLanguage as markdownLanguage2, markdown } from "@codemirror/lang-markdown";
279
733
  import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
280
734
  import { languages } from "@codemirror/language-data";
281
735
  import { highlightSelectionMatches, searchKeymap } from "@codemirror/search";
282
736
  import { EditorState } from "@codemirror/state";
283
737
  import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/theme-one-dark";
284
- import { crosshairCursor, drawSelection, dropCursor, EditorView as EditorView4, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, keymap as keymap3, placeholder as placeholder2, rectangularSelection } from "@codemirror/view";
738
+ import { crosshairCursor, drawSelection, dropCursor, EditorView as EditorView6, highlightActiveLine, highlightActiveLineGutter, highlightSpecialChars, keymap as keymap5, placeholder as placeholder2, rectangularSelection } from "@codemirror/view";
285
739
 
286
740
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/highlight.ts
287
741
  import { markdownLanguage } from "@codemirror/lang-markdown";
288
742
  import { HighlightStyle } from "@codemirror/language";
289
743
  import { tags, styleTags, Tag } from "@lezer/highlight";
744
+ import { Table } from "@lezer/markdown";
290
745
  import get from "lodash.get";
746
+ import { mx as mx2 } from "@dxos/react-ui-theme";
291
747
 
292
748
  // packages/ui/react-ui-editor/src/styles/markdown.ts
293
749
  import { mx } from "@dxos/react-ui-theme";
294
- var heading = {
295
- 1: "mbs-4 mbe-2 font-medium text-inherit no-underline text-4xl",
296
- 2: "mbs-4 mbe-2 font-medium text-inherit no-underline text-3xl",
297
- 3: "mbs-4 mbe-2 font-medium text-inherit no-underline text-2xl",
298
- 4: "mbs-4 mbe-2 font-medium text-inherit no-underline text-xl",
299
- 5: "mbs-4 mbe-2 font-medium text-inherit no-underline text-lg",
300
- 6: "mbs-4 mbe-2 font-medium text-inherit no-underline"
750
+ var headings = {
751
+ 1: [
752
+ "mbs-4 mbe-2 font-medium text-inherit no-underline text-4xl",
753
+ "-ml-1.5"
754
+ ],
755
+ 2: [
756
+ "mbs-4 mbe-2 font-medium text-inherit no-underline text-3xl",
757
+ "-ml-1.5"
758
+ ],
759
+ 3: [
760
+ "mbs-4 mbe-2 font-medium text-inherit no-underline text-2xl",
761
+ "-ml-1.5"
762
+ ],
763
+ 4: [
764
+ "mbs-4 mbe-2 font-medium text-inherit no-underline text-xl",
765
+ "-ml-[5px]"
766
+ ],
767
+ 5: [
768
+ "mbs-4 mbe-2 font-medium text-inherit no-underline text-lg",
769
+ "-ml-[5px]"
770
+ ],
771
+ 6: [
772
+ "mbs-4 mbe-2 font-medium text-inherit no-underline",
773
+ "-ml-[4px]"
774
+ ]
775
+ };
776
+ var heading = (level, readonly) => {
777
+ const [style, offset] = headings[level];
778
+ return mx(style, readonly && offset);
301
779
  };
302
780
  var light = "text-neutral-200 dark:text-neutral-800";
303
781
  var mark = mx("!font-normal !no-underline !text-inherit opacity-40", light);
@@ -308,7 +786,7 @@ var code = "font-mono !no-underline text-neutral-700 dark:text-neutral-300";
308
786
  var codeMark = "font-mono text-primary-500";
309
787
  var inlineUrl = mx(code, "px-1");
310
788
  var blockquote = mx("pl-1 mr-1 border-is-4 border-primary-500/70 dark:border-primary-500/30", light);
311
- var horizontalRule = "flex mlb-4 border-b text-neutral-100 dark:text-neutral-900 border-neutral-500/50";
789
+ var horizontalRule = "flex mlb-4 border-b text-neutral-100 dark:text-neutral-900 border-neutral-200 dark:border-neutral-800";
312
790
 
313
791
  // packages/ui/react-ui-editor/src/styles/tokens.ts
314
792
  import { tailwindConfig } from "@dxos/react-ui-theme";
@@ -327,159 +805,193 @@ var markdownTags = {
327
805
  LinkReference: Tag.define(),
328
806
  ListMark: Tag.define(),
329
807
  QuoteMark: Tag.define(),
330
- URL: Tag.define()
808
+ URL: Tag.define(),
809
+ // Custom.
810
+ TableCell: Tag.define()
331
811
  };
332
- var markdownTagsExtension = {
333
- props: [
334
- styleTags(markdownTags)
335
- ]
336
- };
337
- var markdownHighlightStyle = HighlightStyle.define([
338
- {
339
- tag: [
340
- tags.keyword,
341
- tags.name,
342
- tags.deleted,
343
- tags.character,
344
- tags.propertyName,
345
- tags.macroName,
346
- tags.color,
347
- tags.constant(tags.name),
348
- tags.standard(tags.name),
349
- tags.definition(tags.name),
350
- tags.separator,
351
- tags.typeName,
352
- tags.className,
353
- tags.number,
354
- tags.changed,
355
- tags.annotation,
356
- tags.modifier,
357
- tags.self,
358
- tags.namespace,
359
- tags.operator,
360
- tags.operatorKeyword,
361
- tags.escape,
362
- tags.regexp,
363
- tags.special(tags.string),
364
- tags.meta,
365
- tags.comment,
366
- tags.atom,
367
- tags.bool,
368
- tags.special(tags.variableName),
369
- tags.processingInstruction,
370
- tags.string,
371
- tags.inserted,
372
- tags.invalid
373
- ],
374
- color: "inherit !important"
375
- },
376
- // Markdown marks.
377
- {
378
- tag: [
379
- tags.meta,
380
- tags.processingInstruction,
381
- markdownTags.CodeMark,
382
- markdownTags.EmphasisMark,
383
- markdownTags.HeaderMark,
384
- markdownTags.LinkLabel,
385
- markdownTags.LinkReference,
386
- markdownTags.ListMark,
387
- markdownTags.QuoteMark
388
- ],
389
- class: mark
390
- },
391
- // Headings.
392
- {
393
- tag: tags.heading1,
394
- class: heading[1]
395
- },
396
- {
397
- tag: tags.heading2,
398
- class: heading[2]
399
- },
400
- {
401
- tag: tags.heading3,
402
- class: heading[3]
403
- },
404
- {
405
- tag: tags.heading4,
406
- class: heading[4]
407
- },
408
- {
409
- tag: tags.heading5,
410
- class: heading[5]
411
- },
412
- {
413
- tag: tags.heading6,
414
- class: heading[6]
415
- },
416
- // Emphasis.
417
- {
418
- tag: tags.emphasis,
419
- class: italic
420
- },
421
- {
422
- tag: tags.strong,
423
- class: bold
424
- },
425
- {
426
- tag: tags.strikethrough,
427
- class: strikethrough
428
- },
429
- // Naked URLs.
430
- {
431
- tag: [
432
- markdownTags.URL
433
- ],
434
- class: inlineUrl
435
- },
436
- // E.g., code block language (after ```).
437
- {
438
- tag: [
439
- tags.function(tags.variableName),
440
- tags.labelName
441
- ],
442
- class: codeMark
443
- },
444
- // NOTE: The `markdown` extension configures extensions for `lezer` to parse markdown tokens (incl. below).
445
- // However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
446
- // when a language is specified. In this case, the syntax highlighting extensions will colorize
447
- // the code, but all other CSS properties will be inherited.
448
- // IMPORTANT: Therefore, the fenced code block will use the base editor font.
449
- {
450
- tag: [
451
- markdownTags.CodeText,
452
- markdownTags.InlineCode
453
- ],
454
- class: code
455
- },
456
- {
457
- tag: [
458
- markdownTags.QuoteMark
459
- ],
460
- class: blockquote
461
- },
462
- {
463
- tag: [
464
- markdownTags.HorizontalRule
465
- ],
466
- class: horizontalRule
467
- }
468
- ], {
469
- scope: markdownLanguage,
470
- all: {
471
- fontFamily: get(tokens, "fontFamily.body", []).join(",")
812
+ Table.defineNodes?.forEach((node) => {
813
+ switch (node?.name) {
814
+ case "TableCell": {
815
+ node.style = markdownTags.TableCell;
816
+ break;
817
+ }
472
818
  }
473
819
  });
820
+ var markdownTagsExtensions = [
821
+ Table,
822
+ {
823
+ props: [
824
+ styleTags(markdownTags)
825
+ ]
826
+ }
827
+ ];
828
+ var markdownHighlightStyle = (readonly) => {
829
+ return HighlightStyle.define([
830
+ {
831
+ tag: [
832
+ tags.keyword,
833
+ tags.name,
834
+ tags.deleted,
835
+ tags.character,
836
+ tags.propertyName,
837
+ tags.macroName,
838
+ tags.color,
839
+ tags.constant(tags.name),
840
+ tags.standard(tags.name),
841
+ tags.definition(tags.name),
842
+ tags.separator,
843
+ tags.typeName,
844
+ tags.className,
845
+ tags.number,
846
+ tags.changed,
847
+ tags.annotation,
848
+ tags.modifier,
849
+ tags.self,
850
+ tags.namespace,
851
+ tags.operator,
852
+ tags.operatorKeyword,
853
+ tags.escape,
854
+ tags.regexp,
855
+ tags.special(tags.string),
856
+ tags.meta,
857
+ tags.comment,
858
+ tags.atom,
859
+ tags.bool,
860
+ tags.special(tags.variableName),
861
+ tags.processingInstruction,
862
+ tags.string,
863
+ tags.inserted,
864
+ tags.invalid
865
+ ],
866
+ color: "inherit !important"
867
+ },
868
+ // Markdown marks.
869
+ {
870
+ tag: [
871
+ tags.meta,
872
+ tags.processingInstruction,
873
+ markdownTags.LinkLabel,
874
+ markdownTags.LinkReference,
875
+ markdownTags.ListMark
876
+ ],
877
+ class: mark
878
+ },
879
+ // Markdown marks.
880
+ {
881
+ tag: [
882
+ markdownTags.CodeMark,
883
+ markdownTags.HeaderMark,
884
+ markdownTags.QuoteMark,
885
+ markdownTags.EmphasisMark
886
+ ],
887
+ class: readonly ? "hidden" : mark
888
+ },
889
+ // E.g., code block language (after ```).
890
+ {
891
+ tag: [
892
+ tags.function(tags.variableName),
893
+ tags.labelName
894
+ ],
895
+ class: readonly ? "hidden" : codeMark
896
+ },
897
+ {
898
+ tag: [
899
+ tags.monospace
900
+ ],
901
+ class: "font-mono"
902
+ },
903
+ // Headings.
904
+ {
905
+ tag: tags.heading1,
906
+ class: heading(1, readonly)
907
+ },
908
+ {
909
+ tag: tags.heading2,
910
+ class: heading(2, readonly)
911
+ },
912
+ {
913
+ tag: tags.heading3,
914
+ class: heading(3, readonly)
915
+ },
916
+ {
917
+ tag: tags.heading4,
918
+ class: heading(4, readonly)
919
+ },
920
+ {
921
+ tag: tags.heading5,
922
+ class: heading(5, readonly)
923
+ },
924
+ {
925
+ tag: tags.heading6,
926
+ class: heading(6, readonly)
927
+ },
928
+ // Emphasis.
929
+ {
930
+ tag: tags.emphasis,
931
+ class: italic
932
+ },
933
+ {
934
+ tag: tags.strong,
935
+ class: bold
936
+ },
937
+ {
938
+ tag: tags.strikethrough,
939
+ class: strikethrough
940
+ },
941
+ // Naked URLs.
942
+ {
943
+ tag: [
944
+ markdownTags.URL
945
+ ],
946
+ class: inlineUrl
947
+ },
948
+ // NOTE: The `markdown` extension configures extensions for `lezer` to parse markdown tokens (incl. below).
949
+ // However, since `codeLanguages` is also defined, the `lezer` will not parse fenced code blocks,
950
+ // when a language is specified. In this case, the syntax highlighting extensions will colorize
951
+ // the code, but all other CSS properties will be inherited.
952
+ // IMPORTANT: Therefore, the fenced code block will use the base editor font.
953
+ {
954
+ tag: [
955
+ markdownTags.CodeText,
956
+ markdownTags.InlineCode
957
+ ],
958
+ class: code
959
+ },
960
+ {
961
+ tag: [
962
+ markdownTags.QuoteMark
963
+ ],
964
+ class: blockquote
965
+ },
966
+ {
967
+ tag: [
968
+ markdownTags.HorizontalRule
969
+ ],
970
+ class: mx2(horizontalRule, readonly && "-indent-[100rem]")
971
+ },
972
+ // TODO(burdon): Only if being edited.
973
+ {
974
+ tag: [
975
+ markdownTags.TableCell
976
+ ],
977
+ class: "font-mono"
978
+ }
979
+ ], {
980
+ scope: markdownLanguage,
981
+ all: {
982
+ fontFamily: get(tokens, "fontFamily.body", []).join(",")
983
+ }
984
+ });
985
+ };
474
986
 
475
987
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/markdown/bundle.ts
476
- var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
988
+ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
477
989
  return [
478
990
  bracketMatching2(),
479
991
  closeBrackets2(),
480
992
  _placeholder && placeholder2(_placeholder),
481
993
  EditorState.allowMultipleSelections.of(true),
482
- EditorView4.lineWrapping,
994
+ EditorView6.lineWrapping,
483
995
  crosshairCursor(),
484
996
  dropCursor(),
485
997
  drawSelection(),
@@ -490,16 +1002,7 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
490
1002
  history(),
491
1003
  indentOnInput(),
492
1004
  rectangularSelection(),
493
- // TODO(burdon): Review.
494
- keymap3.of([
495
- ...closeBracketsKeymap,
496
- ...defaultKeymap,
497
- // ...foldKeymap,
498
- // ...historyKeymap,
499
- // ...lintKeymap,
500
- ...searchKeymap,
501
- indentWithTab
502
- ]),
1005
+ customkeymap(),
503
1006
  // Main extension.
504
1007
  // https://github.com/codemirror/lang-markdown
505
1008
  // https://codemirror.net/5/mode/markdown/index.html (demo).
@@ -514,20 +1017,153 @@ var markdownBundle = ({ themeMode, placeholder: _placeholder }) => {
514
1017
  codeLanguages: languages,
515
1018
  // Parser extensions.
516
1019
  extensions: [
517
- // GFM, // TODO(burdon): Provided by default?
518
- markdownTagsExtension
1020
+ // GFM provided by default.
1021
+ markdownTagsExtensions
519
1022
  ]
520
1023
  }),
1024
+ // https://github.com/codemirror/theme-one-dark
1025
+ themeMode === "dark" ? syntaxHighlighting2(oneDarkHighlightStyle2) : syntaxHighlighting2(defaultHighlightStyle2),
521
1026
  // Custom styles.
522
- syntaxHighlighting2(markdownHighlightStyle),
523
- // TODO(thure): All but one rule here apply to both themes; rename or refactor.
524
- themeMode === "dark" ? syntaxHighlighting2(oneDarkHighlightStyle2) : syntaxHighlighting2(defaultHighlightStyle2)
1027
+ syntaxHighlighting2(markdownHighlightStyle(readonly))
525
1028
  ].filter(Boolean);
526
1029
  };
1030
+ var customkeymap = () => keymap5.of([
1031
+ // https://codemirror.net/docs/ref/#commands.indentWithTab
1032
+ indentWithTab,
1033
+ // https://codemirror.net/docs/ref/#commands.standardKeymap
1034
+ ...standardKeymap,
1035
+ // https://codemirror.net/docs/ref/#commands.historyKeymap
1036
+ ...historyKeymap,
1037
+ // https://codemirror.net/docs/ref/#autocomplete.closeBracketsKeymap
1038
+ ...closeBracketsKeymap,
1039
+ // https://codemirror.net/docs/ref/#search.searchKeymap
1040
+ ...searchKeymap
1041
+ ]);
1042
+
1043
+ // packages/ui/react-ui-editor/src/components/TextEditor/extensions/mention.ts
1044
+ import { autocompletion as autocompletion2 } from "@codemirror/autocomplete";
1045
+ var mention = ({ onSearch }) => {
1046
+ return autocompletion2({
1047
+ closeOnBlur: false,
1048
+ override: [
1049
+ (context) => {
1050
+ const match = context.matchBefore(/@(\w+)?/);
1051
+ if (!match || match.from === match.to && !context.explicit) {
1052
+ return null;
1053
+ }
1054
+ console.log(match);
1055
+ return {
1056
+ from: match.from,
1057
+ options: onSearch(match.text.slice(1).toLowerCase()).map((value) => ({
1058
+ label: `@${value}`
1059
+ }))
1060
+ };
1061
+ }
1062
+ ]
1063
+ });
1064
+ };
1065
+
1066
+ // packages/ui/react-ui-editor/src/components/TextEditor/extensions/table.ts
1067
+ import { syntaxTree as syntaxTree3 } from "@codemirror/language";
1068
+ import { RangeSetBuilder as RangeSetBuilder3, StateField as StateField5 } from "@codemirror/state";
1069
+ import { Decoration as Decoration4, EditorView as EditorView7, WidgetType as WidgetType4 } from "@codemirror/view";
1070
+ var table = (options = {}) => {
1071
+ return StateField5.define({
1072
+ create: (state) => update3(state, options),
1073
+ update: (_, tr) => update3(tr.state, options),
1074
+ provide: (field) => EditorView7.decorations.from(field)
1075
+ });
1076
+ };
1077
+ var update3 = (state, options) => {
1078
+ const builder = new RangeSetBuilder3();
1079
+ const cursor = state.selection.main.head;
1080
+ const tables = [];
1081
+ const getTable = () => tables[tables.length - 1];
1082
+ const getRow = () => {
1083
+ const table2 = getTable();
1084
+ return table2.rows?.[table2.rows.length - 1];
1085
+ };
1086
+ syntaxTree3(state).iterate({
1087
+ enter: (node) => {
1088
+ switch (node.name) {
1089
+ case "Table": {
1090
+ tables.push({
1091
+ from: node.from,
1092
+ to: node.to
1093
+ });
1094
+ break;
1095
+ }
1096
+ case "TableHeader": {
1097
+ getTable().header = [];
1098
+ break;
1099
+ }
1100
+ case "TableRow": {
1101
+ (getTable().rows ??= []).push([]);
1102
+ break;
1103
+ }
1104
+ case "TableCell": {
1105
+ const row = getRow();
1106
+ if (row) {
1107
+ row.push(state.sliceDoc(node.from, node.to));
1108
+ } else {
1109
+ getTable().header?.push(state.sliceDoc(node.from, node.to));
1110
+ }
1111
+ break;
1112
+ }
1113
+ }
1114
+ }
1115
+ });
1116
+ tables.forEach((table2) => {
1117
+ const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
1118
+ hide && builder.add(table2.from, table2.to, Decoration4.replace({
1119
+ widget: new TableWidget(table2)
1120
+ }));
1121
+ });
1122
+ return builder.finish();
1123
+ };
1124
+ var TableWidget = class extends WidgetType4 {
1125
+ constructor(_table) {
1126
+ super();
1127
+ this._table = _table;
1128
+ }
1129
+ eq(other) {
1130
+ return this._table.from === other?._table?.from;
1131
+ }
1132
+ toDOM(view) {
1133
+ const table2 = document.createElement("table");
1134
+ {
1135
+ const header = table2.appendChild(document.createElement("thead"));
1136
+ const tr = header.appendChild(document.createElement("tr"));
1137
+ this._table.header?.forEach((cell) => {
1138
+ const th = document.createElement("th");
1139
+ th.setAttribute("class", "cm-table-head");
1140
+ tr.appendChild(th).textContent = cell;
1141
+ });
1142
+ }
1143
+ {
1144
+ const body = table2.appendChild(document.createElement("tbody"));
1145
+ this._table.rows?.forEach((row) => {
1146
+ const tr = body.appendChild(document.createElement("tr"));
1147
+ row.forEach((cell) => {
1148
+ const td = document.createElement("td");
1149
+ td.setAttribute("class", "cm-table-cell");
1150
+ tr.appendChild(td).textContent = cell;
1151
+ });
1152
+ });
1153
+ }
1154
+ return table2;
1155
+ }
1156
+ };
527
1157
 
528
1158
  // packages/ui/react-ui-editor/src/components/TextEditor/extensions/tasklist.ts
529
- import { EditorView as EditorView5, Decoration as Decoration3, WidgetType as WidgetType3, MatchDecorator as MatchDecorator2, ViewPlugin as ViewPlugin2 } from "@codemirror/view";
530
- var CheckboxWidget = class extends WidgetType3 {
1159
+ import { EditorView as EditorView8, Decoration as Decoration5, WidgetType as WidgetType5, MatchDecorator as MatchDecorator2, ViewPlugin as ViewPlugin2 } from "@codemirror/view";
1160
+ var styles2 = EditorView8.baseTheme({
1161
+ "& .cm-task-item": {
1162
+ paddingLeft: "4px",
1163
+ paddingRight: "8px"
1164
+ }
1165
+ });
1166
+ var CheckboxWidget = class extends WidgetType5 {
531
1167
  constructor(_pos, _checked, _indent, _onCheck) {
532
1168
  super();
533
1169
  this._pos = _pos;
@@ -546,30 +1182,29 @@ var CheckboxWidget = class extends WidgetType3 {
546
1182
  const input = wrap.appendChild(document.createElement("input"));
547
1183
  input.type = "checkbox";
548
1184
  input.checked = this._checked;
549
- input.onchange = (event) => {
550
- this._onCheck(event.target.checked);
551
- return true;
552
- };
1185
+ if (!this._onCheck) {
1186
+ input.setAttribute("disabled", "true");
1187
+ }
1188
+ if (this._onCheck) {
1189
+ input.onchange = (event) => {
1190
+ this._onCheck?.(event.target.checked);
1191
+ return true;
1192
+ };
1193
+ }
553
1194
  return wrap;
554
1195
  }
555
1196
  ignoreEvent() {
556
1197
  return false;
557
1198
  }
558
1199
  };
559
- var styles2 = EditorView5.baseTheme({
560
- "& .cm-task-item": {
561
- paddingLeft: "4px",
562
- paddingRight: "8px"
563
- }
564
- });
565
- var tasklist = () => {
1200
+ var tasklist = (options = {}) => {
566
1201
  const taskMatcher = new MatchDecorator2({
567
1202
  regexp: /^(\s*)- \[([ xX])\]\s/g,
568
1203
  decoration: (match, view, pos) => {
569
1204
  const indent = Math.floor(match[1].length / 2);
570
1205
  const checked = match[2] === "x" || match[2] === "X";
571
- return Decoration3.replace({
572
- widget: new CheckboxWidget(pos, checked, indent, (checked2) => {
1206
+ return Decoration5.replace({
1207
+ widget: new CheckboxWidget(pos, checked, indent, view.state.readOnly ? void 0 : (checked2) => {
573
1208
  const idx = pos + match[0].indexOf("[") + 1;
574
1209
  view.dispatch({
575
1210
  changes: {
@@ -590,13 +1225,13 @@ var tasklist = () => {
590
1225
  constructor(view) {
591
1226
  this.tasks = taskMatcher.createDeco(view);
592
1227
  }
593
- update(update2) {
594
- this.tasks = taskMatcher.updateDeco(update2, this.tasks);
1228
+ update(update4) {
1229
+ this.tasks = taskMatcher.updateDeco(update4, this.tasks);
595
1230
  }
596
1231
  }, {
597
1232
  decorations: (instance) => instance.tasks,
598
- provide: (plugin) => EditorView5.atomicRanges.of((view) => {
599
- return view.plugin(plugin)?.tasks || Decoration3.none;
1233
+ provide: (plugin) => EditorView8.atomicRanges.of((view) => {
1234
+ return view.plugin(plugin)?.tasks || Decoration5.none;
600
1235
  })
601
1236
  });
602
1237
  return [
@@ -763,8 +1398,51 @@ var defaultTheme = {
763
1398
  "& .cm-tooltip": {
764
1399
  border: "none"
765
1400
  },
766
- // '& .cm-tooltip-below': {},
767
- // '& .cm-tooltip-autocomplete': {},
1401
+ "& .cm-tooltip-below": {},
1402
+ //
1403
+ // autocomplete
1404
+ //
1405
+ "& .cm-tooltip-autocomplete": {
1406
+ marginTop: "4px",
1407
+ marginLeft: "-3px"
1408
+ },
1409
+ "& .cm-tooltip-autocomplete ul li": {},
1410
+ "& .cm-tooltip-autocomplete ul li[aria-selected]": {},
1411
+ "& .cm-completionIcon": {
1412
+ display: "none"
1413
+ },
1414
+ "& .cm-completionLabel": {
1415
+ fontFamily: get2(tokens, "fontFamily.body", []).join(",")
1416
+ },
1417
+ "& .cm-completionMatchedText": {
1418
+ textDecoration: "none"
1419
+ },
1420
+ //
1421
+ // widgets
1422
+ //
1423
+ "& .cm-widgetBuffer": {
1424
+ display: "none",
1425
+ height: 0
1426
+ },
1427
+ //
1428
+ // table
1429
+ //
1430
+ "& .cm-table-head": {
1431
+ padding: "2px 16px 2px 0px",
1432
+ borderBottom: `1px solid ${get2(tokens, "extend.colors.neutral.500")}`,
1433
+ fontWeight: 100,
1434
+ textAlign: "left",
1435
+ color: get2(tokens, "extend.colors.neutral.500")
1436
+ },
1437
+ "& .cm-table-cell": {
1438
+ padding: "2px 16px 2px 0px"
1439
+ },
1440
+ //
1441
+ // image
1442
+ //
1443
+ "& .cm-image": {
1444
+ margin: "0.5rem 0"
1445
+ },
768
1446
  //
769
1447
  // font size
770
1448
  // TODO(thure): This appears to be the best or only way to set selection caret heights, but it's far more verbose than it needs to be.
@@ -814,19 +1492,19 @@ var codeTheme = {
814
1492
 
815
1493
  // packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
816
1494
  import { EditorState as EditorState2 } from "@codemirror/state";
817
- import { EditorView as EditorView6 } from "@codemirror/view";
1495
+ import { EditorView as EditorView9 } from "@codemirror/view";
818
1496
  import { useFocusableGroup } from "@fluentui/react-tabster";
819
1497
  import { vim } from "@replit/codemirror-vim";
820
- import defaultsDeep from "lodash.defaultsdeep";
1498
+ import defaultsDeep2 from "lodash.defaultsdeep";
821
1499
  import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from "react";
822
1500
  import { generateName } from "@dxos/display-name";
823
1501
  import { useThemeContext } from "@dxos/react-ui";
824
- import { getColorForValue, inputSurface, mx as mx2 } from "@dxos/react-ui-theme";
1502
+ import { getColorForValue, inputSurface, mx as mx3 } from "@dxos/react-ui-theme";
825
1503
  var EditorModes = [
826
1504
  "default",
827
1505
  "vim"
828
1506
  ];
829
- var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots = defaultSlots, editorMode }, forwardedRef) => {
1507
+ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, editorMode, extensions = [], slots = defaultSlots }, forwardedRef) => {
830
1508
  const { themeMode } = useThemeContext();
831
1509
  const tabsterDOMAttribute = useFocusableGroup({
832
1510
  tabBehavior: "limited"
@@ -871,13 +1549,14 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
871
1549
  const state2 = EditorState2.create({
872
1550
  doc: model.text(),
873
1551
  extensions: [
1552
+ readonly && EditorState2.readOnly.of(readonly),
874
1553
  // TODO(burdon): Factor out VIM mode?
875
1554
  editorMode === "vim" && vim(),
876
1555
  // Theme.
877
- EditorView6.baseTheme(defaultTheme),
878
- EditorView6.theme(slots?.editor?.theme ?? {}),
1556
+ EditorView9.baseTheme(defaultTheme),
1557
+ EditorView9.theme(slots?.editor?.theme ?? {}),
879
1558
  // TODO(burdon): themeMode doesn't change in storybooks.
880
- EditorView6.darkTheme.of(themeMode === "dark"),
1559
+ EditorView9.darkTheme.of(themeMode === "dark"),
881
1560
  // Storage and replication.
882
1561
  model.extension,
883
1562
  // Custom.
@@ -885,7 +1564,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
885
1564
  ].filter(Boolean)
886
1565
  });
887
1566
  view?.destroy();
888
- setView(new EditorView6({
1567
+ setView(new EditorView9({
889
1568
  state: state2,
890
1569
  parent: root
891
1570
  }));
@@ -899,6 +1578,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
899
1578
  root,
900
1579
  model,
901
1580
  themeMode,
1581
+ readonly,
902
1582
  editorMode
903
1583
  ]);
904
1584
  const handleKeyUp = useCallback((event) => {
@@ -926,13 +1606,15 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, extensions = [], slots
926
1606
  onKeyUp: handleKeyUp
927
1607
  });
928
1608
  });
929
- var TextEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slots, ...props }, forwardedRef) => {
1609
+ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
930
1610
  const { themeMode } = useThemeContext();
931
- const slots = defaultsDeep({}, _slots, defaultTextSlots);
1611
+ const slots = defaultsDeep2({}, _slots, defaultTextSlots);
932
1612
  return /* @__PURE__ */ React.createElement(BaseTextEditor, {
933
1613
  ref: forwardedRef,
1614
+ readonly,
934
1615
  extensions: [
935
1616
  basicBundle({
1617
+ readonly,
936
1618
  themeMode,
937
1619
  placeholder: slots?.editor?.placeholder
938
1620
  }),
@@ -942,13 +1624,15 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slots, .
942
1624
  ...props
943
1625
  });
944
1626
  });
945
- var MarkdownEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slots, ...props }, forwardedRef) => {
1627
+ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
946
1628
  const { themeMode } = useThemeContext();
947
- const slots = defaultsDeep({}, _slots, defaultMarkdownSlots);
1629
+ const slots = defaultsDeep2({}, _slots, defaultMarkdownSlots);
948
1630
  return /* @__PURE__ */ React.createElement(BaseTextEditor, {
949
1631
  ref: forwardedRef,
1632
+ readonly,
950
1633
  extensions: [
951
1634
  markdownBundle({
1635
+ readonly,
952
1636
  themeMode,
953
1637
  placeholder: slots?.editor?.placeholder
954
1638
  }),
@@ -960,7 +1644,7 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ extensions = [], slots: _slot
960
1644
  });
961
1645
  var defaultSlots = {
962
1646
  root: {
963
- className: mx2("p-2", inputSurface)
1647
+ className: mx3("p-2", inputSurface)
964
1648
  }
965
1649
  };
966
1650
  var defaultTextSlots = {
@@ -980,20 +1664,20 @@ var defaultMarkdownSlots = {
980
1664
  import get3 from "lodash.get";
981
1665
  import { useEffect as useEffect2, useState as useState2 } from "react";
982
1666
  import { yCollab } from "y-codemirror.next";
983
- import { invariant as invariant2 } from "@dxos/invariant";
1667
+ import { invariant as invariant3 } from "@dxos/invariant";
984
1668
  import { getRawDoc, isActualAutomergeObject } from "@dxos/react-client/echo";
985
1669
 
986
1670
  // packages/ui/react-ui-editor/src/hooks/automerge/plugin.ts
987
- import { Annotation, Facet, StateEffect, StateField as StateField3 } from "@codemirror/state";
1671
+ import { Annotation, Facet, StateEffect, StateField as StateField6 } from "@codemirror/state";
988
1672
  import { ViewPlugin as ViewPlugin3 } from "@codemirror/view";
989
1673
  import * as automerge2 from "@dxos/automerge/automerge";
990
1674
 
991
1675
  // packages/ui/react-ui-editor/src/hooks/automerge/PatchSemaphore.ts
992
1676
  import { next as automerge } from "@dxos/automerge/automerge";
993
1677
 
994
- // packages/ui/react-ui-editor/src/hooks/automerge/amToCodemirror.ts
1678
+ // packages/ui/react-ui-editor/src/hooks/automerge/translation/automerge-to-codemirror.ts
995
1679
  import { ChangeSet } from "@codemirror/state";
996
- var amToCodemirror_default = (view, selection, target, patches) => {
1680
+ var automergeToCodemirror = (view, selection, target, patches) => {
997
1681
  for (const patch of patches) {
998
1682
  const changeSpec = handlePatch(patch, target, view.state);
999
1683
  if (changeSpec != null) {
@@ -1098,9 +1782,9 @@ var charPath = (textPath, candidatePath) => {
1098
1782
  return null;
1099
1783
  };
1100
1784
 
1101
- // packages/ui/react-ui-editor/src/hooks/automerge/codeMirrorToAm.ts
1785
+ // packages/ui/react-ui-editor/src/hooks/automerge/translation/codemirror-to-automerge.ts
1102
1786
  import { next as am } from "@dxos/automerge/automerge";
1103
- var codeMirrorToAm_default = (field, handle, transactions, state) => {
1787
+ var codemirrorToAutomerge = (field, handle, transactions, state) => {
1104
1788
  const { lastHeads, path } = state.field(field);
1105
1789
  let hasChanges = false;
1106
1790
  for (const tr of transactions) {
@@ -1144,12 +1828,12 @@ var PatchSemaphore = class {
1144
1828
  annotations: reconcileAnnotationType.of(true)
1145
1829
  });
1146
1830
  }
1147
- let newHeads = codeMirrorToAm_default(this._field, handle, transactions, view.state);
1831
+ let newHeads = codemirrorToAutomerge(this._field, handle, transactions, view.state);
1148
1832
  if (newHeads === null || newHeads === void 0) {
1149
1833
  newHeads = automerge.getHeads(handle.docSync());
1150
1834
  }
1151
1835
  const diff = automerge.equals(oldHeads, newHeads) ? [] : automerge.diff(handle.docSync(), oldHeads, newHeads);
1152
- amToCodemirror_default(view, selection, path, diff);
1836
+ automergeToCodemirror(view, selection, path, diff);
1153
1837
  view.dispatch({
1154
1838
  effects: updateHeads(newHeads),
1155
1839
  annotations: reconcileAnnotationType.of({})
@@ -1173,7 +1857,7 @@ var semaphoreFacet = Facet.define({
1173
1857
  combine: (values) => values.at(-1)
1174
1858
  });
1175
1859
  var automergePlugin = (handle, path) => {
1176
- const stateField = StateField3.define({
1860
+ const stateField = StateField6.define({
1177
1861
  create: () => ({
1178
1862
  lastHeads: automerge2.getHeads(handle.docSync()),
1179
1863
  unreconciledTransactions: [],
@@ -1211,8 +1895,8 @@ var automergePlugin = (handle, path) => {
1211
1895
  this._view = view;
1212
1896
  handle.addListener("change", this._handleChange);
1213
1897
  }
1214
- update(update2) {
1215
- if (update2.transactions.length > 0 && update2.transactions.some((t) => !isReconcileTx(t))) {
1898
+ update(update4) {
1899
+ if (update4.transactions.length > 0 && update4.transactions.some((t) => !isReconcileTx(t))) {
1216
1900
  queueMicrotask(() => {
1217
1901
  this._view.state.facet(semaphoreFacet).reconcile(handle, this._view);
1218
1902
  });
@@ -1234,7 +1918,7 @@ var reconcileAnnotationType = Annotation.define();
1234
1918
  var isReconcileTx = (tr) => !!tr.annotation(reconcileAnnotationType);
1235
1919
 
1236
1920
  // packages/ui/react-ui-editor/src/hooks/yjs/cursors.ts
1237
- import * as random from "lib0/random";
1921
+ import * as random2 from "lib0/random";
1238
1922
  var cursorColors = [
1239
1923
  {
1240
1924
  color: "#30bced",
@@ -1269,7 +1953,7 @@ var cursorColors = [
1269
1953
  light: "#1be7ff33"
1270
1954
  }
1271
1955
  ];
1272
- var cursorColor = cursorColors[random.uint32() % cursorColors.length];
1956
+ var cursorColor = cursorColors[random2.uint32() % cursorColors.length];
1273
1957
 
1274
1958
  // packages/ui/react-ui-editor/src/hooks/yjs/space-provider.ts
1275
1959
  import * as decoding from "lib0/decoding";
@@ -1277,7 +1961,7 @@ import * as encoding from "lib0/encoding";
1277
1961
  import { Observable } from "lib0/observable";
1278
1962
  import * as awarenessProtocol from "y-protocols/awareness";
1279
1963
  import { log } from "@dxos/log";
1280
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/yjs/space-provider.ts";
1964
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/yjs/space-provider.ts";
1281
1965
  var messageAwareness = 1;
1282
1966
  var messageQueryAwareness = 3;
1283
1967
  var SpaceAwarenessProvider = class extends Observable {
@@ -1314,7 +1998,7 @@ var SpaceAwarenessProvider = class extends Observable {
1314
1998
  removed,
1315
1999
  origin
1316
2000
  }, {
1317
- F: __dxlog_file2,
2001
+ F: __dxlog_file3,
1318
2002
  L: 67,
1319
2003
  S: this,
1320
2004
  C: (f, a) => f(...a)
@@ -1327,7 +2011,7 @@ var SpaceAwarenessProvider = class extends Observable {
1327
2011
  }
1328
2012
  _handleSpaceMessage({ payload }) {
1329
2013
  log("space message", payload, {
1330
- F: __dxlog_file2,
2014
+ F: __dxlog_file3,
1331
2015
  L: 79,
1332
2016
  S: this,
1333
2017
  C: (f, a) => f(...a)
@@ -1372,7 +2056,7 @@ var SpaceAwarenessProvider = class extends Observable {
1372
2056
  };
1373
2057
 
1374
2058
  // packages/ui/react-ui-editor/src/hooks/useTextModel.ts
1375
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
2059
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
1376
2060
  var useTextModel = ({ identity, space, text }) => {
1377
2061
  const [model, setModel] = useState2(() => createModel({
1378
2062
  identity,
@@ -1404,8 +2088,8 @@ var createModel = (options) => {
1404
2088
  }
1405
2089
  };
1406
2090
  var createYjsModel = ({ identity, space, text }) => {
1407
- invariant2(text?.doc && text?.content, void 0, {
1408
- F: __dxlog_file3,
2091
+ invariant3(text?.doc && text?.content, void 0, {
2092
+ F: __dxlog_file4,
1409
2093
  L: 74,
1410
2094
  S: void 0,
1411
2095
  A: [
@@ -1458,20 +2142,26 @@ export {
1458
2142
  YXmlFragment,
1459
2143
  autocomplete,
1460
2144
  basicBundle,
2145
+ blast,
1461
2146
  codeTheme,
1462
2147
  comments,
1463
2148
  cursorColor,
1464
2149
  defaultMarkdownSlots,
2150
+ defaultOptions,
1465
2151
  defaultSlots,
1466
2152
  defaultTextSlots,
1467
2153
  defaultTheme,
2154
+ demo,
2155
+ image,
1468
2156
  link,
1469
2157
  listener,
1470
2158
  markdownBundle,
1471
2159
  markdownHighlightStyle,
1472
2160
  markdownTags,
1473
- markdownTagsExtension,
2161
+ markdownTagsExtensions,
1474
2162
  markdownTheme,
2163
+ mention,
2164
+ table,
1475
2165
  tags2 as tags,
1476
2166
  tasklist,
1477
2167
  textTheme,