@dxos/react-ui-editor 0.3.11-main.a8d7a97 → 0.3.11-main.b00882f

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 (81) hide show
  1. package/dist/lib/browser/index.mjs +690 -519
  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 +13 -14
  5. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
  6. package/dist/types/src/components/TextEditor/TextEditor.d.ts +14 -6
  7. package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +1 -1
  8. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts +1 -1
  9. package/dist/types/src/components/TextEditor/comments.stories.d.ts +1 -1
  10. package/dist/types/src/components/TextEditor/comments.stories.d.ts.map +1 -1
  11. package/dist/types/src/extensions/autocomplete.d.ts.map +1 -1
  12. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  13. package/dist/types/src/extensions/automerge/defs.d.ts +7 -9
  14. package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
  15. package/dist/types/src/extensions/automerge/index.d.ts +0 -1
  16. package/dist/types/src/extensions/automerge/index.d.ts.map +1 -1
  17. package/dist/types/src/extensions/automerge/semaphore.d.ts +7 -12
  18. package/dist/types/src/extensions/automerge/semaphore.d.ts.map +1 -1
  19. package/dist/types/src/extensions/automerge/update-automerge.d.ts +2 -2
  20. package/dist/types/src/extensions/awareness.d.ts +2 -0
  21. package/dist/types/src/extensions/awareness.d.ts.map +1 -1
  22. package/dist/types/src/extensions/basic.d.ts +4 -5
  23. package/dist/types/src/extensions/basic.d.ts.map +1 -1
  24. package/dist/types/src/extensions/code.d.ts.map +1 -1
  25. package/dist/types/src/extensions/comments.d.ts +30 -17
  26. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  27. package/dist/types/src/extensions/cursor.d.ts +3 -3
  28. package/dist/types/src/extensions/cursor.d.ts.map +1 -1
  29. package/dist/types/src/extensions/hr.d.ts.map +1 -1
  30. package/dist/types/src/extensions/index.d.ts +1 -0
  31. package/dist/types/src/extensions/index.d.ts.map +1 -1
  32. package/dist/types/src/extensions/markdown/bundle.d.ts +2 -5
  33. package/dist/types/src/extensions/markdown/bundle.d.ts.map +1 -1
  34. package/dist/types/src/extensions/mention.d.ts.map +1 -1
  35. package/dist/types/src/extensions/outliner.d.ts +4 -0
  36. package/dist/types/src/extensions/outliner.d.ts.map +1 -0
  37. package/dist/types/src/extensions/tasklist.d.ts.map +1 -1
  38. package/dist/types/src/hooks/automerge.d.ts +2 -1
  39. package/dist/types/src/hooks/automerge.d.ts.map +1 -1
  40. package/dist/types/src/hooks/defs.d.ts +28 -0
  41. package/dist/types/src/hooks/defs.d.ts.map +1 -0
  42. package/dist/types/src/hooks/index.d.ts +3 -1
  43. package/dist/types/src/hooks/index.d.ts.map +1 -1
  44. package/dist/types/src/hooks/useTextEditor.d.ts +17 -0
  45. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -0
  46. package/dist/types/src/hooks/useTextModel.d.ts +2 -27
  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/util.d.ts +2 -0
  51. package/dist/types/src/util.d.ts.map +1 -1
  52. package/package.json +32 -32
  53. package/src/components/TextEditor/MarkdownEditor.stories.tsx +64 -69
  54. package/src/components/TextEditor/TextEditor.tsx +97 -69
  55. package/src/components/TextEditor/comments.stories.tsx +113 -71
  56. package/src/extensions/autocomplete.ts +6 -3
  57. package/src/extensions/automerge/automerge.ts +39 -45
  58. package/src/extensions/automerge/defs.ts +10 -31
  59. package/src/extensions/automerge/index.ts +0 -1
  60. package/src/extensions/automerge/semaphore.ts +23 -20
  61. package/src/extensions/automerge/update-automerge.ts +2 -2
  62. package/src/extensions/awareness.ts +20 -2
  63. package/src/extensions/basic.ts +22 -17
  64. package/src/extensions/code.ts +15 -17
  65. package/src/extensions/comments.ts +239 -136
  66. package/src/extensions/cursor.ts +7 -3
  67. package/src/extensions/hr.ts +49 -50
  68. package/src/extensions/index.ts +1 -0
  69. package/src/extensions/link.ts +3 -3
  70. package/src/extensions/markdown/bundle.ts +18 -24
  71. package/src/extensions/mention.ts +9 -2
  72. package/src/extensions/outliner.ts +12 -0
  73. package/src/extensions/tasklist.ts +76 -84
  74. package/src/extensions/yjs/yjs.test.ts +1 -1
  75. package/src/hooks/automerge.ts +2 -1
  76. package/src/hooks/defs.ts +47 -0
  77. package/src/hooks/index.ts +4 -1
  78. package/src/hooks/useTextEditor.ts +29 -0
  79. package/src/hooks/useTextModel.ts +2 -45
  80. package/src/hooks/yjs.ts +2 -1
  81. package/src/util.ts +26 -3
@@ -12,11 +12,16 @@ import {
12
12
  type ViewUpdate,
13
13
  WidgetType,
14
14
  } from '@codemirror/view';
15
+ import { useEffect } from 'react';
15
16
 
16
17
  import { Event } from '@dxos/async';
17
18
  import { Context } from '@dxos/context';
19
+ import { generateName } from '@dxos/display-name';
20
+ import { useThemeContext } from '@dxos/react-ui';
21
+ import { getColorForValue } from '@dxos/react-ui-theme';
18
22
 
19
23
  import { Cursor, type CursorConverter } from './cursor';
24
+ import { type EditorModel } from '../hooks';
20
25
 
21
26
  export interface AwarenessProvider {
22
27
  remoteStateChange: Event<void>;
@@ -66,7 +71,6 @@ export type AwarenessState = {
66
71
  /**
67
72
  * Extension provides presence information about other peers.
68
73
  */
69
- // TODO(burdon): Why provide default?
70
74
  export const awareness = (provider = dummyProvider): Extension => {
71
75
  return [
72
76
  AwarenessProvider.of(provider),
@@ -77,6 +81,19 @@ export const awareness = (provider = dummyProvider): Extension => {
77
81
  ];
78
82
  };
79
83
 
84
+ export const useAwareness = ({ awareness, peer }: EditorModel) => {
85
+ const { themeMode } = useThemeContext();
86
+ useEffect(() => {
87
+ if (awareness && peer) {
88
+ awareness.setLocalStateField('user', {
89
+ name: peer.name ?? generateName(peer.id),
90
+ color: getColorForValue({ value: peer.id, type: 'color' }),
91
+ colorLight: getColorForValue({ value: peer.id, themeMode, type: 'highlight' }),
92
+ });
93
+ }
94
+ }, [awareness, peer, themeMode]);
95
+ };
96
+
80
97
  /**
81
98
  * Generates selection decorations from remote peers.
82
99
  */
@@ -251,6 +268,7 @@ class RemoteCaretWidget extends WidgetType {
251
268
  }
252
269
  }
253
270
 
271
+ // TODO(burdon): Mixed case?
254
272
  const styles = EditorView.baseTheme({
255
273
  '.cm-collab-selection': {},
256
274
  '.cm-collab-selectionLine': {
@@ -297,7 +315,7 @@ const styles = EditorView.baseTheme({
297
315
  zIndex: 101,
298
316
  transition: 'opacity .3s ease-in-out',
299
317
  backgroundColor: 'inherit',
300
- // these should be separate
318
+ // These should be separate.
301
319
  opacity: 0,
302
320
  transitionDelay: '0s',
303
321
  whiteSpace: 'nowrap',
@@ -3,30 +3,35 @@
3
3
  //
4
4
 
5
5
  import { closeBrackets } from '@codemirror/autocomplete';
6
+ import { history } from '@codemirror/commands';
6
7
  import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from '@codemirror/language';
7
8
  import { type Extension } from '@codemirror/state';
8
9
  import { oneDarkHighlightStyle } from '@codemirror/theme-one-dark';
9
- import { drawSelection, EditorView, placeholder } from '@codemirror/view';
10
+ import { drawSelection, EditorView, highlightActiveLine, placeholder } from '@codemirror/view';
10
11
 
11
- import type { ThemeMode } from '@dxos/react-ui';
12
+ import { type ThemeMode } from '@dxos/react-ui';
13
+
14
+ import { type TextEditorProps } from '../components';
12
15
 
13
16
  export type BasicBundleOptions = {
14
- readonly?: boolean;
15
17
  themeMode?: ThemeMode;
16
- placeholder?: string;
17
- };
18
+ } & Pick<TextEditorProps, 'placeholder' | 'lineWrapping'>;
18
19
 
19
- export const basicBundle = ({ readonly, themeMode, placeholder: _placeholder }: BasicBundleOptions): Extension[] =>
20
- [
21
- EditorView.lineWrapping,
20
+ export const basicBundle = ({
21
+ themeMode,
22
+ placeholder: _placeholder,
23
+ lineWrapping = true,
24
+ }: BasicBundleOptions): Extension[] => [
25
+ lineWrapping ? EditorView.lineWrapping : [],
22
26
 
23
- // TODO(burdon): Compare with minimalSetup.
24
- // https://codemirror.net/docs/ref/#codemirror.minimalSetup
25
- bracketMatching(),
26
- closeBrackets(),
27
- drawSelection(),
28
- _placeholder && placeholder(_placeholder),
27
+ // https://codemirror.net/docs/ref/#codemirror.minimalSetup
28
+ bracketMatching(),
29
+ closeBrackets(),
30
+ drawSelection(),
31
+ highlightActiveLine(),
32
+ history(),
33
+ _placeholder ? placeholder(_placeholder) : [],
29
34
 
30
- // TODO(burdon): Is this required?
31
- themeMode === 'dark' ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
32
- ].filter(Boolean) as Extension[];
35
+ // https://github.com/codemirror/theme-one-dark
36
+ themeMode === 'dark' ? syntaxHighlighting(oneDarkHighlightStyle) : syntaxHighlighting(defaultHighlightStyle),
37
+ ];
@@ -53,22 +53,20 @@ const getLineRange = (lines: BlockInfo[], from: number, to: number) => {
53
53
  };
54
54
 
55
55
  export const code = () => {
56
- const getDecorations = (view: EditorView) => {
56
+ const buildDecorations = (view: EditorView) => {
57
57
  const decorations: Range<Decoration>[] = [];
58
- if (!view.hasFocus || view.state.readOnly) {
59
- const text = view.state.doc.sliceString(0);
60
- const matches = text.matchAll(CODE_REGEX);
61
- const blocks = view.viewportLineBlocks;
62
- for (const match of matches) {
63
- const range = getLineRange(blocks, match.index!, match.index! + match[0].length);
64
- for (let i = range[0]; i <= range[1]; i++) {
65
- const block = blocks[i];
66
- decorations.push(
67
- Decoration.line({
68
- class: mx('cm-codeblock', i === range[0] && 'cm-codeblock-first', i === range[1] && 'cm-codeblock-last'),
69
- }).range(block.from),
70
- );
71
- }
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
+ );
72
70
  }
73
71
  }
74
72
 
@@ -81,7 +79,7 @@ export const code = () => {
81
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) {
@@ -93,7 +91,7 @@ export const code = () => {
93
91
  update.viewportChanged
94
92
  ) {
95
93
  this.hasFocus = update.view.hasFocus;
96
- this.decorations = getDecorations(update.view);
94
+ this.decorations = buildDecorations(update.view);
97
95
  }
98
96
  }
99
97
  },