@portabletext/plugin-emoji-picker 1.0.3 → 1.0.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.
package/dist/index.cjs CHANGED
@@ -1,22 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var compilerRuntime = require("react/compiler-runtime"), editor = require("@portabletext/editor"), react = require("@xstate/react"), behaviors = require("@portabletext/editor/behaviors"), selectors = require("@portabletext/editor/selectors"), utils = require("@portabletext/editor/utils"), keyboardShortcuts = require("@portabletext/keyboard-shortcuts"), pluginInputRule = require("@portabletext/plugin-input-rule"), xstate = require("xstate");
4
- function _interopNamespaceCompat(e) {
5
- if (e && typeof e == "object" && "default" in e) return e;
6
- var n = /* @__PURE__ */ Object.create(null);
7
- return e && Object.keys(e).forEach(function(k) {
8
- if (k !== "default") {
9
- var d = Object.getOwnPropertyDescriptor(e, k);
10
- Object.defineProperty(n, k, d.get ? d : {
11
- enumerable: !0,
12
- get: function() {
13
- return e[k];
14
- }
15
- });
16
- }
17
- }), n.default = e, Object.freeze(n);
18
- }
19
- var selectors__namespace = /* @__PURE__ */ _interopNamespaceCompat(selectors), utils__namespace = /* @__PURE__ */ _interopNamespaceCompat(utils);
3
+ var compilerRuntime = require("react/compiler-runtime"), editor = require("@portabletext/editor"), react = require("@xstate/react"), behaviors = require("@portabletext/editor/behaviors"), selectors = require("@portabletext/editor/selectors"), keyboardShortcuts = require("@portabletext/keyboard-shortcuts"), pluginInputRule = require("@portabletext/plugin-input-rule"), xstate = require("xstate");
20
4
  function createMatchEmojis(config) {
21
5
  return ({
22
6
  keyword
@@ -72,22 +56,99 @@ const arrowUpShortcut = keyboardShortcuts.createKeyboardShortcut({
72
56
  default: [{
73
57
  key: "Escape"
74
58
  }]
75
- }), triggerRule = pluginInputRule.defineInputRule({
59
+ }), getTriggerState = (snapshot) => {
60
+ const focusSpan = selectors.getFocusSpan(snapshot), markState = selectors.getMarkState(snapshot);
61
+ if (!focusSpan || !markState || !snapshot.context.selection)
62
+ return;
63
+ const focusSpanTextBefore = focusSpan.node.text.slice(0, snapshot.context.selection.focus.offset), focusSpanTextAfter = focusSpan.node.text.slice(snapshot.context.selection.focus.offset), nextSpan = selectors.getNextSpan(snapshot);
64
+ return {
65
+ focusSpan,
66
+ markState,
67
+ focusSpanTextBefore,
68
+ focusSpanTextAfter,
69
+ nextSpan
70
+ };
71
+ };
72
+ function createTriggerActions({
73
+ snapshot,
74
+ payload,
75
+ keywordState
76
+ }) {
77
+ if (payload.markState.state === "unchanged") {
78
+ const focusSpan2 = {
79
+ node: {
80
+ _key: payload.focusSpan.node._key,
81
+ _type: payload.focusSpan.node._type,
82
+ text: `${payload.focusSpanTextBefore}${payload.lastMatch.text}${payload.focusSpanTextAfter}`,
83
+ marks: payload.markState.marks
84
+ },
85
+ path: payload.focusSpan.path,
86
+ textBefore: payload.focusSpanTextBefore,
87
+ textAfter: payload.focusSpanTextAfter
88
+ };
89
+ return keywordState === "complete" ? [behaviors.raise(createKeywordFoundEvent({
90
+ focusSpan: focusSpan2
91
+ }))] : [behaviors.raise(createTriggerFoundEvent({
92
+ focusSpan: focusSpan2
93
+ }))];
94
+ }
95
+ const newSpan = {
96
+ _key: snapshot.context.keyGenerator(),
97
+ _type: payload.focusSpan.node._type,
98
+ text: payload.lastMatch.text,
99
+ marks: payload.markState.marks
100
+ }, focusSpan = {
101
+ node: {
102
+ _key: newSpan._key,
103
+ _type: newSpan._type,
104
+ text: `${newSpan.text}${payload.nextSpan?.node.text ?? ""}`,
105
+ marks: payload.markState.marks
106
+ },
107
+ path: [{
108
+ _key: payload.focusSpan.path[0]._key
109
+ }, "children", {
110
+ _key: newSpan._key
111
+ }],
112
+ textBefore: "",
113
+ textAfter: payload.nextSpan?.node.text ?? ""
114
+ };
115
+ return [behaviors.raise({
116
+ type: "select",
117
+ at: payload.lastMatch.targetOffsets
118
+ }), behaviors.raise({
119
+ type: "delete",
120
+ at: payload.lastMatch.targetOffsets
121
+ }), behaviors.raise({
122
+ type: "insert.child",
123
+ child: newSpan
124
+ }), ...keywordState === "complete" ? [behaviors.raise(createKeywordFoundEvent({
125
+ focusSpan
126
+ }))] : [behaviors.raise(createTriggerFoundEvent({
127
+ focusSpan
128
+ }))]];
129
+ }
130
+ const triggerRule = pluginInputRule.defineInputRule({
76
131
  on: /:/,
77
132
  guard: ({
133
+ snapshot,
78
134
  event
79
135
  }) => {
80
136
  const lastMatch = event.matches.at(-1);
81
- return lastMatch === void 0 ? !1 : {
82
- keyword: lastMatch.text,
83
- keywordAnchor: {
84
- point: lastMatch.selection.anchor,
85
- blockOffset: lastMatch.targetOffsets.anchor
86
- },
87
- keywordFocus: lastMatch.targetOffsets.focus
88
- };
137
+ if (lastMatch === void 0)
138
+ return !1;
139
+ const triggerState = getTriggerState(snapshot);
140
+ return triggerState ? {
141
+ lastMatch,
142
+ ...triggerState
143
+ } : !1;
89
144
  },
90
- actions: [(_, payload) => [behaviors.raise(createTriggerFoundEvent(payload))]]
145
+ actions: [({
146
+ snapshot
147
+ }, payload) => createTriggerActions({
148
+ snapshot,
149
+ payload,
150
+ keywordState: "partial"
151
+ })]
91
152
  });
92
153
  function createTriggerFoundEvent(payload) {
93
154
  return {
@@ -98,48 +159,47 @@ function createTriggerFoundEvent(payload) {
98
159
  const partialKeywordRule = pluginInputRule.defineInputRule({
99
160
  on: /:[\S]+/,
100
161
  guard: ({
162
+ snapshot,
101
163
  event
102
164
  }) => {
103
165
  const lastMatch = event.matches.at(-1);
104
- if (lastMatch === void 0)
166
+ if (lastMatch === void 0 || lastMatch.targetOffsets.anchor.offset < event.textBefore.length)
105
167
  return !1;
106
- const keyword = lastMatch.text, keywordAnchor = {
107
- point: lastMatch.selection.anchor,
108
- blockOffset: lastMatch.targetOffsets.anchor
109
- }, keywordFocus = lastMatch.targetOffsets.focus;
110
- return {
111
- keyword,
112
- keywordAnchor,
113
- keywordFocus
114
- };
168
+ const triggerState = getTriggerState(snapshot);
169
+ return triggerState ? {
170
+ ...triggerState,
171
+ lastMatch
172
+ } : !1;
115
173
  },
116
- actions: [(_, payload) => [behaviors.raise(createPartialKeywordFoundEvent(payload))]]
117
- });
118
- function createPartialKeywordFoundEvent(payload) {
119
- return {
120
- type: "custom.partial keyword found",
121
- ...payload
122
- };
123
- }
124
- const keywordRule = pluginInputRule.defineInputRule({
174
+ actions: [({
175
+ snapshot
176
+ }, payload) => createTriggerActions({
177
+ snapshot,
178
+ payload,
179
+ keywordState: "partial"
180
+ })]
181
+ }), keywordRule = pluginInputRule.defineInputRule({
125
182
  on: /:[\S]+:/,
126
183
  guard: ({
184
+ snapshot,
127
185
  event
128
186
  }) => {
129
187
  const lastMatch = event.matches.at(-1);
130
- if (lastMatch === void 0)
188
+ if (lastMatch === void 0 || lastMatch.targetOffsets.anchor.offset < event.textBefore.length)
131
189
  return !1;
132
- const keyword = lastMatch.text, keywordAnchor = {
133
- point: lastMatch.selection.anchor,
134
- blockOffset: lastMatch.targetOffsets.anchor
135
- }, keywordFocus = lastMatch.targetOffsets.focus;
136
- return {
137
- keyword,
138
- keywordAnchor,
139
- keywordFocus
140
- };
190
+ const triggerState = getTriggerState(snapshot);
191
+ return triggerState ? {
192
+ ...triggerState,
193
+ lastMatch
194
+ } : !1;
141
195
  },
142
- actions: [(_, payload) => [behaviors.raise(createKeywordFoundEvent(payload))]]
196
+ actions: [({
197
+ snapshot
198
+ }, payload) => createTriggerActions({
199
+ snapshot,
200
+ payload,
201
+ keywordState: "complete"
202
+ })]
143
203
  });
144
204
  function createKeywordFoundEvent(payload) {
145
205
  return {
@@ -164,15 +224,6 @@ const triggerListenerCallback = ({
164
224
  sendBack(event);
165
225
  })]]
166
226
  })
167
- }), input.editor.registerBehavior({
168
- behavior: behaviors.defineBehavior({
169
- on: "custom.partial keyword found",
170
- actions: [({
171
- event
172
- }) => [behaviors.effect(() => {
173
- sendBack(event);
174
- })]]
175
- })
176
227
  }), input.editor.registerBehavior({
177
228
  behavior: behaviors.defineBehavior({
178
229
  on: "custom.trigger found",
@@ -248,10 +299,16 @@ const triggerListenerCallback = ({
248
299
  type: "dismiss"
249
300
  });
250
301
  }), behaviors.raise({
251
- type: "delete.text",
302
+ type: "delete",
252
303
  at: {
253
- anchor: event.anchor,
254
- focus: event.focus
304
+ anchor: {
305
+ path: event.focusSpan.path,
306
+ offset: event.focusSpan.textBefore.length
307
+ },
308
+ focus: {
309
+ path: event.focusSpan.path,
310
+ offset: event.focusSpan.node.text.length - event.focusSpan.textAfter.length
311
+ }
255
312
  }
256
313
  }), behaviors.raise({
257
314
  type: "insert.text",
@@ -275,22 +332,19 @@ const triggerListenerCallback = ({
275
332
  }) => {
276
333
  if (!enterShortcut.guard(event.originEvent) && !tabShortcut.guard(event.originEvent))
277
334
  return !1;
278
- const anchor = context.keywordAnchor?.blockOffset, focus = context.keywordFocus, match = context.matches[context.selectedIndex];
279
- return match && anchor && focus ? {
280
- anchor,
281
- focus,
335
+ const focusSpan = context.focusSpan, match = context.matches[context.selectedIndex];
336
+ return match && focusSpan ? {
337
+ focusSpan,
282
338
  emoji: match.emoji
283
339
  } : !1;
284
340
  },
285
341
  actions: [(_, {
286
- anchor,
287
- focus,
342
+ focusSpan,
288
343
  emoji
289
344
  }) => [behaviors.raise({
290
345
  type: "custom.insert emoji",
291
346
  emoji,
292
- anchor,
293
- focus
347
+ focusSpan
294
348
  })]]
295
349
  })
296
350
  }), input.context.editor.registerBehavior({
@@ -305,19 +359,6 @@ const triggerListenerCallback = ({
305
359
  });
306
360
  })]]
307
361
  })
308
- }), input.context.editor.registerBehavior({
309
- behavior: pluginInputRule.defineInputRuleBehavior({
310
- rules: [keywordRule]
311
- })
312
- }), input.context.editor.registerBehavior({
313
- behavior: behaviors.defineBehavior({
314
- on: "custom.keyword found",
315
- actions: [({
316
- event
317
- }) => [behaviors.effect(() => {
318
- sendBack(event);
319
- })]]
320
- })
321
362
  })];
322
363
  return () => {
323
364
  for (const unregister of unregisterBehaviors)
@@ -332,75 +373,7 @@ const triggerListenerCallback = ({
332
373
  type: "selection changed",
333
374
  snapshot
334
375
  });
335
- }).unsubscribe, textChangeListener = ({
336
- sendBack,
337
- input
338
- }) => {
339
- const unregisterBehaviors = [input.editor.registerBehavior({
340
- behavior: behaviors.defineBehavior({
341
- on: "insert.text",
342
- guard: ({
343
- snapshot
344
- }) => snapshot.context.selection ? {
345
- focus: snapshot.context.selection.focus
346
- } : !1,
347
- actions: [({
348
- event
349
- }, {
350
- focus
351
- }) => [behaviors.effect(() => {
352
- sendBack({
353
- ...event,
354
- focus
355
- });
356
- }), behaviors.forward(event)]]
357
- })
358
- }), input.editor.registerBehavior({
359
- behavior: behaviors.defineBehavior({
360
- on: "delete.backward",
361
- guard: ({
362
- snapshot,
363
- event
364
- }) => event.unit === "character" && snapshot.context.selection ? {
365
- focus: snapshot.context.selection.focus
366
- } : !1,
367
- actions: [({
368
- event
369
- }, {
370
- focus
371
- }) => [behaviors.effect(() => {
372
- sendBack({
373
- type: "delete.backward",
374
- focus
375
- });
376
- }), behaviors.forward(event)]]
377
- })
378
- }), input.editor.registerBehavior({
379
- behavior: behaviors.defineBehavior({
380
- on: "delete.forward",
381
- guard: ({
382
- snapshot,
383
- event
384
- }) => event.unit === "character" && snapshot.context.selection ? {
385
- focus: snapshot.context.selection.focus
386
- } : !1,
387
- actions: [({
388
- event
389
- }, {
390
- focus
391
- }) => [behaviors.effect(() => {
392
- sendBack({
393
- type: "delete.forward",
394
- focus
395
- });
396
- }), behaviors.forward(event)]]
397
- })
398
- })];
399
- return () => {
400
- for (const unregister of unregisterBehaviors)
401
- unregister();
402
- };
403
- }, emojiPickerMachine = xstate.setup({
376
+ }).unsubscribe, emojiPickerMachine = xstate.setup({
404
377
  types: {
405
378
  context: {},
406
379
  input: {},
@@ -412,60 +385,44 @@ const triggerListenerCallback = ({
412
385
  "arrow listener": xstate.fromCallback(arrowListenerCallback),
413
386
  "trigger listener": xstate.fromCallback(triggerListenerCallback),
414
387
  "escape listener": xstate.fromCallback(escapeListenerCallback),
415
- "selection listener": xstate.fromCallback(selectionListenerCallback),
416
- "text change listener": xstate.fromCallback(textChangeListener)
388
+ "selection listener": xstate.fromCallback(selectionListenerCallback)
417
389
  },
418
390
  actions: {
419
- "init keyword": xstate.assign({
420
- keyword: ({
391
+ "set focus span": xstate.assign({
392
+ focusSpan: ({
421
393
  context,
422
394
  event
423
- }) => event.type !== "custom.trigger found" && event.type !== "custom.partial keyword found" && event.type !== "custom.keyword found" ? context.keyword : event.keyword
395
+ }) => event.type !== "custom.trigger found" && event.type !== "custom.keyword found" ? context.focusSpan : event.focusSpan
424
396
  }),
425
- "set keyword anchor": xstate.assign({
426
- keywordAnchor: ({
427
- context,
428
- event
429
- }) => event.type !== "custom.trigger found" && event.type !== "custom.partial keyword found" && event.type !== "custom.keyword found" ? context.keywordAnchor : event.keywordAnchor
430
- }),
431
- "set keyword focus": xstate.assign({
432
- keywordFocus: ({
433
- context,
434
- event
435
- }) => event.type !== "custom.trigger found" && event.type !== "custom.partial keyword found" && event.type !== "custom.keyword found" ? context.keywordFocus : event.keywordFocus
436
- }),
437
- "update keyword focus": xstate.assign({
438
- keywordFocus: ({
439
- context,
440
- event
441
- }) => (xstate.assertEvent(event, ["insert.text", "delete.backward", "delete.forward"]), context.keywordFocus ? {
442
- path: context.keywordFocus.path,
443
- offset: event.type === "insert.text" ? context.keywordFocus.offset + event.text.length : event.type === "delete.backward" || event.type === "delete.forward" ? context.keywordFocus.offset - 1 : event.focus.offset
444
- } : context.keywordFocus)
397
+ "update focus span": xstate.assign({
398
+ focusSpan: ({
399
+ context
400
+ }) => {
401
+ if (!context.focusSpan)
402
+ return;
403
+ const snapshot = context.editor.getSnapshot(), focusSpan = selectors.getFocusSpan(snapshot);
404
+ if (!focusSpan || JSON.stringify(focusSpan.path) !== JSON.stringify(context.focusSpan.path) || !focusSpan.node.text.startsWith(context.focusSpan.textBefore) || !focusSpan.node.text.endsWith(context.focusSpan.textAfter))
405
+ return;
406
+ const keywordAnchor = {
407
+ path: focusSpan.path,
408
+ offset: context.focusSpan.textBefore.length
409
+ }, keywordFocus = {
410
+ path: focusSpan.path,
411
+ offset: focusSpan.node.text.length - context.focusSpan.textAfter.length
412
+ }, selectionIsBeforeKeyword = selectors.isPointAfterSelection(keywordAnchor)(snapshot), selectionIsAfterKeyword = selectors.isPointBeforeSelection(keywordFocus)(snapshot);
413
+ if (!(selectionIsBeforeKeyword || selectionIsAfterKeyword))
414
+ return {
415
+ node: focusSpan.node,
416
+ path: focusSpan.path,
417
+ textBefore: context.focusSpan.textBefore,
418
+ textAfter: context.focusSpan.textAfter
419
+ };
420
+ }
445
421
  }),
446
422
  "update keyword": xstate.assign({
447
423
  keyword: ({
448
- context,
449
- event
450
- }) => {
451
- if (xstate.assertEvent(event, "selection changed"), !context.keywordAnchor || !context.keywordFocus)
452
- return "";
453
- const keywordFocusPoint = utils__namespace.blockOffsetToSpanSelectionPoint({
454
- context: event.snapshot.context,
455
- blockOffset: context.keywordFocus,
456
- direction: "forward"
457
- });
458
- return keywordFocusPoint ? selectors__namespace.getSelectionText({
459
- ...event.snapshot,
460
- context: {
461
- ...event.snapshot.context,
462
- selection: {
463
- anchor: context.keywordAnchor.point,
464
- focus: keywordFocusPoint
465
- }
466
- }
467
- }) : "";
468
- }
424
+ context
425
+ }) => context.focusSpan ? context.focusSpan.textBefore.length > 0 && context.focusSpan.textAfter.length > 0 ? context.focusSpan.node.text.slice(context.focusSpan.textBefore.length, -context.focusSpan.textAfter.length) : context.focusSpan.textBefore.length > 0 ? context.focusSpan.node.text.slice(context.focusSpan.textBefore.length) : context.focusSpan.textAfter.length > 0 ? context.focusSpan.node.text.slice(0, -context.focusSpan.textAfter.length) : context.focusSpan.node.text : ""
469
426
  }),
470
427
  "update matches": xstate.assign({
471
428
  matches: ({
@@ -495,12 +452,6 @@ const triggerListenerCallback = ({
495
452
  event
496
453
  }) => (xstate.assertEvent(event, "navigate to"), event.index)
497
454
  }),
498
- "update emoji insert listener context": xstate.sendTo("emoji insert listener", ({
499
- context
500
- }) => ({
501
- type: "context changed",
502
- context
503
- })),
504
455
  "update submit listener context": xstate.sendTo("submit listener", ({
505
456
  context
506
457
  }) => ({
@@ -508,86 +459,52 @@ const triggerListenerCallback = ({
508
459
  context
509
460
  })),
510
461
  "insert selected match": ({
511
- context,
512
- event
462
+ context
513
463
  }) => {
514
464
  const match = context.matches[context.selectedIndex];
515
- !match || !context.keywordAnchor || !context.keywordFocus || event.type === "custom.keyword found" && match.type !== "exact" || context.editor.send({
465
+ !match || !context.focusSpan || context.editor.send({
516
466
  type: "custom.insert emoji",
517
467
  emoji: match.emoji,
518
- anchor: context.keywordAnchor.blockOffset,
519
- focus: context.keywordFocus
468
+ focusSpan: context.focusSpan
520
469
  });
521
470
  },
522
471
  reset: xstate.assign({
523
- keywordAnchor: void 0,
524
- keywordFocus: void 0,
472
+ focusSpan: void 0,
525
473
  keyword: "",
526
474
  matches: [],
527
475
  selectedIndex: 0
528
476
  })
529
477
  },
530
478
  guards: {
479
+ "no focus span": ({
480
+ context
481
+ }) => !context.focusSpan,
531
482
  "has matches": ({
532
483
  context
533
484
  }) => context.matches.length > 0,
534
485
  "no matches": xstate.not("has matches"),
535
- "keyword is wel-formed": ({
486
+ "keyword is malformed": ({
487
+ context
488
+ }) => !context.incompleteKeywordRegex.test(context.keyword),
489
+ "keyword is direct match": ({
536
490
  context
537
- }) => context.incompleteKeywordRegex.test(context.keyword),
538
- "keyword is malformed": xstate.not("keyword is wel-formed"),
539
- "selection is before keyword": ({
540
- context,
541
- event
542
- }) => (xstate.assertEvent(event, "selection changed"), context.keywordAnchor ? selectors__namespace.isPointAfterSelection(context.keywordAnchor.point)(event.snapshot) : !0),
543
- "selection is after keyword": ({
544
- context,
545
- event
546
- }) => {
547
- if (xstate.assertEvent(event, "selection changed"), context.keywordFocus === void 0)
548
- return !0;
549
- const keywordFocusPoint = utils__namespace.blockOffsetToSpanSelectionPoint({
550
- context: event.snapshot.context,
551
- blockOffset: context.keywordFocus,
552
- direction: "forward"
553
- });
554
- return keywordFocusPoint ? selectors__namespace.isPointBeforeSelection(keywordFocusPoint)(event.snapshot) : !0;
555
- },
556
- "selection is expanded": ({
557
- event
558
- }) => (xstate.assertEvent(event, "selection changed"), selectors__namespace.isSelectionExpanded(event.snapshot)),
559
- "selection moved unexpectedly": xstate.or(["selection is before keyword", "selection is after keyword", "selection is expanded"]),
560
- "unexpected text insertion": ({
561
- context,
562
- event
563
491
  }) => {
564
- if (event.type !== "insert.text" || !context.keywordAnchor)
492
+ if (!/^:[\S]+:$/.test(context.keyword))
565
493
  return !1;
566
- const snapshot = context.editor.getSnapshot();
567
- return selectors__namespace.isPointBeforeSelection(event.focus)({
568
- ...snapshot,
569
- context: {
570
- ...snapshot.context,
571
- selection: {
572
- anchor: context.keywordAnchor.point,
573
- focus: context.keywordAnchor.point
574
- }
575
- }
576
- }) || utils__namespace.isEqualSelectionPoints(event.focus, context.keywordAnchor.point);
494
+ const match = context.matches.at(context.selectedIndex);
495
+ return !(!match || match.type !== "exact");
577
496
  }
578
497
  }
579
498
  }).createMachine({
580
- /** @xstate-layout N4IgpgJg5mDOIC5RgLYHsBWBLABABywGMBrMAJwDosIAbMAYkLRrQDsctXZyAXSAbQAMAXUSg8aWFh5Y2YkAA9EARmUB2AJwUAzADYNADgCs65YO1q1ygDQgAnojUG1O5c+W7tAJmdfdRgF8A21RMXAIScgpuAEMyQgALTih6Tm4yHgo+BR4hUSQQCSkZOQKlBABaZW0DHSMAFksNQUF6oyNzL1sHBC9vCnrGtS8GtQaNNt0gkPRsfCJSSlj4pNYUiDA6PgoAMzQyAHc4iDz5IulZVnlyr3MKE30LA31DZoNuxD6vAaHdP29vOo1NNwLNwgsostEsl6BstmAKAAjGIkI5kE4iM6SC6lUDlerabT3arDfS3eoaPQfXr9QaWEaNcaTEGhOYRRbRMBxaFrWFYWAofmwU4Fc4lK5lFTqWqDAwUjReeoGbwaNTU1TPCh-QxNNS6XQGHwssHzSJLLkrGHcOiEcU4RIxNYCTGi7Hi66IfxE1oeZX1EbeZXUhUUZSKjxOOV6bTmY1hU0cqGrFLWsC2y72hKOmAnZT5cRuy4ehDVXQUVXDIyWGpmAzveyfLRKwQaVRVwR1ixeONsiHm7nJ+gigvFIuSkvKVuhgwaEwKmMKwbqkaCAaverqVuvKbBUHx9mQi08qAUVhoHAoGI8RJwHCwBJoA4w4eFQu4xSfaoDA3KOmCVSTn06r-i4-hGH0ZiEoI4H1D24JmpyA7JNED5PmsF5XjesD0KwMQAG5YFAV5gDgECPqwL5imOeKIIM9ShsoRh1i2erPB41L6C40GqISUb6n8cEJoeSFrChj7JBh14JHAOH4YRxE4AArnglFvhKNEIGoq4+E0yraPULa6PUHGqhQ3HVDUBL8dogkHv2lqife4noZeUkybhBFEXwOA8Ggqmju+5RGPqFBqP6ujDD4v4tjYDYIMqLjVKo5gdM4TGBLurLwYmR7JmJaFQJJWGpFwvB3psaZ8BARUJP5OLqR+CD1Loq5ymYfyeP4spGOqv70fpv7NBSBKtBlMz7n2iEOSeTkFTVMl1e645eB49wGP+K0UpBbjaMBzQUF4IzBYq7TNa2QS7meGzwAUWVCWQWIBQ15RVJq2ijJoLRtB03jUhUVYUHKtz-gqeoxkYGi2ZN1B0I99XFqobTlh4-5-Ot4H1j0ZirbcENhR4RmKrBmUmnZU3HnDS0aVUjHlh2cqtkqfTBdSSr0RMGieBS7htASUMIUmyFnvNsB3qhySU9RjUVBFdN1ltTPvbowZOGZEWHe9xgTHo-M5SJM3iy5mHSTdI7w+OlnlgY6heJzbgUv4ytxaqtSCBFg1eJFM4XQEQA */
581
499
  id: "emoji picker",
582
500
  context: ({
583
501
  input
584
502
  }) => ({
585
503
  editor: input.editor,
586
504
  keyword: "",
587
- keywordAnchor: void 0,
588
- keywordFocus: void 0,
505
+ focusSpan: void 0,
589
506
  matchEmojis: input.matchEmojis,
590
- incompleteKeywordRegex: /:[\S]*$/,
507
+ incompleteKeywordRegex: /^:[\S]*$/,
591
508
  matches: [],
592
509
  selectedIndex: 0
593
510
  }),
@@ -615,14 +532,10 @@ const triggerListenerCallback = ({
615
532
  on: {
616
533
  "custom.trigger found": {
617
534
  target: "searching",
618
- actions: ["set keyword anchor", "set keyword focus", "init keyword"]
619
- },
620
- "custom.partial keyword found": {
621
- target: "searching",
622
- actions: ["set keyword anchor", "set keyword focus", "init keyword"]
535
+ actions: ["set focus span", "update keyword"]
623
536
  },
624
537
  "custom.keyword found": {
625
- actions: ["set keyword anchor", "set keyword focus", "init keyword", "update matches", "insert selected match"],
538
+ actions: ["set focus span", "update keyword", "update matches", "insert selected match"],
626
539
  target: "idle",
627
540
  reenter: !0
628
541
  }
@@ -651,43 +564,25 @@ const triggerListenerCallback = ({
651
564
  }) => ({
652
565
  editor: context.editor
653
566
  })
654
- }, {
655
- src: "text change listener",
656
- input: ({
657
- context
658
- }) => ({
659
- editor: context.editor
660
- })
661
567
  }],
662
568
  on: {
663
- "custom.keyword found": {
664
- actions: ["set keyword anchor", "set keyword focus", "init keyword", "update matches", "insert selected match"]
665
- },
666
- "insert.text": [{
667
- guard: "unexpected text insertion",
668
- target: "idle"
669
- }, {
670
- actions: ["update keyword focus"]
671
- }],
672
- "delete.forward": {
673
- actions: ["update keyword focus"]
674
- },
675
- "delete.backward": {
676
- actions: ["update keyword focus"]
677
- },
678
569
  dismiss: {
679
570
  target: "idle"
680
571
  },
681
572
  "selection changed": [{
682
- guard: "selection moved unexpectedly",
683
- target: "idle"
684
- }, {
685
- actions: ["update keyword", "update matches", "reset selected index", "update submit listener context"]
573
+ actions: ["update focus span", "update keyword", "update matches", "reset selected index", "update submit listener context"]
686
574
  }]
687
575
  },
688
576
  always: [{
577
+ guard: "no focus span",
578
+ target: "idle"
579
+ }, {
689
580
  guard: "keyword is malformed",
690
581
  target: "idle"
582
+ }, {
583
+ guard: "keyword is direct match",
584
+ actions: ["insert selected match"],
585
+ target: "idle"
691
586
  }],
692
587
  initial: "no matches showing",
693
588
  states: {