@dxos/react-ui-editor 0.6.2-next.5b5129c → 0.6.3-main.0308ae2

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.
@@ -1348,7 +1348,7 @@ var command = (options) => {
1348
1348
  // packages/ui/react-ui-editor/src/extensions/comments.ts
1349
1349
  import { invertedEffects } from "@codemirror/commands";
1350
1350
  import { Facet as Facet4, StateEffect as StateEffect3, StateField as StateField4 } from "@codemirror/state";
1351
- import { hoverTooltip, keymap as keymap4, Decoration as Decoration4, EditorView as EditorView7 } from "@codemirror/view";
1351
+ import { hoverTooltip, keymap as keymap4, Decoration as Decoration4, EditorView as EditorView7, ViewPlugin as ViewPlugin4 } from "@codemirror/view";
1352
1352
  import sortBy from "lodash.sortby";
1353
1353
  import { useEffect, useMemo, useState } from "react";
1354
1354
  import { debounce } from "@dxos/async";
@@ -1523,15 +1523,13 @@ var styles3 = EditorView7.baseTheme({
1523
1523
  backgroundColor: getToken("extend.colors.yellow.900")
1524
1524
  }
1525
1525
  });
1526
- var createCommentMark = (id, isCurrent) => {
1527
- return Decoration4.mark({
1528
- class: isCurrent ? "cm-comment-current" : "cm-comment",
1529
- attributes: {
1530
- "data-testid": "cm-comment",
1531
- "data-comment-id": id
1532
- }
1533
- });
1534
- };
1526
+ var createCommentMark = (id, isCurrent) => Decoration4.mark({
1527
+ class: isCurrent ? "cm-comment-current" : "cm-comment",
1528
+ attributes: {
1529
+ "data-testid": "cm-comment",
1530
+ "data-comment-id": id
1531
+ }
1532
+ });
1535
1533
  var commentsDecorations = EditorView7.decorations.compute([
1536
1534
  commentsState
1537
1535
  ], (state2) => {
@@ -1541,7 +1539,7 @@ var commentsDecorations = EditorView7.decorations.compute([
1541
1539
  if (!range) {
1542
1540
  log4.warn("Invalid range:", range, {
1543
1541
  F: __dxlog_file6,
1544
- L: 160,
1542
+ L: 169,
1545
1543
  S: void 0,
1546
1544
  C: (f, a) => f(...a)
1547
1545
  });
@@ -1843,20 +1841,26 @@ var scrollThreadIntoView = (view, id, center = true) => {
1843
1841
  }
1844
1842
  const range = Cursor.getRangeFromCursor(view.state, comment.comment.cursor);
1845
1843
  if (range) {
1846
- view.dispatch({
1847
- selection: {
1848
- anchor: range.from
1849
- },
1850
- effects: [
1851
- //
1852
- EditorView7.scrollIntoView(range.from, center ? {
1853
- y: "center"
1854
- } : void 0),
1855
- setSelection.of({
1856
- current: id
1857
- })
1858
- ]
1859
- });
1844
+ const currentSelection = view.state.selection.main;
1845
+ const currentScrollPosition = view.scrollDOM.scrollTop;
1846
+ const targetScrollPosition = view.coordsAtPos(range.from)?.top;
1847
+ const needsScroll = targetScrollPosition !== void 0 && (targetScrollPosition < currentScrollPosition || targetScrollPosition > currentScrollPosition + view.scrollDOM.clientHeight);
1848
+ const needsSelectionUpdate = currentSelection.from !== range.from || currentSelection.to !== range.from;
1849
+ if (needsScroll || needsSelectionUpdate) {
1850
+ view.dispatch({
1851
+ selection: needsSelectionUpdate ? {
1852
+ anchor: range.from
1853
+ } : void 0,
1854
+ effects: [
1855
+ needsScroll ? EditorView7.scrollIntoView(range.from, center ? {
1856
+ y: "center"
1857
+ } : void 0) : [],
1858
+ needsSelectionUpdate ? setSelection.of({
1859
+ current: id
1860
+ }) : []
1861
+ ].flat()
1862
+ });
1863
+ }
1860
1864
  }
1861
1865
  };
1862
1866
  var selectionOverlapsComment = (state2) => {
@@ -1872,24 +1876,34 @@ var selectionOverlapsComment = (state2) => {
1872
1876
  var hasActiveSelection = (state2) => {
1873
1877
  return state2.selection.ranges.some((range) => !range.empty);
1874
1878
  };
1875
- var useComments = (view, id, comments2) => {
1876
- useEffect(() => {
1877
- if (view) {
1879
+ var ExternalCommentSync = class {
1880
+ constructor(view, id, subscribe, getThreads) {
1881
+ this.destroy = () => {
1882
+ this.unsubscribe();
1883
+ };
1884
+ const updateComments = () => {
1885
+ const threads = getThreads();
1886
+ const comments2 = threads.filter(nonNullable).filter((thread) => thread.anchor).map((thread) => ({
1887
+ id: thread.id,
1888
+ cursor: thread.anchor
1889
+ }));
1878
1890
  if (id === view.state.facet(documentId)) {
1879
- view.dispatch({
1891
+ queueMicrotask(() => view.dispatch({
1880
1892
  effects: setComments.of({
1881
1893
  id,
1882
- comments: comments2 ?? []
1894
+ comments: comments2
1883
1895
  })
1884
- });
1896
+ }));
1885
1897
  }
1886
- }
1887
- }, [
1888
- id,
1889
- view,
1890
- comments2
1891
- ]);
1898
+ };
1899
+ this.unsubscribe = subscribe(updateComments);
1900
+ }
1892
1901
  };
1902
+ var createExternalCommentSync = (id, subscribe, getThreads) => ViewPlugin4.fromClass(class {
1903
+ constructor(view) {
1904
+ return new ExternalCommentSync(view, id, subscribe, getThreads);
1905
+ }
1906
+ });
1893
1907
  var useCommentState = () => {
1894
1908
  const [state2, setState] = useState({
1895
1909
  comment: false,
@@ -1908,6 +1922,20 @@ var useCommentState = () => {
1908
1922
  observer
1909
1923
  ];
1910
1924
  };
1925
+ var useComments = (view, id, comments2) => {
1926
+ useEffect(() => {
1927
+ if (view) {
1928
+ if (id === view.state.facet(documentId)) {
1929
+ view.dispatch({
1930
+ effects: setComments.of({
1931
+ id,
1932
+ comments: comments2 ?? []
1933
+ })
1934
+ });
1935
+ }
1936
+ }
1937
+ });
1938
+ };
1911
1939
  var useCommentClickListener = (onCommentClick) => {
1912
1940
  const observer = useMemo(() => EditorView7.updateListener.of((update2) => {
1913
1941
  update2.transactions.forEach((transaction) => {
@@ -3709,7 +3737,7 @@ var markdownHighlightStyle = (readonly) => {
3709
3737
  // packages/ui/react-ui-editor/src/extensions/markdown/linkPaste.ts
3710
3738
  import { syntaxTree as syntaxTree2 } from "@codemirror/language";
3711
3739
  import { Transaction } from "@codemirror/state";
3712
- import { ViewPlugin as ViewPlugin4 } from "@codemirror/view";
3740
+ import { ViewPlugin as ViewPlugin5 } from "@codemirror/view";
3713
3741
  var VALID_PROTOCOLS = [
3714
3742
  "http:",
3715
3743
  "https:",
@@ -3746,7 +3774,7 @@ var isValidUrl = (str) => {
3746
3774
  }
3747
3775
  };
3748
3776
  var onNextUpdate = (callback) => setTimeout(callback, 0);
3749
- var linkPastePlugin = ViewPlugin4.fromClass(class {
3777
+ var linkPastePlugin = ViewPlugin5.fromClass(class {
3750
3778
  constructor(view) {
3751
3779
  this.view = view;
3752
3780
  }
@@ -3841,7 +3869,7 @@ var createMarkdownExtensions = ({ themeMode } = {}) => {
3841
3869
  // packages/ui/react-ui-editor/src/extensions/markdown/decorate.ts
3842
3870
  import { syntaxTree as syntaxTree3 } from "@codemirror/language";
3843
3871
  import { RangeSetBuilder as RangeSetBuilder2, StateEffect as StateEffect4 } from "@codemirror/state";
3844
- import { EditorView as EditorView12, Decoration as Decoration5, WidgetType as WidgetType3, ViewPlugin as ViewPlugin5 } from "@codemirror/view";
3872
+ import { EditorView as EditorView12, Decoration as Decoration5, WidgetType as WidgetType3, ViewPlugin as ViewPlugin6 } from "@codemirror/view";
3845
3873
  import { mx as mx2 } from "@dxos/react-ui-theme";
3846
3874
  var HorizontalRuleWidget = class extends WidgetType3 {
3847
3875
  toDOM() {
@@ -4057,7 +4085,7 @@ var buildDecorations = (view, options, focus) => {
4057
4085
  var forceUpdate = StateEffect4.define();
4058
4086
  var decorateMarkdown = (options = {}) => {
4059
4087
  return [
4060
- ViewPlugin5.fromClass(class {
4088
+ ViewPlugin6.fromClass(class {
4061
4089
  constructor(view) {
4062
4090
  ({ deco: this.deco, atomicDeco: this.atomicDeco } = buildDecorations(view, options, view.hasFocus));
4063
4091
  }
@@ -5188,6 +5216,7 @@ export {
5188
5216
  createBasicExtensions,
5189
5217
  createComment,
5190
5218
  createDataExtensions,
5219
+ createExternalCommentSync,
5191
5220
  createMarkdownExtensions,
5192
5221
  createThemeExtensions,
5193
5222
  decorateMarkdown,