@dxos/react-ui-editor 0.4.4-main.fcf0b00 → 0.4.4-next.ac77e71

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 (43) hide show
  1. package/dist/lib/browser/index.mjs +187 -139
  2. package/dist/lib/browser/index.mjs.map +3 -3
  3. package/dist/lib/browser/meta.json +1 -1
  4. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts +3 -2
  5. package/dist/types/src/components/TextEditor/MarkdownEditor.stories.d.ts.map +1 -1
  6. package/dist/types/src/components/TextEditor/TextEditor.d.ts +3 -3
  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/automerge.stories.d.ts.map +1 -1
  10. package/dist/types/src/components/TextEditor/hooks.stories.d.ts +1 -1
  11. package/dist/types/src/components/TextEditor/hooks.stories.d.ts.map +1 -1
  12. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
  13. package/dist/types/src/extensions/automerge/defs.d.ts.map +1 -1
  14. package/dist/types/src/extensions/basic.d.ts +2 -1
  15. package/dist/types/src/extensions/basic.d.ts.map +1 -1
  16. package/dist/types/src/extensions/comments.d.ts +15 -7
  17. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  18. package/dist/types/src/extensions/cursor.d.ts +1 -1
  19. package/dist/types/src/extensions/cursor.d.ts.map +1 -1
  20. package/dist/types/src/hooks/useEditorView.d.ts +6 -4
  21. package/dist/types/src/hooks/useEditorView.d.ts.map +1 -1
  22. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  23. package/dist/types/src/hooks/useTextModel.d.ts +3 -0
  24. package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
  25. package/dist/types/src/styles/layout.d.ts +1 -1
  26. package/dist/types/src/styles/layout.d.ts.map +1 -1
  27. package/package.json +26 -26
  28. package/src/components/TextEditor/MarkdownEditor.stories.tsx +9 -2
  29. package/src/components/TextEditor/TextEditor.tsx +21 -8
  30. package/src/components/TextEditor/automerge.stories.tsx +10 -7
  31. package/src/components/TextEditor/hooks.stories.tsx +44 -10
  32. package/src/components/Toolbar/Toolbar.stories.tsx +4 -4
  33. package/src/extensions/autocomplete.ts +1 -1
  34. package/src/extensions/automerge/cursor.ts +15 -4
  35. package/src/extensions/automerge/defs.ts +0 -1
  36. package/src/extensions/basic.ts +3 -1
  37. package/src/extensions/comments.ts +111 -82
  38. package/src/extensions/cursor.ts +4 -2
  39. package/src/extensions/markdown/image.ts +1 -1
  40. package/src/hooks/useEditorView.ts +13 -11
  41. package/src/hooks/useTextEditor.ts +6 -2
  42. package/src/hooks/useTextModel.ts +7 -7
  43. package/src/styles/layout.ts +1 -1
@@ -11,8 +11,8 @@ import { EditorState as EditorState2 } from "@codemirror/state";
11
11
  import { EditorView as EditorView15 } from "@codemirror/view";
12
12
  import { useFocusableGroup } from "@fluentui/react-tabster";
13
13
  import defaultsDeep2 from "lodash.defaultsdeep";
14
- import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2 } from "react";
15
- import { log as log2 } from "@dxos/log";
14
+ import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2, useMemo as useMemo2 } from "react";
15
+ import { log as log3 } from "@dxos/log";
16
16
  import { useThemeContext } from "@dxos/react-ui";
17
17
  import { focusRing } from "@dxos/react-ui-theme";
18
18
  import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
@@ -31,7 +31,9 @@ var defaultCursorConverter = {
31
31
  var Cursor = class _Cursor {
32
32
  static {
33
33
  this.converter = Facet.define({
34
- combine: (providers) => providers[0] ?? defaultCursorConverter
34
+ combine: (providers) => {
35
+ return providers[0] ?? defaultCursorConverter;
36
+ }
35
37
  });
36
38
  }
37
39
  static {
@@ -130,7 +132,7 @@ var autocomplete = ({ onSearch }) => {
130
132
  // https://codemirror.net/examples/autocompletion
131
133
  // https://codemirror.net/docs/ref/#autocomplete.autocompletion
132
134
  autocompletion({
133
- activateOnTyping: true,
135
+ activateOnTyping: false,
134
136
  // closeOnBlur: false,
135
137
  // defaultKeymap: false,
136
138
  // TODO(burdon): Styles/fragments.
@@ -161,6 +163,8 @@ import { next as A4 } from "@dxos/automerge/automerge";
161
163
  // packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
162
164
  import get from "lodash.get";
163
165
  import { next as A } from "@dxos/automerge/automerge";
166
+ import { log } from "@dxos/log";
167
+ var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts";
164
168
  var cursorConverter = (handle, path) => ({
165
169
  // TODO(burdon): Handle assoc to associate with a previous character.
166
170
  toCursor: (pos) => {
@@ -172,7 +176,17 @@ var cursorConverter = (handle, path) => ({
172
176
  if (typeof value === "string" && value.length <= pos) {
173
177
  return "end";
174
178
  }
175
- return A.getCursor(doc, path.slice(), pos);
179
+ try {
180
+ return A.getCursor(doc, path.slice(), pos);
181
+ } catch (err) {
182
+ log.catch(err, void 0, {
183
+ F: __dxlog_file,
184
+ L: 31,
185
+ S: void 0,
186
+ C: (f, a) => f(...a)
187
+ });
188
+ return "";
189
+ }
176
190
  },
177
191
  fromCursor: (cursor) => {
178
192
  if (cursor === "") {
@@ -190,7 +204,17 @@ var cursorConverter = (handle, path) => ({
190
204
  return 0;
191
205
  }
192
206
  }
193
- return A.getCursorPosition(doc, path.slice(), cursor);
207
+ try {
208
+ return A.getCursorPosition(doc, path.slice(), cursor);
209
+ } catch (err) {
210
+ log.catch(err, void 0, {
211
+ F: __dxlog_file,
212
+ L: 59,
213
+ S: void 0,
214
+ C: (f, a) => f(...a)
215
+ });
216
+ return 0;
217
+ }
194
218
  }
195
219
  });
196
220
 
@@ -691,10 +715,10 @@ import { bracketMatching, defaultHighlightStyle, syntaxHighlighting } from "@cod
691
715
  import { oneDarkHighlightStyle } from "@codemirror/theme-one-dark";
692
716
  import { drawSelection, EditorView as EditorView4, highlightActiveLine, placeholder } from "@codemirror/view";
693
717
  import { isNotFalsy as isNotFalsy2 } from "@dxos/util";
694
- var createBasicBundle = ({ themeMode, placeholder: _placeholder, lineWrapping = true } = {}) => [
718
+ var createBasicBundle = ({ themeMode, placeholder: _placeholder, lineWrapping = true, bracketMatching: _bracketMatching = true } = {}) => [
695
719
  lineWrapping && EditorView4.lineWrapping,
696
720
  // https://codemirror.net/docs/ref/#codemirror.minimalSetup
697
- bracketMatching(),
721
+ _bracketMatching && bracketMatching(),
698
722
  closeBrackets(),
699
723
  drawSelection(),
700
724
  highlightActiveLine(),
@@ -708,7 +732,7 @@ var createBasicBundle = ({ themeMode, placeholder: _placeholder, lineWrapping =
708
732
  import { EditorView as EditorView5, keymap as keymap2 } from "@codemirror/view";
709
733
  import defaultsDeep from "lodash.defaultsdeep";
710
734
  import { invariant } from "@dxos/invariant";
711
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
735
+ var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/blast.ts";
712
736
  var defaultOptions = {
713
737
  effect: 2,
714
738
  maxParticles: 200,
@@ -835,7 +859,7 @@ var Blaster = class {
835
859
  }
836
860
  initialize() {
837
861
  invariant(!this._canvas && !this._ctx, void 0, {
838
- F: __dxlog_file,
862
+ F: __dxlog_file2,
839
863
  L: 141,
840
864
  S: this,
841
865
  A: [
@@ -872,7 +896,7 @@ var Blaster = class {
872
896
  }
873
897
  start() {
874
898
  invariant(this._canvas && this._ctx, void 0, {
875
- F: __dxlog_file,
899
+ F: __dxlog_file2,
876
900
  L: 180,
877
901
  S: this,
878
902
  A: [
@@ -1091,20 +1115,20 @@ var tokens = tailwindConfig({}).theme;
1091
1115
  var getToken = (path, defaultValue = void 0) => get2(tokens, path, defaultValue);
1092
1116
 
1093
1117
  // packages/ui/react-ui-editor/src/styles/layout.ts
1094
- var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] justify-center content-start overflow-hidden";
1118
+ var editorWithToolbarLayout = "grid grid-cols-1 grid-rows-[min-content_1fr] data-[toolbar=disabled]:grid-rows-[1fr] justify-center content-start overflow-hidden";
1095
1119
  var editorFillLayoutRoot = "min-bs-full grid";
1096
1120
  var editorFillLayoutEditor = "min-bs-full";
1097
1121
  var editorHalfViewportOverscrollContent = "after:block after:min-bs-[50dvh] after:pointer-events-none";
1098
1122
 
1099
1123
  // packages/ui/react-ui-editor/src/util.ts
1100
- import { log } from "@dxos/log";
1101
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
1124
+ import { log as log2 } from "@dxos/log";
1125
+ var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/util.ts";
1102
1126
  var callbackWrapper = (fn) => (...args) => {
1103
1127
  try {
1104
1128
  return fn(...args);
1105
1129
  } catch (err) {
1106
- log.catch(err, void 0, {
1107
- F: __dxlog_file2,
1130
+ log2.catch(err, void 0, {
1131
+ F: __dxlog_file3,
1108
1132
  L: 18,
1109
1133
  S: void 0,
1110
1134
  C: (f, a) => f(...a)
@@ -1132,68 +1156,15 @@ var logChanges = (trs) => {
1132
1156
  };
1133
1157
 
1134
1158
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1135
- var styles3 = EditorView6.baseTheme({
1136
- "&light .cm-comment, &light .cm-comment-current": {
1137
- mixBlendMode: "darken"
1138
- },
1139
- "&dark .cm-comment, &dark .cm-comment-current": {
1140
- mixBlendMode: "plus-lighter"
1141
- },
1142
- "&light .cm-comment": {
1143
- backgroundColor: getToken("extend.colors.yellow.50")
1144
- },
1145
- "&light .cm-comment-current": {
1146
- backgroundColor: getToken("extend.colors.yellow.100")
1147
- },
1148
- "&dark .cm-comment": {
1149
- color: getToken("extend.colors.yellow.50"),
1150
- backgroundColor: getToken("extend.colors.yellow.900")
1151
- },
1152
- "&dark .cm-comment-current": {
1153
- color: getToken("extend.colors.yellow.100"),
1154
- backgroundColor: getToken("extend.colors.yellow.950")
1155
- }
1156
- });
1157
- var commentMark = Decoration3.mark({
1158
- class: "cm-comment",
1159
- attributes: {
1160
- "data-testid": "cm-comment"
1161
- }
1162
- });
1163
- var commentCurrentMark = Decoration3.mark({
1164
- class: "cm-comment-current",
1165
- attributes: {
1166
- "data-testid": "cm-comment"
1167
- }
1159
+ var documentId = Facet3.define({
1160
+ combine: (values) => values[0]
1168
1161
  });
1169
- var focusComment = (view, id, center = true) => {
1170
- const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
1171
- if (!comment?.comment.cursor) {
1172
- return;
1173
- }
1174
- const range = Cursor.getRangeFromCursor(view.state, comment.comment.cursor);
1175
- if (range) {
1176
- view.dispatch({
1177
- selection: {
1178
- anchor: range.from
1179
- },
1180
- effects: [
1181
- //
1182
- EditorView6.scrollIntoView(range.from, center ? {
1183
- y: "center"
1184
- } : void 0),
1185
- setSelection.of({
1186
- current: id
1187
- })
1188
- ]
1189
- });
1190
- }
1191
- };
1192
1162
  var setComments = StateEffect2.define();
1193
1163
  var setSelection = StateEffect2.define();
1194
1164
  var setCommentState = StateEffect2.define();
1195
1165
  var commentsState = StateField3.define({
1196
- create: () => ({
1166
+ create: (state) => ({
1167
+ id: state.facet(documentId),
1197
1168
  comments: [],
1198
1169
  selection: {}
1199
1170
  }),
@@ -1206,7 +1177,8 @@ var commentsState = StateField3.define({
1206
1177
  };
1207
1178
  }
1208
1179
  if (effect.is(setComments)) {
1209
- const comments2 = effect.value.map((comment) => {
1180
+ const { comments: comments2 } = effect.value;
1181
+ const commentStates = comments2.map((comment) => {
1210
1182
  if (!comment.cursor) {
1211
1183
  return void 0;
1212
1184
  }
@@ -1218,7 +1190,7 @@ var commentsState = StateField3.define({
1218
1190
  }).filter(nonNullable);
1219
1191
  return {
1220
1192
  ...value,
1221
- comments: comments2
1193
+ comments: commentStates
1222
1194
  };
1223
1195
  }
1224
1196
  if (effect.is(setCommentState)) {
@@ -1228,6 +1200,40 @@ var commentsState = StateField3.define({
1228
1200
  return value;
1229
1201
  }
1230
1202
  });
1203
+ var styles3 = EditorView6.baseTheme({
1204
+ "&light .cm-comment, &light .cm-comment-current": {
1205
+ mixBlendMode: "darken"
1206
+ },
1207
+ "&dark .cm-comment, &dark .cm-comment-current": {
1208
+ mixBlendMode: "plus-lighter"
1209
+ },
1210
+ "&light .cm-comment": {
1211
+ backgroundColor: getToken("extend.colors.yellow.50")
1212
+ },
1213
+ "&light .cm-comment-current": {
1214
+ backgroundColor: getToken("extend.colors.yellow.100")
1215
+ },
1216
+ "&dark .cm-comment": {
1217
+ color: getToken("extend.colors.yellow.50"),
1218
+ backgroundColor: getToken("extend.colors.yellow.900")
1219
+ },
1220
+ "&dark .cm-comment-current": {
1221
+ color: getToken("extend.colors.yellow.100"),
1222
+ backgroundColor: getToken("extend.colors.yellow.950")
1223
+ }
1224
+ });
1225
+ var commentMark = Decoration3.mark({
1226
+ class: "cm-comment",
1227
+ attributes: {
1228
+ "data-testid": "cm-comment"
1229
+ }
1230
+ });
1231
+ var commentCurrentMark = Decoration3.mark({
1232
+ class: "cm-comment-current",
1233
+ attributes: {
1234
+ "data-testid": "cm-comment"
1235
+ }
1236
+ });
1231
1237
  var commentsDecorations = EditorView6.decorations.compute([
1232
1238
  commentsState
1233
1239
  ], (state) => {
@@ -1347,9 +1353,6 @@ var mapTrackedComment = (comment, changes) => ({
1347
1353
  var restoreCommentEffect = StateEffect2.define({
1348
1354
  map: mapTrackedComment
1349
1355
  });
1350
- var optionsFacet = Facet3.define({
1351
- combine: (providers) => providers[0]
1352
- });
1353
1356
  var createComment = (view) => {
1354
1357
  const options = view.state.facet(optionsFacet);
1355
1358
  const { from, to } = view.state.selection.main;
@@ -1388,11 +1391,15 @@ var createComment = (view) => {
1388
1391
  }
1389
1392
  return false;
1390
1393
  };
1394
+ var optionsFacet = Facet3.define({
1395
+ combine: (providers) => providers[0]
1396
+ });
1391
1397
  var comments = (options = {}) => {
1392
1398
  const { key: shortcut = "meta-'" } = options;
1393
1399
  const handleSelect = debounce((state) => options.onSelect?.(state), 200);
1394
1400
  return [
1395
1401
  optionsFacet.of(options),
1402
+ documentId.of(options.id),
1396
1403
  commentsState,
1397
1404
  commentsDecorations,
1398
1405
  styles3,
@@ -1494,6 +1501,7 @@ var comments = (options = {}) => {
1494
1501
  });
1495
1502
  handleSelect({
1496
1503
  selection,
1504
+ id: state.facet(documentId),
1497
1505
  comments: comments2.map(({ comment, range }) => ({
1498
1506
  comment,
1499
1507
  range,
@@ -1505,14 +1513,41 @@ var comments = (options = {}) => {
1505
1513
  options.onUpdate ? trackPastedComments(options.onUpdate) : []
1506
1514
  ];
1507
1515
  };
1508
- var useComments = (view, comments2 = []) => {
1516
+ var focusComment = (view, id, center = true) => {
1517
+ const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
1518
+ if (!comment?.comment.cursor) {
1519
+ return;
1520
+ }
1521
+ const range = Cursor.getRangeFromCursor(view.state, comment.comment.cursor);
1522
+ if (range) {
1523
+ view.dispatch({
1524
+ selection: {
1525
+ anchor: range.from
1526
+ },
1527
+ effects: [
1528
+ //
1529
+ EditorView6.scrollIntoView(range.from, center ? {
1530
+ y: "center"
1531
+ } : void 0),
1532
+ setSelection.of({
1533
+ current: id
1534
+ })
1535
+ ]
1536
+ });
1537
+ }
1538
+ };
1539
+ var useComments = (view, id, comments2 = []) => {
1509
1540
  useEffect(() => {
1510
1541
  if (view) {
1511
1542
  view.dispatch({
1512
- effects: setComments.of(comments2)
1543
+ effects: setComments.of({
1544
+ id,
1545
+ comments: comments2
1546
+ })
1513
1547
  });
1514
1548
  }
1515
1549
  }, [
1550
+ id,
1516
1551
  view,
1517
1552
  comments2
1518
1553
  ]);
@@ -3871,7 +3906,7 @@ var codeTheme = {
3871
3906
  };
3872
3907
 
3873
3908
  // packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
3874
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
3909
+ var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
3875
3910
  var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo, selection, theme, slots = defaultSlots, extensions = [], debug }, forwardedRef) => {
3876
3911
  const tabsterDOMAttribute = useFocusableGroup({
3877
3912
  tabBehavior: "limited"
@@ -3908,9 +3943,9 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
3908
3943
  extensions: [
3909
3944
  // TODO(burdon): Doesn't catch errors in keymap functions.
3910
3945
  EditorView15.exceptionSink.of((err) => {
3911
- log2.catch(err, void 0, {
3912
- F: __dxlog_file3,
3913
- L: 112,
3946
+ log3.catch(err, void 0, {
3947
+ F: __dxlog_file4,
3948
+ L: 113,
3914
3949
  S: void 0,
3915
3950
  C: (f, a) => f(...a)
3916
3951
  });
@@ -3968,6 +4003,7 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
3968
4003
  };
3969
4004
  }, [
3970
4005
  rootRef,
4006
+ extensions,
3971
4007
  model,
3972
4008
  readonly,
3973
4009
  themeMode
@@ -3993,38 +4029,49 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
3993
4029
  ...tabsterDOMAttribute
3994
4030
  });
3995
4031
  });
3996
- var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, lineWrapping, theme = textTheme, slots, extensions = [], ...props }, forwardedRef) => {
4032
+ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, lineWrapping, theme = textTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
3997
4033
  const { themeMode } = useThemeContext();
3998
4034
  const updatedSlots = defaultsDeep2({}, slots, defaultTextSlots);
4035
+ const extensions = useMemo2(() => [
4036
+ createBasicBundle({
4037
+ themeMode,
4038
+ placeholder: placeholder3,
4039
+ lineWrapping
4040
+ }),
4041
+ ..._extensions ?? []
4042
+ ], [
4043
+ themeMode,
4044
+ placeholder3,
4045
+ lineWrapping,
4046
+ _extensions
4047
+ ]);
3999
4048
  return /* @__PURE__ */ React.createElement(BaseTextEditor, {
4000
4049
  ref: forwardedRef,
4001
4050
  readonly,
4002
- extensions: [
4003
- createBasicBundle({
4004
- themeMode,
4005
- placeholder: placeholder3,
4006
- lineWrapping
4007
- }),
4008
- ...extensions
4009
- ],
4051
+ extensions,
4010
4052
  theme,
4011
4053
  slots: updatedSlots,
4012
4054
  ...props
4013
4055
  });
4014
4056
  });
4015
- var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, theme = markdownTheme, slots, extensions = [], ...props }, forwardedRef) => {
4057
+ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, placeholder: placeholder3, theme = markdownTheme, slots, extensions: _extensions, ...props }, forwardedRef) => {
4016
4058
  const { themeMode } = useThemeContext();
4017
4059
  const updatedSlots = defaultsDeep2({}, slots, defaultMarkdownSlots);
4060
+ const extensions = useMemo2(() => [
4061
+ createMarkdownExtensions({
4062
+ themeMode,
4063
+ placeholder: placeholder3
4064
+ }),
4065
+ ..._extensions ?? []
4066
+ ], [
4067
+ themeMode,
4068
+ placeholder3,
4069
+ _extensions
4070
+ ]);
4018
4071
  return /* @__PURE__ */ React.createElement(BaseTextEditor, {
4019
4072
  ref: forwardedRef,
4020
4073
  readonly,
4021
- extensions: [
4022
- createMarkdownExtensions({
4023
- themeMode,
4024
- placeholder: placeholder3
4025
- }),
4026
- ...extensions
4027
- ],
4074
+ extensions,
4028
4075
  theme,
4029
4076
  slots: updatedSlots,
4030
4077
  ...props
@@ -4311,8 +4358,8 @@ var Toolbar = {
4311
4358
  import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
4312
4359
  import { Context as Context2 } from "@dxos/context";
4313
4360
  import { invariant as invariant2 } from "@dxos/invariant";
4314
- import { log as log3 } from "@dxos/log";
4315
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
4361
+ import { log as log4 } from "@dxos/log";
4362
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
4316
4363
  var DEBOUNCE_INTERVAL = 100;
4317
4364
  var SpaceAwarenessProvider = class {
4318
4365
  constructor(params) {
@@ -4349,10 +4396,10 @@ var SpaceAwarenessProvider = class {
4349
4396
  void this._space.postMessage(this._channel, {
4350
4397
  kind: "query"
4351
4398
  }).catch((err) => {
4352
- log3.debug("failed to query awareness", {
4399
+ log4.debug("failed to query awareness", {
4353
4400
  err
4354
4401
  }, {
4355
- F: __dxlog_file4,
4402
+ F: __dxlog_file5,
4356
4403
  L: 89,
4357
4404
  S: this,
4358
4405
  C: (f, a) => f(...a)
@@ -4369,7 +4416,7 @@ var SpaceAwarenessProvider = class {
4369
4416
  }
4370
4417
  update(position) {
4371
4418
  invariant2(this._postTask, void 0, {
4372
- F: __dxlog_file4,
4419
+ F: __dxlog_file5,
4373
4420
  L: 104,
4374
4421
  S: this,
4375
4422
  A: [
@@ -4386,7 +4433,7 @@ var SpaceAwarenessProvider = class {
4386
4433
  }
4387
4434
  _handleQueryMessage() {
4388
4435
  invariant2(this._postTask, void 0, {
4389
- F: __dxlog_file4,
4436
+ F: __dxlog_file5,
4390
4437
  L: 115,
4391
4438
  S: this,
4392
4439
  A: [
@@ -4398,7 +4445,7 @@ var SpaceAwarenessProvider = class {
4398
4445
  }
4399
4446
  _handlePostMessage(message) {
4400
4447
  invariant2(message.kind === "post", void 0, {
4401
- F: __dxlog_file4,
4448
+ F: __dxlog_file5,
4402
4449
  L: 120,
4403
4450
  S: this,
4404
4451
  A: [
@@ -4467,29 +4514,38 @@ var useActionHandler = (view) => {
4467
4514
  };
4468
4515
 
4469
4516
  // packages/ui/react-ui-editor/src/hooks/useEditorView.ts
4470
- import { useState as useState3 } from "react";
4471
- var useEditorView = () => {
4472
- const [view, setView] = useState3(null);
4517
+ import { useRef as useRef2, useState as useState3 } from "react";
4518
+ var useEditorView = (id) => {
4519
+ const editorRef = useRef2(null);
4520
+ const [prev, setPrev] = useState3([
4521
+ null,
4522
+ ""
4523
+ ]);
4524
+ if (prev[0] !== editorRef.current) {
4525
+ setPrev([
4526
+ editorRef.current,
4527
+ id
4528
+ ]);
4529
+ }
4473
4530
  return [
4474
- (ref) => {
4475
- setView(ref);
4476
- },
4477
- view
4531
+ editorRef,
4532
+ prev[1] !== id
4478
4533
  ];
4479
4534
  };
4480
4535
 
4481
4536
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
4482
4537
  import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
4483
4538
  import { EditorView as EditorView16 } from "@codemirror/view";
4484
- import { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
4485
- import { log as log4 } from "@dxos/log";
4539
+ import { useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
4540
+ import { log as log5 } from "@dxos/log";
4486
4541
  import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
4487
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
4542
+ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
4488
4543
  var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}) => {
4489
- const onUpdate = useRef2();
4544
+ const onUpdate = useRef3();
4490
4545
  const [view, setView] = useState4();
4491
- const parentRef = useRef2(null);
4546
+ const parentRef = useRef3(null);
4492
4547
  useEffect3(() => {
4548
+ let view2;
4493
4549
  if (parentRef.current) {
4494
4550
  const state = EditorState3.create({
4495
4551
  doc,
@@ -4497,9 +4553,9 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
4497
4553
  extensions: [
4498
4554
  // TODO(burdon): Doesn't catch errors in keymap functions.
4499
4555
  EditorView16.exceptionSink.of((err) => {
4500
- log4.catch(err, void 0, {
4501
- F: __dxlog_file5,
4502
- L: 57,
4556
+ log5.catch(err, void 0, {
4557
+ F: __dxlog_file6,
4558
+ L: 60,
4503
4559
  S: void 0,
4504
4560
  C: (f, a) => f(...a)
4505
4561
  });
@@ -4510,7 +4566,7 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
4510
4566
  })
4511
4567
  ].filter(isNotFalsy5)
4512
4568
  });
4513
- const view2 = new EditorView16({
4569
+ view2 = new EditorView16({
4514
4570
  parent: parentRef.current,
4515
4571
  scrollTo,
4516
4572
  state,
@@ -4526,10 +4582,11 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
4526
4582
  setView(view2);
4527
4583
  }
4528
4584
  return () => {
4529
- view?.destroy();
4585
+ view2?.destroy();
4530
4586
  };
4531
4587
  }, [
4532
- parentRef
4588
+ parentRef,
4589
+ extensions
4533
4590
  ]);
4534
4591
  useEffect3(() => {
4535
4592
  if (view) {
@@ -4587,22 +4644,13 @@ var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
4587
4644
 
4588
4645
  // packages/ui/react-ui-editor/src/hooks/useTextModel.ts
4589
4646
  import get4 from "lodash.get";
4590
- import { useEffect as useEffect4, useState as useState5 } from "react";
4647
+ import { useState as useState5, useMemo as useMemo3 } from "react";
4591
4648
  import { generateName } from "@dxos/display-name";
4592
4649
  import { getRawDoc } from "@dxos/echo-schema";
4593
4650
  import { invariant as invariant3 } from "@dxos/invariant";
4594
4651
  import { isAutomergeObject } from "@dxos/react-client/echo";
4595
- var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
4596
- var useTextModel = (props) => {
4597
- const { identity, space, text } = props;
4598
- const [model, setModel] = useState5();
4599
- useEffect4(() => setModel(createModel(props)), [
4600
- identity,
4601
- space,
4602
- text
4603
- ]);
4604
- return model;
4605
- };
4652
+ var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
4653
+ var useTextModel = (props) => useMemo3(() => createModel(props), Object.values(props));
4606
4654
  var useInMemoryTextModel = ({ id, defaultContent }) => {
4607
4655
  const [content, setContent] = useState5(defaultContent ?? "");
4608
4656
  return {
@@ -4617,7 +4665,7 @@ var createModel = ({ space, identity, text }) => {
4617
4665
  return void 0;
4618
4666
  }
4619
4667
  invariant3(isAutomergeObject(text), void 0, {
4620
- F: __dxlog_file6,
4668
+ F: __dxlog_file7,
4621
4669
  L: 54,
4622
4670
  S: void 0,
4623
4671
  A: [