@portabletext/editor 1.36.6 → 1.38.0
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/behavior.core.cjs +84 -49
- package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
- package/lib/_chunks-cjs/behavior.markdown.cjs +1 -1
- package/lib/_chunks-cjs/editor-provider.cjs +919 -526
- package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
- package/lib/_chunks-cjs/{util.block-offsets-to-selection.cjs → parse-blocks.cjs} +36 -21
- package/lib/_chunks-cjs/parse-blocks.cjs.map +1 -0
- package/lib/_chunks-cjs/selector.get-text-before.cjs +2 -2
- package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
- package/lib/_chunks-cjs/{selector.is-active-style.cjs → selector.is-overlapping-selection.cjs} +144 -3
- package/lib/_chunks-cjs/selector.is-overlapping-selection.cjs.map +1 -0
- package/lib/_chunks-cjs/util.slice-blocks.cjs +12 -0
- package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
- package/lib/_chunks-es/behavior.core.js +84 -49
- package/lib/_chunks-es/behavior.core.js.map +1 -1
- package/lib/_chunks-es/behavior.markdown.js +1 -1
- package/lib/_chunks-es/editor-provider.js +911 -517
- package/lib/_chunks-es/editor-provider.js.map +1 -1
- package/lib/_chunks-es/{util.block-offsets-to-selection.js → parse-blocks.js} +37 -22
- package/lib/_chunks-es/parse-blocks.js.map +1 -0
- package/lib/_chunks-es/selector.get-text-before.js +1 -2
- package/lib/_chunks-es/selector.get-text-before.js.map +1 -1
- package/lib/_chunks-es/{selector.is-active-style.js → selector.is-overlapping-selection.js} +146 -5
- package/lib/_chunks-es/selector.is-overlapping-selection.js.map +1 -0
- package/lib/_chunks-es/util.slice-blocks.js +12 -0
- package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
- package/lib/behaviors/index.d.cts +10535 -4689
- package/lib/behaviors/index.d.ts +10535 -4689
- package/lib/index.cjs +582 -209
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +5297 -1178
- package/lib/index.d.ts +5297 -1178
- package/lib/index.js +591 -213
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.cjs +2 -2
- package/lib/plugins/index.cjs.map +1 -1
- package/lib/plugins/index.d.cts +5297 -1178
- package/lib/plugins/index.d.ts +5297 -1178
- package/lib/plugins/index.js +2 -2
- package/lib/selectors/index.cjs +21 -103
- package/lib/selectors/index.cjs.map +1 -1
- package/lib/selectors/index.d.cts +5313 -1178
- package/lib/selectors/index.d.ts +5313 -1178
- package/lib/selectors/index.js +13 -96
- package/lib/selectors/index.js.map +1 -1
- package/lib/utils/index.cjs +4 -4
- package/lib/utils/index.cjs.map +1 -1
- package/lib/utils/index.d.cts +5297 -1178
- package/lib/utils/index.d.ts +5297 -1178
- package/lib/utils/index.js +3 -4
- package/lib/utils/index.js.map +1 -1
- package/package.json +15 -14
- package/src/behavior-actions/behavior.action.blur.ts +8 -0
- package/src/behavior-actions/behavior.action.decorator.add.ts +2 -1
- package/src/behavior-actions/behavior.action.delete.backward.ts +7 -0
- package/src/behavior-actions/behavior.action.delete.block.ts +24 -0
- package/src/behavior-actions/behavior.action.delete.forward.ts +7 -0
- package/src/behavior-actions/behavior.action.delete.text.ts +2 -1
- package/src/behavior-actions/behavior.action.delete.ts +1 -3
- package/src/behavior-actions/behavior.action.deserialization.failure.ts +9 -0
- package/src/behavior-actions/behavior.action.deserialization.success.ts +16 -0
- package/src/behavior-actions/behavior.action.effect.ts +7 -0
- package/src/behavior-actions/behavior.action.focus.ts +8 -0
- package/src/behavior-actions/behavior.action.insert-blocks.ts +118 -74
- package/src/behavior-actions/behavior.action.insert-break.ts +1 -0
- package/src/behavior-actions/{behavior.action.insert-block-object.ts → behavior.action.insert.block-object.ts} +9 -14
- package/src/behavior-actions/behavior.action.insert.block.ts +247 -2
- package/src/behavior-actions/behavior.action.insert.text-block.ts +33 -0
- package/src/behavior-actions/behavior.action.insert.text.ts +7 -0
- package/src/behavior-actions/behavior.action.move.block-down.ts +48 -0
- package/src/behavior-actions/behavior.action.move.block-up.ts +53 -0
- package/src/behavior-actions/behavior.action.move.block.ts +16 -0
- package/src/behavior-actions/behavior.action.noop.ts +5 -0
- package/src/behavior-actions/behavior.action.select.next-block.ts +44 -0
- package/src/behavior-actions/behavior.action.select.previous-block.ts +48 -0
- package/src/behavior-actions/behavior.action.select.ts +15 -0
- package/src/behavior-actions/behavior.action.serialization.failure.ts +9 -0
- package/src/behavior-actions/behavior.action.serialization.success.ts +14 -0
- package/src/behavior-actions/behavior.actions.ts +54 -212
- package/src/behaviors/behavior.core.block-objects.ts +35 -6
- package/src/behaviors/behavior.core.insert-break.ts +1 -0
- package/src/behaviors/behavior.core.ts +2 -0
- package/src/behaviors/behavior.default.ts +241 -33
- package/src/behaviors/behavior.types.ts +138 -20
- package/src/converters/converter.portable-text.ts +5 -2
- package/src/converters/converter.text-html.serialize.test.ts +4 -4
- package/src/converters/converter.text-html.ts +5 -2
- package/src/converters/converter.text-plain.test.ts +6 -6
- package/src/converters/converter.text-plain.ts +5 -2
- package/src/converters/converter.types.ts +3 -3
- package/src/editor/Editable.tsx +403 -48
- package/src/editor/components/Element.tsx +133 -18
- package/src/editor/components/use-draggable.ts +34 -102
- package/src/editor/editor-machine.ts +66 -10
- package/src/editor/editor-selector.ts +2 -0
- package/src/editor/editor-snapshot.ts +17 -0
- package/src/editor/plugins/create-with-event-listeners.ts +6 -40
- package/src/internal-utils/create-test-snapshot.ts +2 -0
- package/src/internal-utils/event-position.ts +210 -0
- package/src/internal-utils/slate-utils.ts +56 -0
- package/src/internal-utils/weakMaps.ts +1 -15
- package/src/selectors/index.ts +2 -0
- package/src/selectors/selector.get-focus-inline-object.ts +21 -0
- package/src/selectors/selector.is-overlapping-selection.test.ts +171 -0
- package/src/selectors/selector.is-overlapping-selection.ts +108 -4
- package/src/selectors/selector.is-point-after-selection.ts +3 -1
- package/src/selectors/selector.is-point-before-selection.ts +3 -1
- package/src/selectors/selector.is-selecting-entire-blocks.ts +34 -0
- package/lib/_chunks-cjs/selector.is-active-style.cjs.map +0 -1
- package/lib/_chunks-cjs/util.block-offsets-to-selection.cjs.map +0 -1
- package/lib/_chunks-cjs/util.reverse-selection.cjs +0 -14
- package/lib/_chunks-cjs/util.reverse-selection.cjs.map +0 -1
- package/lib/_chunks-es/selector.is-active-style.js.map +0 -1
- package/lib/_chunks-es/util.block-offsets-to-selection.js.map +0 -1
- package/lib/_chunks-es/util.reverse-selection.js +0 -15
- package/lib/_chunks-es/util.reverse-selection.js.map +0 -1
- package/src/behavior-actions/behavior.action-utils.insert-block.ts +0 -61
- package/src/editor/__tests__/handleClick.test.tsx +0 -277
- package/src/editor/components/use-droppable.ts +0 -135
package/lib/utils/index.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { isKeyedSegment, sliceBlocks, isSpan } from "../_chunks-es/util.slice-blocks.js";
|
|
2
|
-
import { blockOffsetToSpanSelectionPoint, getBlockEndPoint, getBlockStartPoint, getTextBlockText, isEmptyTextBlock, isEqualSelectionPoints, spanSelectionPointToBlockOffset } from "../_chunks-es/util.slice-blocks.js";
|
|
3
|
-
import { parseBlock } from "../_chunks-es/
|
|
4
|
-
import { blockOffsetsToSelection } from "../_chunks-es/
|
|
2
|
+
import { blockOffsetToSpanSelectionPoint, getBlockEndPoint, getBlockStartPoint, getTextBlockText, isEmptyTextBlock, isEqualSelectionPoints, reverseSelection, spanSelectionPointToBlockOffset } from "../_chunks-es/util.slice-blocks.js";
|
|
3
|
+
import { parseBlock } from "../_chunks-es/parse-blocks.js";
|
|
4
|
+
import { blockOffsetsToSelection } from "../_chunks-es/parse-blocks.js";
|
|
5
5
|
import { isPortableTextTextBlock, isPortableTextSpan } from "@sanity/types";
|
|
6
|
-
import { reverseSelection } from "../_chunks-es/util.reverse-selection.js";
|
|
7
6
|
function childSelectionPointToBlockOffset({
|
|
8
7
|
value,
|
|
9
8
|
selectionPoint
|
package/lib/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/utils/util.child-selection-point-to-block-offset.ts","../../src/utils/util.is-text-block.ts","../../src/utils/util.merge-text-blocks.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import {\n isPortableTextSpan,\n isPortableTextTextBlock,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {isKeyedSegment} from './util.is-keyed-segment'\n\n/**\n * @public\n */\nexport function childSelectionPointToBlockOffset({\n value,\n selectionPoint,\n}: {\n value: Array<PortableTextBlock>\n selectionPoint: EditorSelectionPoint\n}): BlockOffset | undefined {\n let offset = 0\n\n const blockKey = isKeyedSegment(selectionPoint.path[0])\n ? selectionPoint.path[0]._key\n : undefined\n const childKey = isKeyedSegment(selectionPoint.path[2])\n ? selectionPoint.path[2]._key\n : undefined\n\n if (!blockKey || !childKey) {\n return undefined\n }\n\n for (const block of value) {\n if (block._key !== blockKey) {\n continue\n }\n\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n for (const child of block.children) {\n if (child._key === childKey) {\n return {\n path: [{_key: block._key}],\n offset: offset + selectionPoint.offset,\n }\n }\n\n if (isPortableTextSpan(child)) {\n offset += child.text.length\n }\n }\n }\n}\n","import type {PortableTextBlock, PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '..'\n\n/**\n * @public\n */\nexport function isTextBlock(\n context: Pick<EditorContext, 'schema'>,\n block: PortableTextBlock,\n): block is PortableTextTextBlock {\n return block._type === context.schema.block.name\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '..'\nimport {parseBlock} from '../internal-utils/parse-blocks'\nimport {isTextBlock} from './util.is-text-block'\n\n/**\n * @beta\n */\nexport function mergeTextBlocks({\n context,\n targetBlock,\n incomingBlock,\n}: {\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n targetBlock: PortableTextTextBlock\n incomingBlock: PortableTextTextBlock\n}) {\n const parsedIncomingBlock = parseBlock({\n context,\n block: incomingBlock,\n options: {refreshKeys: true},\n })\n\n if (!parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock)) {\n return targetBlock\n }\n\n return {\n ...targetBlock,\n children: [...targetBlock.children, ...parsedIncomingBlock.children],\n markDefs: [\n ...(targetBlock.markDefs ?? []),\n ...(parsedIncomingBlock.markDefs ?? []),\n ],\n }\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":["childSelectionPointToBlockOffset","value","selectionPoint","offset","blockKey","isKeyedSegment","path","_key","undefined","childKey","block","isPortableTextTextBlock","child","children","isPortableTextSpan","text","length","isTextBlock","context","_type","schema","name","mergeTextBlocks","targetBlock","incomingBlock","parsedIncomingBlock","parseBlock","options","refreshKeys","markDefs","splitTextBlock","point","firstChild","at","lastChild","before","sliceBlocks","blocks","selection","anchor","focus","after","isSpan"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/utils/util.child-selection-point-to-block-offset.ts","../../src/utils/util.is-text-block.ts","../../src/utils/util.merge-text-blocks.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import {\n isPortableTextSpan,\n isPortableTextTextBlock,\n type PortableTextBlock,\n} from '@sanity/types'\nimport type {BlockOffset} from '../types/block-offset'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {isKeyedSegment} from './util.is-keyed-segment'\n\n/**\n * @public\n */\nexport function childSelectionPointToBlockOffset({\n value,\n selectionPoint,\n}: {\n value: Array<PortableTextBlock>\n selectionPoint: EditorSelectionPoint\n}): BlockOffset | undefined {\n let offset = 0\n\n const blockKey = isKeyedSegment(selectionPoint.path[0])\n ? selectionPoint.path[0]._key\n : undefined\n const childKey = isKeyedSegment(selectionPoint.path[2])\n ? selectionPoint.path[2]._key\n : undefined\n\n if (!blockKey || !childKey) {\n return undefined\n }\n\n for (const block of value) {\n if (block._key !== blockKey) {\n continue\n }\n\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n for (const child of block.children) {\n if (child._key === childKey) {\n return {\n path: [{_key: block._key}],\n offset: offset + selectionPoint.offset,\n }\n }\n\n if (isPortableTextSpan(child)) {\n offset += child.text.length\n }\n }\n }\n}\n","import type {PortableTextBlock, PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '..'\n\n/**\n * @public\n */\nexport function isTextBlock(\n context: Pick<EditorContext, 'schema'>,\n block: PortableTextBlock,\n): block is PortableTextTextBlock {\n return block._type === context.schema.block.name\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport type {EditorContext} from '..'\nimport {parseBlock} from '../internal-utils/parse-blocks'\nimport {isTextBlock} from './util.is-text-block'\n\n/**\n * @beta\n */\nexport function mergeTextBlocks({\n context,\n targetBlock,\n incomingBlock,\n}: {\n context: Pick<EditorContext, 'keyGenerator' | 'schema'>\n targetBlock: PortableTextTextBlock\n incomingBlock: PortableTextTextBlock\n}) {\n const parsedIncomingBlock = parseBlock({\n context,\n block: incomingBlock,\n options: {refreshKeys: true},\n })\n\n if (!parsedIncomingBlock || !isTextBlock(context, parsedIncomingBlock)) {\n return targetBlock\n }\n\n return {\n ...targetBlock,\n children: [...targetBlock.children, ...parsedIncomingBlock.children],\n markDefs: [\n ...(targetBlock.markDefs ?? []),\n ...(parsedIncomingBlock.markDefs ?? []),\n ],\n }\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":["childSelectionPointToBlockOffset","value","selectionPoint","offset","blockKey","isKeyedSegment","path","_key","undefined","childKey","block","isPortableTextTextBlock","child","children","isPortableTextSpan","text","length","isTextBlock","context","_type","schema","name","mergeTextBlocks","targetBlock","incomingBlock","parsedIncomingBlock","parseBlock","options","refreshKeys","markDefs","splitTextBlock","point","firstChild","at","lastChild","before","sliceBlocks","blocks","selection","anchor","focus","after","isSpan"],"mappings":";;;;;AAYO,SAASA,iCAAiC;AAAA,EAC/CC;AAAAA,EACAC;AAIF,GAA4B;AAC1B,MAAIC,SAAS;AAEPC,QAAAA,WAAWC,eAAeH,eAAeI,KAAK,CAAC,CAAC,IAClDJ,eAAeI,KAAK,CAAC,EAAEC,OACvBC,QACEC,WAAWJ,eAAeH,eAAeI,KAAK,CAAC,CAAC,IAClDJ,eAAeI,KAAK,CAAC,EAAEC,OACvBC;AAEA,MAAA,EAAA,CAACJ,YAAY,CAACK;AAIlB,eAAWC,SAAST;AAClB,UAAIS,MAAMH,SAASH,YAIdO,wBAAwBD,KAAK;AAIvBE,mBAAAA,SAASF,MAAMG,UAAU;AAClC,cAAID,MAAML,SAASE;AACV,mBAAA;AAAA,cACLH,MAAM,CAAC;AAAA,gBAACC,MAAMG,MAAMH;AAAAA,cAAAA,CAAK;AAAA,cACzBJ,QAAQA,SAASD,eAAeC;AAAAA,YAClC;AAGEW,6BAAmBF,KAAK,MAC1BT,UAAUS,MAAMG,KAAKC;AAAAA,QAAAA;AAAAA;AAI7B;AChDgBC,SAAAA,YACdC,SACAR,OACgC;AAChC,SAAOA,MAAMS,UAAUD,QAAQE,OAAOV,MAAMW;AAC9C;ACHO,SAASC,gBAAgB;AAAA,EAC9BJ;AAAAA,EACAK;AAAAA,EACAC;AAKF,GAAG;AACD,QAAMC,sBAAsBC,WAAW;AAAA,IACrCR;AAAAA,IACAR,OAAOc;AAAAA,IACPG,SAAS;AAAA,MAACC,aAAa;AAAA,IAAA;AAAA,EAAI,CAC5B;AAED,SAAI,CAACH,uBAAuB,CAACR,YAAYC,SAASO,mBAAmB,IAC5DF,cAGF;AAAA,IACL,GAAGA;AAAAA,IACHV,UAAU,CAAC,GAAGU,YAAYV,UAAU,GAAGY,oBAAoBZ,QAAQ;AAAA,IACnEgB,UAAU,CACR,GAAIN,YAAYM,YAAY,CAAA,GAC5B,GAAIJ,oBAAoBI,YAAY,CAAG,CAAA;AAAA,EAE3C;AACF;ACzBO,SAASC,eAAe;AAAA,EAC7BZ;AAAAA,EACAR;AAAAA,EACAqB;AAKF,GAA8E;AAC5E,QAAMC,aAAatB,MAAMG,SAASoB,GAAG,CAAC,GAChCC,YAAYxB,MAAMG,SAASoB,GAAGvB,MAAMG,SAASG,SAAS,CAAC;AAEzD,MAAA,CAACgB,cAAc,CAACE;AAClB;AAGF,QAAMC,SAASC,YAAY;AAAA,IACzBC,QAAQ,CAAC3B,KAAK;AAAA,IACd4B,WAAW;AAAA,MACTC,QAAQ;AAAA,QACNjC,MAAM,CAAC;AAAA,UAACC,MAAMG,MAAMH;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMyB,WAAWzB;AAAAA,QAAAA,CAAK;AAAA,QAC9DJ,QAAQ;AAAA,MACV;AAAA,MACAqC,OAAOT;AAAAA,IAAAA;AAAAA,EAEV,CAAA,EAAEE,GAAG,CAAC,GACDQ,QAAQL,YAAY;AAAA,IACxBC,QAAQ,CAAC3B,KAAK;AAAA,IACd4B,WAAW;AAAA,MACTC,QAAQR;AAAAA,MACRS,OAAO;AAAA,QACLlC,MAAM,CAAC;AAAA,UAACC,MAAMG,MAAMH;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAM2B,UAAU3B;AAAAA,QAAAA,CAAK;AAAA,QAC7DJ,QAAQuC,OAAOxB,SAASgB,SAAS,IAAIA,UAAUnB,KAAKC,SAAS;AAAA,MAAA;AAAA,IAC/D;AAAA,EACF,CACD,EAAEiB,GAAG,CAAC;AAEP,MAAI,EAACE,CAAAA,UAAU,CAACM,UAIZ,EAACxB,CAAAA,YAAYC,SAASiB,MAAM,KAAK,CAAClB,YAAYC,SAASuB,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.
|
|
3
|
+
"version": "1.38.0",
|
|
4
4
|
"description": "Portable Text Editor made in React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -68,26 +68,26 @@
|
|
|
68
68
|
],
|
|
69
69
|
"dependencies": {
|
|
70
70
|
"@portabletext/to-html": "^2.0.14",
|
|
71
|
-
"@xstate/react": "^5.0.
|
|
71
|
+
"@xstate/react": "^5.0.3",
|
|
72
72
|
"debug": "^4.4.0",
|
|
73
73
|
"get-random-values-esm": "^1.0.2",
|
|
74
74
|
"lodash": "^4.17.21",
|
|
75
75
|
"lodash.startcase": "^4.4.0",
|
|
76
|
-
"react-compiler-runtime": "19.0.0-beta-
|
|
76
|
+
"react-compiler-runtime": "19.0.0-beta-e1e972c-20250221",
|
|
77
77
|
"slate": "0.112.0",
|
|
78
78
|
"slate-dom": "^0.112.2",
|
|
79
79
|
"slate-react": "0.112.1",
|
|
80
80
|
"use-effect-event": "^1.0.2",
|
|
81
81
|
"xstate": "^5.19.2",
|
|
82
|
-
"@portabletext/block-tools": "1.1.
|
|
82
|
+
"@portabletext/block-tools": "1.1.13",
|
|
83
83
|
"@portabletext/patches": "1.1.3"
|
|
84
84
|
},
|
|
85
85
|
"devDependencies": {
|
|
86
86
|
"@portabletext/toolkit": "^2.0.17",
|
|
87
87
|
"@sanity/diff-match-patch": "^3.2.0",
|
|
88
88
|
"@sanity/pkg-utils": "^7.0.4",
|
|
89
|
-
"@sanity/schema": "^3.
|
|
90
|
-
"@sanity/types": "^3.
|
|
89
|
+
"@sanity/schema": "^3.79.0",
|
|
90
|
+
"@sanity/types": "^3.79.0",
|
|
91
91
|
"@testing-library/jest-dom": "^6.6.3",
|
|
92
92
|
"@testing-library/react": "^16.2.0",
|
|
93
93
|
"@types/debug": "^4.1.12",
|
|
@@ -98,11 +98,11 @@
|
|
|
98
98
|
"@typescript-eslint/eslint-plugin": "^8.18.1",
|
|
99
99
|
"@typescript-eslint/parser": "^8.18.1",
|
|
100
100
|
"@vitejs/plugin-react": "^4.3.4",
|
|
101
|
-
"@vitest/browser": "^3.0.
|
|
102
|
-
"@vitest/coverage-istanbul": "^3.0.
|
|
103
|
-
"babel-plugin-react-compiler": "19.0.0-beta-
|
|
101
|
+
"@vitest/browser": "^3.0.8",
|
|
102
|
+
"@vitest/coverage-istanbul": "^3.0.8",
|
|
103
|
+
"babel-plugin-react-compiler": "19.0.0-beta-bafa41b-20250307",
|
|
104
104
|
"eslint": "8.57.1",
|
|
105
|
-
"eslint-plugin-react-compiler": "19.0.0-beta-
|
|
105
|
+
"eslint-plugin-react-compiler": "19.0.0-beta-bafa41b-20250307",
|
|
106
106
|
"eslint-plugin-react-hooks": "experimental",
|
|
107
107
|
"jsdom": "^26.0.0",
|
|
108
108
|
"react": "^19.0.0",
|
|
@@ -110,13 +110,13 @@
|
|
|
110
110
|
"rxjs": "^7.8.2",
|
|
111
111
|
"typescript": "5.7.3",
|
|
112
112
|
"vite": "^6.2.0",
|
|
113
|
-
"vitest": "^3.0.
|
|
113
|
+
"vitest": "^3.0.8",
|
|
114
114
|
"vitest-browser-react": "^0.1.1",
|
|
115
|
-
"racejar": "1.2.
|
|
115
|
+
"racejar": "1.2.2"
|
|
116
116
|
},
|
|
117
117
|
"peerDependencies": {
|
|
118
|
-
"@sanity/schema": "^3.
|
|
119
|
-
"@sanity/types": "^3.
|
|
118
|
+
"@sanity/schema": "^3.79.0",
|
|
119
|
+
"@sanity/types": "^3.79.0",
|
|
120
120
|
"react": "^16.9 || ^17 || ^18 || ^19",
|
|
121
121
|
"rxjs": "^7.8.2"
|
|
122
122
|
},
|
|
@@ -138,6 +138,7 @@
|
|
|
138
138
|
"test": "vitest --run",
|
|
139
139
|
"test:watch": "vitest",
|
|
140
140
|
"test:e2e:chromium": "vitest --run --project \"browser.bak (chromium)\"",
|
|
141
|
+
"test:e2e:chromium:watch": "vitest --project \"browser.bak (chromium)\"",
|
|
141
142
|
"test:browser": "vitest --run --project browser",
|
|
142
143
|
"test:browser:watch": "vitest --project browser",
|
|
143
144
|
"test:browser:chromium": "vitest --run --project \"browser (chromium)\"",
|
|
@@ -88,11 +88,12 @@ export const decoratorAddActionImplementation: BehaviorActionImplementation<
|
|
|
88
88
|
})
|
|
89
89
|
|
|
90
90
|
const trimmedSelection = selectors.getTrimmedSelection({
|
|
91
|
-
beta: {hasTag: () => false},
|
|
91
|
+
beta: {hasTag: () => false, internalDrag: undefined},
|
|
92
92
|
context: {
|
|
93
93
|
activeDecorators: [],
|
|
94
94
|
converters: [],
|
|
95
95
|
keyGenerator: context.keyGenerator,
|
|
96
|
+
readOnly: false,
|
|
96
97
|
schema: context.schema,
|
|
97
98
|
selection: newSelection,
|
|
98
99
|
value: newValue,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import {Transforms} from 'slate'
|
|
2
|
+
import {toSlateRange} from '../internal-utils/ranges'
|
|
3
|
+
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
4
|
+
|
|
5
|
+
export const deleteBlockActionImplementation: BehaviorActionImplementation<
|
|
6
|
+
'delete.block'
|
|
7
|
+
> = ({action}) => {
|
|
8
|
+
const range = toSlateRange(
|
|
9
|
+
{
|
|
10
|
+
anchor: {path: action.blockPath, offset: 0},
|
|
11
|
+
focus: {path: action.blockPath, offset: 0},
|
|
12
|
+
},
|
|
13
|
+
action.editor,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
if (!range) {
|
|
17
|
+
console.error('Unable to find Slate range from selection points')
|
|
18
|
+
return
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
Transforms.removeNodes(action.editor, {
|
|
22
|
+
at: range,
|
|
23
|
+
})
|
|
24
|
+
}
|
|
@@ -28,12 +28,13 @@ export const deleteTextActionImplementation: BehaviorActionImplementation<
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
const trimmedSelection = selectors.getTrimmedSelection({
|
|
31
|
-
beta: {hasTag: () => false},
|
|
31
|
+
beta: {hasTag: () => false, internalDrag: undefined},
|
|
32
32
|
context: {
|
|
33
33
|
converters: [],
|
|
34
34
|
schema: context.schema,
|
|
35
35
|
keyGenerator: context.keyGenerator,
|
|
36
36
|
activeDecorators: [],
|
|
37
|
+
readOnly: false,
|
|
37
38
|
value,
|
|
38
39
|
selection,
|
|
39
40
|
},
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {deleteFragment, select} from 'slate'
|
|
2
1
|
import {toSlateRange} from '../internal-utils/ranges'
|
|
3
2
|
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
4
3
|
|
|
@@ -13,6 +12,5 @@ export const deleteActionImplementation: BehaviorActionImplementation<
|
|
|
13
12
|
)
|
|
14
13
|
}
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
deleteFragment(action.editor)
|
|
15
|
+
action.editor.delete({at: range})
|
|
18
16
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
2
|
+
|
|
3
|
+
export const deserializationFailureActionImplementation: BehaviorActionImplementation<
|
|
4
|
+
'deserialization.failure'
|
|
5
|
+
> = ({action}) => {
|
|
6
|
+
console.warn(
|
|
7
|
+
`Deserialization of ${action.mimeType} failed with reason "${action.reason}"`,
|
|
8
|
+
)
|
|
9
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {insertBlocksActionImplementation} from './behavior.action.insert-blocks'
|
|
2
|
+
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
3
|
+
|
|
4
|
+
export const deserializationSuccessActionImplementation: BehaviorActionImplementation<
|
|
5
|
+
'deserialization.success'
|
|
6
|
+
> = ({context, action}) => {
|
|
7
|
+
insertBlocksActionImplementation({
|
|
8
|
+
context,
|
|
9
|
+
action: {
|
|
10
|
+
type: 'insert.blocks',
|
|
11
|
+
blocks: action.data,
|
|
12
|
+
editor: action.editor,
|
|
13
|
+
placement: 'auto',
|
|
14
|
+
},
|
|
15
|
+
})
|
|
16
|
+
}
|
|
@@ -1,92 +1,136 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import {parseBlocks} from '../internal-utils/parse-blocks'
|
|
2
|
+
import {getFocusBlock} from '../internal-utils/slate-utils'
|
|
3
|
+
import {toSlateValue} from '../internal-utils/values'
|
|
4
|
+
import {insertBreakActionImplementation} from './behavior.action.insert-break'
|
|
5
|
+
import {insertBlock} from './behavior.action.insert.block'
|
|
6
|
+
import {selectNextBlockActionImplementation} from './behavior.action.select.next-block'
|
|
7
|
+
import {selectPreviousBlockActionImplementation} from './behavior.action.select.previous-block'
|
|
4
8
|
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
5
9
|
|
|
6
10
|
export const insertBlocksActionImplementation: BehaviorActionImplementation<
|
|
7
11
|
'insert.blocks'
|
|
8
12
|
> = ({context, action}) => {
|
|
9
|
-
const
|
|
13
|
+
const parsedBlocks = parseBlocks({
|
|
14
|
+
context,
|
|
15
|
+
blocks: action.blocks,
|
|
16
|
+
options: {refreshKeys: false},
|
|
17
|
+
})
|
|
10
18
|
|
|
11
|
-
if (
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
at: Editor.start(action.editor, []),
|
|
15
|
-
})
|
|
16
|
-
return
|
|
17
|
-
}
|
|
19
|
+
if (parsedBlocks.length === 0) {
|
|
20
|
+
throw new Error(`Failed to parse blocks ${JSON.stringify(action.blocks)}`)
|
|
21
|
+
}
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
action.editor.insertFragment(fragment, {
|
|
21
|
-
at: Editor.end(action.editor, []),
|
|
22
|
-
})
|
|
23
|
-
return
|
|
24
|
-
}
|
|
23
|
+
const fragment = toSlateValue(parsedBlocks, {schemaTypes: context.schema})
|
|
25
24
|
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
if (fragment.length === 0) {
|
|
26
|
+
throw new Error(
|
|
27
|
+
`Failed to convert blocks to Slate fragment ${JSON.stringify(
|
|
28
|
+
parsedBlocks,
|
|
29
|
+
)}`,
|
|
30
|
+
)
|
|
28
31
|
}
|
|
29
32
|
|
|
30
|
-
const [focusBlock
|
|
31
|
-
action.editor,
|
|
32
|
-
action.editor.selection,
|
|
33
|
-
{
|
|
34
|
-
depth: 1,
|
|
35
|
-
},
|
|
36
|
-
)
|
|
33
|
+
const [focusBlock] = getFocusBlock({editor: action.editor})
|
|
37
34
|
|
|
38
|
-
if (action.placement === 'before'
|
|
39
|
-
|
|
40
|
-
return
|
|
41
|
-
}
|
|
35
|
+
if (action.placement === 'before') {
|
|
36
|
+
let index = 0
|
|
42
37
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
38
|
+
for (const block of fragment) {
|
|
39
|
+
insertBlock({
|
|
40
|
+
block,
|
|
41
|
+
placement: index === 0 ? 'before' : 'after',
|
|
42
|
+
select: 'end',
|
|
43
|
+
editor: action.editor,
|
|
44
|
+
schema: context.schema,
|
|
45
|
+
})
|
|
52
46
|
|
|
53
|
-
|
|
54
|
-
if (
|
|
55
|
-
action.editor.isTextBlock(focusBlock) &&
|
|
56
|
-
action.editor.isTextBlock(fragment[0])
|
|
57
|
-
) {
|
|
58
|
-
const {markDefs} = focusBlock
|
|
59
|
-
if (!isEqual(markDefs, fragment[0].markDefs)) {
|
|
60
|
-
Transforms.setNodes(
|
|
61
|
-
action.editor,
|
|
62
|
-
{
|
|
63
|
-
markDefs: uniq([
|
|
64
|
-
...(fragment[0].markDefs || []),
|
|
65
|
-
...(markDefs || []),
|
|
66
|
-
]),
|
|
67
|
-
},
|
|
68
|
-
{at: focusPath, mode: 'lowest', voids: false},
|
|
69
|
-
)
|
|
47
|
+
index++
|
|
70
48
|
}
|
|
71
|
-
}
|
|
49
|
+
} else if (action.placement === 'after') {
|
|
50
|
+
for (const block of fragment) {
|
|
51
|
+
insertBlock({
|
|
52
|
+
block,
|
|
53
|
+
placement: 'after',
|
|
54
|
+
select: 'end',
|
|
55
|
+
editor: action.editor,
|
|
56
|
+
schema: context.schema,
|
|
57
|
+
})
|
|
58
|
+
}
|
|
59
|
+
} else {
|
|
60
|
+
if (focusBlock && action.editor.isTextBlock(focusBlock)) {
|
|
61
|
+
if (fragment.length === 1) {
|
|
62
|
+
insertBlock({
|
|
63
|
+
block: fragment[0],
|
|
64
|
+
placement: 'auto',
|
|
65
|
+
select: 'end',
|
|
66
|
+
editor: action.editor,
|
|
67
|
+
schema: context.schema,
|
|
68
|
+
})
|
|
72
69
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
context.schema,
|
|
76
|
-
)
|
|
70
|
+
return
|
|
71
|
+
}
|
|
77
72
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
73
|
+
let index = 0
|
|
74
|
+
|
|
75
|
+
for (const block of fragment) {
|
|
76
|
+
if (index === 0) {
|
|
77
|
+
insertBreakActionImplementation({
|
|
78
|
+
context,
|
|
79
|
+
action: {type: 'insert.break', editor: action.editor},
|
|
80
|
+
})
|
|
81
|
+
selectPreviousBlockActionImplementation({
|
|
82
|
+
context,
|
|
83
|
+
action: {
|
|
84
|
+
type: 'select.previous block',
|
|
85
|
+
editor: action.editor,
|
|
86
|
+
select: 'end',
|
|
87
|
+
},
|
|
88
|
+
})
|
|
89
|
+
insertBlock({
|
|
90
|
+
block,
|
|
91
|
+
placement: 'auto',
|
|
92
|
+
select: 'end',
|
|
93
|
+
editor: action.editor,
|
|
94
|
+
schema: context.schema,
|
|
95
|
+
})
|
|
96
|
+
} else if (index === fragment.length - 1) {
|
|
97
|
+
selectNextBlockActionImplementation({
|
|
98
|
+
context,
|
|
99
|
+
action: {
|
|
100
|
+
type: 'select.next block',
|
|
101
|
+
editor: action.editor,
|
|
102
|
+
select: 'start',
|
|
103
|
+
},
|
|
104
|
+
})
|
|
105
|
+
insertBlock({
|
|
106
|
+
block,
|
|
107
|
+
placement: 'auto',
|
|
108
|
+
select: 'end',
|
|
109
|
+
editor: action.editor,
|
|
110
|
+
schema: context.schema,
|
|
111
|
+
})
|
|
112
|
+
} else {
|
|
113
|
+
insertBlock({
|
|
114
|
+
block,
|
|
115
|
+
placement: 'after',
|
|
116
|
+
select: 'end',
|
|
117
|
+
editor: action.editor,
|
|
118
|
+
schema: context.schema,
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
index++
|
|
123
|
+
}
|
|
124
|
+
} else {
|
|
125
|
+
for (const block of fragment) {
|
|
126
|
+
insertBlock({
|
|
127
|
+
block,
|
|
128
|
+
placement: 'auto',
|
|
129
|
+
select: 'end',
|
|
130
|
+
editor: action.editor,
|
|
131
|
+
schema: context.schema,
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
}
|
|
91
135
|
}
|
|
92
136
|
}
|
|
@@ -1,25 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {insertBlock} from './behavior.action-utils.insert-block'
|
|
1
|
+
import {insertBlockActionImplementation} from './behavior.action.insert.block'
|
|
3
2
|
import type {BehaviorActionImplementation} from './behavior.actions'
|
|
4
3
|
|
|
5
4
|
export const insertBlockObjectActionImplementation: BehaviorActionImplementation<
|
|
6
5
|
'insert.block object'
|
|
7
6
|
> = ({context, action}) => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
insertBlockActionImplementation({
|
|
8
|
+
context,
|
|
9
|
+
action: {
|
|
10
|
+
type: 'insert.block',
|
|
11
|
+
block: {
|
|
11
12
|
_key: context.keyGenerator(),
|
|
12
13
|
_type: action.blockObject.name,
|
|
13
14
|
...(action.blockObject.value ? action.blockObject.value : {}),
|
|
14
15
|
},
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
insertBlock({
|
|
20
|
-
block,
|
|
21
|
-
placement: action.placement,
|
|
22
|
-
editor: action.editor,
|
|
23
|
-
schema: context.schema,
|
|
16
|
+
editor: action.editor,
|
|
17
|
+
placement: action.placement,
|
|
18
|
+
},
|
|
24
19
|
})
|
|
25
20
|
}
|