@dxos/react-ui-editor 0.6.6-main.e1a6e1f → 0.6.6-staging.41c080b

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 (49) hide show
  1. package/dist/lib/browser/index.mjs +203 -307
  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/index.d.ts +0 -1
  5. package/dist/types/src/components/index.d.ts.map +1 -1
  6. package/dist/types/src/extensions/automerge/automerge.d.ts.map +1 -1
  7. package/dist/types/src/extensions/automerge/automerge.stories.d.ts +5 -2
  8. package/dist/types/src/extensions/automerge/automerge.stories.d.ts.map +1 -1
  9. package/dist/types/src/extensions/automerge/cursor.d.ts.map +1 -1
  10. package/dist/types/src/extensions/awareness/awareness-provider.d.ts.map +1 -1
  11. package/dist/types/src/extensions/awareness/awareness.d.ts +6 -6
  12. package/dist/types/src/extensions/awareness/awareness.d.ts.map +1 -1
  13. package/dist/types/src/extensions/comments.d.ts +1 -2
  14. package/dist/types/src/extensions/comments.d.ts.map +1 -1
  15. package/dist/types/src/extensions/cursor.d.ts +1 -1
  16. package/dist/types/src/extensions/cursor.d.ts.map +1 -1
  17. package/dist/types/src/extensions/factories.d.ts.map +1 -1
  18. package/dist/types/src/extensions/markdown/link.d.ts +1 -3
  19. package/dist/types/src/extensions/markdown/link.d.ts.map +1 -1
  20. package/dist/types/src/hooks/{useTextEditor.stories.d.ts → InputMode.stories.d.ts} +5 -9
  21. package/dist/types/src/hooks/InputMode.stories.d.ts.map +1 -0
  22. package/dist/types/src/{components/TextEditor → hooks}/TextEditor.stories.d.ts +4 -16
  23. package/dist/types/src/hooks/TextEditor.stories.d.ts.map +1 -0
  24. package/dist/types/src/hooks/useTextEditor.d.ts +20 -3
  25. package/dist/types/src/hooks/useTextEditor.d.ts.map +1 -1
  26. package/dist/types/src/themes/default.d.ts.map +1 -1
  27. package/package.json +25 -25
  28. package/src/components/Toolbar/Toolbar.stories.tsx +1 -1
  29. package/src/components/index.ts +0 -1
  30. package/src/extensions/automerge/automerge.stories.tsx +25 -18
  31. package/src/extensions/automerge/automerge.ts +2 -0
  32. package/src/extensions/automerge/cursor.ts +3 -4
  33. package/src/extensions/awareness/awareness-provider.ts +2 -0
  34. package/src/extensions/awareness/awareness.ts +34 -30
  35. package/src/extensions/comments.ts +6 -14
  36. package/src/extensions/cursor.ts +1 -1
  37. package/src/extensions/factories.ts +19 -13
  38. package/src/hooks/{useTextEditor.stories.tsx → InputMode.stories.tsx} +30 -35
  39. package/src/{components/TextEditor → hooks}/TextEditor.stories.tsx +22 -28
  40. package/src/hooks/useTextEditor.ts +75 -23
  41. package/src/themes/default.ts +20 -4
  42. package/dist/types/src/components/TextEditor/TextEditor.d.ts +0 -34
  43. package/dist/types/src/components/TextEditor/TextEditor.d.ts.map +0 -1
  44. package/dist/types/src/components/TextEditor/TextEditor.stories.d.ts.map +0 -1
  45. package/dist/types/src/components/TextEditor/index.d.ts +0 -2
  46. package/dist/types/src/components/TextEditor/index.d.ts.map +0 -1
  47. package/dist/types/src/hooks/useTextEditor.stories.d.ts.map +0 -1
  48. package/src/components/TextEditor/TextEditor.tsx +0 -184
  49. package/src/components/TextEditor/index.ts +0 -5
@@ -35,14 +35,13 @@ import { keymap as keymap11 } from "@codemirror/view";
35
35
  import { tags as tags2 } from "@lezer/highlight";
36
36
  import { TextKind } from "@dxos/protocols/proto/dxos/echo/model/text";
37
37
 
38
- // packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
39
- import { EditorState as EditorState2 } from "@codemirror/state";
40
- import { EditorView as EditorView16 } from "@codemirror/view";
41
- import { useFocusableGroup } from "@fluentui/react-tabster";
42
- import React, { forwardRef, useCallback, useEffect as useEffect2, useImperativeHandle, useRef, useState as useState3 } from "react";
43
- import { log as log7 } from "@dxos/log";
44
- import { useDefaultValue } from "@dxos/react-ui";
45
- import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
38
+ // packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
39
+ import { ChatText, Code, CodeBlock, Image, Link, ListBullets, ListChecks, ListNumbers, Paragraph, Quotes, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, CaretDown, Check, PencilSimpleSlash, MarkdownLogo, PencilSimple } from "@phosphor-icons/react";
40
+ import { createContext } from "@radix-ui/react-context";
41
+ import React, { useEffect as useEffect2, useRef, useState as useState3 } from "react";
42
+ import { useDropzone } from "react-dropzone";
43
+ import { Button, DensityProvider, DropdownMenu, ElevationProvider, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
44
+ import { getSize } from "@dxos/react-ui-theme";
46
45
 
47
46
  // packages/ui/react-ui-editor/src/extensions/annotations.ts
48
47
  import { StateField } from "@codemirror/state";
@@ -188,17 +187,16 @@ import { next as A3 } from "@dxos/automerge/automerge";
188
187
 
189
188
  // packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts
190
189
  import { log } from "@dxos/log";
191
- import { toCursor, fromCursor } from "@dxos/react-client/echo";
190
+ import { fromCursor, toCursor } from "@dxos/react-client/echo";
192
191
  var __dxlog_file = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/extensions/automerge/cursor.ts";
193
192
  var cursorConverter = (accessor) => ({
194
- // TODO(burdon): Handle assoc to associate with a previous character.
195
- toCursor: (pos) => {
193
+ toCursor: (pos, assoc) => {
196
194
  try {
197
- return toCursor(accessor, pos);
195
+ return toCursor(accessor, pos, assoc);
198
196
  } catch (err) {
199
197
  log.catch(err, void 0, {
200
198
  F: __dxlog_file,
201
- L: 16,
199
+ L: 15,
202
200
  S: void 0,
203
201
  C: (f, a) => f(...a)
204
202
  });
@@ -211,7 +209,7 @@ var cursorConverter = (accessor) => ({
211
209
  } catch (err) {
212
210
  log.catch(err, void 0, {
213
211
  F: __dxlog_file,
214
- L: 25,
212
+ L: 24,
215
213
  S: void 0,
216
214
  C: (f, a) => f(...a)
217
215
  });
@@ -452,6 +450,7 @@ var automerge = (accessor) => {
452
450
  const syncer = new Syncer(accessor.handle, syncState);
453
451
  return [
454
452
  Cursor.converter.of(cursorConverter(accessor)),
453
+ // Track heads.
455
454
  syncState,
456
455
  // Reconcile external updates.
457
456
  ViewPlugin.fromClass(class {
@@ -506,13 +505,11 @@ var awareness = (provider = dummyProvider) => {
506
505
  };
507
506
  var RemoteSelectionsDecorator = class {
508
507
  constructor(view) {
509
- this.decorations = RangeSet.of([]);
510
508
  this._ctx = new Context(void 0, {
511
509
  F: __dxlog_file2,
512
- L: 85
510
+ L: 82
513
511
  });
514
- this._lastAnchor = void 0;
515
- this._lastHead = void 0;
512
+ this.decorations = RangeSet.of([]);
516
513
  this._cursorConverter = view.state.facet(Cursor.converter);
517
514
  this._provider = view.state.facet(awarenessProvider);
518
515
  this._provider.open();
@@ -529,12 +526,12 @@ var RemoteSelectionsDecorator = class {
529
526
  this._provider.close();
530
527
  }
531
528
  update(update2) {
532
- this._updateLocalSelection(update2);
533
- this._updateRemoteSelections(update2);
529
+ this._updateLocalSelection(update2.view);
530
+ this._updateRemoteSelections(update2.view);
534
531
  }
535
- _updateLocalSelection(update2) {
536
- const hasFocus = update2.view.hasFocus && update2.view.dom.ownerDocument.hasFocus();
537
- const { anchor = void 0, head = void 0 } = hasFocus ? update2.state.selection.main : {};
532
+ _updateLocalSelection(view) {
533
+ const hasFocus = view.hasFocus && view.dom.ownerDocument.hasFocus();
534
+ const { anchor = void 0, head = void 0 } = hasFocus ? view.state.selection.main : {};
538
535
  if (this._lastAnchor === anchor && this._lastHead === head) {
539
536
  return;
540
537
  }
@@ -542,10 +539,10 @@ var RemoteSelectionsDecorator = class {
542
539
  this._lastHead = head;
543
540
  this._provider.update(anchor !== void 0 && head !== void 0 ? {
544
541
  anchor: this._cursorConverter.toCursor(anchor),
545
- head: this._cursorConverter.toCursor(head)
542
+ head: this._cursorConverter.toCursor(head, -1)
546
543
  } : void 0);
547
544
  }
548
- _updateRemoteSelections(update2) {
545
+ _updateRemoteSelections(view) {
549
546
  const decorations = [];
550
547
  const awarenessStates = this._provider.getRemoteStates();
551
548
  for (const state2 of awarenessStates) {
@@ -554,12 +551,12 @@ var RemoteSelectionsDecorator = class {
554
551
  if (anchor == null || head == null) {
555
552
  continue;
556
553
  }
557
- const start = Math.min(Math.min(anchor, head), update2.view.state.doc.length);
558
- const end = Math.min(Math.max(anchor, head), update2.view.state.doc.length);
559
- const startLine = update2.view.state.doc.lineAt(start);
560
- const endLine = update2.view.state.doc.lineAt(end);
561
- const color = state2.info.color ?? "#30bced";
562
- const lightColor = state2.info.lightColor ?? color + "33";
554
+ const start = Math.min(Math.min(anchor, head), view.state.doc.length);
555
+ const end = Math.min(Math.max(anchor, head), view.state.doc.length);
556
+ const startLine = view.state.doc.lineAt(start);
557
+ const endLine = view.state.doc.lineAt(end);
558
+ const darkColor = state2.info.darkColor;
559
+ const lightColor = state2.info.lightColor;
563
560
  if (startLine.number === endLine.number) {
564
561
  decorations.push({
565
562
  from: start,
@@ -593,7 +590,7 @@ var RemoteSelectionsDecorator = class {
593
590
  })
594
591
  });
595
592
  for (let i = startLine.number + 1; i < endLine.number; i++) {
596
- const linePos = update2.view.state.doc.line(i).from;
593
+ const linePos = view.state.doc.line(i).from;
597
594
  decorations.push({
598
595
  from: linePos,
599
596
  to: linePos,
@@ -612,7 +609,7 @@ var RemoteSelectionsDecorator = class {
612
609
  value: Decoration2.widget({
613
610
  side: head - anchor > 0 ? -1 : 1,
614
611
  block: false,
615
- widget: new RemoteCaretWidget(state2.info.displayName ?? "Anonymous", color)
612
+ widget: new RemoteCaretWidget(state2.info.displayName ?? "Anonymous", darkColor)
616
613
  })
617
614
  });
618
615
  }
@@ -698,12 +695,11 @@ var styles2 = EditorView3.baseTheme({
698
695
  lineHeight: "normal",
699
696
  userSelect: "none",
700
697
  color: "white",
701
- padding: "2px",
698
+ padding: "2px 6px",
702
699
  zIndex: 101,
703
700
  transition: "opacity .3s ease-in-out",
704
701
  backgroundColor: "inherit",
705
702
  borderRadius: "2px",
706
- // These should be separate.
707
703
  opacity: 0,
708
704
  transitionDelay: "0s",
709
705
  whiteSpace: "nowrap"
@@ -763,7 +759,7 @@ var SpaceAwarenessProvider = class {
763
759
  err
764
760
  }, {
765
761
  F: __dxlog_file3,
766
- L: 89,
762
+ L: 91,
767
763
  S: this,
768
764
  C: (f, a) => f(...a)
769
765
  });
@@ -780,7 +776,7 @@ var SpaceAwarenessProvider = class {
780
776
  update(position) {
781
777
  invariant(this._postTask, void 0, {
782
778
  F: __dxlog_file3,
783
- L: 104,
779
+ L: 106,
784
780
  S: this,
785
781
  A: [
786
782
  "this._postTask",
@@ -797,7 +793,7 @@ var SpaceAwarenessProvider = class {
797
793
  _handleQueryMessage() {
798
794
  invariant(this._postTask, void 0, {
799
795
  F: __dxlog_file3,
800
- L: 115,
796
+ L: 117,
801
797
  S: this,
802
798
  A: [
803
799
  "this._postTask",
@@ -809,7 +805,7 @@ var SpaceAwarenessProvider = class {
809
805
  _handlePostMessage(message) {
810
806
  invariant(message.kind === "post", void 0, {
811
807
  F: __dxlog_file3,
812
- L: 120,
808
+ L: 122,
813
809
  S: this,
814
810
  A: [
815
811
  "message.kind === 'post'",
@@ -1545,7 +1541,7 @@ var commentsDecorations = EditorView7.decorations.compute([
1545
1541
  if (!range) {
1546
1542
  log4.warn("Invalid range:", range, {
1547
1543
  F: __dxlog_file6,
1548
- L: 182,
1544
+ L: 181,
1549
1545
  S: void 0,
1550
1546
  C: (f, a) => f(...a)
1551
1547
  });
@@ -1883,16 +1879,12 @@ var hasActiveSelection = (state2) => {
1883
1879
  return state2.selection.ranges.some((range) => !range.empty);
1884
1880
  };
1885
1881
  var ExternalCommentSync = class {
1886
- constructor(view, id, subscribe, getThreads) {
1882
+ constructor(view, id, subscribe, getComments) {
1887
1883
  this.destroy = () => {
1888
1884
  this.unsubscribe();
1889
1885
  };
1890
1886
  const updateComments = () => {
1891
- const threads = getThreads();
1892
- const comments2 = threads.filter(nonNullable).filter((thread) => thread.anchor).map((thread) => ({
1893
- id: thread.id,
1894
- cursor: thread.anchor
1895
- }));
1887
+ const comments2 = getComments();
1896
1888
  if (id === view.state.facet(documentId)) {
1897
1889
  queueMicrotask(() => view.dispatch({
1898
1890
  effects: setComments.of({
@@ -1905,9 +1897,9 @@ var ExternalCommentSync = class {
1905
1897
  this.unsubscribe = subscribe(updateComments);
1906
1898
  }
1907
1899
  };
1908
- var createExternalCommentSync = (id, subscribe, getThreads) => ViewPlugin4.fromClass(class {
1900
+ var createExternalCommentSync = (id, subscribe, getComments) => ViewPlugin4.fromClass(class {
1909
1901
  constructor(view) {
1910
- return new ExternalCommentSync(view, id, subscribe, getThreads);
1902
+ return new ExternalCommentSync(view, id, subscribe, getComments);
1911
1903
  }
1912
1904
  });
1913
1905
  var useCommentState = () => {
@@ -1943,7 +1935,7 @@ var useComments = (view, id, comments2) => {
1943
1935
  });
1944
1936
  };
1945
1937
  var useCommentClickListener = (onCommentClick) => {
1946
- const observer = useMemo(() => EditorView7.updateListener.of((update2) => {
1938
+ return useMemo(() => EditorView7.updateListener.of((update2) => {
1947
1939
  update2.transactions.forEach((transaction) => {
1948
1940
  transaction.effects.forEach((effect) => {
1949
1941
  if (effect.is(commentClickedEffect)) {
@@ -1954,15 +1946,14 @@ var useCommentClickListener = (onCommentClick) => {
1954
1946
  }), [
1955
1947
  onCommentClick
1956
1948
  ]);
1957
- return observer;
1958
1949
  };
1959
1950
 
1960
1951
  // packages/ui/react-ui-editor/src/extensions/debug.ts
1961
1952
  import { syntaxTree } from "@codemirror/language";
1962
1953
  import { StateField as StateField5 } from "@codemirror/state";
1963
- var debugNodeLogger = (log9 = console.log) => {
1954
+ var debugNodeLogger = (log8 = console.log) => {
1964
1955
  const logTokens = (state2) => syntaxTree(state2).iterate({
1965
- enter: (node) => log9(node.type)
1956
+ enter: (node) => log8(node.type)
1966
1957
  });
1967
1958
  return StateField5.define({
1968
1959
  create: (state2) => logTokens(state2),
@@ -2159,19 +2150,34 @@ var defaultTheme = {
2159
2150
  // tooltip
2160
2151
  //
2161
2152
  ".cm-tooltip": {
2162
- border: "none",
2163
- background: "unset"
2153
+ border: "none"
2154
+ },
2155
+ "&light .cm-tooltip": {
2156
+ background: `${get2(tokens, "extend.colors.neutral.100")} !important`
2157
+ },
2158
+ "&dark .cm-tooltip": {
2159
+ background: `${get2(tokens, "extend.colors.neutral.900")} !important`
2164
2160
  },
2165
2161
  ".cm-tooltip-below": {},
2166
2162
  //
2167
2163
  // autocomplete
2164
+ // https://github.com/codemirror/autocomplete/blob/main/src/completion.ts
2168
2165
  //
2169
2166
  ".cm-tooltip-autocomplete": {
2170
2167
  marginTop: "4px",
2171
2168
  marginLeft: "-3px"
2172
2169
  },
2173
- ".cm-tooltip-autocomplete ul li": {},
2174
- ".cm-tooltip-autocomplete ul li[aria-selected]": {},
2170
+ ".cm-tooltip-autocomplete > ul": {
2171
+ maxHeight: "20em !important"
2172
+ },
2173
+ ".cm-tooltip-autocomplete > ul > li": {},
2174
+ ".cm-tooltip-autocomplete > ul > li[aria-selected]": {},
2175
+ // TODO(burdon): Can we add a class prefix to avoid adding !important?
2176
+ ".cm-tooltip.cm-tooltip-autocomplete > ul > completion-section": {
2177
+ paddingLeft: "4px !important",
2178
+ borderBottom: "none !important",
2179
+ color: get2(tokens, "extend.colors.primary.500")
2180
+ },
2175
2181
  ".cm-completionIcon": {
2176
2182
  display: "none"
2177
2183
  },
@@ -2179,7 +2185,8 @@ var defaultTheme = {
2179
2185
  fontFamily: get2(tokens, "fontFamily.body", []).join(",")
2180
2186
  },
2181
2187
  ".cm-completionMatchedText": {
2182
- textDecoration: "none"
2188
+ textDecoration: "none !important",
2189
+ opacity: 0.5
2183
2190
  },
2184
2191
  //
2185
2192
  // table
@@ -2365,23 +2372,23 @@ var createThemeExtensions = ({ theme, themeMode, slots: _slots } = {}) => {
2365
2372
  ].filter(isNotFalsy2);
2366
2373
  };
2367
2374
  var createDataExtensions = ({ id, text, space, identity }) => {
2368
- const extensions = text ? [
2369
- automerge(text)
2370
- ] : [];
2375
+ const extensions = [];
2376
+ if (text) {
2377
+ extensions.push(automerge(text));
2378
+ }
2371
2379
  if (space && identity) {
2372
2380
  const peerId = identity?.identityKey.toHex();
2373
2381
  const { cursorLightValue, cursorDarkValue } = hueTokens[identity?.profile?.data?.hue ?? hexToHue(peerId ?? "0")];
2374
- const awarenessProvider2 = new SpaceAwarenessProvider({
2382
+ extensions.push(awareness(new SpaceAwarenessProvider({
2375
2383
  space,
2376
2384
  channel: `awareness.${id}`,
2377
2385
  peerId: identity.identityKey.toHex(),
2378
2386
  info: {
2379
2387
  displayName: identity.profile?.displayName ?? generateName(identity.identityKey.toHex()),
2380
- color: cursorDarkValue,
2388
+ darkColor: cursorDarkValue,
2381
2389
  lightColor: cursorLightValue
2382
2390
  }
2383
- });
2384
- extensions.push(awareness(awarenessProvider2));
2391
+ })));
2385
2392
  }
2386
2393
  return extensions;
2387
2394
  };
@@ -4645,168 +4652,27 @@ var typewriter = ({ delay = 75, items = defaultItems } = {}) => {
4645
4652
  ];
4646
4653
  };
4647
4654
 
4648
- // packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx
4649
- var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/components/TextEditor/TextEditor.tsx";
4650
- var instanceCount = 0;
4651
- var TextEditor = /* @__PURE__ */ forwardRef(({
4652
- id,
4653
- // TODO(wittjosiah): Rename initialText?
4654
- doc,
4655
- selection,
4656
- extensions,
4657
- className,
4658
- autoFocus,
4659
- scrollTo: propsScrollTo,
4660
- moveToEndOfLine,
4661
- debug,
4662
- dataTestId
4663
- }, forwardedRef) => {
4664
- const [instanceId] = useState3(() => `text-editor-${++instanceCount}`);
4665
- const scrollTo = useDefaultValue(propsScrollTo, EditorView16.scrollIntoView(0, {
4666
- yMargin: 0
4667
- }));
4668
- const tabsterDOMAttribute = useFocusableGroup({
4669
- tabBehavior: "limited"
4670
- });
4671
- const rootRef = useRef(null);
4672
- const [view, setView] = useState3(null);
4673
- useImperativeHandle(forwardedRef, () => view, [
4674
- view
4675
- ]);
4676
- useEffect2(() => {
4677
- if (autoFocus) {
4678
- view?.focus();
4679
- }
4680
- }, [
4681
- view,
4682
- autoFocus
4683
- ]);
4684
- useEffect2(() => {
4685
- log7("create", {
4686
- id,
4687
- instanceId
4688
- }, {
4689
- F: __dxlog_file11,
4690
- L: 91,
4691
- S: void 0,
4692
- C: (f, a) => f(...a)
4693
- });
4694
- const state2 = EditorState2.create({
4695
- doc,
4696
- extensions: [
4697
- id && documentId2.of(id),
4698
- // TODO(burdon): NOTE: Doesn't catch errors in keymap functions.
4699
- EditorView16.exceptionSink.of((err) => {
4700
- log7.catch(err, void 0, {
4701
- F: __dxlog_file11,
4702
- L: 104,
4703
- S: void 0,
4704
- C: (f, a) => f(...a)
4705
- });
4706
- }),
4707
- // Focus.
4708
- EditorView16.updateListener.of((update2) => {
4709
- update2.transactions.forEach((transaction) => {
4710
- if (transaction.isUserEvent(focusEvent)) {
4711
- rootRef.current?.focus();
4712
- }
4713
- });
4714
- }),
4715
- extensions
4716
- ].filter(isNotFalsy4)
4717
- });
4718
- const view2 = new EditorView16({
4719
- state: state2,
4720
- parent: rootRef.current,
4721
- scrollTo,
4722
- // NOTE: Uncomment to debug/monitor all transactions.
4723
- // https://codemirror.net/docs/ref/#view.EditorView.dispatch
4724
- dispatchTransactions: (trs, view3) => {
4725
- if (debug) {
4726
- logChanges(trs);
4727
- }
4728
- view3.update(trs);
4729
- }
4730
- });
4731
- if (moveToEndOfLine && !(scrollTo || selection)) {
4732
- const { to } = view2.state.doc.lineAt(0);
4733
- view2.dispatch({
4734
- selection: {
4735
- anchor: to
4736
- }
4737
- });
4738
- }
4739
- if (state2.facet(editorInputMode).noTabster) {
4740
- rootRef.current?.removeAttribute("data-tabster");
4741
- }
4742
- setView(view2);
4743
- return () => {
4744
- log7("destroy", {
4745
- id,
4746
- instanceId
4747
- }, {
4748
- F: __dxlog_file11,
4749
- L: 153,
4750
- S: void 0,
4751
- C: (f, a) => f(...a)
4752
- });
4753
- view2?.destroy();
4754
- };
4755
- }, [
4756
- id,
4757
- selection,
4758
- scrollTo,
4759
- extensions
4760
- ]);
4761
- const handleKeyUp = useCallback((event) => {
4762
- const { key } = event;
4763
- switch (key) {
4764
- case "Enter": {
4765
- view?.focus();
4766
- break;
4767
- }
4768
- }
4769
- }, [
4770
- view
4771
- ]);
4772
- return /* @__PURE__ */ React.createElement("div", {
4773
- role: "none",
4774
- ref: rootRef,
4775
- tabIndex: 0,
4776
- className,
4777
- "data-testid": dataTestId,
4778
- ...tabsterDOMAttribute,
4779
- onKeyUp: handleKeyUp
4780
- });
4781
- });
4782
-
4783
4655
  // packages/ui/react-ui-editor/src/components/Toolbar/Toolbar.tsx
4784
- import { ChatText, Code, CodeBlock, Image, Link, ListBullets, ListChecks, ListNumbers, Paragraph, Quotes, TextStrikethrough, Table as Table2, TextB, TextHOne, TextHTwo, TextHThree, TextHFour, TextHFive, TextHSix, TextItalic, CaretDown, Check, PencilSimpleSlash, MarkdownLogo, PencilSimple } from "@phosphor-icons/react";
4785
- import { createContext } from "@radix-ui/react-context";
4786
- import React2, { useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
4787
- import { useDropzone } from "react-dropzone";
4788
- import { Button, DensityProvider, DropdownMenu, ElevationProvider, Toolbar as NaturalToolbar, Tooltip, useTranslation } from "@dxos/react-ui";
4789
- import { getSize } from "@dxos/react-ui-theme";
4790
4656
  var iconStyles = getSize(5);
4791
4657
  var buttonStyles = "min-bs-0 p-2";
4792
4658
  var tooltipProps = {
4793
4659
  side: "top",
4794
4660
  classNames: "z-10"
4795
4661
  };
4796
- var ToolbarSeparator = () => /* @__PURE__ */ React2.createElement("div", {
4662
+ var ToolbarSeparator = () => /* @__PURE__ */ React.createElement("div", {
4797
4663
  role: "separator",
4798
4664
  className: "grow"
4799
4665
  });
4800
4666
  var [ToolbarContextProvider, useToolbarContext] = createContext("Toolbar");
4801
4667
  var ToolbarRoot = ({ children, onAction, classNames, state: state2 }) => {
4802
- return /* @__PURE__ */ React2.createElement(ToolbarContextProvider, {
4668
+ return /* @__PURE__ */ React.createElement(ToolbarContextProvider, {
4803
4669
  onAction,
4804
4670
  state: state2
4805
- }, /* @__PURE__ */ React2.createElement(DensityProvider, {
4671
+ }, /* @__PURE__ */ React.createElement(DensityProvider, {
4806
4672
  density: "fine"
4807
- }, /* @__PURE__ */ React2.createElement(ElevationProvider, {
4673
+ }, /* @__PURE__ */ React.createElement(ElevationProvider, {
4808
4674
  elevation: "chrome"
4809
- }, /* @__PURE__ */ React2.createElement(NaturalToolbar.Root, {
4675
+ }, /* @__PURE__ */ React.createElement(NaturalToolbar.Root, {
4810
4676
  classNames: [
4811
4677
  "p-1 is-full shrink-0 overflow-x-auto overflow-y-hidden",
4812
4678
  classNames
@@ -4817,30 +4683,30 @@ var ToolbarRoot = ({ children, onAction, classNames, state: state2 }) => {
4817
4683
  }, children))));
4818
4684
  };
4819
4685
  var ToolbarToggleButton = ({ Icon, children, ...props }) => {
4820
- return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
4686
+ return /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
4821
4687
  asChild: true
4822
- }, /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroupItem, {
4688
+ }, /* @__PURE__ */ React.createElement(NaturalToolbar.ToggleGroupItem, {
4823
4689
  variant: "ghost",
4824
4690
  ...props,
4825
4691
  classNames: buttonStyles
4826
- }, /* @__PURE__ */ React2.createElement(Icon, {
4692
+ }, /* @__PURE__ */ React.createElement(Icon, {
4827
4693
  className: iconStyles
4828
- }), /* @__PURE__ */ React2.createElement("span", {
4694
+ }), /* @__PURE__ */ React.createElement("span", {
4829
4695
  className: "sr-only"
4830
- }, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
4696
+ }, children))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
4831
4697
  };
4832
4698
  var ToolbarButton = ({ Icon, children, ...props }) => {
4833
- return /* @__PURE__ */ React2.createElement(Tooltip.Root, null, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
4699
+ return /* @__PURE__ */ React.createElement(Tooltip.Root, null, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
4834
4700
  asChild: true
4835
- }, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4701
+ }, /* @__PURE__ */ React.createElement(NaturalToolbar.Button, {
4836
4702
  variant: "ghost",
4837
4703
  ...props,
4838
4704
  classNames: buttonStyles
4839
- }, /* @__PURE__ */ React2.createElement(Icon, {
4705
+ }, /* @__PURE__ */ React.createElement(Icon, {
4840
4706
  className: iconStyles
4841
- }), /* @__PURE__ */ React2.createElement("span", {
4707
+ }), /* @__PURE__ */ React.createElement("span", {
4842
4708
  className: "sr-only"
4843
- }, children))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
4709
+ }, children))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, tooltipProps, children, /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
4844
4710
  };
4845
4711
  var ViewModeIcons = {
4846
4712
  preview: PencilSimple,
@@ -4851,10 +4717,10 @@ var MarkdownView = ({ mode }) => {
4851
4717
  const { t } = useTranslation(translationKey);
4852
4718
  const { onAction } = useToolbarContext("ViewMode");
4853
4719
  const ModeIcon = ViewModeIcons[mode ?? "preview"];
4854
- const suppressNextTooltip = useRef2(false);
4855
- const [tooltipOpen, setTooltipOpen] = useState4(false);
4856
- const [selectOpen, setSelectOpen] = useState4(false);
4857
- return /* @__PURE__ */ React2.createElement(Tooltip.Root, {
4720
+ const suppressNextTooltip = useRef(false);
4721
+ const [tooltipOpen, setTooltipOpen] = useState3(false);
4722
+ const [selectOpen, setSelectOpen] = useState3(false);
4723
+ return /* @__PURE__ */ React.createElement(Tooltip.Root, {
4858
4724
  open: tooltipOpen,
4859
4725
  onOpenChange: (nextOpen) => {
4860
4726
  if (nextOpen && suppressNextTooltip.current) {
@@ -4864,7 +4730,7 @@ var MarkdownView = ({ mode }) => {
4864
4730
  return setTooltipOpen(nextOpen);
4865
4731
  }
4866
4732
  }
4867
- }, /* @__PURE__ */ React2.createElement(DropdownMenu.Root, {
4733
+ }, /* @__PURE__ */ React.createElement(DropdownMenu.Root, {
4868
4734
  open: selectOpen,
4869
4735
  onOpenChange: (nextOpen) => {
4870
4736
  if (!nextOpen) {
@@ -4872,39 +4738,39 @@ var MarkdownView = ({ mode }) => {
4872
4738
  }
4873
4739
  return setSelectOpen(nextOpen);
4874
4740
  }
4875
- }, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
4741
+ }, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
4876
4742
  asChild: true
4877
- }, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4743
+ }, /* @__PURE__ */ React.createElement(NaturalToolbar.Button, {
4878
4744
  asChild: true
4879
- }, /* @__PURE__ */ React2.createElement(DropdownMenu.Trigger, {
4745
+ }, /* @__PURE__ */ React.createElement(DropdownMenu.Trigger, {
4880
4746
  asChild: true
4881
- }, /* @__PURE__ */ React2.createElement(Button, {
4747
+ }, /* @__PURE__ */ React.createElement(Button, {
4882
4748
  variant: "ghost",
4883
4749
  classNames: buttonStyles
4884
- }, /* @__PURE__ */ React2.createElement("span", {
4750
+ }, /* @__PURE__ */ React.createElement("span", {
4885
4751
  className: "sr-only"
4886
- }, t("mode label")), /* @__PURE__ */ React2.createElement(ModeIcon, {
4752
+ }, t("mode label")), /* @__PURE__ */ React.createElement(ModeIcon, {
4887
4753
  className: iconStyles
4888
- }), /* @__PURE__ */ React2.createElement(CaretDown, null))))), /* @__PURE__ */ React2.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React2.createElement(DropdownMenu.Content, {
4754
+ }), /* @__PURE__ */ React.createElement(CaretDown, null))))), /* @__PURE__ */ React.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React.createElement(DropdownMenu.Content, {
4889
4755
  classNames: "is-min md:is-min",
4890
4756
  onCloseAutoFocus: (e) => e.preventDefault()
4891
- }, /* @__PURE__ */ React2.createElement(DropdownMenu.Viewport, null, EditorViewModes.map((value) => {
4757
+ }, /* @__PURE__ */ React.createElement(DropdownMenu.Viewport, null, EditorViewModes.map((value) => {
4892
4758
  const Icon = ViewModeIcons[value];
4893
- return /* @__PURE__ */ React2.createElement(DropdownMenu.CheckboxItem, {
4759
+ return /* @__PURE__ */ React.createElement(DropdownMenu.CheckboxItem, {
4894
4760
  key: value,
4895
4761
  checked: value === mode,
4896
4762
  onClick: () => onAction?.({
4897
4763
  type: "view-mode",
4898
4764
  data: value
4899
4765
  })
4900
- }, /* @__PURE__ */ React2.createElement(Icon, {
4766
+ }, /* @__PURE__ */ React.createElement(Icon, {
4901
4767
  className: iconStyles
4902
- }), /* @__PURE__ */ React2.createElement("span", {
4768
+ }), /* @__PURE__ */ React.createElement("span", {
4903
4769
  className: "whitespace-nowrap grow"
4904
- }, t(`${value} mode label`)), /* @__PURE__ */ React2.createElement(Check, {
4770
+ }, t(`${value} mode label`)), /* @__PURE__ */ React.createElement(Check, {
4905
4771
  className: value === mode ? "visible" : "invisible"
4906
4772
  }));
4907
- })), /* @__PURE__ */ React2.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, t("view mode label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
4773
+ })), /* @__PURE__ */ React.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, tooltipProps, t("view mode label"), /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
4908
4774
  };
4909
4775
  var HeadingIcons = {
4910
4776
  "0": Paragraph,
@@ -4922,10 +4788,10 @@ var MarkdownHeading = () => {
4922
4788
  const header = blockType && /heading(\d)/.exec(blockType);
4923
4789
  const value = header ? header[1] : blockType === "paragraph" || !blockType ? "0" : void 0;
4924
4790
  const HeadingIcon = HeadingIcons[value ?? "0"];
4925
- const suppressNextTooltip = useRef2(false);
4926
- const [tooltipOpen, setTooltipOpen] = useState4(false);
4927
- const [selectOpen, setSelectOpen] = useState4(false);
4928
- return /* @__PURE__ */ React2.createElement(Tooltip.Root, {
4791
+ const suppressNextTooltip = useRef(false);
4792
+ const [tooltipOpen, setTooltipOpen] = useState3(false);
4793
+ const [selectOpen, setSelectOpen] = useState3(false);
4794
+ return /* @__PURE__ */ React.createElement(Tooltip.Root, {
4929
4795
  open: tooltipOpen,
4930
4796
  onOpenChange: (nextOpen) => {
4931
4797
  if (nextOpen && suppressNextTooltip.current) {
@@ -4935,7 +4801,7 @@ var MarkdownHeading = () => {
4935
4801
  return setTooltipOpen(nextOpen);
4936
4802
  }
4937
4803
  }
4938
- }, /* @__PURE__ */ React2.createElement(DropdownMenu.Root, {
4804
+ }, /* @__PURE__ */ React.createElement(DropdownMenu.Root, {
4939
4805
  open: selectOpen,
4940
4806
  onOpenChange: (nextOpen) => {
4941
4807
  if (!nextOpen) {
@@ -4943,40 +4809,40 @@ var MarkdownHeading = () => {
4943
4809
  }
4944
4810
  return setSelectOpen(nextOpen);
4945
4811
  }
4946
- }, /* @__PURE__ */ React2.createElement(Tooltip.Trigger, {
4812
+ }, /* @__PURE__ */ React.createElement(Tooltip.Trigger, {
4947
4813
  asChild: true
4948
- }, /* @__PURE__ */ React2.createElement(NaturalToolbar.Button, {
4814
+ }, /* @__PURE__ */ React.createElement(NaturalToolbar.Button, {
4949
4815
  asChild: true
4950
- }, /* @__PURE__ */ React2.createElement(DropdownMenu.Trigger, {
4816
+ }, /* @__PURE__ */ React.createElement(DropdownMenu.Trigger, {
4951
4817
  asChild: true
4952
- }, /* @__PURE__ */ React2.createElement(Button, {
4818
+ }, /* @__PURE__ */ React.createElement(Button, {
4953
4819
  variant: "ghost",
4954
4820
  classNames: buttonStyles,
4955
4821
  disabled: value === null
4956
- }, /* @__PURE__ */ React2.createElement("span", {
4822
+ }, /* @__PURE__ */ React.createElement("span", {
4957
4823
  className: "sr-only"
4958
- }, t("heading label")), /* @__PURE__ */ React2.createElement(HeadingIcon, {
4824
+ }, t("heading label")), /* @__PURE__ */ React.createElement(HeadingIcon, {
4959
4825
  className: iconStyles
4960
- }), /* @__PURE__ */ React2.createElement(CaretDown, null))))), /* @__PURE__ */ React2.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React2.createElement(DropdownMenu.Content, {
4826
+ }), /* @__PURE__ */ React.createElement(CaretDown, null))))), /* @__PURE__ */ React.createElement(DropdownMenu.Portal, null, /* @__PURE__ */ React.createElement(DropdownMenu.Content, {
4961
4827
  classNames: "is-min md:is-min",
4962
4828
  onCloseAutoFocus: (e) => e.preventDefault()
4963
- }, /* @__PURE__ */ React2.createElement(DropdownMenu.Viewport, null, Object.keys(HeadingIcons).map((level) => {
4829
+ }, /* @__PURE__ */ React.createElement(DropdownMenu.Viewport, null, Object.keys(HeadingIcons).map((level) => {
4964
4830
  const Icon = HeadingIcons[level];
4965
- return /* @__PURE__ */ React2.createElement(DropdownMenu.CheckboxItem, {
4831
+ return /* @__PURE__ */ React.createElement(DropdownMenu.CheckboxItem, {
4966
4832
  key: level,
4967
4833
  checked: value === level,
4968
4834
  onClick: () => onAction?.({
4969
4835
  type: "heading",
4970
4836
  data: level
4971
4837
  })
4972
- }, /* @__PURE__ */ React2.createElement("span", {
4838
+ }, /* @__PURE__ */ React.createElement("span", {
4973
4839
  className: "sr-only"
4974
4840
  }, t("heading level label", {
4975
4841
  count: parseInt(level)
4976
- })), /* @__PURE__ */ React2.createElement(Icon, {
4842
+ })), /* @__PURE__ */ React.createElement(Icon, {
4977
4843
  className: iconStyles
4978
- }), /* @__PURE__ */ React2.createElement(DropdownMenu.ItemIndicator, null, /* @__PURE__ */ React2.createElement(Check, null)));
4979
- })), /* @__PURE__ */ React2.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React2.createElement(Tooltip.Portal, null, /* @__PURE__ */ React2.createElement(Tooltip.Content, tooltipProps, t("heading label"), /* @__PURE__ */ React2.createElement(Tooltip.Arrow, null))));
4844
+ }), /* @__PURE__ */ React.createElement(DropdownMenu.ItemIndicator, null, /* @__PURE__ */ React.createElement(Check, null)));
4845
+ })), /* @__PURE__ */ React.createElement(DropdownMenu.Arrow, null)))), /* @__PURE__ */ React.createElement(Tooltip.Portal, null, /* @__PURE__ */ React.createElement(Tooltip.Content, tooltipProps, t("heading label"), /* @__PURE__ */ React.createElement(Tooltip.Arrow, null))));
4980
4846
  };
4981
4847
  var markdownStyles = [
4982
4848
  {
@@ -5008,10 +4874,10 @@ var markdownStyles = [
5008
4874
  var MarkdownStyles = () => {
5009
4875
  const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
5010
4876
  const { t } = useTranslation(translationKey);
5011
- return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
4877
+ return /* @__PURE__ */ React.createElement(NaturalToolbar.ToggleGroup, {
5012
4878
  type: "multiple",
5013
4879
  value: markdownStyles.filter(({ getState }) => state2 && getState(state2)).map(({ type }) => type)
5014
- }, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
4880
+ }, markdownStyles.map(({ type, getState, Icon }) => /* @__PURE__ */ React.createElement(ToolbarToggleButton, {
5015
4881
  key: type,
5016
4882
  value: type,
5017
4883
  Icon,
@@ -5042,10 +4908,10 @@ var markdownLists = [
5042
4908
  var MarkdownLists = () => {
5043
4909
  const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
5044
4910
  const { t } = useTranslation(translationKey);
5045
- return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
4911
+ return /* @__PURE__ */ React.createElement(NaturalToolbar.ToggleGroup, {
5046
4912
  type: "single",
5047
4913
  value: state2?.listStyle ? `list-${state2.listStyle}` : ""
5048
- }, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
4914
+ }, markdownLists.map(({ type, getState, Icon }) => /* @__PURE__ */ React.createElement(ToolbarToggleButton, {
5049
4915
  key: type,
5050
4916
  value: type,
5051
4917
  Icon,
@@ -5077,10 +4943,10 @@ var MarkdownBlocks = () => {
5077
4943
  const { onAction, state: state2 } = useToolbarContext("MarkdownStyles");
5078
4944
  const { t } = useTranslation(translationKey);
5079
4945
  const value = markdownBlocks.find(({ getState }) => state2 && getState(state2));
5080
- return /* @__PURE__ */ React2.createElement(NaturalToolbar.ToggleGroup, {
4946
+ return /* @__PURE__ */ React.createElement(NaturalToolbar.ToggleGroup, {
5081
4947
  type: "single",
5082
4948
  value: value?.type ?? ""
5083
- }, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React2.createElement(ToolbarToggleButton, {
4949
+ }, markdownBlocks.map(({ type, disabled, getState, Icon }) => /* @__PURE__ */ React.createElement(ToolbarToggleButton, {
5084
4950
  key: type,
5085
4951
  value: type,
5086
4952
  Icon,
@@ -5091,7 +4957,7 @@ var MarkdownBlocks = () => {
5091
4957
  }) : void 0
5092
4958
  }, t(`${type} label`))));
5093
4959
  };
5094
- var MarkdownStandard = () => /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(MarkdownHeading, null), /* @__PURE__ */ React2.createElement(MarkdownStyles, null), /* @__PURE__ */ React2.createElement(MarkdownLists, null), /* @__PURE__ */ React2.createElement(MarkdownBlocks, null));
4960
+ var MarkdownStandard = () => /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(MarkdownHeading, null), /* @__PURE__ */ React.createElement(MarkdownStyles, null), /* @__PURE__ */ React.createElement(MarkdownLists, null), /* @__PURE__ */ React.createElement(MarkdownBlocks, null));
5095
4961
  var MarkdownCustom = ({ onUpload } = {}) => {
5096
4962
  const { onAction } = useToolbarContext("MarkdownStyles");
5097
4963
  const { t } = useTranslation(translationKey);
@@ -5107,7 +4973,7 @@ var MarkdownCustom = ({ onUpload } = {}) => {
5107
4973
  ]
5108
4974
  }
5109
4975
  });
5110
- useEffect3(() => {
4976
+ useEffect2(() => {
5111
4977
  if (onUpload && acceptedFiles.length) {
5112
4978
  requestAnimationFrame(async () => {
5113
4979
  const f = acceptedFiles[0];
@@ -5129,7 +4995,7 @@ var MarkdownCustom = ({ onUpload } = {}) => {
5129
4995
  }, [
5130
4996
  acceptedFiles
5131
4997
  ]);
5132
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("input", getInputProps()), /* @__PURE__ */ React2.createElement(ToolbarButton, {
4998
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("input", getInputProps()), /* @__PURE__ */ React.createElement(ToolbarButton, {
5133
4999
  value: "image",
5134
5000
  Icon: Image,
5135
5001
  onClick: () => open()
@@ -5138,7 +5004,7 @@ var MarkdownCustom = ({ onUpload } = {}) => {
5138
5004
  var MarkdownActions = () => {
5139
5005
  const { onAction, state: state2 } = useToolbarContext("MarkdownActions");
5140
5006
  const { t } = useTranslation(translationKey);
5141
- return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(ToolbarButton, {
5007
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(ToolbarButton, {
5142
5008
  value: "comment",
5143
5009
  Icon: ChatText,
5144
5010
  "data-testid": "editor.toolbar.comment",
@@ -5164,51 +5030,71 @@ var useActionHandler = (view) => {
5164
5030
  };
5165
5031
 
5166
5032
  // packages/ui/react-ui-editor/src/hooks/useTextEditor.ts
5167
- import { EditorSelection as EditorSelection2, EditorState as EditorState3 } from "@codemirror/state";
5168
- import { EditorView as EditorView17 } from "@codemirror/view";
5169
- import { useFocusableGroup as useFocusableGroup2 } from "@fluentui/react-tabster";
5170
- import { useCallback as useCallback2, useEffect as useEffect4, useMemo as useMemo3, useRef as useRef3, useState as useState5 } from "react";
5171
- import { log as log8 } from "@dxos/log";
5172
- import { isNotFalsy as isNotFalsy5 } from "@dxos/util";
5173
- var __dxlog_file12 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5174
- var useTextEditor = (cb = () => ({}), deps = []) => {
5175
- let { id, doc, selection, extensions, autoFocus, scrollTo, debug } = useMemo3(cb, deps ?? []);
5176
- const onUpdate = useRef3();
5177
- const [view, setView] = useState5();
5178
- const parentRef = useRef3(null);
5179
- useEffect4(() => {
5033
+ import { EditorState as EditorState2 } from "@codemirror/state";
5034
+ import { EditorView as EditorView16 } from "@codemirror/view";
5035
+ import { useFocusableGroup } from "@fluentui/react-tabster";
5036
+ import { useCallback, useEffect as useEffect3, useMemo as useMemo3, useRef as useRef2, useState as useState4 } from "react";
5037
+ import { log as log7 } from "@dxos/log";
5038
+ import { useDefaultValue } from "@dxos/react-ui";
5039
+ import { isNotFalsy as isNotFalsy4 } from "@dxos/util";
5040
+ var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/ui/react-ui-editor/src/hooks/useTextEditor.ts";
5041
+ var instanceCount = 0;
5042
+ var useTextEditor = (props = {}, deps = []) => {
5043
+ const { id, initialValue, selection, extensions, autoFocus, scrollTo: _scrollTo, moveToEndOfLine, debug } = useMemo3(() => {
5044
+ return typeof props === "function" ? props() : props;
5045
+ }, deps ?? []);
5046
+ const [instanceId] = useState4(() => `text-editor-${++instanceCount}`);
5047
+ const scrollTo = useDefaultValue(_scrollTo, EditorView16.scrollIntoView(0, {
5048
+ yMargin: 0
5049
+ }));
5050
+ const onUpdate = useRef2();
5051
+ const [view, setView] = useState4();
5052
+ const parentRef = useRef2(null);
5053
+ useEffect3(() => {
5180
5054
  let view2;
5181
5055
  if (parentRef.current) {
5182
- log8("create", {
5183
- id
5056
+ log7("create", {
5057
+ id,
5058
+ instanceId,
5059
+ doc: initialValue?.length ?? 0
5184
5060
  }, {
5185
- F: __dxlog_file12,
5186
- L: 50,
5061
+ F: __dxlog_file11,
5062
+ L: 86,
5187
5063
  S: void 0,
5188
5064
  C: (f, a) => f(...a)
5189
5065
  });
5190
- const state2 = EditorState3.create({
5191
- doc,
5066
+ let initialSelection = selection;
5067
+ if (moveToEndOfLine && selection === void 0) {
5068
+ const index = initialValue?.indexOf("\n");
5069
+ const anchor = !index || index === -1 ? 0 : index;
5070
+ initialSelection = {
5071
+ anchor
5072
+ };
5073
+ }
5074
+ const state2 = EditorState2.create({
5075
+ doc: initialValue,
5076
+ selection: initialSelection,
5192
5077
  extensions: [
5193
5078
  id && documentId2.of(id),
5194
5079
  // TODO(burdon): Doesn't catch errors in keymap functions.
5195
- EditorView17.exceptionSink.of((err) => {
5196
- log8.catch(err, void 0, {
5197
- F: __dxlog_file12,
5198
- L: 60,
5080
+ EditorView16.exceptionSink.of((err) => {
5081
+ log7.catch(err, void 0, {
5082
+ F: __dxlog_file11,
5083
+ L: 104,
5199
5084
  S: void 0,
5200
5085
  C: (f, a) => f(...a)
5201
5086
  });
5202
5087
  }),
5203
5088
  extensions,
5204
- EditorView17.updateListener.of(() => {
5089
+ EditorView16.updateListener.of(() => {
5205
5090
  onUpdate.current?.();
5206
5091
  })
5207
- ].filter(isNotFalsy5)
5092
+ ].filter(isNotFalsy4)
5208
5093
  });
5209
- view2 = new EditorView17({
5094
+ view2 = new EditorView16({
5210
5095
  parent: parentRef.current,
5211
5096
  scrollTo,
5097
+ selection: initialSelection,
5212
5098
  state: state2,
5213
5099
  // NOTE: Uncomment to debug/monitor all transactions.
5214
5100
  // https://codemirror.net/docs/ref/#view.EditorView.dispatch
@@ -5219,30 +5105,34 @@ var useTextEditor = (cb = () => ({}), deps = []) => {
5219
5105
  view3.update(trs);
5220
5106
  }
5221
5107
  });
5108
+ if (!initialValue && moveToEndOfLine) {
5109
+ const { to } = view2.state.doc.lineAt(0);
5110
+ view2.dispatch({
5111
+ selection: {
5112
+ anchor: to
5113
+ }
5114
+ });
5115
+ }
5222
5116
  setView(view2);
5223
5117
  }
5224
5118
  return () => {
5225
- log8("destroy", {
5119
+ log7("destroy", {
5226
5120
  id
5227
5121
  }, {
5228
- F: __dxlog_file12,
5229
- L: 88,
5122
+ F: __dxlog_file11,
5123
+ L: 139,
5230
5124
  S: void 0,
5231
5125
  C: (f, a) => f(...a)
5232
5126
  });
5233
5127
  view2?.destroy();
5234
5128
  };
5235
5129
  }, deps);
5236
- useEffect4(() => {
5130
+ useEffect3(() => {
5237
5131
  if (view) {
5238
- if (!selection && !view.state.selection.main.anchor) {
5239
- selection = EditorSelection2.single(view.state.doc.line(1).to);
5240
- }
5241
- if (selection || scrollTo) {
5132
+ if (scrollTo) {
5242
5133
  onUpdate.current = () => {
5243
5134
  onUpdate.current = void 0;
5244
5135
  view.dispatch({
5245
- selection,
5246
5136
  effects: scrollTo && [
5247
5137
  scrollTo
5248
5138
  ],
@@ -5250,20 +5140,27 @@ var useTextEditor = (cb = () => ({}), deps = []) => {
5250
5140
  });
5251
5141
  };
5252
5142
  }
5253
- if (autoFocus) {
5254
- view.focus();
5143
+ if (view.state.facet(editorInputMode).noTabster) {
5144
+ parentRef.current?.removeAttribute("data-tabster");
5255
5145
  }
5256
5146
  }
5257
5147
  }, [
5258
5148
  view,
5259
- autoFocus,
5260
5149
  selection,
5261
5150
  scrollTo
5262
5151
  ]);
5263
- const focusableGroup = useFocusableGroup2({
5152
+ useEffect3(() => {
5153
+ if (view && autoFocus) {
5154
+ view.focus();
5155
+ }
5156
+ }, [
5157
+ autoFocus,
5158
+ view
5159
+ ]);
5160
+ const focusableGroup = useFocusableGroup({
5264
5161
  tabBehavior: "limited"
5265
5162
  });
5266
- const handleKeyUp = useCallback2((event) => {
5163
+ const handleKeyUp = useCallback((event) => {
5267
5164
  const { key, target, currentTarget } = event;
5268
5165
  if (target === currentTarget) {
5269
5166
  switch (key) {
@@ -5296,7 +5193,6 @@ export {
5296
5193
  List,
5297
5194
  RemoteSelectionsDecorator,
5298
5195
  SpaceAwarenessProvider,
5299
- TextEditor,
5300
5196
  TextKind,
5301
5197
  Toolbar,
5302
5198
  addBlockquote,