@portabletext/editor 1.8.0 → 1.9.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/index.mjs CHANGED
@@ -554,6 +554,65 @@ function createMarkdownBehaviors(config) {
554
554
  };
555
555
  return [automaticBlockquoteOnSpace, automaticBreak, automaticHeadingOnSpace, clearStyleOnBackspace, automaticListOnSpace];
556
556
  }
557
+ function createLinkBehaviors(config) {
558
+ const pasteLinkOnSelection = {
559
+ on: "paste",
560
+ guard: ({
561
+ context,
562
+ event
563
+ }) => {
564
+ const selectionCollapsed = selectionIsCollapsed(context), text = event.clipboardData.getData("text/plain"), url = looksLikeUrl(text) ? text : void 0, annotation = url !== void 0 ? config.mapLinkAnnotation?.({
565
+ url,
566
+ schema: context.schema
567
+ }) : void 0;
568
+ return annotation && !selectionCollapsed ? {
569
+ annotation
570
+ } : !1;
571
+ },
572
+ actions: [(_, {
573
+ annotation
574
+ }) => [{
575
+ type: "annotation.add",
576
+ annotation
577
+ }]]
578
+ }, pasteLinkAtCaret = {
579
+ on: "paste",
580
+ guard: ({
581
+ context,
582
+ event
583
+ }) => {
584
+ const focusSpan = getFocusSpan(context), selectionCollapsed = selectionIsCollapsed(context);
585
+ if (!focusSpan || !selectionCollapsed)
586
+ return !1;
587
+ const text = event.clipboardData.getData("text/plain"), url = looksLikeUrl(text) ? text : void 0, annotation = url !== void 0 ? config.mapLinkAnnotation?.({
588
+ url,
589
+ schema: context.schema
590
+ }) : void 0;
591
+ return url && annotation && selectionCollapsed ? {
592
+ focusSpan,
593
+ annotation,
594
+ url
595
+ } : !1;
596
+ },
597
+ actions: [(_, {
598
+ annotation,
599
+ url
600
+ }) => [{
601
+ type: "insert span",
602
+ text: url,
603
+ annotations: [annotation]
604
+ }]]
605
+ };
606
+ return [pasteLinkOnSelection, pasteLinkAtCaret];
607
+ }
608
+ function looksLikeUrl(text) {
609
+ let looksLikeUrl2 = !1;
610
+ try {
611
+ new URL(text), looksLikeUrl2 = !0;
612
+ } catch {
613
+ }
614
+ return looksLikeUrl2;
615
+ }
557
616
  function getPortableTextMemberSchemaTypes(portableTextType) {
558
617
  if (!portableTextType)
559
618
  throw new Error("Parameter 'portabletextType' missing (required)");
@@ -4468,11 +4527,11 @@ function isDecoratorActive({
4468
4527
  }) {
4469
4528
  if (!editor.selection)
4470
4529
  return !1;
4471
- const selectedNodes = Array.from(Editor.nodes(editor, {
4530
+ const selectedTextNodes = Array.from(Editor.nodes(editor, {
4472
4531
  match: Text.isText,
4473
4532
  at: editor.selection
4474
4533
  }));
4475
- return Range.isExpanded(editor.selection) ? selectedNodes.every((n) => {
4534
+ return selectedTextNodes.length === 0 ? !1 : Range.isExpanded(editor.selection) ? selectedTextNodes.every((n) => {
4476
4535
  const [node] = n;
4477
4536
  return node.marks?.includes(decorator);
4478
4537
  }) : ({
@@ -5300,6 +5359,35 @@ const addAnnotationActionImplementation = ({
5300
5359
  type: "insert break"
5301
5360
  }
5302
5361
  });
5362
+ }, insertSpanActionImplementation = ({
5363
+ context,
5364
+ action
5365
+ }) => {
5366
+ if (!action.editor.selection) {
5367
+ console.error("Unable to perform action without selection", action);
5368
+ return;
5369
+ }
5370
+ const [focusBlock, focusBlockPath] = Array.from(Editor.nodes(action.editor, {
5371
+ at: action.editor.selection.focus.path,
5372
+ match: (node) => action.editor.isTextBlock(node)
5373
+ }))[0] ?? [void 0, void 0];
5374
+ if (!focusBlock || !focusBlockPath) {
5375
+ console.error("Unable to perform action without focus block", action);
5376
+ return;
5377
+ }
5378
+ const markDefs = focusBlock.markDefs ?? [], annotations = action.annotations ? action.annotations.map((annotation) => ({
5379
+ _type: annotation.name,
5380
+ _key: context.keyGenerator(),
5381
+ ...annotation.value
5382
+ })) : void 0;
5383
+ annotations && annotations.length > 0 && Transforms.setNodes(action.editor, {
5384
+ markDefs: [...markDefs, ...annotations]
5385
+ }), Transforms.insertNodes(action.editor, {
5386
+ _type: "span",
5387
+ _key: context.keyGenerator(),
5388
+ text: action.text,
5389
+ marks: [...annotations?.map((annotation) => annotation._key) ?? [], ...action.decorators ?? []]
5390
+ });
5303
5391
  }, behaviorActionImplementations = {
5304
5392
  "annotation.add": addAnnotationActionImplementation,
5305
5393
  "annotation.remove": removeAnnotationActionImplementation,
@@ -5387,6 +5475,7 @@ const addAnnotationActionImplementation = ({
5387
5475
  "insert block object": insertBlockObjectActionImplementation,
5388
5476
  "insert break": insertBreakActionImplementation,
5389
5477
  "insert soft break": insertSoftBreakActionImplementation,
5478
+ "insert span": insertSpanActionImplementation,
5390
5479
  "insert text": ({
5391
5480
  action
5392
5481
  }) => {
@@ -5413,6 +5502,11 @@ const addAnnotationActionImplementation = ({
5413
5502
  }) => {
5414
5503
  action.effect();
5415
5504
  },
5505
+ paste: ({
5506
+ action
5507
+ }) => {
5508
+ action.editor.insertData(action.clipboardData);
5509
+ },
5416
5510
  select: ({
5417
5511
  action
5418
5512
  }) => {
@@ -5449,6 +5543,13 @@ function performAction({
5449
5543
  });
5450
5544
  break;
5451
5545
  }
5546
+ case "insert span": {
5547
+ behaviorActionImplementations["insert span"]({
5548
+ context,
5549
+ action
5550
+ });
5551
+ break;
5552
+ }
5452
5553
  case "insert text block": {
5453
5554
  behaviorActionImplementations["insert text block"]({
5454
5555
  context,
@@ -5580,11 +5681,18 @@ function performDefaultAction({
5580
5681
  });
5581
5682
  break;
5582
5683
  }
5583
- default:
5684
+ case "insert text": {
5584
5685
  behaviorActionImplementations["insert text"]({
5585
5686
  context,
5586
5687
  action
5587
5688
  });
5689
+ break;
5690
+ }
5691
+ default:
5692
+ behaviorActionImplementations.paste({
5693
+ context,
5694
+ action
5695
+ });
5588
5696
  }
5589
5697
  }
5590
5698
  const networkLogic = fromCallback(({
@@ -6650,19 +6758,13 @@ const debug = debugWithName("component:Editable"), PLACEHOLDER_STYLE = {
6650
6758
  const handleCopy = useCallback((event) => {
6651
6759
  onCopy && onCopy(event) !== void 0 && event.preventDefault();
6652
6760
  }, [onCopy]), handlePaste = useCallback((event_0) => {
6653
- if (event_0.preventDefault(), !slateEditor.selection)
6654
- return;
6655
- if (!onPaste) {
6656
- debug("Pasting normally"), slateEditor.insertData(event_0.clipboardData);
6657
- return;
6658
- }
6659
- const value_0 = PortableTextEditor.getValue(portableTextEditor), path = toPortableTextRange(value_0, slateEditor.selection, schemaTypes)?.focus.path || [], onPasteResult = onPaste({
6761
+ const value_0 = PortableTextEditor.getValue(portableTextEditor), path = toPortableTextRange(value_0, slateEditor.selection, schemaTypes)?.focus.path || [], onPasteResult = onPaste?.({
6660
6762
  event: event_0,
6661
6763
  value: value_0,
6662
6764
  path,
6663
6765
  schemaTypes
6664
6766
  });
6665
- onPasteResult === void 0 ? (debug("No result from custom paste handler, pasting normally"), slateEditor.insertData(event_0.clipboardData)) : (editorActor.send({
6767
+ onPasteResult || !slateEditor.selection ? (event_0.preventDefault(), editorActor.send({
6666
6768
  type: "loading"
6667
6769
  }), Promise.resolve(onPasteResult).then((result_0) => {
6668
6770
  debug("Custom paste function from client resolved", result_0), !result_0 || !result_0.insert ? (debug("No result from custom paste handler, pasting normally"), slateEditor.insertData(event_0.clipboardData)) : result_0.insert ? slateEditor.insertFragment(toSlateValue(result_0.insert, {
@@ -6672,7 +6774,14 @@ const debug = debugWithName("component:Editable"), PLACEHOLDER_STYLE = {
6672
6774
  editorActor.send({
6673
6775
  type: "done loading"
6674
6776
  });
6675
- }));
6777
+ })) : event_0.nativeEvent.clipboardData && (event_0.preventDefault(), editorActor.send({
6778
+ type: "behavior event",
6779
+ behaviorEvent: {
6780
+ type: "paste",
6781
+ clipboardData: event_0.nativeEvent.clipboardData
6782
+ },
6783
+ editor: slateEditor
6784
+ })), debug("No result from custom paste handler, pasting normally");
6676
6785
  }, [editorActor, onPaste, portableTextEditor, schemaTypes, slateEditor]), handleOnFocus = useCallback((event_1) => {
6677
6786
  if (onFocus && onFocus(event_1), !event_1.isDefaultPrevented()) {
6678
6787
  const selection = PortableTextEditor.getSelection(portableTextEditor);
@@ -6687,15 +6796,11 @@ const debug = debugWithName("component:Editable"), PLACEHOLDER_STYLE = {
6687
6796
  });
6688
6797
  }
6689
6798
  }, [editorActor, onFocus, portableTextEditor, slateEditor]), handleClick = useCallback((event_2) => {
6690
- if (onClick && onClick(event_2), slateEditor.selection && event_2.target === event_2.currentTarget) {
6691
- const [lastBlock, path_0] = Node.last(slateEditor, []), focusPath = slateEditor.selection.focus.path.slice(0, 1), lastPath = path_0.slice(0, 1);
6692
- if (Path.equals(focusPath, lastPath)) {
6693
- const node = Node.descendant(slateEditor, path_0.slice(0, 1));
6694
- lastBlock && Editor.isVoid(slateEditor, node) && (Transforms.insertNodes(slateEditor, slateEditor.pteCreateTextBlock({
6695
- decorators: []
6696
- })), slateEditor.onChange());
6697
- }
6698
- }
6799
+ onClick && onClick(event_2);
6800
+ const focusBlockPath = slateEditor.selection ? slateEditor.selection.focus.path.slice(0, 1) : void 0, focusBlock = focusBlockPath ? Node.descendant(slateEditor, focusBlockPath) : void 0, [_, lastNodePath] = Node.last(slateEditor, []), lastBlockPath = lastNodePath.slice(0, 1), lastNodeFocused = focusBlockPath ? Path.equals(lastBlockPath, focusBlockPath) : !1, lastBlockIsVoid = focusBlock ? !slateEditor.isTextBlock(focusBlock) : !1;
6801
+ slateEditor.selection && Range.isCollapsed(slateEditor.selection) && lastNodeFocused && lastBlockIsVoid && (Transforms.insertNodes(slateEditor, slateEditor.pteCreateTextBlock({
6802
+ decorators: []
6803
+ })), slateEditor.onChange());
6699
6804
  }, [onClick, slateEditor]), handleOnBlur = useCallback((event_3) => {
6700
6805
  onBlur && onBlur(event_3), event_3.isPropagationStopped() || editorActor.send({
6701
6806
  type: "blur",
@@ -6743,7 +6848,7 @@ const debug = debugWithName("component:Editable"), PLACEHOLDER_STYLE = {
6743
6848
  return scrollSelectionIntoView === null ? noop : (_editor, domRange) => {
6744
6849
  scrollSelectionIntoView(portableTextEditor, domRange);
6745
6850
  };
6746
- }, [portableTextEditor, scrollSelectionIntoView]), decorate = useCallback(([, path_1]) => {
6851
+ }, [portableTextEditor, scrollSelectionIntoView]), decorate = useCallback(([, path_0]) => {
6747
6852
  if (isEqualToEmptyEditor(slateEditor.children, schemaTypes))
6748
6853
  return [{
6749
6854
  anchor: {
@@ -6756,18 +6861,18 @@ const debug = debugWithName("component:Editable"), PLACEHOLDER_STYLE = {
6756
6861
  },
6757
6862
  placeholder: !0
6758
6863
  }];
6759
- if (path_1.length === 0)
6864
+ if (path_0.length === 0)
6760
6865
  return [];
6761
- const result_1 = rangeDecorationState.filter((item) => Range.isCollapsed(item) ? path_1.length !== 2 ? !1 : Path.equals(item.focus.path, path_1) && Path.equals(item.anchor.path, path_1) : Range.intersection(item, {
6866
+ const result_1 = rangeDecorationState.filter((item) => Range.isCollapsed(item) ? path_0.length !== 2 ? !1 : Path.equals(item.focus.path, path_0) && Path.equals(item.anchor.path, path_0) : Range.intersection(item, {
6762
6867
  anchor: {
6763
- path: path_1,
6868
+ path: path_0,
6764
6869
  offset: 0
6765
6870
  },
6766
6871
  focus: {
6767
- path: path_1,
6872
+ path: path_0,
6768
6873
  offset: 0
6769
6874
  }
6770
- }) || Range.includes(item, path_1));
6875
+ }) || Range.includes(item, path_0));
6771
6876
  return result_1.length > 0 ? result_1 : [];
6772
6877
  }, [slateEditor, schemaTypes, rangeDecorationState]);
6773
6878
  return useEffect(() => {
@@ -6838,6 +6943,7 @@ export {
6838
6943
  PortableTextEditor,
6839
6944
  coreBehavior,
6840
6945
  coreBehaviors,
6946
+ createLinkBehaviors,
6841
6947
  createMarkdownBehaviors,
6842
6948
  defineBehavior,
6843
6949
  defineSchema,