@dxos/react-ui-editor 0.3.11-main.008b7c6 → 0.3.11-main.08776d7

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 (102) hide show
  1. package/dist/lib/browser/index.mjs +745 -810
  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 +12 -5
  5. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
  6. package/dist/types/src/components/TextEditor/TextEditor.d.ts +16 -19
  7. package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
  8. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +6 -6
  9. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +1 -1
  10. package/dist/types/src/components/TextEditor/comments.stories.d.ts +26 -0
  11. package/dist/types/src/components/TextEditor/comments.stories.d.ts.map +1 -0
  12. package/dist/types/src/components/TextEditor/yjs.stories.d.ts +1 -1
  13. package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
  14. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  15. package/dist/types/src/extensions/automerge/cursor.d.ts +1 -1
  16. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
  17. package/dist/types/src/extensions/automerge/defs.d.ts +6 -8
  18. package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
  19. package/dist/types/src/extensions/automerge/semaphore.d.ts +7 -11
  20. package/dist/types/src/extensions/automerge/semaphore.d.ts.map +1 -1
  21. package/dist/types/src/extensions/code.d.ts.map +1 -1
  22. package/dist/types/src/extensions/comments.d.ts +26 -17
  23. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  24. package/dist/types/src/{util → extensions}/cursor.d.ts +10 -2
  25. package/dist/types/src/extensions/cursor.d.ts.map +1 -0
  26. package/dist/types/src/extensions/hr.d.ts.map +1 -1
  27. package/dist/types/src/extensions/image.d.ts.map +1 -1
  28. package/dist/types/src/extensions/index.d.ts +3 -1
  29. package/dist/types/src/extensions/index.d.ts.map +1 -1
  30. package/dist/types/src/extensions/link.d.ts.map +1 -1
  31. package/dist/types/src/extensions/markdown/highlight.d.ts.map +1 -1
  32. package/dist/types/src/extensions/outliner.d.ts +4 -0
  33. package/dist/types/src/extensions/outliner.d.ts.map +1 -0
  34. package/dist/types/src/extensions/sync.d.ts +7 -0
  35. package/dist/types/src/extensions/sync.d.ts.map +1 -0
  36. package/dist/types/src/extensions/tasklist.d.ts +5 -1
  37. package/dist/types/src/extensions/tasklist.d.ts.map +1 -1
  38. package/dist/types/src/extensions/yjs/cursor.d.ts +1 -1
  39. package/dist/types/src/extensions/yjs/cursor.d.ts.map +1 -1
  40. package/dist/types/src/hooks/automerge.d.ts +2 -1
  41. package/dist/types/src/hooks/automerge.d.ts.map +1 -1
  42. package/dist/types/src/hooks/defs.d.ts +28 -0
  43. package/dist/types/src/hooks/defs.d.ts.map +1 -0
  44. package/dist/types/src/hooks/index.d.ts +2 -1
  45. package/dist/types/src/hooks/index.d.ts.map +1 -1
  46. package/dist/types/src/hooks/useTextModel.d.ts +2 -32
  47. package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
  48. package/dist/types/src/hooks/yjs.d.ts +2 -1
  49. package/dist/types/src/hooks/yjs.d.ts.map +1 -1
  50. package/dist/types/src/index.d.ts +3 -0
  51. package/dist/types/src/index.d.ts.map +1 -1
  52. package/dist/types/src/styles/markdown.d.ts.map +1 -1
  53. package/dist/types/src/styles/tokens.d.ts +1 -0
  54. package/dist/types/src/styles/tokens.d.ts.map +1 -1
  55. package/dist/types/src/themes/default.d.ts.map +1 -1
  56. package/dist/types/src/util.d.ts.map +1 -0
  57. package/package.json +25 -24
  58. package/src/components/TextEditor/MarkdownEditor.stories.tsx +45 -41
  59. package/src/components/TextEditor/TextEditor.stories.tsx +12 -46
  60. package/src/components/TextEditor/TextEditor.tsx +101 -89
  61. package/src/components/TextEditor/comments.stories.tsx +362 -0
  62. package/src/extensions/autocomplete.ts +18 -17
  63. package/src/extensions/automerge/automerge.ts +15 -46
  64. package/src/extensions/automerge/cursor.ts +2 -1
  65. package/src/extensions/automerge/defs.ts +13 -14
  66. package/src/extensions/automerge/semaphore.ts +21 -16
  67. package/src/extensions/awareness.ts +27 -33
  68. package/src/extensions/code.ts +28 -23
  69. package/src/extensions/comments.ts +234 -236
  70. package/src/extensions/cursor.ts +50 -0
  71. package/src/extensions/hr.ts +10 -12
  72. package/src/extensions/image.ts +40 -22
  73. package/src/extensions/index.ts +3 -1
  74. package/src/extensions/link.ts +86 -88
  75. package/src/extensions/markdown/highlight.ts +3 -12
  76. package/src/extensions/outliner.ts +12 -0
  77. package/src/extensions/sync.ts +15 -0
  78. package/src/extensions/table.ts +10 -4
  79. package/src/extensions/tasklist.ts +54 -79
  80. package/src/extensions/yjs/cursor.ts +2 -1
  81. package/src/extensions/yjs/yjs.test.ts +1 -1
  82. package/src/extensions/yjs/yjs.ts +2 -2
  83. package/src/hooks/automerge.ts +2 -1
  84. package/src/hooks/defs.ts +47 -0
  85. package/src/hooks/index.ts +3 -1
  86. package/src/hooks/useTextModel.ts +3 -49
  87. package/src/hooks/yjs.ts +2 -23
  88. package/src/index.ts +3 -0
  89. package/src/styles/markdown.ts +0 -2
  90. package/src/styles/tokens.ts +3 -0
  91. package/src/themes/default.ts +51 -78
  92. package/dist/types/src/extensions/mermaid.d.ts +0 -3
  93. package/dist/types/src/extensions/mermaid.d.ts.map +0 -1
  94. package/dist/types/src/util/cursor.d.ts.map +0 -1
  95. package/dist/types/src/util/index.d.ts +0 -3
  96. package/dist/types/src/util/index.d.ts.map +0 -1
  97. package/dist/types/src/util/util.d.ts.map +0 -1
  98. package/src/extensions/mermaid.ts +0 -11
  99. package/src/util/cursor.ts +0 -29
  100. package/src/util/index.ts +0 -6
  101. /package/dist/types/src/{util/util.d.ts → util.d.ts} +0 -0
  102. /package/src/{util/util.ts → util.ts} +0 -0
@@ -16,7 +16,7 @@ import {
16
16
  import { Event } from '@dxos/async';
17
17
  import { Context } from '@dxos/context';
18
18
 
19
- import { CursorConverter } from '../util';
19
+ import { Cursor, type CursorConverter } from './cursor';
20
20
 
21
21
  export interface AwarenessProvider {
22
22
  remoteStateChange: Event<void>;
@@ -91,7 +91,7 @@ export class RemoteSelectionsDecorator implements PluginValue {
91
91
  private _lastHead?: number = undefined;
92
92
 
93
93
  constructor(view: EditorView) {
94
- this._cursorConverter = view.state.facet(CursorConverter);
94
+ this._cursorConverter = view.state.facet(Cursor.converter);
95
95
  this._provider = view.state.facet(AwarenessProvider);
96
96
  this._provider.open();
97
97
  this._provider.remoteStateChange.on(this._ctx, () => {
@@ -156,7 +156,7 @@ export class RemoteSelectionsDecorator implements PluginValue {
156
156
  to: end,
157
157
  value: Decoration.mark({
158
158
  attributes: { style: `background-color: ${lightColor}` },
159
- class: 'cm-ySelection',
159
+ class: 'cm-collab-selection',
160
160
  }),
161
161
  });
162
162
  } else {
@@ -166,7 +166,7 @@ export class RemoteSelectionsDecorator implements PluginValue {
166
166
  to: startLine.from + startLine.length,
167
167
  value: Decoration.mark({
168
168
  attributes: { style: `background-color: ${color}` },
169
- class: 'cm-ySelection',
169
+ class: 'cm-collab-selection',
170
170
  }),
171
171
  });
172
172
 
@@ -176,7 +176,7 @@ export class RemoteSelectionsDecorator implements PluginValue {
176
176
  to: end,
177
177
  value: Decoration.mark({
178
178
  attributes: { style: `background-color: ${color}` },
179
- class: 'cm-ySelection',
179
+ class: 'cm-collab-selection',
180
180
  }),
181
181
  });
182
182
 
@@ -186,7 +186,7 @@ export class RemoteSelectionsDecorator implements PluginValue {
186
186
  from: linePos,
187
187
  to: linePos,
188
188
  value: Decoration.line({
189
- attributes: { style: `background-color: ${color}`, class: 'cm-yLineSelection' },
189
+ attributes: { style: `background-color: ${color}`, class: 'cm-collab-selectionLine' },
190
190
  }),
191
191
  });
192
192
  }
@@ -208,24 +208,22 @@ export class RemoteSelectionsDecorator implements PluginValue {
208
208
  }
209
209
 
210
210
  class RemoteCaretWidget extends WidgetType {
211
- constructor(public name: string, public color: string) {
211
+ constructor(private readonly _name: string, private readonly _color: string) {
212
212
  super();
213
- this.name = name;
214
- this.color = color;
215
213
  }
216
214
 
217
- toDOM(): HTMLElement {
215
+ override toDOM(): HTMLElement {
218
216
  const span = document.createElement('span');
219
- span.className = 'cm-ySelectionCaret';
220
- span.style.backgroundColor = this.color;
221
- span.style.borderColor = this.color;
217
+ span.className = 'cm-collab-selectionCaret';
218
+ span.style.backgroundColor = this._color;
219
+ span.style.borderColor = this._color;
222
220
 
223
221
  const dot = document.createElement('div');
224
- dot.className = 'cm-ySelectionCaretDot';
222
+ dot.className = 'cm-collab-selectionCaretDot';
225
223
 
226
224
  const info = document.createElement('div');
227
- info.className = 'cm-ySelectionInfo';
228
- info.innerText = this.name;
225
+ info.className = 'cm-collab-selectionInfo';
226
+ info.innerText = this._name;
229
227
 
230
228
  span.appendChild(document.createTextNode('\u2060'));
231
229
  span.appendChild(dot);
@@ -236,18 +234,14 @@ class RemoteCaretWidget extends WidgetType {
236
234
  return span;
237
235
  }
238
236
 
239
- override eq(widget: this) {
240
- return widget.color === this.color;
241
- }
242
-
243
- compare(widget: this) {
244
- return widget.color === this.color;
245
- }
246
-
247
237
  override updateDOM() {
248
238
  return false;
249
239
  }
250
240
 
241
+ override eq(widget: this) {
242
+ return widget._color === this._color;
243
+ }
244
+
251
245
  override get estimatedHeight() {
252
246
  return -1;
253
247
  }
@@ -257,14 +251,14 @@ class RemoteCaretWidget extends WidgetType {
257
251
  }
258
252
  }
259
253
 
260
- // TODO(burdon): Rename prefix (y for yjs?)
254
+ // TODO(burdon): Mixed case?
261
255
  const styles = EditorView.baseTheme({
262
- '.cm-ySelection': {},
263
- '.cm-yLineSelection': {
256
+ '.cm-collab-selection': {},
257
+ '.cm-collab-selectionLine': {
264
258
  padding: 0,
265
259
  margin: '0px 2px 0px 4px',
266
260
  },
267
- '.cm-ySelectionCaret': {
261
+ '.cm-collab-selectionCaret': {
268
262
  position: 'relative',
269
263
  borderLeft: '1px solid black',
270
264
  borderRight: '1px solid black',
@@ -273,7 +267,7 @@ const styles = EditorView.baseTheme({
273
267
  boxSizing: 'border-box',
274
268
  display: 'inline',
275
269
  },
276
- '.cm-ySelectionCaretDot': {
270
+ '.cm-collab-selectionCaretDot': {
277
271
  borderRadius: '50%',
278
272
  position: 'absolute',
279
273
  width: '.4em',
@@ -284,11 +278,11 @@ const styles = EditorView.baseTheme({
284
278
  transition: 'transform .3s ease-in-out',
285
279
  boxSizing: 'border-box',
286
280
  },
287
- '.cm-ySelectionCaret:hover > .cm-ySelectionCaretDot': {
281
+ '.cm-collab-selectionCaret:hover > .cm-collab-selectionCaretDot': {
288
282
  transformOrigin: 'bottom center',
289
283
  transform: 'scale(0)',
290
284
  },
291
- '.cm-ySelectionInfo': {
285
+ '.cm-collab-selectionInfo': {
292
286
  position: 'absolute',
293
287
  top: '-1.05em',
294
288
  left: '-1px',
@@ -304,12 +298,12 @@ const styles = EditorView.baseTheme({
304
298
  zIndex: 101,
305
299
  transition: 'opacity .3s ease-in-out',
306
300
  backgroundColor: 'inherit',
307
- // these should be separate
301
+ // These should be separate.
308
302
  opacity: 0,
309
303
  transitionDelay: '0s',
310
304
  whiteSpace: 'nowrap',
311
305
  },
312
- '.cm-ySelectionCaret:hover > .cm-ySelectionInfo': {
306
+ '.cm-collab-selectionCaret:hover > .cm-collab-selectionInfo': {
313
307
  opacity: 1,
314
308
  transitionDelay: '0s',
315
309
  },
@@ -11,24 +11,23 @@ import {
11
11
  Decoration,
12
12
  type BlockInfo,
13
13
  } from '@codemirror/view';
14
- import get from 'lodash.get';
15
14
 
16
15
  import { mx } from '@dxos/react-ui-theme';
17
16
 
18
- import { tokens } from '../styles';
17
+ import { getToken } from '../styles';
19
18
 
20
19
  const CODE_REGEX = /```[\s\S]*?```/gs;
21
20
 
22
21
  // TODO(burdon): Reconcile with theme.
23
22
  const styles = EditorView.baseTheme({
24
23
  '& .cm-codeblock': {
25
- fontFamily: get(tokens, 'fontFamily.mono', []).join(','),
24
+ fontFamily: getToken('fontFamily.mono', []).join(','),
26
25
  },
27
26
  '&light [aria-readonly="true"] .cm-codeblock': {
28
- background: get(tokens, 'extend.colors.neutral.50'),
27
+ background: getToken('extend.colors.neutral.50'),
29
28
  },
30
29
  '&dark [aria-readonly="true"] .cm-codeblock': {
31
- background: get(tokens, 'extend.colors.neutral.850'),
30
+ background: getToken('extend.colors.neutral.850'),
32
31
  },
33
32
  '& [aria-readonly="true"] .cm-codeblock': {
34
33
  display: 'block',
@@ -54,22 +53,20 @@ const getLineRange = (lines: BlockInfo[], from: number, to: number) => {
54
53
  };
55
54
 
56
55
  export const code = () => {
57
- const getDecorations = (view: EditorView) => {
56
+ const buildDecorations = (view: EditorView) => {
58
57
  const decorations: Range<Decoration>[] = [];
59
- if (view.state.readOnly) {
60
- const text = view.state.doc.sliceString(0);
61
- const matches = text.matchAll(CODE_REGEX);
62
- const blocks = view.viewportLineBlocks;
63
- for (const match of matches) {
64
- const range = getLineRange(blocks, match.index!, match.index! + match[0].length);
65
- for (let i = range[0]; i <= range[1]; i++) {
66
- const block = blocks[i];
67
- decorations.push(
68
- Decoration.line({
69
- class: mx('cm-codeblock', i === range[0] && 'cm-codeblock-first', i === range[1] && 'cm-codeblock-last'),
70
- }).range(block.from),
71
- );
72
- }
58
+ const text = view.state.doc.sliceString(0);
59
+ const matches = text.matchAll(CODE_REGEX);
60
+ const blocks = view.viewportLineBlocks;
61
+ for (const match of matches) {
62
+ const range = getLineRange(blocks, match.index!, match.index! + match[0].length);
63
+ for (let i = range[0]; i <= range[1]; i++) {
64
+ const block = blocks[i];
65
+ decorations.push(
66
+ Decoration.line({
67
+ class: mx('cm-codeblock', i === range[0] && 'cm-codeblock-first', i === range[1] && 'cm-codeblock-last'),
68
+ }).range(block.from),
69
+ );
73
70
  }
74
71
  }
75
72
 
@@ -79,14 +76,22 @@ export const code = () => {
79
76
  return [
80
77
  ViewPlugin.fromClass(
81
78
  class {
79
+ hasFocus = false;
82
80
  decorations: DecorationSet;
83
81
  constructor(view: EditorView) {
84
- this.decorations = getDecorations(view);
82
+ this.decorations = buildDecorations(view);
85
83
  }
86
84
 
87
85
  update(update: ViewUpdate) {
88
- if (update.docChanged || update.viewportChanged) {
89
- this.decorations = getDecorations(update.view);
86
+ if (
87
+ // TODO(burdon): Generalize for other extensions.
88
+ this.hasFocus !== update.view.hasFocus ||
89
+ update.startState.readOnly !== update.view.state.readOnly ||
90
+ update.docChanged ||
91
+ update.viewportChanged
92
+ ) {
93
+ this.hasFocus = update.view.hasFocus;
94
+ this.decorations = buildDecorations(update.view);
90
95
  }
91
96
  }
92
97
  },