@dxos/react-ui-editor 0.4.4-main.8a6f0d0 → 0.4.4-main.8d0e03e

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 (50) hide show
  1. package/dist/lib/browser/index.mjs +202 -144
  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/hooks.stories.d.ts +1 -1
  10. package/dist/types/src/components/Toolbar/Toolbar.d.ts.map +1 -1
  11. package/dist/types/src/components/Toolbar/Toolbar.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/extensions/markdown/code.d.ts.map +1 -1
  21. package/dist/types/src/extensions/markdown/formatting.d.ts.map +1 -1
  22. package/dist/types/src/hooks/useEditorView.d.ts +6 -4
  23. package/dist/types/src/hooks/useEditorView.d.ts.map +1 -1
  24. package/dist/types/src/hooks/useTextModel.d.ts +3 -0
  25. package/dist/types/src/hooks/useTextModel.d.ts.map +1 -1
  26. package/dist/types/src/index.d.ts +1 -1
  27. package/dist/types/src/index.d.ts.map +1 -1
  28. package/dist/types/src/styles/layout.d.ts +4 -1
  29. package/dist/types/src/styles/layout.d.ts.map +1 -1
  30. package/package.json +26 -26
  31. package/src/components/TextEditor/MarkdownEditor.stories.tsx +3 -2
  32. package/src/components/TextEditor/TextEditor.tsx +3 -3
  33. package/src/components/TextEditor/automerge.stories.tsx +1 -1
  34. package/src/components/TextEditor/hooks.stories.tsx +4 -4
  35. package/src/components/Toolbar/Toolbar.stories.tsx +9 -6
  36. package/src/components/Toolbar/Toolbar.tsx +10 -13
  37. package/src/extensions/autocomplete.ts +1 -1
  38. package/src/extensions/automerge/cursor.ts +15 -4
  39. package/src/extensions/automerge/defs.ts +0 -1
  40. package/src/extensions/basic.ts +3 -1
  41. package/src/extensions/comments.ts +111 -82
  42. package/src/extensions/cursor.ts +4 -2
  43. package/src/extensions/markdown/code.ts +37 -25
  44. package/src/extensions/markdown/formatting.test.ts +1 -1
  45. package/src/extensions/markdown/formatting.ts +1 -0
  46. package/src/extensions/markdown/image.ts +1 -1
  47. package/src/hooks/useEditorView.ts +13 -11
  48. package/src/hooks/useTextModel.ts +7 -7
  49. package/src/index.ts +7 -1
  50. package/src/styles/layout.ts +6 -1
@@ -12,7 +12,7 @@ import { EditorView as EditorView15 } from "@codemirror/view";
12
12
  import { useFocusableGroup } from "@fluentui/react-tabster";
13
13
  import defaultsDeep2 from "lodash.defaultsdeep";
14
14
  import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState2 } from "react";
15
- import { log as log2 } from "@dxos/log";
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,17 +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 = "fixed inset-0 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";
1119
+ var editorFillLayoutRoot = "min-bs-full grid";
1120
+ var editorFillLayoutEditor = "min-bs-full";
1121
+ var editorHalfViewportOverscrollContent = "after:block after:min-bs-[50dvh] after:pointer-events-none";
1095
1122
 
1096
1123
  // packages/ui/react-ui-editor/src/util.ts
1097
- import { log } from "@dxos/log";
1098
- 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";
1099
1126
  var callbackWrapper = (fn) => (...args) => {
1100
1127
  try {
1101
1128
  return fn(...args);
1102
1129
  } catch (err) {
1103
- log.catch(err, void 0, {
1104
- F: __dxlog_file2,
1130
+ log2.catch(err, void 0, {
1131
+ F: __dxlog_file3,
1105
1132
  L: 18,
1106
1133
  S: void 0,
1107
1134
  C: (f, a) => f(...a)
@@ -1129,68 +1156,15 @@ var logChanges = (trs) => {
1129
1156
  };
1130
1157
 
1131
1158
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1132
- var styles3 = EditorView6.baseTheme({
1133
- "&light .cm-comment, &light .cm-comment-current": {
1134
- mixBlendMode: "darken"
1135
- },
1136
- "&dark .cm-comment, &dark .cm-comment-current": {
1137
- mixBlendMode: "plus-lighter"
1138
- },
1139
- "&light .cm-comment": {
1140
- backgroundColor: getToken("extend.colors.yellow.50")
1141
- },
1142
- "&light .cm-comment-current": {
1143
- backgroundColor: getToken("extend.colors.yellow.100")
1144
- },
1145
- "&dark .cm-comment": {
1146
- color: getToken("extend.colors.yellow.50"),
1147
- backgroundColor: getToken("extend.colors.yellow.900")
1148
- },
1149
- "&dark .cm-comment-current": {
1150
- color: getToken("extend.colors.yellow.100"),
1151
- backgroundColor: getToken("extend.colors.yellow.950")
1152
- }
1153
- });
1154
- var commentMark = Decoration3.mark({
1155
- class: "cm-comment",
1156
- attributes: {
1157
- "data-testid": "cm-comment"
1158
- }
1159
+ var documentId = Facet3.define({
1160
+ combine: (values) => values[0]
1159
1161
  });
1160
- var commentCurrentMark = Decoration3.mark({
1161
- class: "cm-comment-current",
1162
- attributes: {
1163
- "data-testid": "cm-comment"
1164
- }
1165
- });
1166
- var focusComment = (view, id, center = true) => {
1167
- const comment = view.state.field(commentsState).comments.find((range2) => range2.comment.id === id);
1168
- if (!comment?.comment.cursor) {
1169
- return;
1170
- }
1171
- const range = Cursor.getRangeFromCursor(view.state, comment.comment.cursor);
1172
- if (range) {
1173
- view.dispatch({
1174
- selection: {
1175
- anchor: range.from
1176
- },
1177
- effects: [
1178
- //
1179
- EditorView6.scrollIntoView(range.from, center ? {
1180
- y: "center"
1181
- } : void 0),
1182
- setSelection.of({
1183
- current: id
1184
- })
1185
- ]
1186
- });
1187
- }
1188
- };
1189
1162
  var setComments = StateEffect2.define();
1190
1163
  var setSelection = StateEffect2.define();
1191
1164
  var setCommentState = StateEffect2.define();
1192
1165
  var commentsState = StateField3.define({
1193
- create: () => ({
1166
+ create: (state) => ({
1167
+ id: state.facet(documentId),
1194
1168
  comments: [],
1195
1169
  selection: {}
1196
1170
  }),
@@ -1203,7 +1177,8 @@ var commentsState = StateField3.define({
1203
1177
  };
1204
1178
  }
1205
1179
  if (effect.is(setComments)) {
1206
- const comments2 = effect.value.map((comment) => {
1180
+ const { comments: comments2 } = effect.value;
1181
+ const commentStates = comments2.map((comment) => {
1207
1182
  if (!comment.cursor) {
1208
1183
  return void 0;
1209
1184
  }
@@ -1215,7 +1190,7 @@ var commentsState = StateField3.define({
1215
1190
  }).filter(nonNullable);
1216
1191
  return {
1217
1192
  ...value,
1218
- comments: comments2
1193
+ comments: commentStates
1219
1194
  };
1220
1195
  }
1221
1196
  if (effect.is(setCommentState)) {
@@ -1225,6 +1200,40 @@ var commentsState = StateField3.define({
1225
1200
  return value;
1226
1201
  }
1227
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
+ });
1228
1237
  var commentsDecorations = EditorView6.decorations.compute([
1229
1238
  commentsState
1230
1239
  ], (state) => {
@@ -1344,9 +1353,6 @@ var mapTrackedComment = (comment, changes) => ({
1344
1353
  var restoreCommentEffect = StateEffect2.define({
1345
1354
  map: mapTrackedComment
1346
1355
  });
1347
- var optionsFacet = Facet3.define({
1348
- combine: (providers) => providers[0]
1349
- });
1350
1356
  var createComment = (view) => {
1351
1357
  const options = view.state.facet(optionsFacet);
1352
1358
  const { from, to } = view.state.selection.main;
@@ -1385,11 +1391,15 @@ var createComment = (view) => {
1385
1391
  }
1386
1392
  return false;
1387
1393
  };
1394
+ var optionsFacet = Facet3.define({
1395
+ combine: (providers) => providers[0]
1396
+ });
1388
1397
  var comments = (options = {}) => {
1389
1398
  const { key: shortcut = "meta-'" } = options;
1390
1399
  const handleSelect = debounce((state) => options.onSelect?.(state), 200);
1391
1400
  return [
1392
1401
  optionsFacet.of(options),
1402
+ documentId.of(options.id),
1393
1403
  commentsState,
1394
1404
  commentsDecorations,
1395
1405
  styles3,
@@ -1491,6 +1501,7 @@ var comments = (options = {}) => {
1491
1501
  });
1492
1502
  handleSelect({
1493
1503
  selection,
1504
+ id: state.facet(documentId),
1494
1505
  comments: comments2.map(({ comment, range }) => ({
1495
1506
  comment,
1496
1507
  range,
@@ -1502,14 +1513,41 @@ var comments = (options = {}) => {
1502
1513
  options.onUpdate ? trackPastedComments(options.onUpdate) : []
1503
1514
  ];
1504
1515
  };
1505
- 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 = []) => {
1506
1540
  useEffect(() => {
1507
1541
  if (view) {
1508
1542
  view.dispatch({
1509
- effects: setComments.of(comments2)
1543
+ effects: setComments.of({
1544
+ id,
1545
+ comments: comments2
1546
+ })
1510
1547
  });
1511
1548
  }
1512
1549
  }, [
1550
+ id,
1513
1551
  view,
1514
1552
  comments2
1515
1553
  ]);
@@ -1791,41 +1829,50 @@ var styles4 = EditorView9.baseTheme({
1791
1829
  "& .cm-code": {
1792
1830
  fontFamily: getToken("fontFamily.mono", []).join(",")
1793
1831
  },
1794
- "& .cm-codeblock": {
1832
+ "& .cm-codeblock-line": {
1833
+ paddingInline: "1rem !important"
1834
+ },
1835
+ "& .cm-codeblock-end": {
1836
+ display: "inline-block",
1795
1837
  width: "100%",
1796
- paddingInline: "1rem !important",
1797
1838
  position: "relative",
1798
1839
  "&::after": {
1799
- content: '""',
1800
1840
  position: "absolute",
1801
- inset: 0
1802
- }
1803
- },
1804
- "&light .cm-codeblock": {
1805
- "&::after": {
1806
- background: getToken("extend.semanticColors.input.light"),
1807
- mixBlendMode: "darken"
1808
- }
1809
- },
1810
- "&dark .cm-codeblock": {
1811
- "&::after": {
1812
- background: getToken("extend.semanticColors.input.dark"),
1813
- mixBlendMode: "lighten"
1841
+ inset: 0,
1842
+ content: '""'
1814
1843
  }
1815
1844
  },
1816
1845
  "& .cm-codeblock-first": {
1817
- display: "inline-block",
1818
1846
  "&::after": {
1819
1847
  borderTopLeftRadius: ".5rem",
1820
1848
  borderTopRightRadius: ".5rem"
1821
1849
  }
1822
1850
  },
1823
1851
  "& .cm-codeblock-last": {
1824
- display: "inline-block",
1825
1852
  "&::after": {
1826
1853
  borderBottomLeftRadius: ".5rem",
1827
1854
  borderBottomRightRadius: ".5rem"
1828
1855
  }
1856
+ },
1857
+ "&light .cm-codeblock-line, &light .cm-activeLine.cm-codeblock-line": {
1858
+ background: getToken("extend.semanticColors.input.light"),
1859
+ mixBlendMode: "darken"
1860
+ },
1861
+ "&dark .cm-codeblock-line, &dark .cm-activeLine.cm-codeblock-line": {
1862
+ background: getToken("extend.semanticColors.input.dark"),
1863
+ mixBlendMode: "lighten"
1864
+ },
1865
+ "&light .cm-codeblock-first, &light .cm-codeblock-last": {
1866
+ mixBlendMode: "darken",
1867
+ "&::after": {
1868
+ background: getToken("extend.semanticColors.input.light")
1869
+ }
1870
+ },
1871
+ "&dark .cm-codeblock-first, &dark .cm-codeblock-last": {
1872
+ mixBlendMode: "lighten",
1873
+ "&::after": {
1874
+ background: getToken("extend.semanticColors.input.dark")
1875
+ }
1829
1876
  }
1830
1877
  });
1831
1878
  var getLineRange = (lines, from, to) => {
@@ -1848,8 +1895,8 @@ var LineWidget = class extends WidgetType2 {
1848
1895
  return el;
1849
1896
  }
1850
1897
  };
1851
- var top = new LineWidget("cm-codeblock-first");
1852
- var bottom = new LineWidget("cm-codeblock-last");
1898
+ var top = new LineWidget("cm-codeblock-end cm-codeblock-first");
1899
+ var bottom = new LineWidget("cm-codeblock-end cm-codeblock-last");
1853
1900
  var buildDecorations = (view) => {
1854
1901
  const builder = new RangeSetBuilder();
1855
1902
  const { state } = view;
@@ -1859,17 +1906,17 @@ var buildDecorations = (view) => {
1859
1906
  syntaxTree(state).iterate({
1860
1907
  enter: (node) => {
1861
1908
  if (node.name === "FencedCode") {
1862
- const edit = !view.state.readOnly && cursor >= node.from && cursor <= node.to;
1909
+ const editing = !view.state.readOnly && cursor >= node.from && cursor <= node.to;
1863
1910
  const range = getLineRange(blocks, node.from, node.to);
1864
1911
  for (let i = range[0]; i <= range[1]; i++) {
1865
1912
  const block = blocks[i];
1866
- if (!edit && (i === range[0] || i === range[1])) {
1913
+ if (!editing && (i === range[0] || i === range[1])) {
1867
1914
  builder.add(block.from, block.to, Decoration4.replace({
1868
1915
  widget: i === range[0] ? top : bottom
1869
1916
  }));
1870
1917
  } else {
1871
1918
  builder.add(block.from, block.from, Decoration4.line({
1872
- class: mx2("cm-code cm-codeblock", i === range[0] && "cm-codeblock-first", i === range[1] && "cm-codeblock-last")
1919
+ class: mx2("cm-code cm-codeblock-line", i === range[0] && "cm-codeblock-first", i === range[1] && "cm-codeblock-last")
1873
1920
  }));
1874
1921
  }
1875
1922
  }
@@ -2177,6 +2224,7 @@ var snippets = {
2177
2224
  codeblock: snippet([
2178
2225
  //
2179
2226
  "```#{}",
2227
+ "",
2180
2228
  "```"
2181
2229
  ].join("\n")),
2182
2230
  table: snippet([
@@ -3858,7 +3906,7 @@ var codeTheme = {
3858
3906
  };
3859
3907
 
3860
3908
  // packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
3861
- 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";
3862
3910
  var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, scrollTo, selection, theme, slots = defaultSlots, extensions = [], debug }, forwardedRef) => {
3863
3911
  const tabsterDOMAttribute = useFocusableGroup({
3864
3912
  tabBehavior: "limited"
@@ -3895,8 +3943,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, autoFocus, s
3895
3943
  extensions: [
3896
3944
  // TODO(burdon): Doesn't catch errors in keymap functions.
3897
3945
  EditorView15.exceptionSink.of((err) => {
3898
- log2.catch(err, void 0, {
3899
- F: __dxlog_file3,
3946
+ log3.catch(err, void 0, {
3947
+ F: __dxlog_file4,
3900
3948
  L: 112,
3901
3949
  S: void 0,
3902
3950
  C: (f, a) => f(...a)
@@ -4105,6 +4153,7 @@ var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
4105
4153
  className: "grow"
4106
4154
  });
4107
4155
  var MarkdownHeading = () => {
4156
+ const { t } = useTranslation(translationKey);
4108
4157
  const { onAction, state } = useToolbarContext("MarkdownFormatting");
4109
4158
  const blockType = state ? state.blockType : "paragraph";
4110
4159
  const header = blockType && /heading(\d)/.exec(blockType);
@@ -4117,9 +4166,16 @@ var MarkdownHeading = () => {
4117
4166
  type: "heading",
4118
4167
  data: parseInt(value2)
4119
4168
  })
4120
- }, /* @__PURE__ */ React2.createElement(Select.TriggerButton, null, /* @__PURE__ */ React2.createElement(HeadingIcon, {
4169
+ }, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4170
+ asChild: true
4171
+ }, /* @__PURE__ */ React2.createElement(Select.TriggerButton, {
4172
+ variant: "ghost",
4173
+ classNames: buttonStyles
4174
+ }, /* @__PURE__ */ React2.createElement("span", {
4175
+ className: "sr-only"
4176
+ }, t("heading label")), /* @__PURE__ */ React2.createElement(HeadingIcon, {
4121
4177
  className: iconStyles
4122
- })), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.ScrollUpButton, null), /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
4178
+ }))), /* @__PURE__ */ React2.createElement(Select.Portal, null, /* @__PURE__ */ React2.createElement(Select.Content, null, /* @__PURE__ */ React2.createElement(Select.ScrollUpButton, null), /* @__PURE__ */ React2.createElement(Select.Viewport, null, /* @__PURE__ */ React2.createElement(Select.Option, {
4123
4179
  value: "0"
4124
4180
  }, /* @__PURE__ */ React2.createElement(Paragraph, {
4125
4181
  className: iconStyles
@@ -4213,7 +4269,7 @@ var MarkdownLists = () => {
4213
4269
  const { t } = useTranslation(translationKey);
4214
4270
  return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
4215
4271
  type: "single",
4216
- value: state?.listStyle ?? void 0
4272
+ value: state?.listStyle ? `list-${state.listStyle}` : ""
4217
4273
  }, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
4218
4274
  key: type,
4219
4275
  value: type,
@@ -4233,7 +4289,7 @@ var markdownBlocks = [
4233
4289
  {
4234
4290
  type: "codeblock",
4235
4291
  Icon: CodeBlock,
4236
- getState: (state) => state.blockQuote,
4292
+ getState: (state) => state.blockType === "codeblock",
4237
4293
  disabled: (state) => !state.blankLine
4238
4294
  },
4239
4295
  {
@@ -4249,7 +4305,7 @@ var MarkdownBlocks = () => {
4249
4305
  const value = markdownBlocks.find(({ getState }) => state && getState(state));
4250
4306
  return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
4251
4307
  type: "single",
4252
- value: value?.type
4308
+ value: value?.type ?? ""
4253
4309
  }, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarButton, {
4254
4310
  key: type,
4255
4311
  value: type,
@@ -4290,8 +4346,8 @@ var Toolbar = {
4290
4346
  import { DeferredTask, Event as Event2, sleep } from "@dxos/async";
4291
4347
  import { Context as Context2 } from "@dxos/context";
4292
4348
  import { invariant as invariant2 } from "@dxos/invariant";
4293
- import { log as log3 } from "@dxos/log";
4294
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
4349
+ import { log as log4 } from "@dxos/log";
4350
+ var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/awareness-provider.ts";
4295
4351
  var DEBOUNCE_INTERVAL = 100;
4296
4352
  var SpaceAwarenessProvider = class {
4297
4353
  constructor(params) {
@@ -4328,10 +4384,10 @@ var SpaceAwarenessProvider = class {
4328
4384
  void this._space.postMessage(this._channel, {
4329
4385
  kind: "query"
4330
4386
  }).catch((err) => {
4331
- log3.debug("failed to query awareness", {
4387
+ log4.debug("failed to query awareness", {
4332
4388
  err
4333
4389
  }, {
4334
- F: __dxlog_file4,
4390
+ F: __dxlog_file5,
4335
4391
  L: 89,
4336
4392
  S: this,
4337
4393
  C: (f, a) => f(...a)
@@ -4348,7 +4404,7 @@ var SpaceAwarenessProvider = class {
4348
4404
  }
4349
4405
  update(position) {
4350
4406
  invariant2(this._postTask, void 0, {
4351
- F: __dxlog_file4,
4407
+ F: __dxlog_file5,
4352
4408
  L: 104,
4353
4409
  S: this,
4354
4410
  A: [
@@ -4365,7 +4421,7 @@ var SpaceAwarenessProvider = class {
4365
4421
  }
4366
4422
  _handleQueryMessage() {
4367
4423
  invariant2(this._postTask, void 0, {
4368
- F: __dxlog_file4,
4424
+ F: __dxlog_file5,
4369
4425
  L: 115,
4370
4426
  S: this,
4371
4427
  A: [
@@ -4377,7 +4433,7 @@ var SpaceAwarenessProvider = class {
4377
4433
  }
4378
4434
  _handlePostMessage(message) {
4379
4435
  invariant2(message.kind === "post", void 0, {
4380
- F: __dxlog_file4,
4436
+ F: __dxlog_file5,
4381
4437
  L: 120,
4382
4438
  S: this,
4383
4439
  A: [
@@ -4446,28 +4502,36 @@ var useActionHandler = (view) => {
4446
4502
  };
4447
4503
 
4448
4504
  // packages/ui/react-ui-editor/src/hooks/useEditorView.ts
4449
- import { useState as useState3 } from "react";
4450
- var useEditorView = () => {
4451
- const [view, setView] = useState3(null);
4505
+ import { useRef as useRef2, useState as useState3 } from "react";
4506
+ var useEditorView = (id) => {
4507
+ const editorRef = useRef2(null);
4508
+ const [prev, setPrev] = useState3([
4509
+ null,
4510
+ ""
4511
+ ]);
4512
+ if (prev[0] !== editorRef.current) {
4513
+ setPrev([
4514
+ editorRef.current,
4515
+ id
4516
+ ]);
4517
+ }
4452
4518
  return [
4453
- (ref) => {
4454
- setView(ref);
4455
- },
4456
- view
4519
+ editorRef,
4520
+ prev[1] !== id
4457
4521
  ];
4458
4522
  };
4459
4523
 
4460
4524
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
4461
4525
  import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
4462
4526
  import { EditorView as EditorView16 } from "@codemirror/view";
4463
- import { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
4464
- import { log as log4 } from "@dxos/log";
4527
+ import { useEffect as useEffect3, useRef as useRef3, useState as useState4 } from "react";
4528
+ import { log as log5 } from "@dxos/log";
4465
4529
  import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
4466
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
4530
+ var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
4467
4531
  var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions } = {}) => {
4468
- const onUpdate = useRef2();
4532
+ const onUpdate = useRef3();
4469
4533
  const [view, setView] = useState4();
4470
- const parentRef = useRef2(null);
4534
+ const parentRef = useRef3(null);
4471
4535
  useEffect3(() => {
4472
4536
  if (parentRef.current) {
4473
4537
  const state = EditorState3.create({
@@ -4476,8 +4540,8 @@ var useTextEditor = ({ autoFocus, scrollTo, debug, doc, selection, extensions }
4476
4540
  extensions: [
4477
4541
  // TODO(burdon): Doesn't catch errors in keymap functions.
4478
4542
  EditorView16.exceptionSink.of((err) => {
4479
- log4.catch(err, void 0, {
4480
- F: __dxlog_file5,
4543
+ log5.catch(err, void 0, {
4544
+ F: __dxlog_file6,
4481
4545
  L: 57,
4482
4546
  S: void 0,
4483
4547
  C: (f, a) => f(...a)
@@ -4566,22 +4630,13 @@ var createThemeExtensions = ({ theme, themeMode, slots } = {}) => {
4566
4630
 
4567
4631
  // packages/ui/react-ui-editor/src/hooks/useTextModel.ts
4568
4632
  import get4 from "lodash.get";
4569
- import { useEffect as useEffect4, useState as useState5 } from "react";
4633
+ import { useState as useState5, useMemo as useMemo2 } from "react";
4570
4634
  import { generateName } from "@dxos/display-name";
4571
4635
  import { getRawDoc } from "@dxos/echo-schema";
4572
4636
  import { invariant as invariant3 } from "@dxos/invariant";
4573
4637
  import { isAutomergeObject } from "@dxos/react-client/echo";
4574
- var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
4575
- var useTextModel = (props) => {
4576
- const { identity, space, text } = props;
4577
- const [model, setModel] = useState5();
4578
- useEffect4(() => setModel(createModel(props)), [
4579
- identity,
4580
- space,
4581
- text
4582
- ]);
4583
- return model;
4584
- };
4638
+ var __dxlog_file7 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextModel.ts";
4639
+ var useTextModel = (props) => useMemo2(() => createModel(props), Object.values(props));
4585
4640
  var useInMemoryTextModel = ({ id, defaultContent }) => {
4586
4641
  const [content, setContent] = useState5(defaultContent ?? "");
4587
4642
  return {
@@ -4596,7 +4651,7 @@ var createModel = ({ space, identity, text }) => {
4596
4651
  return void 0;
4597
4652
  }
4598
4653
  invariant3(isAutomergeObject(text), void 0, {
4599
- F: __dxlog_file6,
4654
+ F: __dxlog_file7,
4600
4655
  L: 54,
4601
4656
  S: void 0,
4602
4657
  A: [
@@ -4681,6 +4736,9 @@ export {
4681
4736
  defaultSlots,
4682
4737
  defaultTextSlots,
4683
4738
  defaultTheme,
4739
+ editorFillLayoutEditor,
4740
+ editorFillLayoutRoot,
4741
+ editorHalfViewportOverscrollContent,
4684
4742
  editorMode,
4685
4743
  editorWithToolbarLayout,
4686
4744
  focusComment,