@portabletext/editor 1.23.0 → 1.25.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.
Files changed (71) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +249 -62
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/{selector.is-selection-collapsed.cjs → selector.is-active-style.cjs} +158 -3
  4. package/lib/_chunks-cjs/selector.is-active-style.cjs.map +1 -0
  5. package/lib/_chunks-cjs/util.slice-blocks.cjs +23 -9
  6. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
  7. package/lib/_chunks-es/behavior.core.js +225 -38
  8. package/lib/_chunks-es/behavior.core.js.map +1 -1
  9. package/lib/_chunks-es/{selector.is-selection-collapsed.js → selector.is-active-style.js} +159 -4
  10. package/lib/_chunks-es/selector.is-active-style.js.map +1 -0
  11. package/lib/_chunks-es/util.slice-blocks.js +23 -9
  12. package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
  13. package/lib/behaviors/index.cjs +27 -27
  14. package/lib/behaviors/index.cjs.map +1 -1
  15. package/lib/behaviors/index.d.cts +2830 -139
  16. package/lib/behaviors/index.d.ts +2830 -139
  17. package/lib/behaviors/index.js +1 -1
  18. package/lib/index.cjs +695 -526
  19. package/lib/index.cjs.map +1 -1
  20. package/lib/index.d.cts +8950 -246
  21. package/lib/index.d.ts +8950 -246
  22. package/lib/index.js +696 -525
  23. package/lib/index.js.map +1 -1
  24. package/lib/selectors/index.cjs +24 -171
  25. package/lib/selectors/index.cjs.map +1 -1
  26. package/lib/selectors/index.d.cts +73 -0
  27. package/lib/selectors/index.d.ts +73 -0
  28. package/lib/selectors/index.js +3 -151
  29. package/lib/selectors/index.js.map +1 -1
  30. package/package.json +11 -10
  31. package/src/behavior-actions/behavior.action.data-transfer-set.ts +7 -0
  32. package/src/behavior-actions/behavior.action.insert-blocks.ts +61 -0
  33. package/src/behavior-actions/behavior.actions.ts +159 -83
  34. package/src/behaviors/behavior.core.annotations.ts +29 -0
  35. package/src/behaviors/behavior.core.block-objects.ts +13 -13
  36. package/src/behaviors/behavior.core.decorators.ts +19 -0
  37. package/src/behaviors/behavior.core.deserialize.ts +46 -0
  38. package/src/behaviors/behavior.core.lists.ts +57 -23
  39. package/src/behaviors/behavior.core.serialize.ts +44 -0
  40. package/src/behaviors/behavior.core.style.ts +19 -0
  41. package/src/behaviors/behavior.core.ts +19 -0
  42. package/src/behaviors/behavior.types.ts +126 -89
  43. package/src/converters/converter.json.ts +53 -0
  44. package/src/converters/converter.portable-text.deserialize.test.ts +686 -0
  45. package/src/converters/converter.portable-text.ts +59 -0
  46. package/src/converters/converter.text-html.deserialize.test.ts +349 -0
  47. package/src/converters/converter.text-html.serialize.test.ts +233 -0
  48. package/src/converters/converter.text-html.ts +61 -0
  49. package/src/converters/converter.text-plain.test.ts +241 -0
  50. package/src/converters/converter.text-plain.ts +91 -0
  51. package/src/converters/converter.ts +65 -0
  52. package/src/converters/converters.ts +11 -0
  53. package/src/editor/Editable.tsx +3 -13
  54. package/src/editor/create-editor.ts +48 -6
  55. package/src/editor/editor-machine.ts +56 -2
  56. package/src/editor/editor-selector.ts +1 -0
  57. package/src/editor/editor-snapshot.ts +5 -0
  58. package/src/editor/plugins/create-with-event-listeners.ts +82 -106
  59. package/src/internal-utils/asserters.ts +9 -0
  60. package/src/internal-utils/mime-type.ts +1 -0
  61. package/src/internal-utils/parse-blocks.ts +136 -0
  62. package/src/internal-utils/test-key-generator.ts +9 -0
  63. package/src/selectors/selector.get-selected-spans.test.ts +1 -0
  64. package/src/selectors/selector.get-selection-text.test.ts +1 -0
  65. package/src/selectors/selector.is-active-decorator.test.ts +1 -0
  66. package/src/utils/util.slice-blocks.test.ts +87 -0
  67. package/src/utils/util.slice-blocks.ts +27 -10
  68. package/lib/_chunks-cjs/selector.is-selection-collapsed.cjs.map +0 -1
  69. package/lib/_chunks-es/selector.is-selection-collapsed.js.map +0 -1
  70. package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +0 -181
  71. package/src/editor/plugins/createWithInsertData.ts +0 -425
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/selectors/selector.get-active-list-item.ts","../../src/selectors/selector.get-active-style.ts","../../src/selectors/selector.get-selected-slice.ts","../../src/selectors/selector.get-selected-spans.ts","../../src/selectors/selector.is-active-annotation.ts","../../src/selectors/selector.is-selection-expanded.ts","../../src/selectors/selector.is-active-decorator.ts","../../src/selectors/selector.is-active-list-item.ts","../../src/selectors/selector.is-active-style.ts","../../src/selectors/selector.is-point-after-selection.ts","../../src/selectors/selector.is-point-before-selection.ts"],"sourcesContent":["import type {PortableTextListBlock} from '@sanity/types'\nimport {createGuards} from '../behavior-actions/behavior.guards'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveListItem: EditorSelector<\n PortableTextListBlock['listItem'] | undefined\n> = ({context}) => {\n if (!context.selection) {\n return undefined\n }\n\n const guards = createGuards(context)\n const selectedBlocks = getSelectedBlocks({context}).map((block) => block.node)\n const selectedTextBlocks = selectedBlocks.filter(guards.isTextBlock)\n\n const firstTextBlock = selectedTextBlocks.at(0)\n\n if (!firstTextBlock) {\n return undefined\n }\n\n const firstListItem = firstTextBlock.listItem\n\n if (!firstListItem) {\n return undefined\n }\n\n if (selectedTextBlocks.every((block) => block.listItem === firstListItem)) {\n return firstListItem\n }\n\n return undefined\n}\n","import type {PortableTextTextBlock} from '@sanity/types'\nimport {createGuards} from '../behavior-actions/behavior.guards'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport const getActiveStyle: EditorSelector<PortableTextTextBlock['style']> = ({\n context,\n}) => {\n if (!context.selection) {\n return undefined\n }\n\n const guards = createGuards(context)\n const selectedBlocks = getSelectedBlocks({context}).map((block) => block.node)\n const selectedTextBlocks = selectedBlocks.filter(guards.isTextBlock)\n\n const firstTextBlock = selectedTextBlocks.at(0)\n\n if (!firstTextBlock) {\n return undefined\n }\n\n const firstStyle = firstTextBlock.style\n\n if (!firstStyle) {\n return undefined\n }\n\n if (selectedTextBlocks.every((block) => block.style === firstStyle)) {\n return firstStyle\n }\n\n return undefined\n}\n","import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {sliceBlocks} from '../utils'\n\n/**\n * @public\n */\nexport const getSelectedSlice: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return sliceBlocks({blocks: context.value, selection: context.selection})\n}\n","import {\n isKeySegment,\n isPortableTextSpan,\n isPortableTextTextBlock,\n type KeyedSegment,\n type PortableTextSpan,\n} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\n\n/**\n * @public\n */\nexport const getSelectedSpans: EditorSelector<\n Array<{\n node: PortableTextSpan\n path: [KeyedSegment, 'children', KeyedSegment]\n }>\n> = ({context}) => {\n if (!context.selection) {\n return []\n }\n\n const selectedSpans: Array<{\n node: PortableTextSpan\n path: [KeyedSegment, 'children', KeyedSegment]\n }> = []\n\n const startPoint = context.selection.backward\n ? context.selection.focus\n : context.selection.anchor\n const endPoint = context.selection.backward\n ? context.selection.anchor\n : context.selection.focus\n\n const startBlockKey = isKeySegment(startPoint.path[0])\n ? startPoint.path[0]._key\n : undefined\n const endBlockKey = isKeySegment(endPoint.path[0])\n ? endPoint.path[0]._key\n : undefined\n\n if (!startBlockKey || !endBlockKey) {\n return selectedSpans\n }\n\n const startSpanKey = isKeySegment(startPoint.path[2])\n ? startPoint.path[2]._key\n : undefined\n const endSpanKey = isKeySegment(endPoint.path[2])\n ? endPoint.path[2]._key\n : undefined\n\n for (const block of context.value) {\n if (!isPortableTextTextBlock(block)) {\n continue\n }\n\n if (block._key === startBlockKey) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (startSpanKey && child._key === startSpanKey) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n\n if (startSpanKey === endSpanKey) {\n break\n }\n\n continue\n }\n\n if (endSpanKey && child._key === endSpanKey) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n break\n }\n\n if (selectedSpans.length > 0) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n }\n\n if (startBlockKey === endBlockKey) {\n break\n }\n\n continue\n }\n\n if (block._key === endBlockKey) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n if (endSpanKey && child._key === endSpanKey) {\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n break\n }\n\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n\n break\n }\n\n if (selectedSpans.length > 0) {\n for (const child of block.children) {\n if (!isPortableTextSpan(child)) {\n continue\n }\n\n selectedSpans.push({\n node: child,\n path: [{_key: block._key}, 'children', {_key: child._key}],\n })\n }\n }\n }\n\n return selectedSpans\n}\n","import {isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {getSelectedBlocks} from './selectors'\n\n/**\n * @public\n */\nexport function isActiveAnnotation(\n annotation: string,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selectedBlocks = getSelectedBlocks(snapshot)\n const selectedSpans = getSelectedSpans(snapshot)\n\n if (selectedSpans.length === 0) {\n return false\n }\n\n if (\n selectedSpans.some(\n (span) => !span.node.marks || span.node.marks?.length === 0,\n )\n ) {\n return false\n }\n\n const selectionMarkDefs = selectedBlocks.flatMap((block) =>\n isPortableTextTextBlock(block.node) ? (block.node.markDefs ?? []) : [],\n )\n\n return selectedSpans.every((span) => {\n const spanMarkDefs =\n span.node.marks?.flatMap((mark) => {\n const markDef = selectionMarkDefs.find(\n (markDef) => markDef._key === mark,\n )\n\n return markDef ? [markDef._type] : []\n }) ?? []\n\n return spanMarkDefs.includes(annotation)\n })\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {isSelectionCollapsed} from './selector.is-selection-collapsed'\n\n/**\n * @public\n */\nexport const isSelectionExpanded: EditorSelector<boolean> = ({context}) => {\n return !isSelectionCollapsed({context})\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getSelectedSpans} from './selector.get-selected-spans'\nimport {isSelectionExpanded} from './selector.is-selection-expanded'\n\n/**\n * @public\n */\nexport function isActiveDecorator(decorator: string): EditorSelector<boolean> {\n return (snapshot) => {\n if (isSelectionExpanded(snapshot)) {\n const selectedSpans = getSelectedSpans(snapshot)\n\n return (\n selectedSpans.length > 0 &&\n selectedSpans.every((span) => span.node.marks?.includes(decorator))\n )\n }\n\n return snapshot.context.activeDecorators.includes(decorator)\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getActiveListItem} from './selector.get-active-list-item'\n\n/**\n * @public\n */\nexport function isActiveListItem(listItem: string): EditorSelector<boolean> {\n return (snapshot) => {\n const activeListItem = getActiveListItem(snapshot)\n\n return activeListItem === listItem\n }\n}\n","import type {EditorSelector} from '../editor/editor-selector'\nimport {getActiveStyle} from './selector.get-active-style'\n\n/**\n * @public\n */\nexport function isActiveStyle(style: string): EditorSelector<boolean> {\n return (snapshot) => {\n const activeStyle = getActiveStyle(snapshot)\n\n return activeStyle === style\n }\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointAfterSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const endBlockKey = isKeySegment(selection.focus.path[0])\n ? selection.focus.path[0]._key\n : undefined\n const endChildKey = isKeySegment(selection.focus.path[2])\n ? selection.focus.path[2]._key\n : undefined\n\n if (!pointBlockKey || !endBlockKey) {\n return false\n }\n\n let after = false\n\n for (const block of snapshot.context.value) {\n if (block._key === endBlockKey) {\n if (block._key !== pointBlockKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !endChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === endChildKey) {\n if (child._key !== pointChildKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this child\n\n after = point.offset > selection.focus.offset\n break\n }\n\n if (child._key === pointChildKey) {\n break\n }\n }\n }\n\n if (block._key === pointBlockKey) {\n break\n }\n }\n\n return after\n }\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointBeforeSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const startBlockKey = isKeySegment(selection.anchor.path[0])\n ? selection.anchor.path[0]._key\n : undefined\n const startChildKey = isKeySegment(selection.anchor.path[2])\n ? selection.anchor.path[2]._key\n : undefined\n\n if (!pointBlockKey || !startBlockKey) {\n return false\n }\n\n let before = false\n\n for (const block of snapshot.context.value) {\n if (block._key === pointBlockKey) {\n if (block._key !== startBlockKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !startChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === pointChildKey) {\n if (child._key !== startChildKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this child\n\n before = point.offset < selection.anchor.offset\n break\n }\n\n if (child._key === startChildKey) {\n break\n }\n }\n }\n\n if (block._key === startBlockKey) {\n break\n }\n }\n\n return before\n }\n}\n"],"names":["getActiveListItem","context","selection","guards","createGuards","selectedTextBlocks","getSelectedBlocks","map","block","node","filter","isTextBlock","firstTextBlock","at","firstListItem","listItem","every","getActiveStyle","firstStyle","style","getSelectedSlice","sliceBlocks","blocks","value","getSelectedSpans","selectedSpans","startPoint","backward","focus","anchor","endPoint","startBlockKey","isKeySegment","path","_key","undefined","endBlockKey","startSpanKey","endSpanKey","isPortableTextTextBlock","child","children","isPortableTextSpan","push","length","isActiveAnnotation","annotation","snapshot","selectedBlocks","some","span","marks","selectionMarkDefs","flatMap","markDefs","mark","markDef","find","_type","includes","isSelectionExpanded","isSelectionCollapsed","isActiveDecorator","decorator","activeDecorators","isActiveListItem","isActiveStyle","isPointAfterSelection","point","reverseSelection","pointBlockKey","pointChildKey","endChildKey","after","offset","isPointBeforeSelection","startChildKey","before"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/selectors/selector.get-selected-slice.ts","../../src/selectors/selector.is-point-after-selection.ts","../../src/selectors/selector.is-point-before-selection.ts"],"sourcesContent":["import type {PortableTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport {sliceBlocks} from '../utils'\n\n/**\n * @public\n */\nexport const getSelectedSlice: EditorSelector<Array<PortableTextBlock>> = ({\n context,\n}) => {\n return sliceBlocks({blocks: context.value, selection: context.selection})\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointAfterSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const endBlockKey = isKeySegment(selection.focus.path[0])\n ? selection.focus.path[0]._key\n : undefined\n const endChildKey = isKeySegment(selection.focus.path[2])\n ? selection.focus.path[2]._key\n : undefined\n\n if (!pointBlockKey || !endBlockKey) {\n return false\n }\n\n let after = false\n\n for (const block of snapshot.context.value) {\n if (block._key === endBlockKey) {\n if (block._key !== pointBlockKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !endChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === endChildKey) {\n if (child._key !== pointChildKey) {\n after = true\n break\n }\n\n // Both the point and the selection end in this child\n\n after = point.offset > selection.focus.offset\n break\n }\n\n if (child._key === pointChildKey) {\n break\n }\n }\n }\n\n if (block._key === pointBlockKey) {\n break\n }\n }\n\n return after\n }\n}\n","import {isKeySegment, isPortableTextTextBlock} from '@sanity/types'\nimport type {EditorSelector} from '../editor/editor-selector'\nimport type {EditorSelectionPoint} from '../types/editor'\nimport {reverseSelection} from '../utils/util.reverse-selection'\n\n/**\n * @public\n */\nexport function isPointBeforeSelection(\n point: EditorSelectionPoint,\n): EditorSelector<boolean> {\n return (snapshot) => {\n if (!snapshot.context.selection) {\n return false\n }\n\n const selection = reverseSelection(snapshot.context.selection)\n\n const pointBlockKey = isKeySegment(point.path[0])\n ? point.path[0]._key\n : undefined\n const pointChildKey = isKeySegment(point.path[2])\n ? point.path[2]._key\n : undefined\n\n const startBlockKey = isKeySegment(selection.anchor.path[0])\n ? selection.anchor.path[0]._key\n : undefined\n const startChildKey = isKeySegment(selection.anchor.path[2])\n ? selection.anchor.path[2]._key\n : undefined\n\n if (!pointBlockKey || !startBlockKey) {\n return false\n }\n\n let before = false\n\n for (const block of snapshot.context.value) {\n if (block._key === pointBlockKey) {\n if (block._key !== startBlockKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this block\n\n if (!isPortableTextTextBlock(block)) {\n break\n }\n\n if (!pointChildKey || !startChildKey) {\n break\n }\n\n for (const child of block.children) {\n if (child._key === pointChildKey) {\n if (child._key !== startChildKey) {\n before = true\n break\n }\n\n // Both the point and the selection start in this child\n\n before = point.offset < selection.anchor.offset\n break\n }\n\n if (child._key === startChildKey) {\n break\n }\n }\n }\n\n if (block._key === startBlockKey) {\n break\n }\n }\n\n return before\n }\n}\n"],"names":["getSelectedSlice","context","sliceBlocks","blocks","value","selection","isPointAfterSelection","point","snapshot","reverseSelection","pointBlockKey","isKeySegment","path","_key","undefined","pointChildKey","endBlockKey","focus","endChildKey","after","block","isPortableTextTextBlock","child","children","offset","isPointBeforeSelection","startBlockKey","anchor","startChildKey","before"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "1.23.0",
3
+ "version": "1.25.0",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -61,6 +61,7 @@
61
61
  "src"
62
62
  ],
63
63
  "dependencies": {
64
+ "@portabletext/to-html": "^2.0.13",
64
65
  "@xstate/react": "^5.0.2",
65
66
  "debug": "^4.4.0",
66
67
  "get-random-values-esm": "^1.0.2",
@@ -69,18 +70,18 @@
69
70
  "react-compiler-runtime": "19.0.0-beta-decd7b8-20250118",
70
71
  "slate": "0.112.0",
71
72
  "slate-dom": "^0.111.0",
72
- "slate-react": "0.112.0",
73
+ "slate-react": "0.112.1",
73
74
  "use-effect-event": "^1.0.2",
74
75
  "xstate": "^5.19.2",
75
- "@portabletext/patches": "1.1.1",
76
- "@portabletext/block-tools": "1.1.0"
76
+ "@portabletext/block-tools": "1.1.2",
77
+ "@portabletext/patches": "1.1.2"
77
78
  },
78
79
  "devDependencies": {
79
80
  "@portabletext/toolkit": "^2.0.16",
80
- "@sanity/diff-match-patch": "^3.1.2",
81
- "@sanity/pkg-utils": "^7.0.1",
82
- "@sanity/schema": "^3.70.0",
83
- "@sanity/types": "^3.70.0",
81
+ "@sanity/diff-match-patch": "^3.2.0",
82
+ "@sanity/pkg-utils": "^7.0.2",
83
+ "@sanity/schema": "^3.71.1",
84
+ "@sanity/types": "^3.71.1",
84
85
  "@testing-library/jest-dom": "^6.6.3",
85
86
  "@testing-library/react": "^16.2.0",
86
87
  "@types/debug": "^4.1.12",
@@ -108,8 +109,8 @@
108
109
  "racejar": "1.1.1"
109
110
  },
110
111
  "peerDependencies": {
111
- "@sanity/schema": "^3.70.0",
112
- "@sanity/types": "^3.70.0",
112
+ "@sanity/schema": "^3.71.1",
113
+ "@sanity/types": "^3.71.1",
113
114
  "react": "^16.9 || ^17 || ^18 || ^19",
114
115
  "rxjs": "^7.8.1"
115
116
  },
@@ -0,0 +1,7 @@
1
+ import type {BehaviorActionImplementation} from './behavior.actions'
2
+
3
+ export const dataTransferSetActionImplementation: BehaviorActionImplementation<
4
+ 'data transfer.set'
5
+ > = ({action}) => {
6
+ action.dataTransfer.setData(action.mimeType, action.data)
7
+ }
@@ -0,0 +1,61 @@
1
+ import {isEqual, uniq} from 'lodash'
2
+ import {Editor, Transforms} from 'slate'
3
+ import {isEqualToEmptyEditor, toSlateValue} from '../internal-utils/values'
4
+ import type {BehaviorActionImplementation} from './behavior.actions'
5
+
6
+ export const insertBlocksActionImplementation: BehaviorActionImplementation<
7
+ 'insert.blocks'
8
+ > = ({context, action}) => {
9
+ const fragment = toSlateValue(action.blocks, {schemaTypes: context.schema})
10
+
11
+ if (!action.editor.selection) {
12
+ return
13
+ }
14
+ // Ensure that markDefs for any annotations inside this fragment are copied over to the focused text block.
15
+ const [focusBlock, focusPath] = Editor.node(
16
+ action.editor,
17
+ action.editor.selection,
18
+ {
19
+ depth: 1,
20
+ },
21
+ )
22
+
23
+ if (
24
+ action.editor.isTextBlock(focusBlock) &&
25
+ action.editor.isTextBlock(fragment[0])
26
+ ) {
27
+ const {markDefs} = focusBlock
28
+ if (!isEqual(markDefs, fragment[0].markDefs)) {
29
+ Transforms.setNodes(
30
+ action.editor,
31
+ {
32
+ markDefs: uniq([
33
+ ...(fragment[0].markDefs || []),
34
+ ...(markDefs || []),
35
+ ]),
36
+ },
37
+ {at: focusPath, mode: 'lowest', voids: false},
38
+ )
39
+ }
40
+ }
41
+
42
+ const isPasteToEmptyEditor = isEqualToEmptyEditor(
43
+ action.editor.children,
44
+ context.schema,
45
+ )
46
+
47
+ if (isPasteToEmptyEditor) {
48
+ // Special case for pasting directly into an empty editor (a placeholder block).
49
+ // When pasting content starting with multiple empty blocks,
50
+ // `editor.insertFragment` can potentially duplicate the keys of
51
+ // the placeholder block because of operations that happen
52
+ // inside `editor.insertFragment` (involves an `insert_node` operation).
53
+ // However by splitting the placeholder block first in this situation we are good.
54
+ Transforms.splitNodes(action.editor, {at: [0, 0]})
55
+ action.editor.insertFragment(fragment)
56
+ Transforms.removeNodes(action.editor, {at: [0]})
57
+ } else {
58
+ // All other inserts
59
+ action.editor.insertFragment(fragment)
60
+ }
61
+ }
@@ -28,7 +28,9 @@ import {KEY_TO_VALUE_ELEMENT} from '../internal-utils/weakMaps'
28
28
  import type {PickFromUnion} from '../type-utils'
29
29
  import {blockOffsetToSpanSelectionPoint} from '../utils/util.block-offset'
30
30
  import {insertBlock} from './behavior.action-utils.insert-block'
31
+ import {dataTransferSetActionImplementation} from './behavior.action.data-transfer-set'
31
32
  import {insertBlockObjectActionImplementation} from './behavior.action.insert-block-object'
33
+ import {insertBlocksActionImplementation} from './behavior.action.insert-blocks'
32
34
  import {
33
35
  insertBreakActionImplementation,
34
36
  insertSoftBreakActionImplementation,
@@ -75,6 +77,7 @@ const behaviorActionImplementations: BehaviorActionImplementations = {
75
77
  'blur': ({action}) => {
76
78
  ReactEditor.blur(action.editor)
77
79
  },
80
+ 'data transfer.set': dataTransferSetActionImplementation,
78
81
  'decorator.add': addDecoratorActionImplementation,
79
82
  'decorator.remove': removeDecoratorActionImplementation,
80
83
  'decorator.toggle': toggleDecoratorActionImplementation,
@@ -143,6 +146,22 @@ const behaviorActionImplementations: BehaviorActionImplementations = {
143
146
  at: range,
144
147
  })
145
148
  },
149
+ 'deserialization.failure': ({action}) => {
150
+ console.error(
151
+ `Deserialization of ${action.mimeType} failed with reason ${action.reason}`,
152
+ )
153
+ },
154
+ 'deserialization.success': ({context, action}) => {
155
+ insertBlocksActionImplementation({
156
+ context,
157
+ action: {
158
+ type: 'insert.blocks',
159
+ blocks: action.data,
160
+ editor: action.editor,
161
+ },
162
+ })
163
+ },
164
+ 'insert.blocks': insertBlocksActionImplementation,
146
165
  'insert.block object': insertBlockObjectActionImplementation,
147
166
  'insert.break': insertBreakActionImplementation,
148
167
  'insert.inline object': insertInlineObjectActionImplementation,
@@ -260,6 +279,20 @@ const behaviorActionImplementations: BehaviorActionImplementations = {
260
279
 
261
280
  Transforms.select(action.editor, nextBlockPath)
262
281
  },
282
+ 'serialization.failure': ({action}) => {
283
+ console.error(
284
+ `Serialization of ${action.mimeType} failed with reason ${action.reason}`,
285
+ )
286
+ },
287
+ 'serialization.success': ({context, action}) => {
288
+ dataTransferSetActionImplementation({
289
+ context,
290
+ action: {
291
+ ...action,
292
+ type: 'data transfer.set',
293
+ },
294
+ })
295
+ },
263
296
  'style.toggle': toggleStyleActionImplementation,
264
297
  'style.add': addStyleActionImplementation,
265
298
  'style.remove': removeStyleActionImplementation,
@@ -275,6 +308,55 @@ export function performAction({
275
308
  action: BehaviorAction
276
309
  }) {
277
310
  switch (action.type) {
311
+ case 'noop': {
312
+ behaviorActionImplementations.noop({
313
+ context,
314
+ action,
315
+ })
316
+ break
317
+ }
318
+ case 'effect': {
319
+ behaviorActionImplementations.effect({
320
+ context,
321
+ action,
322
+ })
323
+ break
324
+ }
325
+ case 'select': {
326
+ behaviorActionImplementations.select({
327
+ context,
328
+ action,
329
+ })
330
+ break
331
+ }
332
+ default: {
333
+ performDefaultAction({context, action})
334
+ }
335
+ }
336
+ }
337
+
338
+ function performDefaultAction({
339
+ context,
340
+ action,
341
+ }: {
342
+ context: BehaviorActionImplementationContext
343
+ action: PickFromUnion<BehaviorAction, 'type', SyntheticBehaviorEvent['type']>
344
+ }) {
345
+ switch (action.type) {
346
+ case 'annotation.add': {
347
+ behaviorActionImplementations['annotation.add']({
348
+ context,
349
+ action,
350
+ })
351
+ break
352
+ }
353
+ case 'annotation.remove': {
354
+ behaviorActionImplementations['annotation.remove']({
355
+ context,
356
+ action,
357
+ })
358
+ break
359
+ }
278
360
  case 'annotation.toggle': {
279
361
  behaviorActionImplementations['annotation.toggle']({
280
362
  context,
@@ -282,263 +364,257 @@ export function performAction({
282
364
  })
283
365
  break
284
366
  }
285
- case 'decorator.add': {
286
- behaviorActionImplementations['decorator.add']({
367
+ case 'blur': {
368
+ behaviorActionImplementations.blur({
287
369
  context,
288
370
  action,
289
371
  })
290
372
  break
291
373
  }
292
- case 'decorator.remove': {
293
- behaviorActionImplementations['decorator.remove']({
374
+ case 'data transfer.set': {
375
+ behaviorActionImplementations['data transfer.set']({
294
376
  context,
295
377
  action,
296
378
  })
297
379
  break
298
380
  }
299
- case 'delete.block': {
300
- behaviorActionImplementations['delete.block']({
381
+ case 'decorator.add': {
382
+ behaviorActionImplementations['decorator.add']({
301
383
  context,
302
384
  action,
303
385
  })
304
386
  break
305
387
  }
306
- case 'delete.text': {
307
- behaviorActionImplementations['delete.text']({
388
+ case 'decorator.remove': {
389
+ behaviorActionImplementations['decorator.remove']({
308
390
  context,
309
391
  action,
310
392
  })
311
393
  break
312
394
  }
313
- case 'insert.span': {
314
- behaviorActionImplementations['insert.span']({
395
+ case 'decorator.toggle': {
396
+ behaviorActionImplementations['decorator.toggle']({
315
397
  context,
316
398
  action,
317
399
  })
318
400
  break
319
401
  }
320
- case 'insert.text block': {
321
- behaviorActionImplementations['insert.text block']({
402
+ case 'delete.backward': {
403
+ behaviorActionImplementations['delete.backward']({
322
404
  context,
323
405
  action,
324
406
  })
325
407
  break
326
408
  }
327
- case 'list item.add': {
328
- behaviorActionImplementations['list item.add']({
409
+ case 'delete.block': {
410
+ behaviorActionImplementations['delete.block']({
329
411
  context,
330
412
  action,
331
413
  })
332
414
  break
333
415
  }
334
- case 'list item.remove': {
335
- behaviorActionImplementations['list item.remove']({
416
+ case 'delete.forward': {
417
+ behaviorActionImplementations['delete.forward']({
336
418
  context,
337
419
  action,
338
420
  })
339
421
  break
340
422
  }
341
- case 'move.block': {
342
- behaviorActionImplementations['move.block']({
423
+ case 'delete.text': {
424
+ behaviorActionImplementations['delete.text']({
343
425
  context,
344
426
  action,
345
427
  })
346
428
  break
347
429
  }
348
- case 'move.block down': {
349
- behaviorActionImplementations['move.block down']({
430
+ case 'deserialization.failure': {
431
+ behaviorActionImplementations['deserialization.failure']({
350
432
  context,
351
433
  action,
352
434
  })
353
435
  break
354
436
  }
355
- case 'move.block up': {
356
- behaviorActionImplementations['move.block up']({
437
+ case 'deserialization.success': {
438
+ behaviorActionImplementations['deserialization.success']({
357
439
  context,
358
440
  action,
359
441
  })
360
442
  break
361
443
  }
362
- case 'noop': {
363
- behaviorActionImplementations.noop({
444
+ case 'focus': {
445
+ behaviorActionImplementations.focus({
364
446
  context,
365
447
  action,
366
448
  })
367
449
  break
368
450
  }
369
- case 'effect': {
370
- behaviorActionImplementations.effect({
451
+ case 'insert.blocks': {
452
+ behaviorActionImplementations['insert.blocks']({
371
453
  context,
372
454
  action,
373
455
  })
374
456
  break
375
457
  }
376
- case 'select': {
377
- behaviorActionImplementations.select({
458
+ case 'insert.block object': {
459
+ behaviorActionImplementations['insert.block object']({
378
460
  context,
379
461
  action,
380
462
  })
381
463
  break
382
464
  }
383
- case 'select.previous block': {
384
- behaviorActionImplementations['select.previous block']({
465
+ case 'insert.inline object': {
466
+ behaviorActionImplementations['insert.inline object']({
385
467
  context,
386
468
  action,
387
469
  })
388
470
  break
389
471
  }
390
- case 'select.next block': {
391
- behaviorActionImplementations['select.next block']({
472
+ case 'insert.break': {
473
+ behaviorActionImplementations['insert.break']({
392
474
  context,
393
475
  action,
394
476
  })
395
477
  break
396
478
  }
397
- case 'style.add': {
398
- behaviorActionImplementations['style.add']({
479
+ case 'insert.soft break': {
480
+ behaviorActionImplementations['insert.soft break']({
399
481
  context,
400
482
  action,
401
483
  })
402
484
  break
403
485
  }
404
- case 'style.remove': {
405
- behaviorActionImplementations['style.remove']({
486
+ case 'insert.span': {
487
+ behaviorActionImplementations['insert.span']({
406
488
  context,
407
489
  action,
408
490
  })
409
491
  break
410
492
  }
411
- case 'text block.set': {
412
- behaviorActionImplementations['text block.set']({
493
+ case 'insert.text': {
494
+ behaviorActionImplementations['insert.text']({
413
495
  context,
414
496
  action,
415
497
  })
416
498
  break
417
499
  }
418
- case 'text block.unset': {
419
- behaviorActionImplementations['text block.unset']({
500
+ case 'insert.text block': {
501
+ behaviorActionImplementations['insert.text block']({
420
502
  context,
421
503
  action,
422
504
  })
423
505
  break
424
506
  }
425
- default: {
426
- performDefaultAction({context, action})
507
+ case 'list item.add': {
508
+ behaviorActionImplementations['list item.add']({
509
+ context,
510
+ action,
511
+ })
512
+ break
427
513
  }
428
- }
429
- }
430
-
431
- function performDefaultAction({
432
- context,
433
- action,
434
- }: {
435
- context: BehaviorActionImplementationContext
436
- action: PickFromUnion<BehaviorAction, 'type', SyntheticBehaviorEvent['type']>
437
- }) {
438
- switch (action.type) {
439
- case 'annotation.add': {
440
- behaviorActionImplementations['annotation.add']({
514
+ case 'list item.remove': {
515
+ behaviorActionImplementations['list item.remove']({
441
516
  context,
442
517
  action,
443
518
  })
444
519
  break
445
520
  }
446
- case 'annotation.remove': {
447
- behaviorActionImplementations['annotation.remove']({
521
+ case 'list item.toggle': {
522
+ behaviorActionImplementations['list item.toggle']({
448
523
  context,
449
524
  action,
450
525
  })
451
526
  break
452
527
  }
453
- case 'blur': {
454
- behaviorActionImplementations.blur({
528
+ case 'move.block': {
529
+ behaviorActionImplementations['move.block']({
455
530
  context,
456
531
  action,
457
532
  })
458
533
  break
459
534
  }
460
- case 'decorator.toggle': {
461
- behaviorActionImplementations['decorator.toggle']({
535
+ case 'move.block down': {
536
+ behaviorActionImplementations['move.block down']({
462
537
  context,
463
538
  action,
464
539
  })
465
540
  break
466
541
  }
467
- case 'delete.backward': {
468
- behaviorActionImplementations['delete.backward']({
542
+ case 'move.block up': {
543
+ behaviorActionImplementations['move.block up']({
469
544
  context,
470
545
  action,
471
546
  })
472
547
  break
473
548
  }
474
- case 'delete.forward': {
475
- behaviorActionImplementations['delete.forward']({
549
+ case 'select': {
550
+ behaviorActionImplementations.select({
476
551
  context,
477
552
  action,
478
553
  })
479
554
  break
480
555
  }
481
- case 'focus': {
482
- behaviorActionImplementations.focus({
556
+ case 'select.previous block': {
557
+ behaviorActionImplementations['select.previous block']({
483
558
  context,
484
559
  action,
485
560
  })
486
561
  break
487
562
  }
488
- case 'insert.block object': {
489
- behaviorActionImplementations['insert.block object']({
563
+ case 'select.next block': {
564
+ behaviorActionImplementations['select.next block']({
490
565
  context,
491
566
  action,
492
567
  })
493
568
  break
494
569
  }
495
- case 'insert.inline object': {
496
- behaviorActionImplementations['insert.inline object']({
570
+ case 'serialization.failure': {
571
+ behaviorActionImplementations['serialization.failure']({
497
572
  context,
498
573
  action,
499
574
  })
500
575
  break
501
576
  }
502
- case 'insert.break': {
503
- behaviorActionImplementations['insert.break']({
577
+ case 'serialization.success': {
578
+ behaviorActionImplementations['serialization.success']({
504
579
  context,
505
580
  action,
506
581
  })
507
582
  break
508
583
  }
509
- case 'insert.soft break': {
510
- behaviorActionImplementations['insert.soft break']({
584
+ case 'style.add': {
585
+ behaviorActionImplementations['style.add']({
511
586
  context,
512
587
  action,
513
588
  })
514
589
  break
515
590
  }
516
- case 'insert.text': {
517
- behaviorActionImplementations['insert.text']({
591
+ case 'style.remove': {
592
+ behaviorActionImplementations['style.remove']({
518
593
  context,
519
594
  action,
520
595
  })
521
596
  break
522
597
  }
523
- case 'list item.toggle': {
524
- behaviorActionImplementations['list item.toggle']({
598
+ case 'style.toggle': {
599
+ behaviorActionImplementations['style.toggle']({
525
600
  context,
526
601
  action,
527
602
  })
528
603
  break
529
604
  }
530
- case 'select': {
531
- behaviorActionImplementations.select({
605
+ case 'text block.set': {
606
+ behaviorActionImplementations['text block.set']({
532
607
  context,
533
608
  action,
534
609
  })
535
610
  break
536
611
  }
537
- default: {
538
- behaviorActionImplementations['style.toggle']({
612
+ case 'text block.unset': {
613
+ behaviorActionImplementations['text block.unset']({
539
614
  context,
540
615
  action,
541
616
  })
617
+ break
542
618
  }
543
619
  }
544
620
  }