@portabletext/editor 1.40.3 → 1.40.4

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.
@@ -1,12 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var util_sliceBlocks = require("../_chunks-cjs/util.slice-blocks.cjs"), util_selectionPointToBlockOffset = require("../_chunks-cjs/util.selection-point-to-block-offset.cjs"), util_mergeTextBlocks = require("../_chunks-cjs/util.merge-text-blocks.cjs");
3
+ var util_sliceBlocks = require("../_chunks-cjs/util.slice-blocks.cjs"), util_selectionPointToBlockOffset = require("../_chunks-cjs/util.selection-point-to-block-offset.cjs"), util_isSelectionCollapsed = require("../_chunks-cjs/util.is-selection-collapsed.cjs"), util_mergeTextBlocks = require("../_chunks-cjs/util.merge-text-blocks.cjs");
4
4
  function isEqualSelections(a, b) {
5
5
  return !a && !b ? !0 : !a || !b ? !1 : util_sliceBlocks.isEqualSelectionPoints(a.anchor, b.anchor) && util_sliceBlocks.isEqualSelectionPoints(a.focus, b.focus);
6
6
  }
7
- function isSelectionCollapsed(selection) {
8
- return selection ? selection.anchor.path.join() === selection.focus.path.join() && selection.anchor.offset === selection.focus.offset : !1;
9
- }
10
7
  function splitTextBlock({
11
8
  context,
12
9
  block,
@@ -64,9 +61,9 @@ exports.blockOffsetToSelectionPoint = util_selectionPointToBlockOffset.blockOffs
64
61
  exports.blockOffsetsToSelection = util_selectionPointToBlockOffset.blockOffsetsToSelection;
65
62
  exports.childSelectionPointToBlockOffset = util_selectionPointToBlockOffset.childSelectionPointToBlockOffset;
66
63
  exports.selectionPointToBlockOffset = util_selectionPointToBlockOffset.selectionPointToBlockOffset;
64
+ exports.isSelectionCollapsed = util_isSelectionCollapsed.isSelectionCollapsed;
67
65
  exports.isTextBlock = util_mergeTextBlocks.isTextBlock;
68
66
  exports.mergeTextBlocks = util_mergeTextBlocks.mergeTextBlocks;
69
67
  exports.isEqualSelections = isEqualSelections;
70
- exports.isSelectionCollapsed = isSelectionCollapsed;
71
68
  exports.splitTextBlock = splitTextBlock;
72
69
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../../src/utils/util.is-equal-selections.ts","../../src/utils/util.is-selection-collapsed.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {EditorSelection} from '../types/editor'\nimport {isEqualSelectionPoints} from './util.is-equal-selection-points'\n\n/**\n * @public\n */\nexport function isEqualSelections(a: EditorSelection, b: EditorSelection) {\n if (!a && !b) {\n return true\n }\n\n if (!a || !b) {\n return false\n }\n\n return (\n isEqualSelectionPoints(a.anchor, b.anchor) &&\n isEqualSelectionPoints(a.focus, b.focus)\n )\n}\n","import type {EditorSelection} from '../types/editor'\n\n/**\n * @public\n */\nexport function isSelectionCollapsed(selection: EditorSelection) {\n if (!selection) {\n return false\n }\n\n return (\n selection.anchor.path.join() === selection.focus.path.join() &&\n selection.anchor.offset === selection.focus.offset\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":["isEqualSelections","a","b","isEqualSelectionPoints","anchor","focus","isSelectionCollapsed","selection","path","join","offset","splitTextBlock","context","block","point","firstChild","children","at","lastChild","length","before","sliceBlocks","blocks","_key","after","isSpan","text","isTextBlock"],"mappings":";;;AAMgBA,SAAAA,kBAAkBC,GAAoBC,GAAoB;AACpE,SAAA,CAACD,KAAK,CAACC,IACF,KAGL,CAACD,KAAK,CAACC,IACF,KAIPC,iBAAAA,uBAAuBF,EAAEG,QAAQF,EAAEE,MAAM,KACzCD,wCAAuBF,EAAEI,OAAOH,EAAEG,KAAK;AAE3C;ACdO,SAASC,qBAAqBC,WAA4B;AAC/D,SAAKA,YAKHA,UAAUH,OAAOI,KAAKC,KAAAA,MAAWF,UAAUF,MAAMG,KAAKC,KAAAA,KACtDF,UAAUH,OAAOM,WAAWH,UAAUF,MAAMK,SALrC;AAOX;ACJO,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,MACTH,QAAQ;AAAA,QACNI,MAAM,CAAC;AAAA,UAACe,MAAMV,MAAMU;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMR,WAAWQ;AAAAA,QAAAA,CAAK;AAAA,QAC9Db,QAAQ;AAAA,MACV;AAAA,MACAL,OAAOS;AAAAA,IAAAA;AAAAA,EAEV,CAAA,EAAEG,GAAG,CAAC,GACDO,QAAQH,iBAAAA,YAAY;AAAA,IACxBC,QAAQ,CAACT,KAAK;AAAA,IACdN,WAAW;AAAA,MACTH,QAAQU;AAAAA,MACRT,OAAO;AAAA,QACLG,MAAM,CAAC;AAAA,UAACe,MAAMV,MAAMU;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAML,UAAUK;AAAAA,QAAAA,CAAK;AAAA,QAC7Db,QAAQe,iBAAOb,OAAAA,SAASM,SAAS,IAAIA,UAAUQ,KAAKP,SAAS;AAAA,MAAA;AAAA,IAC/D;AAAA,EACF,CACD,EAAEF,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACI,UAIZ,EAACG,CAAAA,qBAAAA,YAAYf,SAASQ,MAAM,KAAK,CAACO,qBAAYf,YAAAA,SAASY,KAAK;AAIzD,WAAA;AAAA,MAACJ;AAAAA,MAAQI;AAAAA,IAAK;AACvB;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs","sources":["../../src/utils/util.is-equal-selections.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {EditorSelection} from '../types/editor'\nimport {isEqualSelectionPoints} from './util.is-equal-selection-points'\n\n/**\n * @public\n */\nexport function isEqualSelections(a: EditorSelection, b: EditorSelection) {\n if (!a && !b) {\n return true\n }\n\n if (!a || !b) {\n return false\n }\n\n return (\n isEqualSelectionPoints(a.anchor, b.anchor) &&\n isEqualSelectionPoints(a.focus, b.focus)\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":["isEqualSelections","a","b","isEqualSelectionPoints","anchor","focus","splitTextBlock","context","block","point","firstChild","children","at","lastChild","length","before","sliceBlocks","blocks","selection","path","_key","offset","after","isSpan","text","isTextBlock"],"mappings":";;;AAMgBA,SAAAA,kBAAkBC,GAAoBC,GAAoB;AACpE,SAAA,CAACD,KAAK,CAACC,IACF,KAGL,CAACD,KAAK,CAACC,IACF,KAIPC,iBAAAA,uBAAuBF,EAAEG,QAAQF,EAAEE,MAAM,KACzCD,wCAAuBF,EAAEI,OAAOH,EAAEG,KAAK;AAE3C;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,IACdU,WAAW;AAAA,MACTd,QAAQ;AAAA,QACNe,MAAM,CAAC;AAAA,UAACC,MAAMZ,MAAMY;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMV,WAAWU;AAAAA,QAAAA,CAAK;AAAA,QAC9DC,QAAQ;AAAA,MACV;AAAA,MACAhB,OAAOI;AAAAA,IAAAA;AAAAA,EAEV,CAAA,EAAEG,GAAG,CAAC,GACDU,QAAQN,iBAAAA,YAAY;AAAA,IACxBC,QAAQ,CAACT,KAAK;AAAA,IACdU,WAAW;AAAA,MACTd,QAAQK;AAAAA,MACRJ,OAAO;AAAA,QACLc,MAAM,CAAC;AAAA,UAACC,MAAMZ,MAAMY;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMP,UAAUO;AAAAA,QAAAA,CAAK;AAAA,QAC7DC,QAAQE,iBAAOhB,OAAAA,SAASM,SAAS,IAAIA,UAAUW,KAAKV,SAAS;AAAA,MAAA;AAAA,IAC/D;AAAA,EACF,CACD,EAAEF,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACO,UAIZ,EAACG,CAAAA,qBAAAA,YAAYlB,SAASQ,MAAM,KAAK,CAACU,qBAAYlB,YAAAA,SAASe,KAAK;AAIzD,WAAA;AAAA,MAACP;AAAAA,MAAQO;AAAAA,IAAK;AACvB;;;;;;;;;;;;;;;;;;;;;;"}
@@ -6,7 +6,6 @@ import type {
6
6
  BlockStyleDefinition,
7
7
  ObjectSchemaType,
8
8
  Path,
9
- PathSegment,
10
9
  PortableTextChild,
11
10
  PortableTextListBlock,
12
11
  PortableTextTextBlock,
@@ -22139,7 +22138,7 @@ export declare function isEqualSelections(
22139
22138
  * @public
22140
22139
  */
22141
22140
  export declare function isKeyedSegment(
22142
- segment: PathSegment,
22141
+ segment: unknown,
22143
22142
  ): segment is KeyedSegment
22144
22143
 
22145
22144
  /**
@@ -6,7 +6,6 @@ import type {
6
6
  BlockStyleDefinition,
7
7
  ObjectSchemaType,
8
8
  Path,
9
- PathSegment,
10
9
  PortableTextChild,
11
10
  PortableTextListBlock,
12
11
  PortableTextTextBlock,
@@ -22139,7 +22138,7 @@ export declare function isEqualSelections(
22139
22138
  * @public
22140
22139
  */
22141
22140
  export declare function isKeyedSegment(
22142
- segment: PathSegment,
22141
+ segment: unknown,
22143
22142
  ): segment is KeyedSegment
22144
22143
 
22145
22144
  /**
@@ -1,14 +1,12 @@
1
1
  import { isEqualSelectionPoints, sliceBlocks, isSpan } from "../_chunks-es/util.slice-blocks.js";
2
2
  import { blockOffsetToSpanSelectionPoint, getBlockEndPoint, getBlockStartPoint, getTextBlockText, isEmptyTextBlock, 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 { isSelectionCollapsed } from "../_chunks-es/util.is-selection-collapsed.js";
4
5
  import { isTextBlock } from "../_chunks-es/util.merge-text-blocks.js";
5
6
  import { mergeTextBlocks } from "../_chunks-es/util.merge-text-blocks.js";
6
7
  function isEqualSelections(a, b) {
7
8
  return !a && !b ? !0 : !a || !b ? !1 : isEqualSelectionPoints(a.anchor, b.anchor) && isEqualSelectionPoints(a.focus, b.focus);
8
9
  }
9
- function isSelectionCollapsed(selection) {
10
- return selection ? selection.anchor.path.join() === selection.focus.path.join() && selection.anchor.offset === selection.focus.offset : !1;
11
- }
12
10
  function splitTextBlock({
13
11
  context,
14
12
  block,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/utils/util.is-equal-selections.ts","../../src/utils/util.is-selection-collapsed.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {EditorSelection} from '../types/editor'\nimport {isEqualSelectionPoints} from './util.is-equal-selection-points'\n\n/**\n * @public\n */\nexport function isEqualSelections(a: EditorSelection, b: EditorSelection) {\n if (!a && !b) {\n return true\n }\n\n if (!a || !b) {\n return false\n }\n\n return (\n isEqualSelectionPoints(a.anchor, b.anchor) &&\n isEqualSelectionPoints(a.focus, b.focus)\n )\n}\n","import type {EditorSelection} from '../types/editor'\n\n/**\n * @public\n */\nexport function isSelectionCollapsed(selection: EditorSelection) {\n if (!selection) {\n return false\n }\n\n return (\n selection.anchor.path.join() === selection.focus.path.join() &&\n selection.anchor.offset === selection.focus.offset\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":["isEqualSelections","a","b","isEqualSelectionPoints","anchor","focus","isSelectionCollapsed","selection","path","join","offset","splitTextBlock","context","block","point","firstChild","children","at","lastChild","length","before","sliceBlocks","blocks","_key","after","isSpan","text","isTextBlock"],"mappings":";;;;;AAMgBA,SAAAA,kBAAkBC,GAAoBC,GAAoB;AACpE,SAAA,CAACD,KAAK,CAACC,IACF,KAGL,CAACD,KAAK,CAACC,IACF,KAIPC,uBAAuBF,EAAEG,QAAQF,EAAEE,MAAM,KACzCD,uBAAuBF,EAAEI,OAAOH,EAAEG,KAAK;AAE3C;ACdO,SAASC,qBAAqBC,WAA4B;AAC/D,SAAKA,YAKHA,UAAUH,OAAOI,KAAKC,KAAAA,MAAWF,UAAUF,MAAMG,KAAKC,KAAAA,KACtDF,UAAUH,OAAOM,WAAWH,UAAUF,MAAMK,SALrC;AAOX;ACJO,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,MACTH,QAAQ;AAAA,QACNI,MAAM,CAAC;AAAA,UAACe,MAAMV,MAAMU;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMR,WAAWQ;AAAAA,QAAAA,CAAK;AAAA,QAC9Db,QAAQ;AAAA,MACV;AAAA,MACAL,OAAOS;AAAAA,IAAAA;AAAAA,EAEV,CAAA,EAAEG,GAAG,CAAC,GACDO,QAAQH,YAAY;AAAA,IACxBC,QAAQ,CAACT,KAAK;AAAA,IACdN,WAAW;AAAA,MACTH,QAAQU;AAAAA,MACRT,OAAO;AAAA,QACLG,MAAM,CAAC;AAAA,UAACe,MAAMV,MAAMU;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAML,UAAUK;AAAAA,QAAAA,CAAK;AAAA,QAC7Db,QAAQe,OAAOb,SAASM,SAAS,IAAIA,UAAUQ,KAAKP,SAAS;AAAA,MAAA;AAAA,IAC/D;AAAA,EACF,CACD,EAAEF,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACI,UAIZ,EAACG,CAAAA,YAAYf,SAASQ,MAAM,KAAK,CAACO,YAAYf,SAASY,KAAK;AAIzD,WAAA;AAAA,MAACJ;AAAAA,MAAQI;AAAAA,IAAK;AACvB;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/utils/util.is-equal-selections.ts","../../src/utils/util.split-text-block.ts"],"sourcesContent":["import type {EditorSelection} from '../types/editor'\nimport {isEqualSelectionPoints} from './util.is-equal-selection-points'\n\n/**\n * @public\n */\nexport function isEqualSelections(a: EditorSelection, b: EditorSelection) {\n if (!a && !b) {\n return true\n }\n\n if (!a || !b) {\n return false\n }\n\n return (\n isEqualSelectionPoints(a.anchor, b.anchor) &&\n isEqualSelectionPoints(a.focus, b.focus)\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":["isEqualSelections","a","b","isEqualSelectionPoints","anchor","focus","splitTextBlock","context","block","point","firstChild","children","at","lastChild","length","before","sliceBlocks","blocks","selection","path","_key","offset","after","isSpan","text","isTextBlock"],"mappings":";;;;;;AAMgBA,SAAAA,kBAAkBC,GAAoBC,GAAoB;AACpE,SAAA,CAACD,KAAK,CAACC,IACF,KAGL,CAACD,KAAK,CAACC,IACF,KAIPC,uBAAuBF,EAAEG,QAAQF,EAAEE,MAAM,KACzCD,uBAAuBF,EAAEI,OAAOH,EAAEG,KAAK;AAE3C;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,IACdU,WAAW;AAAA,MACTd,QAAQ;AAAA,QACNe,MAAM,CAAC;AAAA,UAACC,MAAMZ,MAAMY;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMV,WAAWU;AAAAA,QAAAA,CAAK;AAAA,QAC9DC,QAAQ;AAAA,MACV;AAAA,MACAhB,OAAOI;AAAAA,IAAAA;AAAAA,EAEV,CAAA,EAAEG,GAAG,CAAC,GACDU,QAAQN,YAAY;AAAA,IACxBC,QAAQ,CAACT,KAAK;AAAA,IACdU,WAAW;AAAA,MACTd,QAAQK;AAAAA,MACRJ,OAAO;AAAA,QACLc,MAAM,CAAC;AAAA,UAACC,MAAMZ,MAAMY;AAAAA,WAAO,YAAY;AAAA,UAACA,MAAMP,UAAUO;AAAAA,QAAAA,CAAK;AAAA,QAC7DC,QAAQE,OAAOhB,SAASM,SAAS,IAAIA,UAAUW,KAAKV,SAAS;AAAA,MAAA;AAAA,IAC/D;AAAA,EACF,CACD,EAAEF,GAAG,CAAC;AAEP,MAAI,EAACG,CAAAA,UAAU,CAACO,UAIZ,EAACG,CAAAA,YAAYlB,SAASQ,MAAM,KAAK,CAACU,YAAYlB,SAASe,KAAK;AAIzD,WAAA;AAAA,MAACP;AAAAA,MAAQO;AAAAA,IAAK;AACvB;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "1.40.3",
3
+ "version": "1.40.4",
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/block-tools": "1.1.14",
83
- "@portabletext/patches": "1.1.3"
82
+ "@portabletext/patches": "1.1.3",
83
+ "@portabletext/block-tools": "1.1.14"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@portabletext/toolkit": "^2.0.17",
@@ -122,14 +122,18 @@ export const insertBlocksActionImplementation: BehaviorActionImplementation<
122
122
  index++
123
123
  }
124
124
  } else {
125
+ let index = 0
126
+
125
127
  for (const block of fragment) {
126
128
  insertBlock({
127
129
  block,
128
- placement: 'auto',
130
+ placement: index === 0 ? 'auto' : 'after',
129
131
  select: 'end',
130
132
  editor: action.editor,
131
133
  schema: context.schema,
132
134
  })
135
+
136
+ index++
133
137
  }
134
138
  }
135
139
  }
@@ -41,10 +41,11 @@ describe(getDragSelection.name, () => {
41
41
  {
42
42
  _key: keyGenerator(),
43
43
  _type: 'span',
44
- text: 'bar',
44
+ text: 'baz',
45
45
  },
46
46
  ],
47
47
  }
48
+ const bazPath = [{_key: baz._key}, 'children', {_key: baz.children[0]._key}]
48
49
  const image = {
49
50
  _key: keyGenerator(),
50
51
  _type: 'image',
@@ -262,6 +263,78 @@ describe(getDragSelection.name, () => {
262
263
  })
263
264
  })
264
265
 
266
+ test('dragging two text blocks with the top drag handle', () => {
267
+ expect(
268
+ getDragSelection({
269
+ eventSelection: {
270
+ anchor: {
271
+ path: fooPath,
272
+ offset: 0,
273
+ },
274
+ focus: {
275
+ path: fooPath,
276
+ offset: 0,
277
+ },
278
+ },
279
+ snapshot: snapshot({
280
+ anchor: {
281
+ path: fooPath,
282
+ offset: 1,
283
+ },
284
+ focus: {
285
+ path: bazPath,
286
+ offset: 3,
287
+ },
288
+ }),
289
+ }),
290
+ ).toEqual({
291
+ anchor: {
292
+ path: fooPath,
293
+ offset: 0,
294
+ },
295
+ focus: {
296
+ path: bazPath,
297
+ offset: 3,
298
+ },
299
+ })
300
+ })
301
+
302
+ test('dragging two text blocks with the bottom drag handle', () => {
303
+ expect(
304
+ getDragSelection({
305
+ eventSelection: {
306
+ anchor: {
307
+ path: bazPath,
308
+ offset: 0,
309
+ },
310
+ focus: {
311
+ path: bazPath,
312
+ offset: 0,
313
+ },
314
+ },
315
+ snapshot: snapshot({
316
+ anchor: {
317
+ path: fooPath,
318
+ offset: 1,
319
+ },
320
+ focus: {
321
+ path: bazPath,
322
+ offset: 3,
323
+ },
324
+ }),
325
+ }),
326
+ ).toEqual({
327
+ anchor: {
328
+ path: fooPath,
329
+ offset: 0,
330
+ },
331
+ focus: {
332
+ path: bazPath,
333
+ offset: 3,
334
+ },
335
+ })
336
+ })
337
+
265
338
  test('dragging a block object with an expanded selected', () => {
266
339
  expect(
267
340
  getDragSelection({
@@ -48,16 +48,32 @@ export function getDragSelection({
48
48
  if (
49
49
  snapshot.context.selection &&
50
50
  selectors.isSelectionExpanded(snapshot) &&
51
- selectors.isOverlappingSelection(eventSelection)(snapshot) &&
52
51
  selectedBlocks.length > 1
53
52
  ) {
54
53
  const selectionStartBlock = selectors.getSelectionStartBlock(snapshot)
55
54
  const selectionEndBlock = selectors.getSelectionEndBlock(snapshot)
56
55
 
57
- if (selectionStartBlock && selectionEndBlock) {
56
+ if (!selectionStartBlock || !selectionEndBlock) {
57
+ return dragSelection
58
+ }
59
+
60
+ const selectionStartPoint = utils.getBlockStartPoint(selectionStartBlock)
61
+ const selectionEndPoint = utils.getBlockEndPoint(selectionEndBlock)
62
+
63
+ const eventSelectionInsideBlocks = selectors.isOverlappingSelection(
64
+ eventSelection,
65
+ )({
66
+ ...snapshot,
67
+ context: {
68
+ ...snapshot.context,
69
+ selection: {anchor: selectionStartPoint, focus: selectionEndPoint},
70
+ },
71
+ })
72
+
73
+ if (eventSelectionInsideBlocks) {
58
74
  dragSelection = {
59
- anchor: utils.getBlockStartPoint(selectionStartBlock),
60
- focus: utils.getBlockEndPoint(selectionEndBlock),
75
+ anchor: selectionStartPoint,
76
+ focus: selectionEndPoint,
61
77
  }
62
78
  }
63
79
  }
@@ -4,6 +4,7 @@ import type {EditorSchema, EditorSelection} from '..'
4
4
  import type {PortableTextSlateEditor} from '../types/editor'
5
5
  import * as utils from '../utils'
6
6
  import {toPortableTextRange} from './ranges'
7
+ import {getNodeBlock} from './slate-utils'
7
8
  import {fromSlateValue} from './values'
8
9
 
9
10
  export type EventPosition = {
@@ -31,6 +32,12 @@ export function getEventPosition({
31
32
  return undefined
32
33
  }
33
34
 
35
+ const block = getNodeBlock({
36
+ editor: slateEditor,
37
+ schema,
38
+ node,
39
+ })
40
+
34
41
  const positionBlock = getEventPositionBlock({node, slateEditor, event})
35
42
  const selection = getEventSelection({
36
43
  schema,
@@ -38,13 +45,7 @@ export function getEventPosition({
38
45
  event,
39
46
  })
40
47
 
41
- if (positionBlock && !selection && !Editor.isEditor(node)) {
42
- const block = fromSlateValue([node], schema.block.name)?.at(0)
43
-
44
- if (!block) {
45
- return undefined
46
- }
47
-
48
+ if (block && positionBlock && !selection && !Editor.isEditor(node)) {
48
49
  return {
49
50
  block: positionBlock,
50
51
  isEditor: false,
@@ -65,6 +66,36 @@ export function getEventPosition({
65
66
  return undefined
66
67
  }
67
68
 
69
+ const focusBlockPath = selection.focus.path.at(0)
70
+ const focusBlockKey = utils.isKeyedSegment(focusBlockPath)
71
+ ? focusBlockPath._key
72
+ : undefined
73
+
74
+ if (!focusBlockKey) {
75
+ return undefined
76
+ }
77
+
78
+ if (
79
+ utils.isSelectionCollapsed(selection) &&
80
+ block &&
81
+ focusBlockKey !== block._key
82
+ ) {
83
+ return {
84
+ block: positionBlock,
85
+ isEditor: false,
86
+ selection: {
87
+ anchor: utils.getBlockStartPoint({
88
+ node: block,
89
+ path: [{_key: block._key}],
90
+ }),
91
+ focus: utils.getBlockEndPoint({
92
+ node: block,
93
+ path: [{_key: block._key}],
94
+ }),
95
+ },
96
+ }
97
+ }
98
+
68
99
  return {
69
100
  block: positionBlock,
70
101
  isEditor: Editor.isEditor(node),
@@ -1,5 +1,7 @@
1
- import {Editor, Node, type Path} from 'slate'
1
+ import {Editor, Element, Node, type Path} from 'slate'
2
+ import type {EditorSchema} from '../editor/define-schema'
2
3
  import type {PortableTextSlateEditor} from '../types/editor'
4
+ import {fromSlateValue} from './values'
3
5
 
4
6
  export function getFocusBlock({
5
7
  editor,
@@ -54,3 +56,60 @@ export function getLastBlock({
54
56
 
55
57
  return lastBlock ?? [undefined, undefined]
56
58
  }
59
+
60
+ export function getNodeBlock({
61
+ editor,
62
+ schema,
63
+ node,
64
+ }: {
65
+ editor: PortableTextSlateEditor
66
+ schema: EditorSchema
67
+ node: Node
68
+ }) {
69
+ if (Editor.isEditor(node)) {
70
+ return undefined
71
+ }
72
+
73
+ if (isBlockElement(schema, node)) {
74
+ return elementToBlock({schema, element: node})
75
+ }
76
+
77
+ const parent = Array.from(
78
+ Editor.nodes(editor, {
79
+ mode: 'highest',
80
+ at: [],
81
+ match: (n) =>
82
+ isBlockElement(schema, n) &&
83
+ n.children.some((child) => child._key === node._key),
84
+ }),
85
+ )
86
+ .at(0)
87
+ ?.at(0)
88
+
89
+ return Element.isElement(parent)
90
+ ? elementToBlock({
91
+ schema,
92
+ element: parent,
93
+ })
94
+ : undefined
95
+ }
96
+
97
+ function elementToBlock({
98
+ schema,
99
+ element,
100
+ }: {
101
+ schema: EditorSchema
102
+ element: Element
103
+ }) {
104
+ return fromSlateValue([element], schema.block.name)?.at(0)
105
+ }
106
+
107
+ function isBlockElement(schema: EditorSchema, node: Node): node is Element {
108
+ return (
109
+ Element.isElement(node) &&
110
+ (schema.block.name === node._type ||
111
+ schema.blockObjects.some(
112
+ (blockObject) => blockObject.name === node._type,
113
+ ))
114
+ )
115
+ }
@@ -1,8 +1,8 @@
1
- import type {KeyedSegment, PathSegment} from '@sanity/types'
1
+ import type {KeyedSegment} from '@sanity/types'
2
2
 
3
3
  /**
4
4
  * @public
5
5
  */
6
- export function isKeyedSegment(segment: PathSegment): segment is KeyedSegment {
6
+ export function isKeyedSegment(segment: unknown): segment is KeyedSegment {
7
7
  return typeof segment === 'object' && segment !== null && '_key' in segment
8
8
  }