@portabletext/plugin-typeahead-picker 2.0.6 → 3.0.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/dist/index.js CHANGED
@@ -295,20 +295,31 @@ function createInputRules(definition) {
295
295
  });
296
296
  return rules.push(triggerRule), rules;
297
297
  }
298
+ function createTriggerGuard(definition) {
299
+ return ({
300
+ event,
301
+ snapshot,
302
+ dom
303
+ }) => event.pickerId !== definition._id ? !1 : definition.guard ? definition.guard({
304
+ snapshot,
305
+ dom,
306
+ event: {
307
+ type: "custom.typeahead trigger found"
308
+ }
309
+ }) : !0;
310
+ }
298
311
  const triggerListenerCallback = () => ({
299
312
  sendBack,
300
313
  input
301
314
  }) => {
302
- const rules = createInputRules(input.definition), unregisterBehaviors = [input.editor.registerBehavior({
315
+ const rules = createInputRules(input.definition), triggerGuard = createTriggerGuard(input.definition), unregisterBehaviors = [input.editor.registerBehavior({
303
316
  behavior: defineInputRuleBehavior({
304
317
  rules
305
318
  })
306
319
  }), input.editor.registerBehavior({
307
320
  behavior: defineBehavior({
308
321
  on: "custom.typeahead keyword found",
309
- guard: ({
310
- event
311
- }) => event.pickerId === input.definition._id,
322
+ guard: triggerGuard,
312
323
  actions: [({
313
324
  event
314
325
  }) => [effect(() => {
@@ -318,9 +329,7 @@ const triggerListenerCallback = () => ({
318
329
  }), input.editor.registerBehavior({
319
330
  behavior: defineBehavior({
320
331
  on: "custom.typeahead trigger found",
321
- guard: ({
322
- event
323
- }) => event.pickerId === input.definition._id,
332
+ guard: triggerGuard,
324
333
  actions: [({
325
334
  event
326
335
  }) => [effect(() => {
@@ -334,20 +343,50 @@ const triggerListenerCallback = () => ({
334
343
  };
335
344
  }, escapeListenerCallback = () => ({
336
345
  sendBack,
337
- input
338
- }) => input.editor.registerBehavior({
339
- behavior: defineBehavior({
340
- on: "keyboard.keydown",
341
- guard: ({
342
- event
343
- }) => escapeShortcut.guard(event.originEvent),
344
- actions: [() => [effect(() => {
345
- sendBack({
346
- type: "dismiss"
347
- });
348
- })]]
349
- })
350
- }), arrowListenerCallback = () => ({
346
+ input,
347
+ receive
348
+ }) => {
349
+ let context = input.context;
350
+ return receive((event) => {
351
+ context = event.context;
352
+ }), input.context.editor.registerBehavior({
353
+ behavior: defineBehavior({
354
+ on: "keyboard.keydown",
355
+ guard: ({
356
+ event
357
+ }) => escapeShortcut.guard(event.originEvent),
358
+ actions: [({
359
+ snapshot,
360
+ dom
361
+ }) => {
362
+ if (!context.focusSpan || !context.definition.onDismiss)
363
+ return [effect(() => sendBack({
364
+ type: "close"
365
+ }))];
366
+ const patternSelection = {
367
+ anchor: {
368
+ path: context.focusSpan.path,
369
+ offset: context.focusSpan.textBefore.length
370
+ },
371
+ focus: {
372
+ path: context.focusSpan.path,
373
+ offset: context.focusSpan.node.text.length - context.focusSpan.textAfter.length
374
+ }
375
+ };
376
+ return [...context.definition.onDismiss.flatMap((actionSet) => actionSet({
377
+ snapshot,
378
+ dom,
379
+ event: {
380
+ type: "custom.typeahead dismiss",
381
+ patternSelection
382
+ }
383
+ }, !0)), effect(() => sendBack({
384
+ type: "close"
385
+ }))];
386
+ }]
387
+ })
388
+ });
389
+ }, arrowListenerCallback = () => ({
351
390
  sendBack,
352
391
  input
353
392
  }) => {
@@ -387,7 +426,52 @@ const triggerListenerCallback = () => ({
387
426
  sendBack({
388
427
  type: "selection changed"
389
428
  });
390
- }).unsubscribe, submitListenerCallback = () => ({
429
+ }).unsubscribe, dismissListenerCallback = () => ({
430
+ sendBack,
431
+ input,
432
+ receive
433
+ }) => {
434
+ let context = input.context;
435
+ return receive((event) => {
436
+ context = event.context;
437
+ }), input.context.editor.registerBehavior({
438
+ behavior: defineBehavior({
439
+ on: "custom.typeahead dismiss",
440
+ guard: ({
441
+ event
442
+ }) => event.pickerId === context.definition._id,
443
+ actions: [({
444
+ snapshot,
445
+ dom
446
+ }) => {
447
+ if (!context.focusSpan || !context.definition.onDismiss)
448
+ return [effect(() => sendBack({
449
+ type: "close"
450
+ }))];
451
+ const patternSelection = {
452
+ anchor: {
453
+ path: context.focusSpan.path,
454
+ offset: context.focusSpan.textBefore.length
455
+ },
456
+ focus: {
457
+ path: context.focusSpan.path,
458
+ offset: context.focusSpan.node.text.length - context.focusSpan.textAfter.length
459
+ }
460
+ };
461
+ return [...context.definition.onDismiss.flatMap((actionSet) => actionSet({
462
+ snapshot,
463
+ dom,
464
+ event: {
465
+ type: "custom.typeahead dismiss",
466
+ patternSelection
467
+ }
468
+ }, !0)), effect(() => sendBack({
469
+ type: "close"
470
+ }))];
471
+ }]
472
+ })
473
+ });
474
+ }, submitListenerCallback = () => ({
391
475
  sendBack,
392
476
  input,
393
477
  receive
@@ -426,7 +510,7 @@ const triggerListenerCallback = () => ({
426
510
  event
427
511
  }) => [forward(event), effect(() => {
428
512
  sendBack({
429
- type: "dismiss"
513
+ type: "close"
430
514
  });
431
515
  })]]
432
516
  })
@@ -436,11 +520,35 @@ const triggerListenerCallback = () => ({
436
520
  guard: ({
437
521
  event
438
522
  }) => (enterShortcut.guard(event.originEvent) || tabShortcut.guard(event.originEvent)) && context.patternText.length > 1 && context.matches.length === 0,
439
- actions: [() => [effect(() => {
440
- sendBack({
441
- type: "dismiss"
442
- });
443
- })]]
523
+ actions: [({
524
+ snapshot,
525
+ dom
526
+ }) => {
527
+ if (!context.focusSpan || !context.definition.onDismiss)
528
+ return [effect(() => sendBack({
529
+ type: "close"
530
+ }))];
531
+ const patternSelection = {
532
+ anchor: {
533
+ path: context.focusSpan.path,
534
+ offset: context.focusSpan.textBefore.length
535
+ },
536
+ focus: {
537
+ path: context.focusSpan.path,
538
+ offset: context.focusSpan.node.text.length - context.focusSpan.textAfter.length
539
+ }
540
+ };
541
+ return [...context.definition.onDismiss.flatMap((actionSet) => actionSet({
542
+ snapshot,
543
+ dom,
544
+ event: {
545
+ type: "custom.typeahead dismiss",
546
+ patternSelection
547
+ }
548
+ }, !0)), effect(() => sendBack({
549
+ type: "close"
550
+ }))];
551
+ }]
444
552
  })
445
553
  })];
446
554
  return () => {
@@ -473,17 +581,17 @@ const triggerListenerCallback = () => ({
473
581
  event
474
582
  }) => [forward(event), effect(() => {
475
583
  sendBack({
476
- type: "dismiss"
584
+ type: "close"
477
585
  });
478
586
  })]]
479
587
  })
480
588
  });
481
- }, insertMatchListenerCallback = () => ({
589
+ }, selectMatchListenerCallback = () => ({
482
590
  sendBack,
483
591
  input
484
592
  }) => input.context.editor.registerBehavior({
485
593
  behavior: defineBehavior({
486
- on: "custom.typeahead insert match",
594
+ on: "custom.typeahead select match",
487
595
  guard: ({
488
596
  event
489
597
  }) => event.pickerId === input.context.definition._id,
@@ -501,34 +609,21 @@ const triggerListenerCallback = () => ({
501
609
  path: event.focusSpan.path,
502
610
  offset: event.focusSpan.node.text.length - event.focusSpan.textAfter.length
503
611
  }
504
- }, allActions = [effect(() => {
612
+ }, selectActions = input.context.definition.onSelect.flatMap((actionSet) => actionSet({
613
+ snapshot,
614
+ dom,
615
+ event: {
616
+ type: "custom.typeahead select",
617
+ match: event.match,
618
+ keyword: event.keyword,
619
+ patternSelection
620
+ }
621
+ }, !0));
622
+ return [effect(() => {
505
623
  sendBack({
506
- type: "dismiss"
507
- });
508
- })];
509
- for (const actionSet of input.context.definition.actions) {
510
- const actions = actionSet({
511
- snapshot,
512
- dom,
513
- event: {
514
- type: "typeahead.select",
515
- match: event.match,
516
- keyword: event.keyword,
517
- patternSelection
518
- }
519
- }, !0);
520
- for (const action of actions)
521
- allActions.push(action);
522
- }
523
- return allActions.push(effect(() => {
524
- queueMicrotask(() => {
525
- const currentSelection = input.context.editor.getSnapshot().context.selection;
526
- currentSelection && input.context.editor.send({
527
- type: "select",
528
- at: currentSelection
529
- });
624
+ type: "close"
530
625
  });
531
- })), allActions;
626
+ }), ...selectActions];
532
627
  }]
533
628
  })
534
629
  });
@@ -551,7 +646,8 @@ function createTypeaheadPickerMachine() {
551
646
  "selection listener": fromCallback(selectionListenerCallback()),
552
647
  "submit listener": fromCallback(submitListenerCallback()),
553
648
  "text insertion listener": fromCallback(textInsertionListenerCallback()),
554
- "insert match listener": fromCallback(insertMatchListenerCallback()),
649
+ "select match listener": fromCallback(selectMatchListenerCallback()),
650
+ "dismiss listener": fromCallback(dismissListenerCallback()),
555
651
  "get matches": fromPromise(async ({
556
652
  input
557
653
  }) => {
@@ -593,83 +689,84 @@ function createTypeaheadPickerMachine() {
593
689
  selectedIndex: 0
594
690
  };
595
691
  }),
596
- "update focus span": assign({
597
- focusSpan: ({
598
- context
599
- }) => {
600
- if (!context.focusSpan)
601
- return context.focusSpan;
602
- const snapshot = context.editor.getSnapshot(), focusSpan = getFocusSpan(snapshot);
603
- if (!snapshot.context.selection || !focusSpan)
604
- return;
605
- const nextSpan = getNextSpan({
606
- ...snapshot,
607
- context: {
608
- ...snapshot.context,
609
- selection: {
610
- anchor: {
611
- path: context.focusSpan.path,
612
- offset: 0
613
- },
614
- focus: {
615
- path: context.focusSpan.path,
616
- offset: 0
617
- }
618
- }
619
- }
620
- });
621
- if (!isEqualPaths(focusSpan.path, context.focusSpan.path))
622
- return nextSpan && context.focusSpan.textAfter.length === 0 && snapshot.context.selection.focus.offset === 0 && isSelectionCollapsed(snapshot) ? context.focusSpan : void 0;
623
- if (!focusSpan.node.text.startsWith(context.focusSpan.textBefore) || !focusSpan.node.text.endsWith(context.focusSpan.textAfter))
624
- return;
625
- const keywordAnchor = {
626
- path: focusSpan.path,
627
- offset: context.focusSpan.textBefore.length
628
- }, keywordFocus = {
629
- path: focusSpan.path,
630
- offset: focusSpan.node.text.length - context.focusSpan.textAfter.length
631
- }, selectionIsBeforeKeyword = isPointAfterSelection(keywordAnchor)(snapshot), selectionIsAfterKeyword = isPointBeforeSelection(keywordFocus)(snapshot);
632
- if (!(selectionIsBeforeKeyword || selectionIsAfterKeyword))
633
- return {
634
- node: focusSpan.node,
635
- path: focusSpan.path,
636
- textBefore: context.focusSpan.textBefore,
637
- textAfter: context.focusSpan.textAfter
638
- };
639
- }
640
- }),
641
- "update pattern text": assign(({
692
+ "handle selection changed": assign(({
642
693
  context
643
694
  }) => {
644
695
  if (!context.focusSpan)
645
- return {};
646
- const patternText = extractPatternTextFromFocusSpan(context.focusSpan);
647
- return patternText === context.patternText ? {} : {
648
- patternText,
649
- selectedIndex: 0
650
- };
651
- }),
652
- "update keyword": assign(({
653
- context
654
- }) => {
655
- if (!context.focusSpan || !context.patternText)
656
- return {};
657
- const keyword = extractKeyword(context.patternText, context.triggerPattern, context.definition.delimiter, context.completePattern);
658
- return keyword === context.keyword ? {} : {
696
+ return {
697
+ focusSpan: void 0
698
+ };
699
+ const snapshot = context.editor.getSnapshot(), currentFocusSpan = getFocusSpan(snapshot);
700
+ if (!snapshot.context.selection || !currentFocusSpan)
701
+ return {
702
+ focusSpan: void 0
703
+ };
704
+ const nextSpan = getNextSpan({
705
+ ...snapshot,
706
+ context: {
707
+ ...snapshot.context,
708
+ selection: {
709
+ anchor: {
710
+ path: context.focusSpan.path,
711
+ offset: 0
712
+ },
713
+ focus: {
714
+ path: context.focusSpan.path,
715
+ offset: 0
716
+ }
717
+ }
718
+ }
719
+ });
720
+ if (!isEqualPaths(currentFocusSpan.path, context.focusSpan.path))
721
+ return nextSpan && context.focusSpan.textAfter.length === 0 && snapshot.context.selection.focus.offset === 0 && isSelectionCollapsed(snapshot) ? {} : {
722
+ focusSpan: void 0
723
+ };
724
+ if (!currentFocusSpan.node.text.startsWith(context.focusSpan.textBefore))
725
+ return {
726
+ focusSpan: void 0
727
+ };
728
+ if (!currentFocusSpan.node.text.endsWith(context.focusSpan.textAfter))
729
+ return {
730
+ focusSpan: void 0
731
+ };
732
+ const keywordAnchor = {
733
+ path: currentFocusSpan.path,
734
+ offset: context.focusSpan.textBefore.length
735
+ }, keywordFocus = {
736
+ path: currentFocusSpan.path,
737
+ offset: currentFocusSpan.node.text.length - context.focusSpan.textAfter.length
738
+ }, selectionIsBeforeKeyword = isPointAfterSelection(keywordAnchor)(snapshot), selectionIsAfterKeyword = isPointBeforeSelection(keywordFocus)(snapshot);
739
+ if (selectionIsBeforeKeyword || selectionIsAfterKeyword)
740
+ return {
741
+ focusSpan: void 0
742
+ };
743
+ const focusSpan = {
744
+ node: currentFocusSpan.node,
745
+ path: currentFocusSpan.path,
746
+ textBefore: context.focusSpan.textBefore,
747
+ textAfter: context.focusSpan.textAfter
748
+ }, patternText = extractPatternTextFromFocusSpan(focusSpan), keyword = extractKeyword(patternText, context.triggerPattern, context.definition.delimiter, context.completePattern);
749
+ if (context.definition.mode === "async" || context.definition.debounceMs)
750
+ return {
751
+ focusSpan,
752
+ patternText,
753
+ keyword,
754
+ selectedIndex: patternText !== context.patternText ? 0 : context.selectedIndex,
755
+ isLoading: context.isLoading || context.requestedKeyword !== keyword
756
+ };
757
+ const matches = context.definition.getMatches({
659
758
  keyword
759
+ });
760
+ return {
761
+ focusSpan,
762
+ patternText,
763
+ keyword,
764
+ matches,
765
+ requestedKeyword: keyword,
766
+ selectedIndex: patternText !== context.patternText ? 0 : context.selectedIndex,
767
+ isLoading: !1
660
768
  };
661
769
  }),
662
- "update matches": assign(({
663
- context
664
- }) => !context.focusSpan || !context.patternText ? {} : context.definition.mode === "async" || context.definition.debounceMs ? {
665
- isLoading: context.isLoading || context.requestedKeyword !== context.keyword
666
- } : {
667
- matches: context.definition.getMatches({
668
- keyword: context.keyword
669
- }),
670
- requestedKeyword: context.keyword,
671
- isLoading: !1
672
- }),
673
770
  "handle async load complete": assign(({
674
771
  context,
675
772
  event
@@ -704,14 +801,14 @@ function createTypeaheadPickerMachine() {
704
801
  } : {
705
802
  selectedIndex: (context.selectedIndex + 1) % context.matches.length
706
803
  }),
707
- "insert match": ({
804
+ "select match": ({
708
805
  context
709
806
  }, params) => {
710
807
  if (!context.focusSpan)
711
808
  return;
712
809
  const match = params.exact ? getFirstExactMatch(context.matches) : context.matches[context.selectedIndex];
713
810
  match && context.editor.send({
714
- type: "custom.typeahead insert match",
811
+ type: "custom.typeahead select match",
715
812
  match,
716
813
  focusSpan: context.focusSpan,
717
814
  keyword: context.keyword,
@@ -730,6 +827,18 @@ function createTypeaheadPickerMachine() {
730
827
  type: "context changed",
731
828
  context
732
829
  })),
830
+ "update escape listener context": sendTo("escape listener", ({
831
+ context
832
+ }) => ({
833
+ type: "context changed",
834
+ context
835
+ })),
836
+ "update request dismiss listener context": sendTo("dismiss listener", ({
837
+ context
838
+ }) => ({
839
+ type: "context changed",
840
+ context
841
+ })),
733
842
  "handle error": assign({
734
843
  isLoading: !1,
735
844
  error: ({
@@ -825,7 +934,7 @@ function createTypeaheadPickerMachine() {
825
934
  },
826
935
  "checking complete": {
827
936
  invoke: [{
828
- src: "insert match listener",
937
+ src: "select match listener",
829
938
  input: ({
830
939
  context
831
940
  }) => ({
@@ -849,7 +958,7 @@ function createTypeaheadPickerMachine() {
849
958
  event
850
959
  }) => event.output.matches
851
960
  }), {
852
- type: "insert match",
961
+ type: "select match",
853
962
  params: {
854
963
  exact: !0
855
964
  }
@@ -870,7 +979,7 @@ function createTypeaheadPickerMachine() {
870
979
  },
871
980
  active: {
872
981
  invoke: [{
873
- src: "insert match listener",
982
+ src: "select match listener",
874
983
  input: ({
875
984
  context
876
985
  }) => ({
@@ -878,10 +987,11 @@ function createTypeaheadPickerMachine() {
878
987
  })
879
988
  }, {
880
989
  src: "escape listener",
990
+ id: "escape listener",
881
991
  input: ({
882
992
  context
883
993
  }) => ({
884
- editor: context.editor
994
+ context
885
995
  })
886
996
  }, {
887
997
  src: "selection listener",
@@ -906,13 +1016,21 @@ function createTypeaheadPickerMachine() {
906
1016
  }) => ({
907
1017
  context
908
1018
  })
1019
+ }, {
1020
+ src: "dismiss listener",
1021
+ id: "dismiss listener",
1022
+ input: ({
1023
+ context
1024
+ }) => ({
1025
+ context
1026
+ })
909
1027
  }],
910
1028
  on: {
911
- dismiss: {
1029
+ close: {
912
1030
  target: "idle"
913
1031
  },
914
1032
  "selection changed": {
915
- actions: ["update focus span", "update pattern text", "update keyword", "update matches", "update submit listener context", "update text insertion listener context"]
1033
+ actions: ["handle selection changed", "update submit listener context", "update text insertion listener context", "update escape listener context", "update request dismiss listener context"]
916
1034
  }
917
1035
  },
918
1036
  always: [{
@@ -924,7 +1042,7 @@ function createTypeaheadPickerMachine() {
924
1042
  }, {
925
1043
  guard: "is complete keyword",
926
1044
  actions: [{
927
- type: "insert match",
1045
+ type: "select match",
928
1046
  params: {
929
1047
  exact: !1
930
1048
  }
@@ -1073,7 +1191,7 @@ function createTypeaheadPickerMachine() {
1073
1191
  select: {
1074
1192
  target: "#typeahead picker.idle",
1075
1193
  actions: [{
1076
- type: "insert match",
1194
+ type: "select match",
1077
1195
  params: {
1078
1196
  exact: !1
1079
1197
  }
@@ -1140,7 +1258,7 @@ function getFirstExactMatch(matches) {
1140
1258
  return matches.find((match) => match?.type === "exact");
1141
1259
  }
1142
1260
  function useTypeaheadPicker(definition) {
1143
- const $ = c(19), editor = useEditor();
1261
+ const $ = c(21), editor = useEditor();
1144
1262
  let t0;
1145
1263
  $[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = createTypeaheadPickerMachine(), $[0] = t0) : t0 = $[0];
1146
1264
  let t1;
@@ -1167,14 +1285,17 @@ function useTypeaheadPicker(definition) {
1167
1285
  context: t4
1168
1286
  }, $[11] = t2, $[12] = t4, $[13] = t5) : t5 = $[13];
1169
1287
  let t6;
1170
- $[14] !== send ? (t6 = (event) => {
1171
- send(event);
1172
- }, $[14] = send, $[15] = t6) : t6 = $[15];
1288
+ $[14] !== definition || $[15] !== editor || $[16] !== send ? (t6 = (event) => {
1289
+ event.type === "dismiss" ? editor.send({
1290
+ type: "custom.typeahead dismiss",
1291
+ pickerId: definition._id
1292
+ }) : send(event);
1293
+ }, $[14] = definition, $[15] = editor, $[16] = send, $[17] = t6) : t6 = $[17];
1173
1294
  let t7;
1174
- return $[16] !== t5 || $[17] !== t6 ? (t7 = {
1295
+ return $[18] !== t5 || $[19] !== t6 ? (t7 = {
1175
1296
  snapshot: t5,
1176
1297
  send: t6
1177
- }, $[16] = t5, $[17] = t6, $[18] = t7) : t7 = $[18], t7;
1298
+ }, $[18] = t5, $[19] = t6, $[20] = t7) : t7 = $[20], t7;
1178
1299
  }
1179
1300
  export {
1180
1301
  defineTypeaheadPicker,