dn-react-text-editor 0.3.0 → 0.3.1

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.
@@ -160,7 +160,12 @@ function createAttachFile({
160
160
  if (!node) {
161
161
  return;
162
162
  }
163
- view.dispatch(tr2.replaceWith($pos, $pos, node));
163
+ const current = view.state.doc.resolve($pos);
164
+ if (current.parentOffset === 0) {
165
+ view.dispatch(tr2.replaceWith($pos - 1, $pos, node));
166
+ } else {
167
+ view.dispatch(tr2.replaceWith($pos, $pos, node));
168
+ }
164
169
  } catch (e) {
165
170
  view.dispatch(tr.setMeta(uploadPlaceholderPlugin, { remove: { id } }));
166
171
  }
@@ -136,7 +136,12 @@ function createAttachFile({
136
136
  if (!node) {
137
137
  return;
138
138
  }
139
- view.dispatch(tr2.replaceWith($pos, $pos, node));
139
+ const current = view.state.doc.resolve($pos);
140
+ if (current.parentOffset === 0) {
141
+ view.dispatch(tr2.replaceWith($pos - 1, $pos, node));
142
+ } else {
143
+ view.dispatch(tr2.replaceWith($pos, $pos, node));
144
+ }
140
145
  } catch (e) {
141
146
  view.dispatch(tr.setMeta(uploadPlaceholderPlugin, { remove: { id } }));
142
147
  }
@@ -1,5 +1,5 @@
1
1
  import { DetailedHTMLProps, InputHTMLAttributes, FC } from 'react';
2
- import { TextEditorController, TextEditorControllerProps, CreateTextEditorOptions } from './text_editor_controller.mjs';
2
+ import { TextEditorController, TextEditorControllerProps } from './text_editor_controller.mjs';
3
3
  import 'prosemirror-model';
4
4
  import 'prosemirror-state';
5
5
  import 'prosemirror-view';
@@ -13,6 +13,7 @@ type TextEditorProps = Omit<HTMLElementProps, "ref"> & {
13
13
  controller?: TextEditorController;
14
14
  name?: string;
15
15
  } & TextEditorControllerProps;
16
+ type CreateTextEditorOptions = Pick<TextEditorControllerProps, "className" | "style" | "attachFile">;
16
17
  declare function createTextEditor(options?: CreateTextEditorOptions): FC<TextEditorProps>;
17
18
 
18
19
  export { type TextEditorProps, createTextEditor };
@@ -1,5 +1,5 @@
1
1
  import { DetailedHTMLProps, InputHTMLAttributes, FC } from 'react';
2
- import { TextEditorController, TextEditorControllerProps, CreateTextEditorOptions } from './text_editor_controller.js';
2
+ import { TextEditorController, TextEditorControllerProps } from './text_editor_controller.js';
3
3
  import 'prosemirror-model';
4
4
  import 'prosemirror-state';
5
5
  import 'prosemirror-view';
@@ -13,6 +13,7 @@ type TextEditorProps = Omit<HTMLElementProps, "ref"> & {
13
13
  controller?: TextEditorController;
14
14
  name?: string;
15
15
  } & TextEditorControllerProps;
16
+ type CreateTextEditorOptions = Pick<TextEditorControllerProps, "className" | "style" | "attachFile">;
16
17
  declare function createTextEditor(options?: CreateTextEditorOptions): FC<TextEditorProps>;
17
18
 
18
19
  export { type TextEditorProps, createTextEditor };
@@ -39,17 +39,12 @@ var import_react3 = require("react");
39
39
  // src/input.tsx
40
40
  var import_react = __toESM(require("react"));
41
41
  var import_rxjs = require("rxjs");
42
- function TextEditorInput({
43
- controller,
44
- onChange,
45
- updateDelay = 0,
46
- ...props
47
- }) {
42
+ function TextEditorInput({ controller, onChange, ...props }) {
48
43
  const inputRef = import_react.default.useRef(null);
49
44
  (0, import_react.useEffect)(() => {
50
45
  const sub = controller.subject.pipe(
51
46
  (0, import_rxjs.filter)((tr) => tr.docChanged),
52
- (0, import_rxjs.debounceTime)(updateDelay)
47
+ (0, import_rxjs.debounceTime)(controller.props.updateDelay || 0)
53
48
  ).subscribe(() => {
54
49
  if (inputRef.current) {
55
50
  inputRef.current.value = controller.value;
@@ -61,7 +56,16 @@ function TextEditorInput({
61
56
  sub.unsubscribe();
62
57
  };
63
58
  }, []);
64
- return /* @__PURE__ */ import_react.default.createElement("input", { ...props, ref: inputRef, type: "hidden", onInput: onChange });
59
+ return /* @__PURE__ */ import_react.default.createElement(
60
+ "input",
61
+ {
62
+ ...props,
63
+ ref: inputRef,
64
+ type: "hidden",
65
+ onInput: onChange,
66
+ defaultValue: controller.props.defaultValue
67
+ }
68
+ );
65
69
  }
66
70
 
67
71
  // src/text_editor_controller.tsx
@@ -212,23 +216,6 @@ function buildKeymap(schema) {
212
216
  bind("Mod-z", import_prosemirror_history.undo);
213
217
  bind("Shift-Mod-z", import_prosemirror_history.redo);
214
218
  bind("Mod-y", import_prosemirror_history.redo);
215
- const li = schema.nodes.list_item;
216
- bind(
217
- "Enter",
218
- (0, import_prosemirror_commands.chainCommands)((0, import_prosemirror_schema_list.splitListItem)(li), (state, dispatch) => {
219
- const { $head } = state.selection;
220
- if ($head.parent.type === state.schema.nodes.paragraph) {
221
- (0, import_prosemirror_commands.splitBlockAs)((n) => {
222
- return {
223
- type: n.type,
224
- attrs: n.attrs
225
- };
226
- })(state, dispatch);
227
- return true;
228
- }
229
- return false;
230
- })
231
- );
232
219
  bind("ArrowDown", (state, dispatch) => {
233
220
  const doc = state.doc;
234
221
  const lastNode = doc.lastChild;
@@ -245,6 +232,51 @@ function buildKeymap(schema) {
245
232
  }
246
233
  return false;
247
234
  });
235
+ const li = schema.nodes.list_item;
236
+ bind(
237
+ "Enter",
238
+ (0, import_prosemirror_commands.chainCommands)(
239
+ (0, import_prosemirror_schema_list.splitListItem)(li),
240
+ (state, dispatch) => {
241
+ const { $head } = state.selection;
242
+ if ($head.parent.type === state.schema.nodes.paragraph) {
243
+ (0, import_prosemirror_commands.splitBlockAs)((n) => {
244
+ return {
245
+ type: n.type,
246
+ attrs: n.attrs
247
+ };
248
+ })(state, dispatch);
249
+ return true;
250
+ }
251
+ return false;
252
+ },
253
+ (state, dispatch) => {
254
+ const { selection } = state;
255
+ const { $from, $to } = selection;
256
+ const lines = state.doc.textBetween($from.before(), $to.pos).split("\n");
257
+ const currentLine = lines[lines.length - 1];
258
+ const match = currentLine.match(/^(\s+).*$/);
259
+ if (match) {
260
+ if (dispatch) {
261
+ dispatch(state.tr.insertText("\n" + match[1], $from.pos));
262
+ }
263
+ return true;
264
+ }
265
+ return false;
266
+ }
267
+ )
268
+ );
269
+ bind("Tab", (state, dispatch) => {
270
+ const { selection } = state;
271
+ const { $from, $to } = selection;
272
+ if ($from.parent.type === schema.nodes.code_block) {
273
+ if (dispatch) {
274
+ dispatch(state.tr.insertText(" ", $from.pos, $to.pos));
275
+ }
276
+ return true;
277
+ }
278
+ return false;
279
+ });
248
280
  return keys;
249
281
  }
250
282
 
@@ -816,7 +848,12 @@ function createAttachFile({
816
848
  if (!node) {
817
849
  return;
818
850
  }
819
- view.dispatch(tr2.replaceWith($pos, $pos, node));
851
+ const current = view.state.doc.resolve($pos);
852
+ if (current.parentOffset === 0) {
853
+ view.dispatch(tr2.replaceWith($pos - 1, $pos, node));
854
+ } else {
855
+ view.dispatch(tr2.replaceWith($pos, $pos, node));
856
+ }
820
857
  } catch (e) {
821
858
  view.dispatch(tr.setMeta(uploadPlaceholderPlugin, { remove: { id } }));
822
859
  }
@@ -905,9 +942,9 @@ var createCommands = (schema, view, options = {}) => {
905
942
  // src/text_editor_controller.tsx
906
943
  var import_prosemirror_model3 = require("prosemirror-model");
907
944
  var import_rxjs2 = require("rxjs");
945
+ var import_prosemirror_highlightjs = require("prosemirror-highlightjs");
908
946
  var TextEditorController = class {
909
947
  schema;
910
- options;
911
948
  props;
912
949
  subject;
913
950
  view;
@@ -930,9 +967,8 @@ var TextEditorController = class {
930
967
  );
931
968
  this.view.dispatch(tr);
932
969
  }
933
- constructor(options = {}, props = {}) {
970
+ constructor(props = {}) {
934
971
  this.schema = createSchema();
935
- this.options = options;
936
972
  this.props = props;
937
973
  this.subject = new import_rxjs2.Subject();
938
974
  this.prosemirrorParser = import_prosemirror_model3.DOMParser.fromSchema(this.schema);
@@ -947,8 +983,8 @@ var TextEditorController = class {
947
983
  attachFile(files) {
948
984
  return createAttachFile({
949
985
  schema: this.schema,
950
- generateMetadata: this.options.attachFile?.generateMetadata,
951
- uploadFile: this.options.attachFile?.uploadFile
986
+ generateMetadata: this.props.attachFile?.generateMetadata,
987
+ uploadFile: this.props.attachFile?.uploadFile
952
988
  })(this.view, files);
953
989
  }
954
990
  bind(container) {
@@ -967,9 +1003,9 @@ var TextEditorController = class {
967
1003
  })();
968
1004
  return {
969
1005
  ...propsAttributes,
970
- class: cn(this.options?.className, propsAttributes?.class),
1006
+ class: cn(this.props?.className, propsAttributes?.class),
971
1007
  spellcheck: propsAttributes?.spellcheck || "false",
972
- style: this.options.style || "width: 100%; height: inherit; outline: none;"
1008
+ style: this.props.style || "width: 100%; height: inherit; outline: none;"
973
1009
  };
974
1010
  },
975
1011
  state: import_prosemirror_state5.EditorState.create({
@@ -987,7 +1023,11 @@ var TextEditorController = class {
987
1023
  dragAndDropPlugin({
988
1024
  attachFile: (view, files) => this.attachFile(files)
989
1025
  }),
990
- this.props.placeholder && placeholderPlugin(this.props.placeholder)
1026
+ this.props.placeholder && placeholderPlugin(this.props.placeholder),
1027
+ (0, import_prosemirror_highlightjs.highlightPlugin)(highlighter, ["code_block"], (node) => {
1028
+ const auto = highlighter.highlightAuto(node.textContent);
1029
+ return auto.language || "";
1030
+ })
991
1031
  ].filter((e) => !!e)
992
1032
  }),
993
1033
  dispatchTransaction: (tr) => {
@@ -1031,6 +1071,7 @@ var TextEditorController = class {
1031
1071
  function createTextEditor(options = {}) {
1032
1072
  function Component({
1033
1073
  controller: externalController,
1074
+ name,
1034
1075
  className,
1035
1076
  autoFocus,
1036
1077
  onChange,
@@ -1044,14 +1085,17 @@ function createTextEditor(options = {}) {
1044
1085
  } = {}) {
1045
1086
  const containerRef = (0, import_react3.useRef)(null);
1046
1087
  const innerController = (0, import_react2.useMemo)(
1047
- () => new TextEditorController(options, {
1088
+ () => new TextEditorController({
1048
1089
  mode,
1049
1090
  state,
1050
1091
  editor,
1051
1092
  autoFocus,
1052
1093
  placeholder,
1053
1094
  updateDelay,
1054
- defaultValue
1095
+ defaultValue,
1096
+ className: options.className,
1097
+ style: options.style,
1098
+ attachFile: options.attachFile
1055
1099
  }),
1056
1100
  []
1057
1101
  );
@@ -1069,9 +1113,8 @@ function createTextEditor(options = {}) {
1069
1113
  return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement("div", { ...props, ref: containerRef, className }), /* @__PURE__ */ import_react2.default.createElement(
1070
1114
  TextEditorInput,
1071
1115
  {
1116
+ name,
1072
1117
  controller,
1073
- updateDelay,
1074
- defaultValue,
1075
1118
  onChange
1076
1119
  }
1077
1120
  ));
@@ -9,17 +9,12 @@ import React, {
9
9
  useEffect
10
10
  } from "react";
11
11
  import { debounceTime, filter } from "rxjs";
12
- function TextEditorInput({
13
- controller,
14
- onChange,
15
- updateDelay = 0,
16
- ...props
17
- }) {
12
+ function TextEditorInput({ controller, onChange, ...props }) {
18
13
  const inputRef = React.useRef(null);
19
14
  useEffect(() => {
20
15
  const sub = controller.subject.pipe(
21
16
  filter((tr) => tr.docChanged),
22
- debounceTime(updateDelay)
17
+ debounceTime(controller.props.updateDelay || 0)
23
18
  ).subscribe(() => {
24
19
  if (inputRef.current) {
25
20
  inputRef.current.value = controller.value;
@@ -31,7 +26,16 @@ function TextEditorInput({
31
26
  sub.unsubscribe();
32
27
  };
33
28
  }, []);
34
- return /* @__PURE__ */ React.createElement("input", { ...props, ref: inputRef, type: "hidden", onInput: onChange });
29
+ return /* @__PURE__ */ React.createElement(
30
+ "input",
31
+ {
32
+ ...props,
33
+ ref: inputRef,
34
+ type: "hidden",
35
+ onInput: onChange,
36
+ defaultValue: controller.props.defaultValue
37
+ }
38
+ );
35
39
  }
36
40
 
37
41
  // src/text_editor_controller.tsx
@@ -184,23 +188,6 @@ function buildKeymap(schema) {
184
188
  bind("Mod-z", undo);
185
189
  bind("Shift-Mod-z", redo);
186
190
  bind("Mod-y", redo);
187
- const li = schema.nodes.list_item;
188
- bind(
189
- "Enter",
190
- chainCommands(splitListItem(li), (state, dispatch) => {
191
- const { $head } = state.selection;
192
- if ($head.parent.type === state.schema.nodes.paragraph) {
193
- splitBlockAs((n) => {
194
- return {
195
- type: n.type,
196
- attrs: n.attrs
197
- };
198
- })(state, dispatch);
199
- return true;
200
- }
201
- return false;
202
- })
203
- );
204
191
  bind("ArrowDown", (state, dispatch) => {
205
192
  const doc = state.doc;
206
193
  const lastNode = doc.lastChild;
@@ -217,6 +204,51 @@ function buildKeymap(schema) {
217
204
  }
218
205
  return false;
219
206
  });
207
+ const li = schema.nodes.list_item;
208
+ bind(
209
+ "Enter",
210
+ chainCommands(
211
+ splitListItem(li),
212
+ (state, dispatch) => {
213
+ const { $head } = state.selection;
214
+ if ($head.parent.type === state.schema.nodes.paragraph) {
215
+ splitBlockAs((n) => {
216
+ return {
217
+ type: n.type,
218
+ attrs: n.attrs
219
+ };
220
+ })(state, dispatch);
221
+ return true;
222
+ }
223
+ return false;
224
+ },
225
+ (state, dispatch) => {
226
+ const { selection } = state;
227
+ const { $from, $to } = selection;
228
+ const lines = state.doc.textBetween($from.before(), $to.pos).split("\n");
229
+ const currentLine = lines[lines.length - 1];
230
+ const match = currentLine.match(/^(\s+).*$/);
231
+ if (match) {
232
+ if (dispatch) {
233
+ dispatch(state.tr.insertText("\n" + match[1], $from.pos));
234
+ }
235
+ return true;
236
+ }
237
+ return false;
238
+ }
239
+ )
240
+ );
241
+ bind("Tab", (state, dispatch) => {
242
+ const { selection } = state;
243
+ const { $from, $to } = selection;
244
+ if ($from.parent.type === schema.nodes.code_block) {
245
+ if (dispatch) {
246
+ dispatch(state.tr.insertText(" ", $from.pos, $to.pos));
247
+ }
248
+ return true;
249
+ }
250
+ return false;
251
+ });
220
252
  return keys;
221
253
  }
222
254
 
@@ -788,7 +820,12 @@ function createAttachFile({
788
820
  if (!node) {
789
821
  return;
790
822
  }
791
- view.dispatch(tr2.replaceWith($pos, $pos, node));
823
+ const current = view.state.doc.resolve($pos);
824
+ if (current.parentOffset === 0) {
825
+ view.dispatch(tr2.replaceWith($pos - 1, $pos, node));
826
+ } else {
827
+ view.dispatch(tr2.replaceWith($pos, $pos, node));
828
+ }
792
829
  } catch (e) {
793
830
  view.dispatch(tr.setMeta(uploadPlaceholderPlugin, { remove: { id } }));
794
831
  }
@@ -877,9 +914,9 @@ var createCommands = (schema, view, options = {}) => {
877
914
  // src/text_editor_controller.tsx
878
915
  import { DOMParser, DOMSerializer } from "prosemirror-model";
879
916
  import { Subject } from "rxjs";
917
+ import { highlightPlugin } from "prosemirror-highlightjs";
880
918
  var TextEditorController = class {
881
919
  schema;
882
- options;
883
920
  props;
884
921
  subject;
885
922
  view;
@@ -902,9 +939,8 @@ var TextEditorController = class {
902
939
  );
903
940
  this.view.dispatch(tr);
904
941
  }
905
- constructor(options = {}, props = {}) {
942
+ constructor(props = {}) {
906
943
  this.schema = createSchema();
907
- this.options = options;
908
944
  this.props = props;
909
945
  this.subject = new Subject();
910
946
  this.prosemirrorParser = DOMParser.fromSchema(this.schema);
@@ -919,8 +955,8 @@ var TextEditorController = class {
919
955
  attachFile(files) {
920
956
  return createAttachFile({
921
957
  schema: this.schema,
922
- generateMetadata: this.options.attachFile?.generateMetadata,
923
- uploadFile: this.options.attachFile?.uploadFile
958
+ generateMetadata: this.props.attachFile?.generateMetadata,
959
+ uploadFile: this.props.attachFile?.uploadFile
924
960
  })(this.view, files);
925
961
  }
926
962
  bind(container) {
@@ -939,9 +975,9 @@ var TextEditorController = class {
939
975
  })();
940
976
  return {
941
977
  ...propsAttributes,
942
- class: cn(this.options?.className, propsAttributes?.class),
978
+ class: cn(this.props?.className, propsAttributes?.class),
943
979
  spellcheck: propsAttributes?.spellcheck || "false",
944
- style: this.options.style || "width: 100%; height: inherit; outline: none;"
980
+ style: this.props.style || "width: 100%; height: inherit; outline: none;"
945
981
  };
946
982
  },
947
983
  state: EditorState2.create({
@@ -959,7 +995,11 @@ var TextEditorController = class {
959
995
  dragAndDropPlugin({
960
996
  attachFile: (view, files) => this.attachFile(files)
961
997
  }),
962
- this.props.placeholder && placeholderPlugin(this.props.placeholder)
998
+ this.props.placeholder && placeholderPlugin(this.props.placeholder),
999
+ highlightPlugin(highlighter, ["code_block"], (node) => {
1000
+ const auto = highlighter.highlightAuto(node.textContent);
1001
+ return auto.language || "";
1002
+ })
963
1003
  ].filter((e) => !!e)
964
1004
  }),
965
1005
  dispatchTransaction: (tr) => {
@@ -1003,6 +1043,7 @@ var TextEditorController = class {
1003
1043
  function createTextEditor(options = {}) {
1004
1044
  function Component({
1005
1045
  controller: externalController,
1046
+ name,
1006
1047
  className,
1007
1048
  autoFocus,
1008
1049
  onChange,
@@ -1016,14 +1057,17 @@ function createTextEditor(options = {}) {
1016
1057
  } = {}) {
1017
1058
  const containerRef = useRef(null);
1018
1059
  const innerController = useMemo(
1019
- () => new TextEditorController(options, {
1060
+ () => new TextEditorController({
1020
1061
  mode,
1021
1062
  state,
1022
1063
  editor,
1023
1064
  autoFocus,
1024
1065
  placeholder,
1025
1066
  updateDelay,
1026
- defaultValue
1067
+ defaultValue,
1068
+ className: options.className,
1069
+ style: options.style,
1070
+ attachFile: options.attachFile
1027
1071
  }),
1028
1072
  []
1029
1073
  );
@@ -1041,9 +1085,8 @@ function createTextEditor(options = {}) {
1041
1085
  return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement("div", { ...props, ref: containerRef, className }), /* @__PURE__ */ React2.createElement(
1042
1086
  TextEditorInput,
1043
1087
  {
1088
+ name,
1044
1089
  controller,
1045
- updateDelay,
1046
- defaultValue,
1047
1090
  onChange
1048
1091
  }
1049
1092
  ));
package/dist/html.js CHANGED
@@ -93,11 +93,12 @@ function createInnerHTML(raw) {
93
93
  return raw.replace(/<\/p>/g, "<br></p>").replace(/(<p><br><\/p>)+$/g, "").replace(
94
94
  /<code class="language-(\w+)">([\s\S]*?)<\/code>/g,
95
95
  (_, lang, code) => {
96
+ if (lang === "undefined") {
97
+ return `<code>${(0, import_html_entities.decode)(code)}</code>`;
98
+ }
96
99
  try {
97
- const highlighted = highlighter.highlight(code, {
98
- language: lang
99
- }).value;
100
- return `<code class="language-${lang}">${(0, import_html_entities.decode)(highlighted)}</code>`;
100
+ const { language, value } = highlighter.highlightAuto(code);
101
+ return `<code class="language-${language}">${(0, import_html_entities.decode)(value)}</code>`;
101
102
  } catch (e) {
102
103
  return `<code class="language-${lang}">${(0, import_html_entities.decode)(code)}</code>`;
103
104
  }
package/dist/html.mjs CHANGED
@@ -56,11 +56,12 @@ function createInnerHTML(raw) {
56
56
  return raw.replace(/<\/p>/g, "<br></p>").replace(/(<p><br><\/p>)+$/g, "").replace(
57
57
  /<code class="language-(\w+)">([\s\S]*?)<\/code>/g,
58
58
  (_, lang, code) => {
59
+ if (lang === "undefined") {
60
+ return `<code>${decode(code)}</code>`;
61
+ }
59
62
  try {
60
- const highlighted = highlighter.highlight(code, {
61
- language: lang
62
- }).value;
63
- return `<code class="language-${lang}">${decode(highlighted)}</code>`;
63
+ const { language, value } = highlighter.highlightAuto(code);
64
+ return `<code class="language-${language}">${decode(value)}</code>`;
64
65
  } catch (e) {
65
66
  return `<code class="language-${lang}">${decode(code)}</code>`;
66
67
  }
package/dist/index.d.mts CHANGED
@@ -2,7 +2,7 @@ export { TextEditorProps, createTextEditor } from './create_text_editor.mjs';
2
2
  export { createSchema } from './schema.mjs';
3
3
  export { AttachFile, AttachFileOptions, GenerateMetadata, UploadFile, createAttachFile } from './attach_file.mjs';
4
4
  export { createInnerHTML, createTextEditorView } from './html.mjs';
5
- export { CreateTextEditorOptions, TextEditorController, TextEditorControllerProps } from './text_editor_controller.mjs';
5
+ export { TextEditorController, TextEditorControllerProps } from './text_editor_controller.mjs';
6
6
  import 'react';
7
7
  import 'orderedmap';
8
8
  import 'prosemirror-model';
package/dist/index.d.ts CHANGED
@@ -2,7 +2,7 @@ export { TextEditorProps, createTextEditor } from './create_text_editor.js';
2
2
  export { createSchema } from './schema.js';
3
3
  export { AttachFile, AttachFileOptions, GenerateMetadata, UploadFile, createAttachFile } from './attach_file.js';
4
4
  export { createInnerHTML, createTextEditorView } from './html.js';
5
- export { CreateTextEditorOptions, TextEditorController, TextEditorControllerProps } from './text_editor_controller.js';
5
+ export { TextEditorController, TextEditorControllerProps } from './text_editor_controller.js';
6
6
  import 'react';
7
7
  import 'orderedmap';
8
8
  import 'prosemirror-model';