@portabletext/plugin-typeahead-picker 2.1.0 → 3.0.1
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/README.md +57 -15
- package/dist/index.d.ts +83 -42
- package/dist/index.js +242 -122
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import { keyGenerator, useEditor } from "@portabletext/editor";
|
|
1
2
|
import { c } from "react/compiler-runtime";
|
|
2
|
-
import { useEditor } from "@portabletext/editor";
|
|
3
3
|
import { useActor } from "@xstate/react";
|
|
4
4
|
import { defineBehavior, effect, forward, raise } from "@portabletext/editor/behaviors";
|
|
5
5
|
import { getFocusSpan, getNextSpan, isSelectionCollapsed, isPointAfterSelection, isPointBeforeSelection, getMarkState, getPreviousSpan } from "@portabletext/editor/selectors";
|
|
@@ -10,7 +10,7 @@ import { setup, assign, sendTo, fromPromise, fromCallback } from "xstate";
|
|
|
10
10
|
function defineTypeaheadPicker(config) {
|
|
11
11
|
return {
|
|
12
12
|
...config,
|
|
13
|
-
_id:
|
|
13
|
+
_id: keyGenerator()
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
16
|
function extractKeyword(patternText, triggerPattern, delimiter, completePattern) {
|
|
@@ -343,20 +343,50 @@ const triggerListenerCallback = () => ({
|
|
|
343
343
|
};
|
|
344
344
|
}, escapeListenerCallback = () => ({
|
|
345
345
|
sendBack,
|
|
346
|
-
input
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
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 = () => ({
|
|
360
390
|
sendBack,
|
|
361
391
|
input
|
|
362
392
|
}) => {
|
|
@@ -396,7 +426,52 @@ const triggerListenerCallback = () => ({
|
|
|
396
426
|
sendBack({
|
|
397
427
|
type: "selection changed"
|
|
398
428
|
});
|
|
399
|
-
}).unsubscribe,
|
|
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 = () => ({
|
|
400
475
|
sendBack,
|
|
401
476
|
input,
|
|
402
477
|
receive
|
|
@@ -435,7 +510,7 @@ const triggerListenerCallback = () => ({
|
|
|
435
510
|
event
|
|
436
511
|
}) => [forward(event), effect(() => {
|
|
437
512
|
sendBack({
|
|
438
|
-
type: "
|
|
513
|
+
type: "close"
|
|
439
514
|
});
|
|
440
515
|
})]]
|
|
441
516
|
})
|
|
@@ -445,11 +520,35 @@ const triggerListenerCallback = () => ({
|
|
|
445
520
|
guard: ({
|
|
446
521
|
event
|
|
447
522
|
}) => (enterShortcut.guard(event.originEvent) || tabShortcut.guard(event.originEvent)) && context.patternText.length > 1 && context.matches.length === 0,
|
|
448
|
-
actions: [(
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
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
|
+
}]
|
|
453
552
|
})
|
|
454
553
|
})];
|
|
455
554
|
return () => {
|
|
@@ -482,7 +581,7 @@ const triggerListenerCallback = () => ({
|
|
|
482
581
|
event
|
|
483
582
|
}) => [forward(event), effect(() => {
|
|
484
583
|
sendBack({
|
|
485
|
-
type: "
|
|
584
|
+
type: "close"
|
|
486
585
|
});
|
|
487
586
|
})]]
|
|
488
587
|
})
|
|
@@ -510,26 +609,21 @@ const triggerListenerCallback = () => ({
|
|
|
510
609
|
path: event.focusSpan.path,
|
|
511
610
|
offset: event.focusSpan.node.text.length - event.focusSpan.textAfter.length
|
|
512
611
|
}
|
|
513
|
-
},
|
|
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(() => {
|
|
514
623
|
sendBack({
|
|
515
|
-
type: "
|
|
624
|
+
type: "close"
|
|
516
625
|
});
|
|
517
|
-
})];
|
|
518
|
-
for (const actionSet of input.context.definition.actions) {
|
|
519
|
-
const actions = actionSet({
|
|
520
|
-
snapshot,
|
|
521
|
-
dom,
|
|
522
|
-
event: {
|
|
523
|
-
type: "custom.typeahead select",
|
|
524
|
-
match: event.match,
|
|
525
|
-
keyword: event.keyword,
|
|
526
|
-
patternSelection
|
|
527
|
-
}
|
|
528
|
-
}, !0);
|
|
529
|
-
for (const action of actions)
|
|
530
|
-
allActions.push(action);
|
|
531
|
-
}
|
|
532
|
-
return allActions;
|
|
626
|
+
}), ...selectActions];
|
|
533
627
|
}]
|
|
534
628
|
})
|
|
535
629
|
});
|
|
@@ -553,6 +647,7 @@ function createTypeaheadPickerMachine() {
|
|
|
553
647
|
"submit listener": fromCallback(submitListenerCallback()),
|
|
554
648
|
"text insertion listener": fromCallback(textInsertionListenerCallback()),
|
|
555
649
|
"select match listener": fromCallback(selectMatchListenerCallback()),
|
|
650
|
+
"dismiss listener": fromCallback(dismissListenerCallback()),
|
|
556
651
|
"get matches": fromPromise(async ({
|
|
557
652
|
input
|
|
558
653
|
}) => {
|
|
@@ -594,83 +689,84 @@ function createTypeaheadPickerMachine() {
|
|
|
594
689
|
selectedIndex: 0
|
|
595
690
|
};
|
|
596
691
|
}),
|
|
597
|
-
"
|
|
598
|
-
focusSpan: ({
|
|
599
|
-
context
|
|
600
|
-
}) => {
|
|
601
|
-
if (!context.focusSpan)
|
|
602
|
-
return context.focusSpan;
|
|
603
|
-
const snapshot = context.editor.getSnapshot(), focusSpan = getFocusSpan(snapshot);
|
|
604
|
-
if (!snapshot.context.selection || !focusSpan)
|
|
605
|
-
return;
|
|
606
|
-
const nextSpan = getNextSpan({
|
|
607
|
-
...snapshot,
|
|
608
|
-
context: {
|
|
609
|
-
...snapshot.context,
|
|
610
|
-
selection: {
|
|
611
|
-
anchor: {
|
|
612
|
-
path: context.focusSpan.path,
|
|
613
|
-
offset: 0
|
|
614
|
-
},
|
|
615
|
-
focus: {
|
|
616
|
-
path: context.focusSpan.path,
|
|
617
|
-
offset: 0
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
|
-
});
|
|
622
|
-
if (!isEqualPaths(focusSpan.path, context.focusSpan.path))
|
|
623
|
-
return nextSpan && context.focusSpan.textAfter.length === 0 && snapshot.context.selection.focus.offset === 0 && isSelectionCollapsed(snapshot) ? context.focusSpan : void 0;
|
|
624
|
-
if (!focusSpan.node.text.startsWith(context.focusSpan.textBefore) || !focusSpan.node.text.endsWith(context.focusSpan.textAfter))
|
|
625
|
-
return;
|
|
626
|
-
const keywordAnchor = {
|
|
627
|
-
path: focusSpan.path,
|
|
628
|
-
offset: context.focusSpan.textBefore.length
|
|
629
|
-
}, keywordFocus = {
|
|
630
|
-
path: focusSpan.path,
|
|
631
|
-
offset: focusSpan.node.text.length - context.focusSpan.textAfter.length
|
|
632
|
-
}, selectionIsBeforeKeyword = isPointAfterSelection(keywordAnchor)(snapshot), selectionIsAfterKeyword = isPointBeforeSelection(keywordFocus)(snapshot);
|
|
633
|
-
if (!(selectionIsBeforeKeyword || selectionIsAfterKeyword))
|
|
634
|
-
return {
|
|
635
|
-
node: focusSpan.node,
|
|
636
|
-
path: focusSpan.path,
|
|
637
|
-
textBefore: context.focusSpan.textBefore,
|
|
638
|
-
textAfter: context.focusSpan.textAfter
|
|
639
|
-
};
|
|
640
|
-
}
|
|
641
|
-
}),
|
|
642
|
-
"update pattern text": assign(({
|
|
692
|
+
"handle selection changed": assign(({
|
|
643
693
|
context
|
|
644
694
|
}) => {
|
|
645
695
|
if (!context.focusSpan)
|
|
646
|
-
return {
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
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({
|
|
660
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
|
|
661
768
|
};
|
|
662
769
|
}),
|
|
663
|
-
"update matches": assign(({
|
|
664
|
-
context
|
|
665
|
-
}) => !context.focusSpan || !context.patternText ? {} : context.definition.mode === "async" || context.definition.debounceMs ? {
|
|
666
|
-
isLoading: context.isLoading || context.requestedKeyword !== context.keyword
|
|
667
|
-
} : {
|
|
668
|
-
matches: context.definition.getMatches({
|
|
669
|
-
keyword: context.keyword
|
|
670
|
-
}),
|
|
671
|
-
requestedKeyword: context.keyword,
|
|
672
|
-
isLoading: !1
|
|
673
|
-
}),
|
|
674
770
|
"handle async load complete": assign(({
|
|
675
771
|
context,
|
|
676
772
|
event
|
|
@@ -731,6 +827,18 @@ function createTypeaheadPickerMachine() {
|
|
|
731
827
|
type: "context changed",
|
|
732
828
|
context
|
|
733
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
|
+
})),
|
|
734
842
|
"handle error": assign({
|
|
735
843
|
isLoading: !1,
|
|
736
844
|
error: ({
|
|
@@ -879,10 +987,11 @@ function createTypeaheadPickerMachine() {
|
|
|
879
987
|
})
|
|
880
988
|
}, {
|
|
881
989
|
src: "escape listener",
|
|
990
|
+
id: "escape listener",
|
|
882
991
|
input: ({
|
|
883
992
|
context
|
|
884
993
|
}) => ({
|
|
885
|
-
|
|
994
|
+
context
|
|
886
995
|
})
|
|
887
996
|
}, {
|
|
888
997
|
src: "selection listener",
|
|
@@ -907,13 +1016,21 @@ function createTypeaheadPickerMachine() {
|
|
|
907
1016
|
}) => ({
|
|
908
1017
|
context
|
|
909
1018
|
})
|
|
1019
|
+
}, {
|
|
1020
|
+
src: "dismiss listener",
|
|
1021
|
+
id: "dismiss listener",
|
|
1022
|
+
input: ({
|
|
1023
|
+
context
|
|
1024
|
+
}) => ({
|
|
1025
|
+
context
|
|
1026
|
+
})
|
|
910
1027
|
}],
|
|
911
1028
|
on: {
|
|
912
|
-
|
|
1029
|
+
close: {
|
|
913
1030
|
target: "idle"
|
|
914
1031
|
},
|
|
915
1032
|
"selection changed": {
|
|
916
|
-
actions: ["
|
|
1033
|
+
actions: ["handle selection changed", "update submit listener context", "update text insertion listener context", "update escape listener context", "update request dismiss listener context"]
|
|
917
1034
|
}
|
|
918
1035
|
},
|
|
919
1036
|
always: [{
|
|
@@ -1141,7 +1258,7 @@ function getFirstExactMatch(matches) {
|
|
|
1141
1258
|
return matches.find((match) => match?.type === "exact");
|
|
1142
1259
|
}
|
|
1143
1260
|
function useTypeaheadPicker(definition) {
|
|
1144
|
-
const $ = c(
|
|
1261
|
+
const $ = c(21), editor = useEditor();
|
|
1145
1262
|
let t0;
|
|
1146
1263
|
$[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel") ? (t0 = createTypeaheadPickerMachine(), $[0] = t0) : t0 = $[0];
|
|
1147
1264
|
let t1;
|
|
@@ -1168,14 +1285,17 @@ function useTypeaheadPicker(definition) {
|
|
|
1168
1285
|
context: t4
|
|
1169
1286
|
}, $[11] = t2, $[12] = t4, $[13] = t5) : t5 = $[13];
|
|
1170
1287
|
let t6;
|
|
1171
|
-
$[14] !== send ? (t6 = (event) => {
|
|
1172
|
-
send(
|
|
1173
|
-
|
|
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];
|
|
1174
1294
|
let t7;
|
|
1175
|
-
return $[
|
|
1295
|
+
return $[18] !== t5 || $[19] !== t6 ? (t7 = {
|
|
1176
1296
|
snapshot: t5,
|
|
1177
1297
|
send: t6
|
|
1178
|
-
}, $[
|
|
1298
|
+
}, $[18] = t5, $[19] = t6, $[20] = t7) : t7 = $[20], t7;
|
|
1179
1299
|
}
|
|
1180
1300
|
export {
|
|
1181
1301
|
defineTypeaheadPicker,
|