@handlewithcare/react-prosemirror 3.1.1 → 3.1.3

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.
package/README.md CHANGED
@@ -90,6 +90,7 @@ import "prosemirror-view/style/prosemirror.css";
90
90
  - [`useIgnoreMutation`](#useignoremutation)
91
91
  - [`useSelectNode`](#useselectnode)
92
92
  - [`useIsNodeSelected`](#useisnodeselected)
93
+ - [`useIsComposingIn`](#useiscomposingin)
93
94
  - [`widget`](#widget)
94
95
  - [`reorderSiblings`](#reordersiblings)
95
96
  - [When should I use this?](#when-should-i-use-this)
@@ -764,6 +765,15 @@ This hook can be used within a node view component to subscribe to a boolean
764
765
  value determining whether this node is selected. The hook will return true when
765
766
  a NodeSelection is created whose node is this one.
766
767
 
768
+ ### `useIsComposingIn`
769
+
770
+ ```tsx
771
+ type useIsComposingIn = (): boolean
772
+ ```
773
+
774
+ This hook can be used within a node view component to subscribe to a boolean
775
+ value determining whether an IME composition is active inside the node.
776
+
767
777
  ### `widget`
768
778
 
769
779
  ```ts
@@ -20,7 +20,7 @@ const _react = /*#__PURE__*/ _interop_require_wildcard(require("react"));
20
20
  const _ChildDescriptionsContext = require("../contexts/ChildDescriptionsContext.js");
21
21
  const _EditorContext = require("../contexts/EditorContext.js");
22
22
  const _iterDeco = require("../decorations/iterDeco.js");
23
- const _useReactKeys = require("../hooks/useReactKeys.js");
23
+ const _reactKeys = require("../plugins/reactKeys.js");
24
24
  const _props = require("../props.js");
25
25
  const _viewdesc = require("../viewdesc.js");
26
26
  const _NativeWidgetView = require("./NativeWidgetView.js");
@@ -305,7 +305,7 @@ function createChildElements(children, getInnerPos) {
305
305
  }
306
306
  const ChildNodeViews = /*#__PURE__*/ (0, _react.memo)(function ChildNodeViews(param) {
307
307
  let { getPos, node, innerDecorations } = param;
308
- const reactKeys = (0, _useReactKeys.useReactKeys)();
308
+ const { view } = (0, _react.useContext)(_EditorContext.EditorContext);
309
309
  const getInnerPos = (0, _react.useCallback)(()=>getPos() + 1, [
310
310
  getPos
311
311
  ]);
@@ -315,11 +315,12 @@ const ChildNodeViews = /*#__PURE__*/ (0, _react.memo)(function ChildNodeViews(pa
315
315
  let widgetChildren = [];
316
316
  let lastNodeChild = null;
317
317
  (0, _iterDeco.iterDeco)(node, innerDecorations, (widget, isNative, offset, index)=>{
318
+ const posToKey = _reactKeys.reactKeysPluginKey.getState(view.state)?.posToKey;
318
319
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
319
320
  const widgetMarks = widget.type.spec.marks ?? [];
320
321
  let key;
321
322
  if (isNative) {
322
- key = createKey(getInnerPos(), offset, index, "native-widget", reactKeys?.posToKey, widget);
323
+ key = createKey(getInnerPos(), offset, index, "native-widget", posToKey, widget);
323
324
  const child = {
324
325
  type: "native-widget",
325
326
  widget,
@@ -336,7 +337,7 @@ const ChildNodeViews = /*#__PURE__*/ (0, _react.memo)(function ChildNodeViews(pa
336
337
  }
337
338
  keysSeen.set(key, keysSeen.size);
338
339
  } else {
339
- key = createKey(getInnerPos(), offset, index, "widget", reactKeys?.posToKey, widget);
340
+ key = createKey(getInnerPos(), offset, index, "widget", posToKey, widget);
340
341
  const child = {
341
342
  type: "widget",
342
343
  widget: widget,
@@ -357,7 +358,8 @@ const ChildNodeViews = /*#__PURE__*/ (0, _react.memo)(function ChildNodeViews(pa
357
358
  widgetChildren.push(child);
358
359
  adjustWidgetMarksForward(lastNodeChild, childMap.get(key));
359
360
  }, (childNode, outerDeco, innerDeco, offset, index)=>{
360
- const key = createKey(getInnerPos(), offset, index, "node", reactKeys?.posToKey);
361
+ const posToKey = _reactKeys.reactKeysPluginKey.getState(view.state)?.posToKey;
362
+ const key = createKey(getInnerPos(), offset, index, "node", posToKey);
361
363
  const child = {
362
364
  type: "node",
363
365
  node: childNode,
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "useIsComposingIn", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return useIsComposingIn;
9
+ }
10
+ });
11
+ const _react = require("react");
12
+ const _NodeView = require("../components/nodes/NodeView.js");
13
+ const _index = require("../index.js");
14
+ function useIsComposingIn() {
15
+ const [isComposing, setIsComposing] = (0, _react.useState)(false);
16
+ const getPos = (0, _react.useContext)(_NodeView.GetPosContext);
17
+ (0, _index.useEditorEventListener)("compositionstart", (view)=>{
18
+ const compositionRoot = view.state.selection.$from.before();
19
+ setIsComposing(compositionRoot === getPos());
20
+ });
21
+ (0, _index.useEditorEventListener)("compositionend", ()=>{
22
+ setIsComposing(false);
23
+ });
24
+ return isComposing;
25
+ }
package/dist/cjs/index.js CHANGED
@@ -37,6 +37,9 @@ _export(exports, {
37
37
  useIgnoreMutation: function() {
38
38
  return _useIgnoreMutation.useIgnoreMutation;
39
39
  },
40
+ useIsComposingIn: function() {
41
+ return _useIsComposingIn.useIsComposingIn;
42
+ },
40
43
  useIsEditorStatic: function() {
41
44
  return _useIsEditorStatic.useIsEditorStatic;
42
45
  },
@@ -62,6 +65,7 @@ _export(exports, {
62
65
  const _ProseMirror = require("./components/ProseMirror.js");
63
66
  const _ProseMirrorDoc = require("./components/ProseMirrorDoc.js");
64
67
  const _reorderSiblings = require("./commands/reorderSiblings.js");
68
+ const _useIsComposingIn = require("./hooks/useIsComposingIn.js");
65
69
  const _useEditorEffect = require("./hooks/useEditorEffect.js");
66
70
  const _useEditorEventCallback = require("./hooks/useEditorEventCallback.js");
67
71
  const _useEditorEventListener = require("./hooks/useEditorEventListener.js");
@@ -219,7 +219,19 @@ function beforeInputPlugin() {
219
219
  }
220
220
  case "insertText":
221
221
  {
222
- insertText(view, event.data);
222
+ const ranges = event.getTargetRanges();
223
+ if (ranges.length === 0 || ranges.length === 1 && ranges[0] && ranges[0].collapsed) {
224
+ insertText(view, event.data);
225
+ } else {
226
+ for (const range of ranges){
227
+ const from = view.posAtDOM(range.startContainer, range.startOffset, 1);
228
+ const to = view.posAtDOM(range.endContainer, range.endOffset, 1);
229
+ insertText(view, event.data, {
230
+ from,
231
+ to
232
+ });
233
+ }
234
+ }
223
235
  break;
224
236
  }
225
237
  case "deleteWordBackward":
@@ -2,7 +2,7 @@ import React, { cloneElement, createElement, memo, useCallback, useContext, useR
2
2
  import { ChildDescriptionsContext } from "../contexts/ChildDescriptionsContext.js";
3
3
  import { EditorContext } from "../contexts/EditorContext.js";
4
4
  import { iterDeco } from "../decorations/iterDeco.js";
5
- import { useReactKeys } from "../hooks/useReactKeys.js";
5
+ import { reactKeysPluginKey } from "../plugins/reactKeys.js";
6
6
  import { htmlAttrsToReactProps, mergeReactProps } from "../props.js";
7
7
  import { sameOuterDeco } from "../viewdesc.js";
8
8
  import { NativeWidgetView } from "./NativeWidgetView.js";
@@ -246,7 +246,7 @@ function createChildElements(children, getInnerPos) {
246
246
  }
247
247
  export const ChildNodeViews = /*#__PURE__*/ memo(function ChildNodeViews(param) {
248
248
  let { getPos, node, innerDecorations } = param;
249
- const reactKeys = useReactKeys();
249
+ const { view } = useContext(EditorContext);
250
250
  const getInnerPos = useCallback(()=>getPos() + 1, [
251
251
  getPos
252
252
  ]);
@@ -256,11 +256,12 @@ export const ChildNodeViews = /*#__PURE__*/ memo(function ChildNodeViews(param)
256
256
  let widgetChildren = [];
257
257
  let lastNodeChild = null;
258
258
  iterDeco(node, innerDecorations, (widget, isNative, offset, index)=>{
259
+ const posToKey = reactKeysPluginKey.getState(view.state)?.posToKey;
259
260
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
260
261
  const widgetMarks = widget.type.spec.marks ?? [];
261
262
  let key;
262
263
  if (isNative) {
263
- key = createKey(getInnerPos(), offset, index, "native-widget", reactKeys?.posToKey, widget);
264
+ key = createKey(getInnerPos(), offset, index, "native-widget", posToKey, widget);
264
265
  const child = {
265
266
  type: "native-widget",
266
267
  widget,
@@ -277,7 +278,7 @@ export const ChildNodeViews = /*#__PURE__*/ memo(function ChildNodeViews(param)
277
278
  }
278
279
  keysSeen.set(key, keysSeen.size);
279
280
  } else {
280
- key = createKey(getInnerPos(), offset, index, "widget", reactKeys?.posToKey, widget);
281
+ key = createKey(getInnerPos(), offset, index, "widget", posToKey, widget);
281
282
  const child = {
282
283
  type: "widget",
283
284
  widget: widget,
@@ -298,7 +299,8 @@ export const ChildNodeViews = /*#__PURE__*/ memo(function ChildNodeViews(param)
298
299
  widgetChildren.push(child);
299
300
  adjustWidgetMarksForward(lastNodeChild, childMap.get(key));
300
301
  }, (childNode, outerDeco, innerDeco, offset, index)=>{
301
- const key = createKey(getInnerPos(), offset, index, "node", reactKeys?.posToKey);
302
+ const posToKey = reactKeysPluginKey.getState(view.state)?.posToKey;
303
+ const key = createKey(getInnerPos(), offset, index, "node", posToKey);
302
304
  const child = {
303
305
  type: "node",
304
306
  node: childNode,
@@ -0,0 +1,17 @@
1
+ import { useContext, useState } from "react";
2
+ import { GetPosContext } from "../components/nodes/NodeView.js";
3
+ import { useEditorEventListener } from "../index.js";
4
+ /**
5
+ * Returns true while an IME composition is active inside the current node.
6
+ */ export function useIsComposingIn() {
7
+ const [isComposing, setIsComposing] = useState(false);
8
+ const getPos = useContext(GetPosContext);
9
+ useEditorEventListener("compositionstart", (view)=>{
10
+ const compositionRoot = view.state.selection.$from.before();
11
+ setIsComposing(compositionRoot === getPos());
12
+ });
13
+ useEditorEventListener("compositionend", ()=>{
14
+ setIsComposing(false);
15
+ });
16
+ return isComposing;
17
+ }
package/dist/esm/index.js CHANGED
@@ -2,6 +2,7 @@
2
2
  export { ProseMirror } from "./components/ProseMirror.js";
3
3
  export { ProseMirrorDoc } from "./components/ProseMirrorDoc.js";
4
4
  export { reorderSiblings } from "./commands/reorderSiblings.js";
5
+ export { useIsComposingIn } from "./hooks/useIsComposingIn.js";
5
6
  export { useEditorEffect } from "./hooks/useEditorEffect.js";
6
7
  export { useEditorEventCallback } from "./hooks/useEditorEventCallback.js";
7
8
  export { useEditorEventListener } from "./hooks/useEditorEventListener.js";
@@ -209,7 +209,19 @@ export function beforeInputPlugin() {
209
209
  }
210
210
  case "insertText":
211
211
  {
212
- insertText(view, event.data);
212
+ const ranges = event.getTargetRanges();
213
+ if (ranges.length === 0 || ranges.length === 1 && ranges[0] && ranges[0].collapsed) {
214
+ insertText(view, event.data);
215
+ } else {
216
+ for (const range of ranges){
217
+ const from = view.posAtDOM(range.startContainer, range.startOffset, 1);
218
+ const to = view.posAtDOM(range.endContainer, range.endOffset, 1);
219
+ insertText(view, event.data, {
220
+ from,
221
+ to
222
+ });
223
+ }
224
+ }
213
225
  break;
214
226
  }
215
227
  case "deleteWordBackward":