@dxos/react-ui-editor 0.3.11-main.f08de7a → 0.3.11-main.f437bee

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.
@@ -2530,21 +2531,23 @@ var EditorModes = [
2530
2531
  "default",
2531
2532
  "vim"
2532
2533
  ];
2533
- var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: comments2, extensions = [], editorMode, slots = defaultSlots }, forwardedRef) => {
2534
- const { themeMode } = useThemeContext();
2534
+ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, focus, selection, readonly, comments: comments2, extensions = [], editorMode, slots = defaultSlots }, forwardedRef) => {
2535
2535
  const tabsterDOMAttribute = useFocusableGroup({
2536
2536
  tabBehavior: "limited"
2537
2537
  });
2538
- const [root, setRoot] = useState(null);
2539
- const [{ state = void 0, view = void 0 } = {}, setEditor] = useState();
2540
- useImperativeHandle(forwardedRef, () => ({
2541
- root,
2542
- state,
2538
+ const { themeMode } = useThemeContext();
2539
+ const rootRef = useRef(null);
2540
+ const [view, setView] = useState(null);
2541
+ useImperativeHandle(forwardedRef, () => view, [
2543
2542
  view
2544
- }), [
2543
+ ]);
2544
+ useEffect(() => {
2545
+ if (view && focus) {
2546
+ view.focus();
2547
+ }
2548
+ }, [
2545
2549
  view,
2546
- state,
2547
- root
2550
+ focus
2548
2551
  ]);
2549
2552
  const { awareness: awareness2, peer } = model;
2550
2553
  useEffect(() => {
@@ -2581,11 +2584,12 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
2581
2584
  comments2
2582
2585
  ]);
2583
2586
  useEffect(() => {
2584
- if (!root) {
2587
+ if (!model || !rootRef.current) {
2585
2588
  return;
2586
2589
  }
2587
- const state2 = EditorState2.create({
2590
+ const state = EditorState2.create({
2588
2591
  doc: model.text(),
2592
+ selection,
2589
2593
  extensions: [
2590
2594
  readonly && EditorState2.readOnly.of(readonly),
2591
2595
  // TODO(burdon): Factor out VIM mode? (manage via MarkdownPlugin).
@@ -2602,19 +2606,17 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
2602
2606
  ].filter(Boolean)
2603
2607
  });
2604
2608
  view?.destroy();
2605
- setEditor({
2606
- state: state2,
2607
- view: new EditorView12({
2608
- state: state2,
2609
- parent: root
2610
- })
2609
+ const newView = new EditorView12({
2610
+ parent: rootRef.current,
2611
+ state
2611
2612
  });
2613
+ setView(newView);
2612
2614
  return () => {
2613
- view?.destroy();
2614
- setEditor(void 0);
2615
+ newView?.destroy();
2616
+ setView(null);
2615
2617
  };
2616
2618
  }, [
2617
- root,
2619
+ rootRef,
2618
2620
  model,
2619
2621
  readonly,
2620
2622
  editorMode,
@@ -2623,12 +2625,8 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
2623
2625
  const handleKeyUp = useCallback((event) => {
2624
2626
  const { key, altKey, shiftKey, metaKey, ctrlKey } = event;
2625
2627
  switch (key) {
2626
- case "Enter": {
2627
- view?.contentDOM.focus();
2628
- break;
2629
- }
2630
2628
  case "Escape": {
2631
- editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey) && root?.focus();
2629
+ editorMode === "vim" && (altKey || shiftKey || metaKey || ctrlKey) && rootRef.current?.focus();
2632
2630
  break;
2633
2631
  }
2634
2632
  }
@@ -2638,16 +2636,16 @@ var BaseTextEditor = /* @__PURE__ */ forwardRef(({ model, readonly, comments: co
2638
2636
  ]);
2639
2637
  return /* @__PURE__ */ React.createElement("div", {
2640
2638
  key: model.id,
2641
- ref: setRoot,
2639
+ ref: rootRef,
2642
2640
  tabIndex: 0,
2643
2641
  ...slots?.root,
2644
2642
  ...editorMode !== "vim" && tabsterDOMAttribute,
2645
2643
  onKeyUp: handleKeyUp
2646
2644
  });
2647
2645
  });
2648
- var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
2646
+ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots, ...props }, forwardedRef) => {
2649
2647
  const { themeMode } = useThemeContext();
2650
- const slots = defaultsDeep2({}, _slots, defaultTextSlots);
2648
+ const updatedSlots = defaultsDeep2({}, slots, defaultTextSlots);
2651
2649
  return /* @__PURE__ */ React.createElement(BaseTextEditor, {
2652
2650
  ref: forwardedRef,
2653
2651
  readonly,
@@ -2655,17 +2653,17 @@ var TextEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots:
2655
2653
  basicBundle({
2656
2654
  readonly,
2657
2655
  themeMode,
2658
- placeholder: slots?.editor?.placeholder
2656
+ placeholder: updatedSlots?.editor?.placeholder
2659
2657
  }),
2660
2658
  ...extensions
2661
2659
  ],
2662
- slots,
2660
+ slots: updatedSlots,
2663
2661
  ...props
2664
2662
  });
2665
2663
  });
2666
- var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots: _slots, ...props }, forwardedRef) => {
2664
+ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], slots, ...props }, forwardedRef) => {
2667
2665
  const { themeMode } = useThemeContext();
2668
- const slots = defaultsDeep2({}, _slots, defaultMarkdownSlots);
2666
+ const updatedSlots = defaultsDeep2({}, slots, defaultMarkdownSlots);
2669
2667
  return /* @__PURE__ */ React.createElement(BaseTextEditor, {
2670
2668
  ref: forwardedRef,
2671
2669
  readonly,
@@ -2673,11 +2671,11 @@ var MarkdownEditor = /* @__PURE__ */ forwardRef(({ readonly, extensions = [], sl
2673
2671
  markdownBundle({
2674
2672
  readonly,
2675
2673
  themeMode,
2676
- placeholder: slots?.editor?.placeholder
2674
+ placeholder: updatedSlots?.editor?.placeholder
2677
2675
  }),
2678
2676
  ...extensions
2679
2677
  ],
2680
- slots,
2678
+ slots: updatedSlots,
2681
2679
  ...props
2682
2680
  });
2683
2681
  });
@@ -2983,7 +2981,7 @@ var modelState = StateField5.define({
2983
2981
  });
2984
2982
  var useTextModel = (props) => {
2985
2983
  const { identity, space, text } = props;
2986
- const [model, setModel] = useState2(() => createModel(props));
2984
+ const [model, setModel] = useState2();
2987
2985
  useEffect2(() => setModel(createModel(props)), [
2988
2986
  identity,
2989
2987
  space,
@@ -3042,6 +3040,7 @@ var createAutomergeModel = ({ space, identity, text }) => {
3042
3040
  export {
3043
3041
  AwarenessProvider,
3044
3042
  BaseTextEditor,
3043
+ CursorConverter,
3045
3044
  Doc,
3046
3045
  EditorModes,
3047
3046
  MarkdownEditor,
@@ -3057,11 +3056,13 @@ export {
3057
3056
  awareness,
3058
3057
  basicBundle,
3059
3058
  blast,
3059
+ callbackWrapper,
3060
3060
  code2 as code,
3061
3061
  codeTheme,
3062
3062
  comments,
3063
3063
  createAutomergeModel,
3064
3064
  createYjsModel,
3065
+ cursorConverter,
3065
3066
  defaultMarkdownSlots,
3066
3067
  defaultOptions,
3067
3068
  defaultSlots,