@portabletext/editor 1.47.2 → 1.47.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/lib/_chunks-cjs/util.is-selection-collapsed.cjs +5 -0
- package/lib/_chunks-cjs/util.is-selection-collapsed.cjs.map +1 -1
- package/lib/_chunks-es/util.is-selection-collapsed.js +5 -0
- package/lib/_chunks-es/util.is-selection-collapsed.js.map +1 -1
- package/lib/index.cjs +15 -7
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +16 -8
- package/lib/index.js.map +1 -1
- package/lib/utils/index.cjs +1 -4
- package/lib/utils/index.cjs.map +1 -1
- package/lib/utils/index.js +3 -6
- package/lib/utils/index.js.map +1 -1
- package/package.json +3 -3
- package/src/editor/Editable.tsx +33 -15
package/lib/utils/index.cjs
CHANGED
|
@@ -4,9 +4,6 @@ var util_sliceBlocks = require("../_chunks-cjs/util.slice-blocks.cjs"), util_sel
|
|
|
4
4
|
function getSelectionStartPoint(selection) {
|
|
5
5
|
return selection ? selection.backward ? selection.focus : selection.anchor : null;
|
|
6
6
|
}
|
|
7
|
-
function isEqualSelections(a, b) {
|
|
8
|
-
return !a && !b ? !0 : !a || !b ? !1 : util_sliceBlocks.isEqualSelectionPoints(a.anchor, b.anchor) && util_sliceBlocks.isEqualSelectionPoints(a.focus, b.focus);
|
|
9
|
-
}
|
|
10
7
|
function splitTextBlock({
|
|
11
8
|
context,
|
|
12
9
|
block,
|
|
@@ -65,10 +62,10 @@ exports.blockOffsetsToSelection = util_selectionPointToBlockOffset.blockOffsetsT
|
|
|
65
62
|
exports.childSelectionPointToBlockOffset = util_selectionPointToBlockOffset.childSelectionPointToBlockOffset;
|
|
66
63
|
exports.selectionPointToBlockOffset = util_selectionPointToBlockOffset.selectionPointToBlockOffset;
|
|
67
64
|
exports.getSelectionEndPoint = util_isSelectionCollapsed.getSelectionEndPoint;
|
|
65
|
+
exports.isEqualSelections = util_isSelectionCollapsed.isEqualSelections;
|
|
68
66
|
exports.isSelectionCollapsed = util_isSelectionCollapsed.isSelectionCollapsed;
|
|
69
67
|
exports.isTextBlock = util_mergeTextBlocks.isTextBlock;
|
|
70
68
|
exports.mergeTextBlocks = util_mergeTextBlocks.mergeTextBlocks;
|
|
71
69
|
exports.getSelectionStartPoint = getSelectionStartPoint;
|
|
72
|
-
exports.isEqualSelections = isEqualSelections;
|
|
73
70
|
exports.splitTextBlock = splitTextBlock;
|
|
74
71
|
//# sourceMappingURL=index.cjs.map
|
package/lib/utils/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../../src/utils/util.get-selection-start-point.ts","../../src/utils/util.
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../../src/utils/util.get-selection-start-point.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {EditorSelection, EditorSelectionPoint} from '..'\n\n/**\n * @public\n */\nexport function getSelectionStartPoint<\n TEditorSelection extends NonNullable<EditorSelection> | null,\n TEditorSelectionPoint extends\n EditorSelectionPoint | null = TEditorSelection extends NonNullable<EditorSelection>\n ? EditorSelectionPoint\n : null,\n>(selection: TEditorSelection): TEditorSelectionPoint {\n if (!selection) {\n return null as TEditorSelectionPoint\n }\n\n return (\n selection.backward ? selection.focus : selection.anchor\n ) as TEditorSelectionPoint\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelectionPoint} from '..'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {isSpan} from './util.is-span'\nimport {isTextBlock} from './util.is-text-block'\nimport {sliceBlocks} from './util.slice-blocks'\n\n/**\n * @beta\n */\nexport function splitTextBlock({\n context,\n block,\n point,\n}: {\n context: Pick<EditorContext, 'schema'>\n block: PortableTextTextBlock\n point: EditorSelectionPoint\n}): {before: PortableTextTextBlock; after: PortableTextTextBlock} | undefined {\n const firstChild = block.children.at(0)\n const lastChild = block.children.at(block.children.length - 1)\n\n if (!firstChild || !lastChild) {\n return undefined\n }\n\n const before = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: {\n path: [{_key: block._key}, 'children', {_key: firstChild._key}],\n offset: 0,\n },\n focus: point,\n },\n }).at(0)\n const after = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: point,\n focus: {\n path: [{_key: block._key}, 'children', {_key: lastChild._key}],\n offset: isSpan(context, lastChild) ? lastChild.text.length : 0,\n },\n },\n }).at(0)\n\n if (!before || !after) {\n return undefined\n }\n\n if (!isTextBlock(context, before) || !isTextBlock(context, after)) {\n return undefined\n }\n\n return {before, after}\n}\n"],"names":["getSelectionStartPoint","selection","backward","focus","anchor","splitTextBlock","context","block","point","firstChild","children","at","lastChild","length","before","sliceBlocks","blocks","path","_key","offset","after","isSpan","text","isTextBlock"],"mappings":";;;AAKO,SAASA,uBAMdC,WAAoD;AACpD,SAAKA,YAKHA,UAAUC,WAAWD,UAAUE,QAAQF,UAAUG,SAJ1C;AAMX;ACTO,SAASC,eAAe;AAAA,EAC7BC;AAAAA,EACAC;AAAAA,EACAC;AAKF,GAA8E;AAC5E,QAAMC,aAAaF,MAAMG,SAASC,GAAG,CAAC,GAChCC,YAAYL,MAAMG,SAASC,GAAGJ,MAAMG,SAASG,SAAS,CAAC;AAEzD,MAAA,CAACJ,cAAc,CAACG;AAClB;AAGF,QAAME,SAASC,iBAAAA,YAAY;AAAA,IACzBC,QAAQ,CAACT,KAAK;AAAA,IACdN,WAAW;AAAA,MACTG,QAAQ;AAAA,QACNa,MAAM,CAAC;AAAA,UAACC,MAAMX,MAAMW;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMT,WAAWS;AAAAA,QAAAA,CAAK;AAAA,QAC9DC,QAAQ;AAAA,MACV;AAAA,MACAhB,OAAOK;AAAAA,IAAAA;AAAAA,EAEV,CAAA,EAAEG,GAAG,CAAC,GACDS,QAAQL,iBAAAA,YAAY;AAAA,IACxBC,QAAQ,CAACT,KAAK;AAAA,IACdN,WAAW;AAAA,MACTG,QAAQI;AAAAA,MACRL,OAAO;AAAA,QACLc,MAAM,CAAC;AAAA,UAACC,MAAMX,MAAMW;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMN,UAAUM;AAAAA,QAAAA,CAAK;AAAA,QAC7DC,QAAQE,iBAAOf,OAAAA,SAASM,SAAS,IAAIA,UAAUU,KAAKT,SAAS;AAAA,MAAA;AAAA,IAC/D;AAAA,EACF,CACD,EAAEF,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACM,UAIZ,EAACG,CAAAA,qBAAAA,YAAYjB,SAASQ,MAAM,KAAK,CAACS,qBAAYjB,YAAAA,SAASc,KAAK;AAIzD,WAAA;AAAA,MAACN;AAAAA,MAAQM;AAAAA,IAAK;AACvB;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/lib/utils/index.js
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { blockOffsetToSpanSelectionPoint, getBlockEndPoint, getBlockStartPoint, getTextBlockText, isEmptyTextBlock, isKeyedSegment, reverseSelection, spanSelectionPointToBlockOffset } from "../_chunks-es/util.slice-blocks.js";
|
|
1
|
+
import { sliceBlocks, isSpan } from "../_chunks-es/util.slice-blocks.js";
|
|
2
|
+
import { blockOffsetToSpanSelectionPoint, getBlockEndPoint, getBlockStartPoint, getTextBlockText, isEmptyTextBlock, isEqualSelectionPoints, isKeyedSegment, reverseSelection, spanSelectionPointToBlockOffset } from "../_chunks-es/util.slice-blocks.js";
|
|
3
3
|
import { blockOffsetToBlockSelectionPoint, blockOffsetToSelectionPoint, blockOffsetsToSelection, childSelectionPointToBlockOffset, selectionPointToBlockOffset } from "../_chunks-es/util.selection-point-to-block-offset.js";
|
|
4
|
-
import { getSelectionEndPoint, isSelectionCollapsed } from "../_chunks-es/util.is-selection-collapsed.js";
|
|
4
|
+
import { getSelectionEndPoint, isEqualSelections, isSelectionCollapsed } from "../_chunks-es/util.is-selection-collapsed.js";
|
|
5
5
|
import { isTextBlock } from "../_chunks-es/util.merge-text-blocks.js";
|
|
6
6
|
import { mergeTextBlocks } from "../_chunks-es/util.merge-text-blocks.js";
|
|
7
7
|
function getSelectionStartPoint(selection) {
|
|
8
8
|
return selection ? selection.backward ? selection.focus : selection.anchor : null;
|
|
9
9
|
}
|
|
10
|
-
function isEqualSelections(a, b) {
|
|
11
|
-
return !a && !b ? !0 : !a || !b ? !1 : isEqualSelectionPoints(a.anchor, b.anchor) && isEqualSelectionPoints(a.focus, b.focus);
|
|
12
|
-
}
|
|
13
10
|
function splitTextBlock({
|
|
14
11
|
context,
|
|
15
12
|
block,
|
package/lib/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/utils/util.get-selection-start-point.ts","../../src/utils/util.
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/utils/util.get-selection-start-point.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {EditorSelection, EditorSelectionPoint} from '..'\n\n/**\n * @public\n */\nexport function getSelectionStartPoint<\n TEditorSelection extends NonNullable<EditorSelection> | null,\n TEditorSelectionPoint extends\n EditorSelectionPoint | null = TEditorSelection extends NonNullable<EditorSelection>\n ? EditorSelectionPoint\n : null,\n>(selection: TEditorSelection): TEditorSelectionPoint {\n if (!selection) {\n return null as TEditorSelectionPoint\n }\n\n return (\n selection.backward ? selection.focus : selection.anchor\n ) as TEditorSelectionPoint\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelectionPoint} from '..'\nimport type {EditorContext} from '../editor/editor-snapshot'\nimport {isSpan} from './util.is-span'\nimport {isTextBlock} from './util.is-text-block'\nimport {sliceBlocks} from './util.slice-blocks'\n\n/**\n * @beta\n */\nexport function splitTextBlock({\n context,\n block,\n point,\n}: {\n context: Pick<EditorContext, 'schema'>\n block: PortableTextTextBlock\n point: EditorSelectionPoint\n}): {before: PortableTextTextBlock; after: PortableTextTextBlock} | undefined {\n const firstChild = block.children.at(0)\n const lastChild = block.children.at(block.children.length - 1)\n\n if (!firstChild || !lastChild) {\n return undefined\n }\n\n const before = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: {\n path: [{_key: block._key}, 'children', {_key: firstChild._key}],\n offset: 0,\n },\n focus: point,\n },\n }).at(0)\n const after = sliceBlocks({\n blocks: [block],\n selection: {\n anchor: point,\n focus: {\n path: [{_key: block._key}, 'children', {_key: lastChild._key}],\n offset: isSpan(context, lastChild) ? lastChild.text.length : 0,\n },\n },\n }).at(0)\n\n if (!before || !after) {\n return undefined\n }\n\n if (!isTextBlock(context, before) || !isTextBlock(context, after)) {\n return undefined\n }\n\n return {before, after}\n}\n"],"names":["getSelectionStartPoint","selection","backward","focus","anchor","splitTextBlock","context","block","point","firstChild","children","at","lastChild","length","before","sliceBlocks","blocks","path","_key","offset","after","isSpan","text","isTextBlock"],"mappings":";;;;;;AAKO,SAASA,uBAMdC,WAAoD;AACpD,SAAKA,YAKHA,UAAUC,WAAWD,UAAUE,QAAQF,UAAUG,SAJ1C;AAMX;ACTO,SAASC,eAAe;AAAA,EAC7BC;AAAAA,EACAC;AAAAA,EACAC;AAKF,GAA8E;AAC5E,QAAMC,aAAaF,MAAMG,SAASC,GAAG,CAAC,GAChCC,YAAYL,MAAMG,SAASC,GAAGJ,MAAMG,SAASG,SAAS,CAAC;AAEzD,MAAA,CAACJ,cAAc,CAACG;AAClB;AAGF,QAAME,SAASC,YAAY;AAAA,IACzBC,QAAQ,CAACT,KAAK;AAAA,IACdN,WAAW;AAAA,MACTG,QAAQ;AAAA,QACNa,MAAM,CAAC;AAAA,UAACC,MAAMX,MAAMW;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMT,WAAWS;AAAAA,QAAAA,CAAK;AAAA,QAC9DC,QAAQ;AAAA,MACV;AAAA,MACAhB,OAAOK;AAAAA,IAAAA;AAAAA,EAEV,CAAA,EAAEG,GAAG,CAAC,GACDS,QAAQL,YAAY;AAAA,IACxBC,QAAQ,CAACT,KAAK;AAAA,IACdN,WAAW;AAAA,MACTG,QAAQI;AAAAA,MACRL,OAAO;AAAA,QACLc,MAAM,CAAC;AAAA,UAACC,MAAMX,MAAMW;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMN,UAAUM;AAAAA,QAAAA,CAAK;AAAA,QAC7DC,QAAQE,OAAOf,SAASM,SAAS,IAAIA,UAAUU,KAAKT,SAAS;AAAA,MAAA;AAAA,IAC/D;AAAA,EACF,CACD,EAAEF,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACM,UAIZ,EAACG,CAAAA,YAAYjB,SAASQ,MAAM,KAAK,CAACS,YAAYjB,SAASc,KAAK;AAIzD,WAAA;AAAA,MAACN;AAAAA,MAAQM;AAAAA,IAAK;AACvB;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/editor",
|
|
3
|
-
"version": "1.47.
|
|
3
|
+
"version": "1.47.3",
|
|
4
4
|
"description": "Portable Text Editor made in React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -79,8 +79,8 @@
|
|
|
79
79
|
"slate-react": "0.112.1",
|
|
80
80
|
"use-effect-event": "^1.0.2",
|
|
81
81
|
"xstate": "^5.19.2",
|
|
82
|
-
"@portabletext/
|
|
83
|
-
"@portabletext/
|
|
82
|
+
"@portabletext/block-tools": "1.1.18",
|
|
83
|
+
"@portabletext/patches": "1.1.3"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"@portabletext/toolkit": "^2.0.17",
|
package/src/editor/Editable.tsx
CHANGED
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
type MutableRefObject,
|
|
17
17
|
type TextareaHTMLAttributes,
|
|
18
18
|
} from 'react'
|
|
19
|
-
import {
|
|
19
|
+
import {Transforms, type Text} from 'slate'
|
|
20
20
|
import {
|
|
21
21
|
ReactEditor,
|
|
22
22
|
Editable as SlateEditable,
|
|
@@ -34,6 +34,7 @@ import {normalizeSelection} from '../internal-utils/selection'
|
|
|
34
34
|
import {getSelectionDomNodes} from '../internal-utils/selection-elements'
|
|
35
35
|
import {slateRangeToSelection} from '../internal-utils/slate-utils'
|
|
36
36
|
import {fromSlateValue} from '../internal-utils/values'
|
|
37
|
+
import {KEY_TO_VALUE_ELEMENT} from '../internal-utils/weakMaps'
|
|
37
38
|
import * as selectors from '../selectors'
|
|
38
39
|
import type {
|
|
39
40
|
EditorSelection,
|
|
@@ -50,7 +51,7 @@ import type {
|
|
|
50
51
|
ScrollSelectionIntoViewFunction,
|
|
51
52
|
} from '../types/editor'
|
|
52
53
|
import type {HotkeyOptions} from '../types/options'
|
|
53
|
-
import {isSelectionCollapsed} from '../utils'
|
|
54
|
+
import {isEqualSelections, isSelectionCollapsed} from '../utils'
|
|
54
55
|
import {getSelectionEndPoint} from '../utils/util.get-selection-end-point'
|
|
55
56
|
import {Element} from './components/Element'
|
|
56
57
|
import {Leaf} from './components/Leaf'
|
|
@@ -58,7 +59,6 @@ import {EditorActorContext} from './editor-actor-context'
|
|
|
58
59
|
import {getEditorSnapshot} from './editor-selector'
|
|
59
60
|
import {usePortableTextEditor} from './hooks/usePortableTextEditor'
|
|
60
61
|
import {createWithHotkeys} from './plugins/createWithHotKeys'
|
|
61
|
-
import {PortableTextEditor} from './PortableTextEditor'
|
|
62
62
|
import {
|
|
63
63
|
createDecorate,
|
|
64
64
|
rangeDecorationsMachine,
|
|
@@ -444,7 +444,11 @@ export const PortableTextEditable = forwardRef<
|
|
|
444
444
|
// Handle incoming pasting events in the editor
|
|
445
445
|
const handlePaste = useCallback(
|
|
446
446
|
(event: ClipboardEvent<HTMLDivElement>): Promise<void> | void => {
|
|
447
|
-
const value =
|
|
447
|
+
const value = fromSlateValue(
|
|
448
|
+
slateEditor.children,
|
|
449
|
+
editorActor.getSnapshot().context.schema.block.name,
|
|
450
|
+
KEY_TO_VALUE_ELEMENT.get(slateEditor),
|
|
451
|
+
)
|
|
448
452
|
const ptRange = slateEditor.selection
|
|
449
453
|
? slateRangeToSelection({
|
|
450
454
|
schema: editorActor.getSnapshot().context.schema,
|
|
@@ -566,24 +570,38 @@ export const PortableTextEditable = forwardRef<
|
|
|
566
570
|
onFocus(event)
|
|
567
571
|
}
|
|
568
572
|
if (!event.isDefaultPrevented()) {
|
|
569
|
-
const
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
573
|
+
const selectionBefore = slateEditor.selection
|
|
574
|
+
? slateRangeToSelection({
|
|
575
|
+
schema: editorActor.getSnapshot().context.schema,
|
|
576
|
+
editor: slateEditor,
|
|
577
|
+
range: slateEditor.selection,
|
|
578
|
+
})
|
|
579
|
+
: null
|
|
580
|
+
|
|
575
581
|
editorActor.send({type: 'notify.focused', event})
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
582
|
+
|
|
583
|
+
const selectionAfter = slateEditor.selection
|
|
584
|
+
? slateRangeToSelection({
|
|
585
|
+
schema: editorActor.getSnapshot().context.schema,
|
|
586
|
+
editor: slateEditor,
|
|
587
|
+
range: slateEditor.selection,
|
|
588
|
+
})
|
|
589
|
+
: null
|
|
590
|
+
|
|
591
|
+
if (
|
|
592
|
+
selectionBefore &&
|
|
593
|
+
selectionAfter &&
|
|
594
|
+
isEqualSelections(selectionBefore, selectionAfter)
|
|
595
|
+
) {
|
|
596
|
+
// If the selection is the same, emit it explicitly here as there is no actual onChange event triggered.
|
|
579
597
|
editorActor.send({
|
|
580
598
|
type: 'notify.selection',
|
|
581
|
-
selection,
|
|
599
|
+
selection: selectionBefore,
|
|
582
600
|
})
|
|
583
601
|
}
|
|
584
602
|
}
|
|
585
603
|
},
|
|
586
|
-
[editorActor, onFocus,
|
|
604
|
+
[editorActor, onFocus, slateEditor],
|
|
587
605
|
)
|
|
588
606
|
|
|
589
607
|
const handleClick = useCallback(
|