@dxos/react-ui-editor 0.3.11-main.8a2cfe6 → 0.3.11-main.8be6c8a

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.
@@ -11,40 +11,41 @@ import { EditorView as EditorView12 } from "@codemirror/view";
11
11
  import { useFocusableGroup } from "@fluentui/react-tabster";
12
12
  import { vim } from "@replit/codemirror-vim";
13
13
  import defaultsDeep2 from "lodash.defaultsdeep";
14
- import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from "react";
14
+ import React, { forwardRef, useCallback, useEffect, useImperativeHandle, useState, useRef } from "react";
15
15
  import { generateName } from "@dxos/display-name";
16
16
  import { useThemeContext } from "@dxos/react-ui";
17
17
  import { getColorForValue, inputSurface, mx as mx3 } from "@dxos/react-ui-theme";
18
18
 
19
19
  // packages/ui/react-ui-editor/src/extensions/autocomplete.ts
20
20
  import { autocompletion, completionKeymap } from "@codemirror/autocomplete";
21
+ import { markdownLanguage } from "@codemirror/lang-markdown";
21
22
  import { keymap } from "@codemirror/view";
22
23
  var autocomplete = ({ onSearch }) => {
23
24
  return [
24
25
  // https://codemirror.net/docs/ref/#view.keymap
25
26
  // https://discuss.codemirror.net/t/how-can-i-replace-the-default-autocompletion-keymap-v6/3322
27
+ // TODO(burdon): Set custom keymap.
26
28
  keymap.of(completionKeymap),
27
29
  // https://codemirror.net/examples/autocompletion
28
30
  // https://codemirror.net/docs/ref/#autocomplete.autocompletion
29
31
  autocompletion({
30
- // TODO(burdon): Set custom keymap.
31
- // defaultKeymap: false,
32
+ defaultKeymap: false,
32
33
  // Don't start unless key press.
33
- activateOnTyping: false,
34
- // TODO(burdon): Option to create new page?
35
- // TODO(burdon): Optional decoration via addToOptions
36
- override: [
37
- (context) => {
38
- const match = context.matchBefore(/\w*/);
39
- if (!match || match.from === match.to && !context.explicit) {
40
- return null;
41
- }
42
- return {
43
- from: match.from,
44
- options: onSearch(match.text.toLowerCase())
45
- };
34
+ activateOnTyping: false
35
+ }),
36
+ // TODO(burdon): Option to create new page?
37
+ // TODO(burdon): Optional decoration via addToOptions
38
+ markdownLanguage.data.of({
39
+ autocomplete: (context) => {
40
+ const match = context.matchBefore(/\w*/);
41
+ if (!match || match.from === match.to && !context.explicit) {
42
+ return null;
46
43
  }
47
- ]
44
+ return {
45
+ from: match.from,
46
+ options: onSearch(match.text.toLowerCase())
47
+ };
48
+ }
48
49
  })
49
50
  ];
50
51
  };
@@ -1708,7 +1709,7 @@ var listener = ({ onFocus, onChange }) => {
1708
1709
  // packages/ui/react-ui-editor/src/extensions/markdown/bundle.ts
1709
1710
  import { closeBrackets as closeBrackets2, closeBracketsKeymap } from "@codemirror/autocomplete";
1710
1711
  import { history, historyKeymap, indentWithTab, standardKeymap } from "@codemirror/commands";
1711
- import { markdownLanguage as markdownLanguage2, markdown } from "@codemirror/lang-markdown";
1712
+ import { markdownLanguage as markdownLanguage3, markdown } from "@codemirror/lang-markdown";
1712
1713
  import { bracketMatching as bracketMatching2, defaultHighlightStyle as defaultHighlightStyle2, indentOnInput, syntaxHighlighting as syntaxHighlighting2 } from "@codemirror/language";
1713
1714
  import { languages } from "@codemirror/language-data";
1714
1715
  import { searchKeymap } from "@codemirror/search";
@@ -1717,7 +1718,7 @@ import { oneDarkHighlightStyle as oneDarkHighlightStyle2 } from "@codemirror/the
1717
1718
  import { crosshairCursor, drawSelection as drawSelection2, dropCursor, EditorView as EditorView9, highlightActiveLine, keymap as keymap4, placeholder as placeholder2 } from "@codemirror/view";
1718
1719
 
1719
1720
  // packages/ui/react-ui-editor/src/extensions/markdown/highlight.ts
1720
- import { markdownLanguage } from "@codemirror/lang-markdown";
1721
+ import { markdownLanguage as markdownLanguage2 } from "@codemirror/lang-markdown";
1721
1722
  import { HighlightStyle } from "@codemirror/language";
1722
1723
  import { tags, styleTags, Tag } from "@lezer/highlight";
1723
1724
  import { Table } from "@lezer/markdown";
@@ -1904,7 +1905,7 @@ var markdownHighlightStyle = (readonly) => {
1904
1905
  class: "font-mono"
1905
1906
  }
1906
1907
  ], {
1907
- scope: markdownLanguage,
1908
+ scope: markdownLanguage2,
1908
1909
  all: {
1909
1910
  fontFamily: getToken("fontFamily.body", []).join(",")
1910
1911
  }
@@ -1936,7 +1937,7 @@ var markdownBundle = ({ readonly, themeMode, placeholder: _placeholder }) => {
1936
1937
  // NOTE: This extends the parser; it doesn't affect rendering.
1937
1938
  // https://github.github.com/gfm
1938
1939
  // https://github.com/lezer-parser/markdown?tab=readme-ov-file#github-flavored-markdown
1939
- base: markdownLanguage2,
1940
+ base: markdownLanguage3,
1940
1941
  // Languages for syntax highlighting fenced code blocks.
1941
1942
  codeLanguages: languages,
1942
1943
  // Parser extensions.
@@ -2040,7 +2041,6 @@ var update = (state, options) => {
2040
2041
  tables.forEach((table2) => {
2041
2042
  const hide = state.readOnly || cursor < table2.from || cursor > table2.to;
2042
2043
  hide && builder.add(table2.from, table2.to, Decoration7.replace({
2043
- block: true,
2044
2044
  widget: new TableWidget(table2)
2045
2045
  }));
2046
2046
  builder.add(table2.from, table2.to, Decoration7.mark({
@@ -2081,6 +2081,9 @@ var TableWidget = class extends WidgetType6 {
2081
2081
  }
2082
2082
  return table2;
2083
2083
  }
2084
+ ignoreEvent(e) {
2085
+ return !/^mouse/.test(e.type);
2086
+ }
2084
2087
  };
2085
2088
 
2086
2089
  // packages/ui/react-ui-editor/src/extensions/tasklist.ts
@@ -2528,21 +2531,23 @@ var EditorModes = [
2528
2531
  "default",
2529
2532
  "vim"
2530
2533
  ];
2531
- var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: comments2, extensions = [], editorMode, slots = defaultSlots }, forwardedRef) => {
2532
- const { themeMode } = useThemeContext();
2534
+ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, focus, selection, readonly, comments: comments2, extensions = [], editorMode, slots = defaultSlots }, forwardedRef) => {
2533
2535
  const tabsterDOMAttribute = useFocusableGroup({
2534
2536
  tabBehavior: "limited"
2535
2537
  });
2536
- const [root, setRoot] = useState(null);
2537
- const [{ state = void 0, view = void 0 } = {}, setEditor] = useState();
2538
- useImperativeHandle(forwardedRef, () => ({
2539
- root,
2540
- state,
2538
+ const { themeMode } = useThemeContext();
2539
+ const rootRef = useRef(null);
2540
+ const [view, setView] = useState(null);
2541
+ useImperativeHandle(forwardedRef, () => view, [
2541
2542
  view
2542
- }), [
2543
+ ]);
2544
+ useEffect(() => {
2545
+ if (view && focus) {
2546
+ view.focus();
2547
+ }
2548
+ }, [
2543
2549
  view,
2544
- state,
2545
- root
2550
+ focus
2546
2551
  ]);
2547
2552
  const { awareness: awareness2, peer } = model;
2548
2553
  useEffect(() => {
@@ -2579,11 +2584,12 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
2579
2584
  comments2
2580
2585
  ]);
2581
2586
  useEffect(() => {
2582
- if (!root) {
2587
+ if (!model || !rootRef.current) {
2583
2588
  return;
2584
2589
  }
2585
- const state2 = EditorState2.create({
2590
+ const state = EditorState2.create({
2586
2591
  doc: model.text(),
2592
+ selection,
2587
2593
  extensions: [
2588
2594
  readonly && EditorState2.readOnly.of(readonly),
2589
2595
  // TODO(burdon): Factor out VIM mode? (manage via MarkdownPlugin).
@@ -2600,19 +2606,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
2600
2606
  ].filter(Boolean)
2601
2607
  });
2602
2608
  view?.destroy();
2603
- setEditor({
2604
- state: state2,
2605
- view: new EditorView12({
2606
- state: state2,
2607
- parent: root
2608
- })
2609
+ const newView = new EditorView12({
2610
+ parent: rootRef.current,
2611
+ state
2609
2612
  });
2613
+ setView(newView);
2610
2614
  return () => {
2611
- view?.destroy();
2612
- setEditor(void 0);
2615
+ newView?.destroy();
2616
+ setView(null);
2613
2617
  };
2614
2618
  }, [
2615
- root,
2619
+ rootRef,
2616
2620
  model,
2617
2621
  readonly,
2618
2622
  editorMode,
@@ -2621,12 +2625,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
2621
2625
  const handleKeyUp = useCallback((event) => {
2622
2626
  const { key, altKey, shiftKey, metaKey, ctrlKey } = event;
2623
2627
  switch (key) {
2624
- case "Enter": {
2625
- view?.contentDOM.focus();
2626
- break;
2627
- }
2628
2628
  case "Escape": {
2629
- editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey) && root?.focus();
2629
+ editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey) && rootRef.current?.focus();
2630
2630
  break;
2631
2631
  }
2632
2632
  }
@@ -2636,16 +2636,16 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
2636
2636
  ]);
2637
2637
  return /* @__PURE__ */ React.createElement("div", {
2638
2638
  key: model.id,
2639
- ref: setRoot,
2639
+ ref: rootRef,
2640
2640
  tabIndex: 0,
2641
2641
  ...slots?.root,
2642
2642
  ...editorMode !== "vim" && tabsterDOMAttribute,
2643
2643
  onKeyUp: handleKeyUp
2644
2644
  });
2645
2645
  });
2646
- var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
2646
+ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots, ...props }, forwardedRef) => {
2647
2647
  const { themeMode } = useThemeContext();
2648
- const slots = defaultsDeep2({}, _slots, defaultTextSlots);
2648
+ const updatedSlots = defaultsDeep2({}, slots, defaultTextSlots);
2649
2649
  return /* @__PURE__ */ React.createElement(BaseTextEditor, {
2650
2650
  ref: forwardedRef,
2651
2651
  readonly,
@@ -2653,17 +2653,17 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots:
2653
2653
  basicBundle({
2654
2654
  readonly,
2655
2655
  themeMode,
2656
- placeholder: slots?.editor?.placeholder
2656
+ placeholder: updatedSlots?.editor?.placeholder
2657
2657
  }),
2658
2658
  ...extensions
2659
2659
  ],
2660
- slots,
2660
+ slots: updatedSlots,
2661
2661
  ...props
2662
2662
  });
2663
2663
  });
2664
- var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
2664
+ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots, ...props }, forwardedRef) => {
2665
2665
  const { themeMode } = useThemeContext();
2666
- const slots = defaultsDeep2({}, _slots, defaultMarkdownSlots);
2666
+ const updatedSlots = defaultsDeep2({}, slots, defaultMarkdownSlots);
2667
2667
  return /* @__PURE__ */ React.createElement(BaseTextEditor, {
2668
2668
  ref: forwardedRef,
2669
2669
  readonly,
@@ -2671,11 +2671,11 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], sl
2671
2671
  markdownBundle({
2672
2672
  readonly,
2673
2673
  themeMode,
2674
- placeholder: slots?.editor?.placeholder
2674
+ placeholder: updatedSlots?.editor?.placeholder
2675
2675
  }),
2676
2676
  ...extensions
2677
2677
  ],
2678
- slots,
2678
+ slots: updatedSlots,
2679
2679
  ...props
2680
2680
  });
2681
2681
  });
@@ -2981,7 +2981,7 @@ var modelState = StateField5.define({
2981
2981
  });
2982
2982
  var useTextModel = (props) => {
2983
2983
  const { identity, space, text } = props;
2984
- const [model, setModel] = useState2(() => createModel(props));
2984
+ const [model, setModel] = useState2();
2985
2985
  useEffect2(() => setModel(createModel(props)), [
2986
2986
  identity,
2987
2987
  space,
@@ -3040,6 +3040,7 @@ var createAutomergeModel = ({ space, identity, text }) => {
3040
3040
  export {
3041
3041
  AwarenessProvider,
3042
3042
  BaseTextEditor,
3043
+ CursorConverter,
3043
3044
  Doc,
3044
3045
  EditorModes,
3045
3046
  MarkdownEditor,
@@ -3055,11 +3056,13 @@ export {
3055
3056
  awareness,
3056
3057
  basicBundle,
3057
3058
  blast,
3059
+ callbackWrapper,
3058
3060
  code2 as code,
3059
3061
  codeTheme,
3060
3062
  comments,
3061
3063
  createAutomergeModel,
3062
3064
  createYjsModel,
3065
+ cursorConverter,
3063
3066
  defaultMarkdownSlots,
3064
3067
  defaultOptions,
3065
3068
  defaultSlots,