@lumel/mention 5.2.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.
Files changed (34) hide show
  1. package/CHANGELOG.md +286 -0
  2. package/LICENSE +7 -0
  3. package/README.md +9 -0
  4. package/lib/Mention.d.ts +22 -0
  5. package/lib/MentionSuggestions/Entry/Avatar/Avatar.d.ts +9 -0
  6. package/lib/MentionSuggestions/Entry/DefaultEntryComponent.d.ts +3 -0
  7. package/lib/MentionSuggestions/Entry/Entry.d.ts +38 -0
  8. package/lib/MentionSuggestions/MentionSuggestions.d.ts +80 -0
  9. package/lib/MentionSuggestions/Popover.d.ts +10 -0
  10. package/lib/MentionSuggestions/__test__/MentionSuggestions.test.d.ts +1 -0
  11. package/lib/MentionSuggestionsPortal.d.ts +11 -0
  12. package/lib/__test__/Mention.test.d.ts +1 -0
  13. package/lib/__test__/mentionSuggestionsStrategy.test.d.ts +1 -0
  14. package/lib/defaultRegExp.d.ts +2 -0
  15. package/lib/index.cjs.js +1215 -0
  16. package/lib/index.d.ts +66 -0
  17. package/lib/index.esm.js +1198 -0
  18. package/lib/mentionStrategy.d.ts +3 -0
  19. package/lib/mentionSuggestionsStrategy.d.ts +6 -0
  20. package/lib/modifiers/addMention.d.ts +3 -0
  21. package/lib/plugin.css +8 -0
  22. package/lib/theme.d.ts +12 -0
  23. package/lib/utils/__test__/getSearchTextAt.test.d.ts +1 -0
  24. package/lib/utils/__test__/getTriggerForMention.test.d.ts +1 -0
  25. package/lib/utils/__test__/getTypeByTrigger.test.d.ts +1 -0
  26. package/lib/utils/decodeOffsetKey.d.ts +7 -0
  27. package/lib/utils/defaultSuggestionsFilter.d.ts +3 -0
  28. package/lib/utils/getSearchText.d.ts +4 -0
  29. package/lib/utils/getSearchTextAt.d.ts +9 -0
  30. package/lib/utils/getTriggerForMention.d.ts +8 -0
  31. package/lib/utils/getTypeByTrigger.d.ts +1 -0
  32. package/lib/utils/positionSuggestions.d.ts +13 -0
  33. package/lib/utils/warning.d.ts +1 -0
  34. package/package.json +60 -0
@@ -0,0 +1,1198 @@
1
+ import { Map } from 'immutable';
2
+ import React, { useRef, useEffect, useState, Component, useLayoutEffect } from 'react';
3
+ import clsx from 'clsx';
4
+ import { Modifier, EditorState, genKey } from 'draft-js';
5
+ import PropTypes from 'prop-types';
6
+ import escapeRegExp from 'lodash-es/escapeRegExp';
7
+ import once from 'lodash-es/once';
8
+ import { usePopper } from 'react-popper';
9
+
10
+ function _extends() {
11
+ _extends = Object.assign ? Object.assign.bind() : function (target) {
12
+ for (var i = 1; i < arguments.length; i++) {
13
+ var source = arguments[i];
14
+
15
+ for (var key in source) {
16
+ if (Object.prototype.hasOwnProperty.call(source, key)) {
17
+ target[key] = source[key];
18
+ }
19
+ }
20
+ }
21
+
22
+ return target;
23
+ };
24
+ return _extends.apply(this, arguments);
25
+ }
26
+
27
+ function _inheritsLoose(subClass, superClass) {
28
+ subClass.prototype = Object.create(superClass.prototype);
29
+ subClass.prototype.constructor = subClass;
30
+
31
+ _setPrototypeOf(subClass, superClass);
32
+ }
33
+
34
+ function _setPrototypeOf(o, p) {
35
+ _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
36
+ o.__proto__ = p;
37
+ return o;
38
+ };
39
+ return _setPrototypeOf(o, p);
40
+ }
41
+
42
+ function _objectWithoutPropertiesLoose(source, excluded) {
43
+ if (source == null) return {};
44
+ var target = {};
45
+ var sourceKeys = Object.keys(source);
46
+ var key, i;
47
+
48
+ for (i = 0; i < sourceKeys.length; i++) {
49
+ key = sourceKeys[i];
50
+ if (excluded.indexOf(key) >= 0) continue;
51
+ target[key] = source[key];
52
+ }
53
+
54
+ return target;
55
+ }
56
+
57
+ function _unsupportedIterableToArray(o, minLen) {
58
+ if (!o) return;
59
+ if (typeof o === "string") return _arrayLikeToArray(o, minLen);
60
+ var n = Object.prototype.toString.call(o).slice(8, -1);
61
+ if (n === "Object" && o.constructor) n = o.constructor.name;
62
+ if (n === "Map" || n === "Set") return Array.from(o);
63
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
64
+ }
65
+
66
+ function _arrayLikeToArray(arr, len) {
67
+ if (len == null || len > arr.length) len = arr.length;
68
+
69
+ for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
70
+
71
+ return arr2;
72
+ }
73
+
74
+ function _createForOfIteratorHelperLoose(o, allowArrayLike) {
75
+ var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
76
+ if (it) return (it = it.call(o)).next.bind(it);
77
+
78
+ if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
79
+ if (it) o = it;
80
+ var i = 0;
81
+ return function () {
82
+ if (i >= o.length) return {
83
+ done: true
84
+ };
85
+ return {
86
+ done: false,
87
+ value: o[i++]
88
+ };
89
+ };
90
+ }
91
+
92
+ throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
93
+ }
94
+
95
+ function MentionLink(_ref) {
96
+ var mention = _ref.mention,
97
+ children = _ref.children,
98
+ className = _ref.className;
99
+ return /*#__PURE__*/React.createElement("a", {
100
+ href: mention.link,
101
+ className: className,
102
+ spellCheck: false,
103
+ "data-testid": "mentionLink"
104
+ }, children);
105
+ }
106
+
107
+ function MentionText(_ref2) {
108
+ var children = _ref2.children,
109
+ className = _ref2.className;
110
+ return /*#__PURE__*/React.createElement("span", {
111
+ className: className,
112
+ spellCheck: false,
113
+ "data-testid": "mentionText"
114
+ }, children);
115
+ }
116
+
117
+ function Mention(props) {
118
+ var entityKey = props.entityKey,
119
+ _props$theme = props.theme,
120
+ theme = _props$theme === void 0 ? {} : _props$theme,
121
+ mentionComponent = props.mentionComponent,
122
+ children = props.children,
123
+ decoratedText = props.decoratedText,
124
+ className = props.className,
125
+ contentState = props.contentState;
126
+ var combinedClassName = clsx(theme.mention, className);
127
+ var mention = contentState.getEntity(entityKey).getData().mention;
128
+ var Component = mentionComponent || (mention.link ? MentionLink : MentionText);
129
+ return /*#__PURE__*/React.createElement(Component, {
130
+ entityKey: entityKey,
131
+ mention: mention,
132
+ theme: theme,
133
+ className: combinedClassName,
134
+ decoratedText: decoratedText
135
+ }, children);
136
+ }
137
+
138
+ /**
139
+ * Return tail end of the string matching trigger upto the position.
140
+ */
141
+ function getSearchTextAt(blockText, position, triggers) {
142
+ var str = blockText.substr(0, position);
143
+ var triggerPattern = triggers.map(function (trigger) {
144
+ return escapeRegExp(trigger);
145
+ }).join('|');
146
+ var TRIGGER_REGEX = new RegExp("(\\s|^)(" + triggerPattern + ")", 'g');
147
+ var matches = str.matchAll(TRIGGER_REGEX);
148
+ var triggerStartIndex = 0;
149
+ var valueStartIndex = 0;
150
+
151
+ for (var _iterator = _createForOfIteratorHelperLoose(matches), _step; !(_step = _iterator()).done;) {
152
+ var match = _step.value;
153
+ var spaceLen = match[1].length;
154
+ var matchLen = match[2].length;
155
+ triggerStartIndex = (match.index || 0) + spaceLen;
156
+ valueStartIndex = triggerStartIndex + matchLen;
157
+ }
158
+
159
+ var matchingString = str.slice(valueStartIndex);
160
+ var end = str.length;
161
+ return {
162
+ begin: triggerStartIndex,
163
+ end: end,
164
+ matchingString: matchingString
165
+ };
166
+ }
167
+
168
+ var getSearchText = (function (editorState, selection, triggers) {
169
+ var anchorKey = selection.getAnchorKey();
170
+ var anchorOffset = selection.getAnchorOffset();
171
+ var currentContent = editorState.getCurrentContent();
172
+ var currentBlock = currentContent.getBlockForKey(anchorKey);
173
+ var blockText = currentBlock.getText();
174
+ return getSearchTextAt(blockText, anchorOffset, triggers);
175
+ });
176
+
177
+ function getTypeByTrigger(trigger) {
178
+ return trigger === '@' ? 'mention' : trigger + "mention";
179
+ }
180
+
181
+ function addMention(editorState, mention, mentionPrefix, mentionTrigger, entityMutability) {
182
+ var contentStateWithEntity = editorState.getCurrentContent().createEntity(getTypeByTrigger(mentionTrigger), entityMutability, {
183
+ mention: mention
184
+ });
185
+ var entityKey = contentStateWithEntity.getLastCreatedEntityKey();
186
+ var currentSelectionState = editorState.getSelection();
187
+
188
+ var _getSearchText = getSearchText(editorState, currentSelectionState, [mentionTrigger]),
189
+ begin = _getSearchText.begin,
190
+ end = _getSearchText.end; // get selection of the @mention search text
191
+
192
+
193
+ var mentionTextSelection = currentSelectionState.merge({
194
+ anchorOffset: begin,
195
+ focusOffset: end
196
+ });
197
+ var mentionReplacedContent = Modifier.replaceText(editorState.getCurrentContent(), mentionTextSelection, "" + mentionPrefix + mention.name, editorState.getCurrentInlineStyle(), entityKey); // If the mention is inserted at the end, a space is appended right after for
198
+ // a smooth writing experience.
199
+
200
+ var blockKey = mentionTextSelection.getAnchorKey();
201
+ var blockSize = editorState.getCurrentContent().getBlockForKey(blockKey).getLength();
202
+
203
+ if (blockSize === end) {
204
+ mentionReplacedContent = Modifier.insertText(mentionReplacedContent, mentionReplacedContent.getSelectionAfter(), ' ');
205
+ }
206
+
207
+ var newEditorState = EditorState.push(editorState, mentionReplacedContent, 'insert-fragment');
208
+ return EditorState.forceSelection(newEditorState, mentionReplacedContent.getSelectionAfter());
209
+ }
210
+
211
+ var decodeOffsetKey = function decodeOffsetKey(offsetKey) {
212
+ var _offsetKey$split = offsetKey.split('-'),
213
+ blockKey = _offsetKey$split[0],
214
+ decoratorKey = _offsetKey$split[1],
215
+ leafKey = _offsetKey$split[2];
216
+
217
+ return {
218
+ blockKey: blockKey,
219
+ decoratorKey: parseInt(decoratorKey, 10),
220
+ leafKey: parseInt(leafKey, 10)
221
+ };
222
+ };
223
+
224
+ var decodeOffsetKey$1 = decodeOffsetKey;
225
+
226
+ function filterUndefineds(value) {
227
+ return value !== undefined;
228
+ }
229
+
230
+ function getTriggerForMention(editorState, searches, mentionTriggers) {
231
+ // get the current selection
232
+ var selection = editorState.getSelection();
233
+ var anchorKey = selection.getAnchorKey();
234
+ var anchorOffset = selection.getAnchorOffset(); // the list should not be visible if a range is selected or the editor has no focus
235
+
236
+ if (!selection.isCollapsed() || !selection.getHasFocus()) {
237
+ return null;
238
+ } // identify the start & end positon of each search-text
239
+
240
+
241
+ var offsetDetails = searches.map(function (offsetKey) {
242
+ return decodeOffsetKey$1(offsetKey);
243
+ }); // a leave can be empty when it is removed due event.g. using backspace
244
+ // do not check leaves, use full decorated portal text
245
+
246
+ var leaves = offsetDetails.filter(function (offsetDetail) {
247
+ return offsetDetail.blockKey === anchorKey;
248
+ }).map(function (offsetDetail) {
249
+ return editorState.getBlockTree(offsetDetail.blockKey).getIn([offsetDetail.decoratorKey]);
250
+ }); // if all leaves are undefined the popover should be removed
251
+
252
+ if (leaves.every(function (leave) {
253
+ return leave === undefined;
254
+ })) {
255
+ return null;
256
+ } // Checks that the cursor is after the @ character but still somewhere in
257
+ // the word (search term). Setting it to allow the cursor to be left of
258
+ // the @ causes troubles due selection confusion.
259
+
260
+
261
+ var blockText = editorState.getCurrentContent().getBlockForKey(anchorKey).getText();
262
+ var triggerForSelectionInsideWord = leaves.filter(filterUndefineds).map(function (_ref) {
263
+ var start = _ref.start,
264
+ end = _ref.end;
265
+ return mentionTriggers.map(function (trigger) {
266
+ return (// @ is the first character
267
+ start === 0 && anchorOffset >= start + trigger.length && //should not trigger if the cursor is before the trigger
268
+ blockText.substr(0, trigger.length) === trigger && anchorOffset <= end || // @ is in the text or at the end, multi triggers
269
+ mentionTriggers.length > 1 && anchorOffset >= start + trigger.length && (blockText.substr(start + 1, trigger.length) === trigger || blockText.substr(start, trigger.length) === trigger) && anchorOffset <= end || // @ is in the text or at the end, single trigger
270
+ mentionTriggers.length === 1 && anchorOffset >= start + trigger.length && anchorOffset <= end ? trigger : undefined
271
+ );
272
+ }).filter(filterUndefineds)[0];
273
+ }).filter(filterUndefineds);
274
+
275
+ if (triggerForSelectionInsideWord.isEmpty()) {
276
+ return null;
277
+ }
278
+
279
+ var _triggerForSelectionI = triggerForSelectionInsideWord.entrySeq().first(),
280
+ activeOffsetKey = _triggerForSelectionI[0],
281
+ activeTrigger = _triggerForSelectionI[1];
282
+
283
+ return {
284
+ activeOffsetKey: activeOffsetKey,
285
+ activeTrigger: activeTrigger
286
+ };
287
+ }
288
+
289
+ var getRelativeParent = function getRelativeParent(element) {
290
+ if (!element) {
291
+ return null;
292
+ }
293
+
294
+ var position = window.getComputedStyle(element).getPropertyValue('position');
295
+
296
+ if (position !== 'static') {
297
+ return element;
298
+ }
299
+
300
+ return getRelativeParent(element.parentElement);
301
+ };
302
+
303
+ function positionSuggestions(_ref) {
304
+ var decoratorRect = _ref.decoratorRect,
305
+ popover = _ref.popover,
306
+ props = _ref.props;
307
+ var relativeParent = getRelativeParent(popover.parentElement);
308
+ var relativeRect;
309
+
310
+ if (relativeParent) {
311
+ var relativeParentRect = relativeParent.getBoundingClientRect();
312
+ relativeRect = {
313
+ scrollLeft: relativeParent.scrollLeft,
314
+ scrollTop: relativeParent.scrollTop,
315
+ left: decoratorRect.left - relativeParentRect.left,
316
+ top: decoratorRect.bottom - relativeParentRect.top
317
+ };
318
+ } else {
319
+ relativeRect = {
320
+ scrollTop: window.pageYOffset || document.documentElement.scrollTop,
321
+ scrollLeft: window.pageXOffset || document.documentElement.scrollLeft,
322
+ top: decoratorRect.bottom,
323
+ left: decoratorRect.left
324
+ };
325
+ }
326
+
327
+ var left = relativeRect.left + relativeRect.scrollLeft;
328
+ var top = relativeRect.top + relativeRect.scrollTop;
329
+ var transform;
330
+ var transition;
331
+
332
+ if (props.open) {
333
+ if (props.suggestions.length > 0) {
334
+ transform = 'scale(1)';
335
+ transition = 'all 0.25s cubic-bezier(.3,1.2,.2,1)';
336
+ } else {
337
+ transform = 'scale(0)';
338
+ transition = 'all 0.35s cubic-bezier(.3,1,.2,1)';
339
+ }
340
+ }
341
+
342
+ return {
343
+ left: left + "px",
344
+ top: top + "px",
345
+ transform: transform,
346
+ transformOrigin: '1em 0%',
347
+ transition: transition
348
+ };
349
+ }
350
+
351
+ var warning = once(function (text) {
352
+ if (process.env.NODE_ENV === 'development') {
353
+ // eslint-disable-next-line no-console
354
+ console.warn(text);
355
+ }
356
+ });
357
+
358
+ function Avatar(_ref) {
359
+ var mention = _ref.mention,
360
+ _ref$theme = _ref.theme,
361
+ theme = _ref$theme === void 0 ? {} : _ref$theme;
362
+
363
+ if (mention.avatar) {
364
+ return /*#__PURE__*/React.createElement("img", {
365
+ src: mention.avatar,
366
+ className: theme.mentionSuggestionsEntryAvatar,
367
+ role: "presentation"
368
+ });
369
+ }
370
+
371
+ return null;
372
+ }
373
+
374
+ var _excluded$1 = ["mention", "theme", "isFocused", "searchValue", "selectMention"];
375
+ function DefaultEntryComponent(props) {
376
+ var mention = props.mention,
377
+ theme = props.theme,
378
+ isFocused = props.isFocused;
379
+ props.searchValue;
380
+ props.selectMention;
381
+ var parentProps = _objectWithoutPropertiesLoose(props, _excluded$1);
382
+
383
+ return /*#__PURE__*/React.createElement("div", _extends({}, parentProps, {
384
+ "aria-selected": isFocused
385
+ }), /*#__PURE__*/React.createElement(Avatar, {
386
+ mention: mention,
387
+ theme: theme
388
+ }), /*#__PURE__*/React.createElement("span", {
389
+ className: theme == null ? void 0 : theme.mentionSuggestionsEntryText
390
+ }, mention.name));
391
+ }
392
+
393
+ var Entry = function Entry(_ref) {
394
+ var onMentionSelect = _ref.onMentionSelect,
395
+ mention = _ref.mention,
396
+ theme = _ref.theme,
397
+ index = _ref.index,
398
+ onMentionFocus = _ref.onMentionFocus,
399
+ isFocused = _ref.isFocused,
400
+ id = _ref.id,
401
+ searchValue = _ref.searchValue,
402
+ EntryComponent = _ref.entryComponent;
403
+ var mouseDown = useRef(false);
404
+ var ref = useRef(null);
405
+ useEffect(function () {
406
+ if (isFocused) {
407
+ //delay the scrolling as the popup needs some time for positioning
408
+ requestAnimationFrame(function () {
409
+ var _ref$current;
410
+
411
+ return (_ref$current = ref.current) == null ? void 0 : _ref$current.scrollIntoView({
412
+ behavior: 'smooth',
413
+ block: 'nearest'
414
+ });
415
+ });
416
+ }
417
+ }, [isFocused]);
418
+ useEffect(function () {
419
+ mouseDown.current = false;
420
+ });
421
+
422
+ var onMouseUp = function onMouseUp() {
423
+ if (mouseDown.current) {
424
+ onMentionSelect(mention);
425
+ mouseDown.current = false;
426
+ }
427
+ };
428
+
429
+ var onMouseDown = function onMouseDown(event) {
430
+ // Note: important to avoid a content edit change
431
+ event.preventDefault();
432
+ mouseDown.current = true;
433
+ };
434
+
435
+ var onMouseEnter = function onMouseEnter() {
436
+ onMentionFocus(index);
437
+ };
438
+
439
+ var className = isFocused ? theme.mentionSuggestionsEntryFocused : theme.mentionSuggestionsEntry;
440
+ return /*#__PURE__*/React.createElement("div", {
441
+ ref: ref
442
+ }, /*#__PURE__*/React.createElement(EntryComponent, {
443
+ className: className,
444
+ onMouseDown: onMouseDown,
445
+ onMouseUp: onMouseUp,
446
+ onMouseEnter: onMouseEnter,
447
+ role: "option",
448
+ id: id,
449
+ "aria-selected": isFocused ? 'true' : undefined,
450
+ theme: theme,
451
+ mention: mention,
452
+ isFocused: isFocused,
453
+ searchValue: searchValue,
454
+ selectMention: onMentionSelect
455
+ }));
456
+ };
457
+
458
+ Entry.propTypes = {
459
+ entryComponent: PropTypes.any.isRequired,
460
+ searchValue: PropTypes.string,
461
+ // eslint-disable-next-line react/no-unused-prop-types
462
+ onMentionSelect: PropTypes.func
463
+ };
464
+ var Entry$1 = Entry;
465
+
466
+ function Popover(_ref) {
467
+ var store = _ref.store,
468
+ children = _ref.children,
469
+ theme = _ref.theme,
470
+ _ref$popperOptions = _ref.popperOptions,
471
+ popperOptions = _ref$popperOptions === void 0 ? {
472
+ placement: 'bottom-start'
473
+ } : _ref$popperOptions;
474
+
475
+ var _useState = useState(function () {
476
+ return clsx(theme.mentionSuggestions, theme.mentionSuggestionsPopup);
477
+ }),
478
+ className = _useState[0],
479
+ setClassName = _useState[1];
480
+
481
+ var _useState2 = useState(null),
482
+ popperElement = _useState2[0],
483
+ setPopperElement = _useState2[1];
484
+
485
+ var _usePopper = usePopper(store.getReferenceElement(), popperElement, popperOptions),
486
+ styles = _usePopper.styles,
487
+ attributes = _usePopper.attributes;
488
+
489
+ useEffect(function () {
490
+ requestAnimationFrame(function () {
491
+ return setClassName(clsx(theme.mentionSuggestions, theme.mentionSuggestionsPopup, theme.mentionSuggestionsPopupVisible));
492
+ });
493
+ }, [theme]);
494
+ return /*#__PURE__*/React.createElement("div", _extends({
495
+ ref: setPopperElement,
496
+ style: styles.popper
497
+ }, attributes.popper, {
498
+ className: className,
499
+ role: "listbox"
500
+ }), children);
501
+ }
502
+
503
+ var _excluded = ["entryComponent", "popoverComponent", "popperOptions", "popoverContainer", "onOpenChange", "onAddMention", "onSearchChange", "suggestions", "ariaProps", "callbacks", "theme", "store", "entityMutability", "positionSuggestions", "mentionTriggers", "mentionPrefix"];
504
+ var MentionSuggestions = /*#__PURE__*/function (_Component) {
505
+ _inheritsLoose(MentionSuggestions, _Component);
506
+
507
+ function MentionSuggestions(props) {
508
+ var _this;
509
+
510
+ _this = _Component.call(this, props) || this;
511
+ _this.state = {
512
+ focusedOptionIndex: 0
513
+ };
514
+ _this.key = genKey();
515
+ _this.popover = void 0;
516
+ _this.activeOffsetKey = void 0;
517
+ _this.lastSearchValue = void 0;
518
+ _this.lastActiveTrigger = '';
519
+ _this.lastSelectionIsInsideWord = void 0;
520
+
521
+ _this.onEditorStateChange = function (editorState) {
522
+ var searches = _this.props.store.getAllSearches(); // if no search portal is active there is no need to show the popover
523
+
524
+
525
+ if (searches.size === 0) {
526
+ return editorState;
527
+ }
528
+
529
+ var removeList = function removeList() {
530
+ _this.props.store.resetEscapedSearch();
531
+
532
+ _this.closeDropdown();
533
+
534
+ return editorState;
535
+ };
536
+
537
+ var triggerForMention = getTriggerForMention(editorState, searches, _this.props.mentionTriggers);
538
+
539
+ if (!triggerForMention) {
540
+ return removeList();
541
+ }
542
+
543
+ var lastActiveOffsetKey = _this.activeOffsetKey;
544
+ _this.activeOffsetKey = triggerForMention.activeOffsetKey;
545
+
546
+ _this.onSearchChange(editorState, editorState.getSelection(), _this.activeOffsetKey, lastActiveOffsetKey, triggerForMention.activeTrigger); // make sure the escaped search is reseted in the cursor since the user
547
+ // already switched to another mention search
548
+
549
+
550
+ if (!_this.props.store.isEscaped(_this.activeOffsetKey || '')) {
551
+ _this.props.store.resetEscapedSearch();
552
+ } // If none of the above triggered to close the window, it's safe to assume
553
+ // the dropdown should be open. This is useful when a user focuses on another
554
+ // input field and then comes back: the dropdown will show again.
555
+
556
+
557
+ if (!_this.props.open && !_this.props.store.isEscaped(_this.activeOffsetKey || '')) {
558
+ _this.openDropdown();
559
+ } // makes sure the focused index is reseted every time a new selection opens
560
+ // or the selection was moved to another mention search
561
+
562
+
563
+ if (lastActiveOffsetKey !== _this.activeOffsetKey) {
564
+ _this.setState({
565
+ focusedOptionIndex: 0
566
+ });
567
+ }
568
+
569
+ return editorState;
570
+ };
571
+
572
+ _this.onSearchChange = function (editorState, selection, activeOffsetKey, lastActiveOffsetKey, trigger) {
573
+ var _getSearchText = getSearchText(editorState, selection, [trigger]),
574
+ searchValue = _getSearchText.matchingString;
575
+
576
+ if (_this.lastActiveTrigger !== trigger || _this.lastSearchValue !== searchValue || activeOffsetKey !== lastActiveOffsetKey) {
577
+ _this.lastActiveTrigger = trigger;
578
+ _this.lastSearchValue = searchValue;
579
+
580
+ _this.props.onSearchChange({
581
+ trigger: trigger,
582
+ value: searchValue
583
+ }); //reset focus item if search is cahnged
584
+
585
+
586
+ _this.setState({
587
+ focusedOptionIndex: 0
588
+ });
589
+ }
590
+ };
591
+
592
+ _this.onDownArrow = function (keyboardEvent) {
593
+ keyboardEvent.preventDefault();
594
+ var newIndex = _this.state.focusedOptionIndex + 1;
595
+
596
+ _this.onMentionFocus(newIndex >= _this.props.suggestions.length ? 0 : newIndex);
597
+ };
598
+
599
+ _this.onTab = function (keyboardEvent) {
600
+ keyboardEvent.preventDefault();
601
+
602
+ _this.commitSelection();
603
+ };
604
+
605
+ _this.onUpArrow = function (keyboardEvent) {
606
+ keyboardEvent.preventDefault();
607
+
608
+ if (_this.props.suggestions.length > 0) {
609
+ var newIndex = _this.state.focusedOptionIndex - 1;
610
+
611
+ _this.onMentionFocus(newIndex < 0 ? _this.props.suggestions.length - 1 : newIndex);
612
+ }
613
+ };
614
+
615
+ _this.onEscape = function (keyboardEvent) {
616
+ keyboardEvent.preventDefault();
617
+
618
+ _this.props.store.escapeSearch(_this.activeOffsetKey || '');
619
+
620
+ _this.closeDropdown(); // to force a re-render of the outer component to change the aria props
621
+
622
+
623
+ _this.props.store.setEditorState(_this.props.store.getEditorState());
624
+ };
625
+
626
+ _this.onMentionSelect = function (mention) {
627
+ // Note: This can happen in case a user typed @xxx (invalid mention) and
628
+ // then hit Enter. Then the mention will be undefined.
629
+ if (!mention) {
630
+ return;
631
+ }
632
+
633
+ if (_this.props.onAddMention) {
634
+ _this.props.onAddMention(mention);
635
+ }
636
+
637
+ _this.closeDropdown();
638
+
639
+ var newEditorState = addMention(_this.props.store.getEditorState(), mention, _this.props.mentionPrefix, _this.lastActiveTrigger || '', _this.props.entityMutability);
640
+
641
+ _this.props.store.setEditorState(newEditorState);
642
+ };
643
+
644
+ _this.onMentionFocus = function (index) {
645
+ var descendant = "mention-option-" + _this.key + "-" + index;
646
+ _this.props.ariaProps.ariaActiveDescendantID = descendant;
647
+
648
+ _this.setState({
649
+ focusedOptionIndex: index
650
+ }); // to force a re-render of the outer component to change the aria props
651
+
652
+
653
+ _this.props.store.setEditorState(_this.props.store.getEditorState());
654
+ };
655
+
656
+ _this.commitSelection = function () {
657
+ var mention = _this.props.suggestions[_this.state.focusedOptionIndex];
658
+
659
+ if (!_this.props.store.getIsOpened() || !mention) {
660
+ return 'not-handled';
661
+ }
662
+
663
+ _this.onMentionSelect(mention);
664
+
665
+ return 'handled';
666
+ };
667
+
668
+ _this.openDropdown = function () {
669
+ // This is a really nasty way of attaching & releasing the key related functions.
670
+ // It assumes that the keyFunctions object will not loose its reference and
671
+ // by this we can replace inner parameters spread over different modules.
672
+ // This better be some registering & unregistering logic. PRs are welcome :)
673
+ _this.props.callbacks.handleReturn = _this.commitSelection;
674
+
675
+ _this.props.callbacks.keyBindingFn = function (keyboardEvent) {
676
+ // arrow down
677
+ if (keyboardEvent.keyCode === 40) {
678
+ _this.onDownArrow(keyboardEvent);
679
+ } // arrow up
680
+
681
+
682
+ if (keyboardEvent.keyCode === 38) {
683
+ _this.onUpArrow(keyboardEvent);
684
+ } // escape
685
+
686
+
687
+ if (keyboardEvent.keyCode === 27) {
688
+ _this.onEscape(keyboardEvent);
689
+ } // tab
690
+
691
+
692
+ if (keyboardEvent.keyCode === 9) {
693
+ _this.onTab(keyboardEvent);
694
+ }
695
+
696
+ return undefined;
697
+ };
698
+
699
+ var descendant = "mention-option-" + _this.key + "-" + _this.state.focusedOptionIndex;
700
+ _this.props.ariaProps.ariaActiveDescendantID = descendant;
701
+ _this.props.ariaProps.ariaOwneeID = "mentions-list-" + _this.key;
702
+ _this.props.ariaProps.ariaHasPopup = 'true';
703
+ _this.props.ariaProps.ariaExpanded = true;
704
+
705
+ _this.props.onOpenChange(true);
706
+ };
707
+
708
+ _this.closeDropdown = function () {
709
+ // make sure none of these callbacks are triggered
710
+ _this.props.callbacks.handleReturn = undefined;
711
+ _this.props.callbacks.keyBindingFn = undefined;
712
+ _this.props.ariaProps.ariaHasPopup = 'false';
713
+ _this.props.ariaProps.ariaExpanded = false;
714
+ _this.props.ariaProps.ariaActiveDescendantID = undefined;
715
+ _this.props.ariaProps.ariaOwneeID = undefined;
716
+
717
+ _this.props.onOpenChange(false);
718
+ };
719
+
720
+ _this.props.callbacks.onChange = _this.onEditorStateChange;
721
+ return _this;
722
+ }
723
+
724
+ var _proto = MentionSuggestions.prototype;
725
+
726
+ _proto.componentDidUpdate = function componentDidUpdate() {
727
+ if (this.popover) {
728
+ // In case the list shrinks there should be still an option focused.
729
+ // Note: this might run multiple times and deduct 1 until the condition is
730
+ // not fullfilled anymore.
731
+ var size = this.props.suggestions.length;
732
+
733
+ if (size > 0 && this.state.focusedOptionIndex >= size) {
734
+ this.setState({
735
+ focusedOptionIndex: size - 1
736
+ });
737
+ } // Note: this is a simple protection for the error when componentDidUpdate
738
+ // try to get new getPortalClientRect, but the key already was deleted by
739
+ // previous action. (right now, it only can happened when set the mention
740
+ // trigger to be multi-characters which not supported anyway!)
741
+
742
+
743
+ if (!this.props.store.getAllSearches().has(this.activeOffsetKey)) {
744
+ return;
745
+ }
746
+
747
+ var decoratorRect = this.props.store.getPortalClientRect(this.activeOffsetKey);
748
+ var positionSuggestions$1 = this.props.positionSuggestions || positionSuggestions;
749
+ var newStyles = positionSuggestions$1({
750
+ decoratorRect: decoratorRect,
751
+ props: this.props,
752
+ popover: this.popover
753
+ });
754
+
755
+ for (var _i = 0, _Object$entries = Object.entries(newStyles); _i < _Object$entries.length; _i++) {
756
+ var _Object$entries$_i = _Object$entries[_i],
757
+ key = _Object$entries$_i[0],
758
+ value = _Object$entries$_i[1];
759
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
760
+ this.popover.style[key] = value;
761
+ }
762
+ }
763
+ };
764
+
765
+ _proto.componentWillUnmount = function componentWillUnmount() {
766
+ this.props.callbacks.onChange = undefined;
767
+ };
768
+
769
+ _proto.render = function render() {
770
+ var _this2 = this;
771
+
772
+ if (!this.props.open) {
773
+ return null;
774
+ }
775
+
776
+ var _this$props = this.props,
777
+ entryComponent = _this$props.entryComponent,
778
+ popoverComponent = _this$props.popoverComponent,
779
+ popperOptions = _this$props.popperOptions,
780
+ _this$props$popoverCo = _this$props.popoverContainer,
781
+ PopoverContainer = _this$props$popoverCo === void 0 ? Popover : _this$props$popoverCo;
782
+ _this$props.onOpenChange;
783
+ _this$props.onAddMention;
784
+ _this$props.onSearchChange;
785
+ _this$props.suggestions;
786
+ _this$props.ariaProps;
787
+ _this$props.callbacks;
788
+ var _this$props$theme = _this$props.theme,
789
+ theme = _this$props$theme === void 0 ? {} : _this$props$theme;
790
+ _this$props.store;
791
+ _this$props.entityMutability;
792
+ var positionSuggestions = _this$props.positionSuggestions;
793
+ _this$props.mentionTriggers;
794
+ _this$props.mentionPrefix;
795
+ var elementProps = _objectWithoutPropertiesLoose(_this$props, _excluded);
796
+
797
+ if (popoverComponent || positionSuggestions) {
798
+ warning('The properties `popoverComponent` and `positionSuggestions` are deprecated and will be removed in @draft-js-plugins/mentions 6.0 . Use `popperOptions` instead');
799
+ return /*#__PURE__*/React.cloneElement(popoverComponent || /*#__PURE__*/React.createElement("div", null), _extends({}, elementProps, {
800
+ className: theme.mentionSuggestions,
801
+ role: 'listbox',
802
+ id: "mentions-list-" + this.key,
803
+ ref: function ref(element) {
804
+ _this2.popover = element;
805
+ }
806
+ }), this.props.suggestions.map(function (mention, index) {
807
+ return /*#__PURE__*/React.createElement(Entry$1, {
808
+ key: mention.id != null ? mention.id : mention.name,
809
+ onMentionSelect: _this2.onMentionSelect,
810
+ onMentionFocus: _this2.onMentionFocus,
811
+ isFocused: _this2.state.focusedOptionIndex === index,
812
+ mention: mention,
813
+ index: index,
814
+ id: "mention-option-" + _this2.key + "-" + index,
815
+ theme: theme,
816
+ searchValue: _this2.lastSearchValue,
817
+ entryComponent: entryComponent || DefaultEntryComponent
818
+ });
819
+ }));
820
+ }
821
+
822
+ if (!this.props.renderEmptyPopup && this.props.suggestions.length === 0) {
823
+ return null;
824
+ }
825
+
826
+ return /*#__PURE__*/React.createElement(PopoverContainer, {
827
+ store: this.props.store,
828
+ popperOptions: popperOptions,
829
+ theme: theme
830
+ }, this.props.suggestions.map(function (mention, index) {
831
+ return /*#__PURE__*/React.createElement(Entry$1, {
832
+ key: mention.id != null ? mention.id : mention.name,
833
+ onMentionSelect: _this2.onMentionSelect,
834
+ onMentionFocus: _this2.onMentionFocus,
835
+ isFocused: _this2.state.focusedOptionIndex === index,
836
+ mention: mention,
837
+ index: index,
838
+ id: "mention-option-" + _this2.key + "-" + index,
839
+ theme: theme,
840
+ searchValue: _this2.lastSearchValue,
841
+ entryComponent: entryComponent || DefaultEntryComponent
842
+ });
843
+ }));
844
+ };
845
+
846
+ return MentionSuggestions;
847
+ }(Component);
848
+ MentionSuggestions.propTypes = {
849
+ open: PropTypes.bool.isRequired,
850
+ onOpenChange: PropTypes.func.isRequired,
851
+ entityMutability: PropTypes.oneOf(['SEGMENTED', 'IMMUTABLE', 'MUTABLE']),
852
+ entryComponent: PropTypes.func,
853
+ onAddMention: PropTypes.func,
854
+ suggestions: PropTypes.array.isRequired
855
+ };
856
+ var MentionSuggestions$1 = MentionSuggestions;
857
+
858
+ var useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
859
+ function MentionSuggestionsPortal(props) {
860
+ var searchPortal = useRef(); // Note: this is a workaround for an obscure issue: https://github.com/draft-js-plugins/draft-js-plugins/pull/667/files
861
+ // Ideally we can remove this in the future.
862
+
863
+ var searchPortalRef = function searchPortalRef(element) {
864
+ searchPortal.current = element;
865
+ props.store.setReferenceElement(element);
866
+ };
867
+
868
+ var updatePortalClientRect = function updatePortalClientRect(currentProps) {
869
+ currentProps.store.updatePortalClientRect(currentProps.offsetKey, function () {
870
+ return searchPortal.current.getBoundingClientRect();
871
+ });
872
+ }; // When inputting Japanese characters (or any complex alphabet which requires
873
+ // hitting enter to commit the characters), that action was causing a race
874
+ // condition when we used UNSAFE_componentWillMount. By using componentDidMount
875
+ // instead of UNSAFE_componentWillMount, the component will unmount unregister and
876
+ // then properly mount and register after. Prior to this change,
877
+ // UNSAFE_componentWillMount would not fire after componentWillUnmount even though it
878
+ // was still in the DOM, so it wasn't re-registering the offsetkey.
879
+
880
+
881
+ useIsomorphicLayoutEffect(function () {
882
+ props.store.register(props.offsetKey);
883
+ props.store.setIsOpened(true);
884
+ updatePortalClientRect(props); // trigger a re-render so the MentionSuggestions becomes active
885
+
886
+ props.store.setEditorState(props.store.getEditorState());
887
+ return function () {
888
+ props.store.unregister(props.offsetKey);
889
+ props.store.setIsOpened(false);
890
+ props.store.setReferenceElement(null);
891
+ };
892
+ }, []);
893
+ useEffect(function () {
894
+ updatePortalClientRect(props);
895
+ });
896
+ return /*#__PURE__*/React.createElement("span", {
897
+ ref: searchPortalRef
898
+ }, props.children);
899
+ }
900
+
901
+ var defaultRegExp = '[' + '\\w-' + // Latin-1 Supplement (letters only) - https://en.wikipedia.org/wiki/List_of_Unicode_characters#Latin-1_Supplement
902
+ "\xC0-\xD6" + "\xD8-\xF6" + "\xF8-\xFF" + // Latin Extended-A (without deprecated character) - https://en.wikipedia.org/wiki/List_of_Unicode_characters#Latin_Extended-A
903
+ "\u0100-\u0148" + "\u014A-\u017F" + // Cyrillic symbols: \u0410-\u044F - https://en.wikipedia.org/wiki/Cyrillic_script_in_Unicode
904
+ "\u0410-\u044F" + // Symbols that are sometimes used in Japanese names: \u3005-\u3006
905
+ "\u3005-\u3006" + // hiragana (japanese): \u3040-\u309F - https://gist.github.com/ryanmcgrath/982242#file-japaneseregex-js
906
+ "\u3040-\u309F" + // katakana (japanese): \u30A0-\u30FF - https://gist.github.com/ryanmcgrath/982242#file-japaneseregex-js
907
+ "\u30A0-\u30FF" + // For an advanced explaination about Hangul see https://github.com/draft-js-plugins/draft-js-plugins/pull/480#issuecomment-254055437
908
+ // Hangul Jamo (korean): \u3130-\u318F - https://en.wikipedia.org/wiki/Korean_language_and_computers#Hangul_in_Unicode
909
+ // Hangul Syllables (korean): \uAC00-\uD7A3 - https://en.wikipedia.org/wiki/Korean_language_and_computers#Hangul_in_Unicode
910
+ "\u3130-\u318F" + "\uAC00-\uD7A3" + // common chinese symbols: \u4e00-\u9eff - http://stackoverflow.com/a/1366113/837709
911
+ // extended to \u9fa5 https://github.com/draft-js-plugins/draft-js-plugins/issues/1888
912
+ "\u4E00-\u9FA5" + // Arabic https://en.wikipedia.org/wiki/Arabic_(Unicode_block)
913
+ "\u0600-\u06FF" + // Vietnamese http://vietunicode.sourceforge.net/charset/
914
+ "\xC0-\u1EF9" + ']';
915
+
916
+ var defaultTheme = {
917
+ mention: "m6zwb4v",
918
+ // CSS class for suggestions component
919
+ mentionSuggestions: "mnw6qvm",
920
+ mentionSuggestionsPopup: "m1ymsnxd",
921
+ mentionSuggestionsPopupVisible: "m126ak5t",
922
+ // CSS classes for an entry in the suggestions component
923
+ mentionSuggestionsEntry: "mtiwdxc",
924
+ mentionSuggestionsEntryFocused: "myz2dw1",
925
+ mentionSuggestionsEntryText: "mpqdcgq",
926
+ mentionSuggestionsEntryAvatar: "m1mfvffo"
927
+ };
928
+
929
+ var findMentionEntities = function findMentionEntities(triggers) {
930
+ return function (contentBlock, callback, contentState) {
931
+ contentBlock.findEntityRanges(function (character) {
932
+ var entityKey = character.getEntity();
933
+ return entityKey !== null && triggers.some(function (trigger) {
934
+ return contentState.getEntity(entityKey).getType() === getTypeByTrigger(trigger);
935
+ });
936
+ }, callback);
937
+ };
938
+ };
939
+
940
+ var mentionStrategy = findMentionEntities;
941
+
942
+ var whitespaceRegEx = /\s/;
943
+
944
+ function checkForWhiteSpaceBeforeTrigger(text, index) {
945
+ if (index === 0) {
946
+ return true;
947
+ }
948
+
949
+ return whitespaceRegEx.test(text[index - 1]);
950
+ }
951
+
952
+ function findInContentBlock(regex, text, nonEntityStart, callback) {
953
+ var matchArr;
954
+ var start;
955
+ var prevLastIndex = regex.lastIndex; // Go through all matches in the text and return the indices to the callback
956
+ // Break the loop if lastIndex is not changed
957
+
958
+ while ((matchArr = regex.exec(text)) !== null) {
959
+ if (regex.lastIndex === prevLastIndex) {
960
+ break;
961
+ }
962
+
963
+ prevLastIndex = regex.lastIndex;
964
+ start = nonEntityStart + matchArr.index;
965
+
966
+ var _end = start + matchArr[0].length;
967
+
968
+ if (whitespaceRegEx.test(text[start])) {
969
+ //trim the result so that we have no whitespaces
970
+ start += 1;
971
+ }
972
+
973
+ callback(start, _end);
974
+ }
975
+ }
976
+
977
+ function findInContentBlockWithWhitespace(regex, text, nonEntityStart, callback) {
978
+ var matchArr;
979
+ var start;
980
+ var prevLastIndex = regex.lastIndex; // Go through all matches in the text and return the indices to the callback
981
+ // Break the loop if lastIndex is not changed
982
+
983
+ while ((matchArr = regex.exec(text)) !== null) {
984
+ if (regex.lastIndex === prevLastIndex) {
985
+ break;
986
+ }
987
+
988
+ prevLastIndex = regex.lastIndex;
989
+ start = nonEntityStart + matchArr.index;
990
+
991
+ var _end2 = start + matchArr[0].length; //check if whitespace support is active that the char before the trigger is a white space #1844
992
+
993
+
994
+ if (checkForWhiteSpaceBeforeTrigger(text, matchArr.index)) {
995
+ callback(start, _end2);
996
+ }
997
+ }
998
+ }
999
+
1000
+ var findWithRegex = function findWithRegex(regex, contentBlock, supportWhiteSpace, callback) {
1001
+ var contentBlockText = contentBlock.getText(); // exclude entities, when matching
1002
+
1003
+ contentBlock.findEntityRanges(function (character) {
1004
+ return !character.getEntity();
1005
+ }, function (nonEntityStart, nonEntityEnd) {
1006
+ var text = contentBlockText.slice(nonEntityStart, nonEntityEnd);
1007
+
1008
+ if (supportWhiteSpace) {
1009
+ findInContentBlockWithWhitespace(regex, text, nonEntityStart, callback);
1010
+ } else {
1011
+ findInContentBlock(regex, text, nonEntityStart, callback);
1012
+ }
1013
+ });
1014
+ };
1015
+
1016
+ var mentionSuggestionsStrategy = (function (triggers, supportWhiteSpace, regExp) {
1017
+ var triggerPattern = "(" + triggers.map(function (trigger) {
1018
+ return escapeRegExp(trigger);
1019
+ }).join('|') + ")";
1020
+ var MENTION_REGEX = supportWhiteSpace ? new RegExp(triggerPattern + "(" + regExp + "|\\s)*", 'g') : new RegExp("(\\s|^)" + triggerPattern + regExp + "*", 'g');
1021
+ return function (contentBlock, callback) {
1022
+ findWithRegex(MENTION_REGEX, contentBlock, supportWhiteSpace, callback);
1023
+ };
1024
+ });
1025
+
1026
+ // Get the first 5 suggestions that match
1027
+ var defaultSuggestionsFilter$1 = function defaultSuggestionsFilter(searchValue, suggestions, trigger) {
1028
+ var value = searchValue.toLowerCase();
1029
+ var triggerSuggestions = trigger && !Array.isArray(suggestions) ? suggestions[trigger] : suggestions;
1030
+ var filteredSuggestions = triggerSuggestions.filter(function (suggestion) {
1031
+ return !value || suggestion.name.toLowerCase().indexOf(value) > -1;
1032
+ });
1033
+ var length = filteredSuggestions.length < 5 ? filteredSuggestions.length : 5;
1034
+ return filteredSuggestions.slice(0, length);
1035
+ };
1036
+
1037
+ var suggestionsFilter = defaultSuggestionsFilter$1;
1038
+
1039
+ var index = (function (config) {
1040
+ if (config === void 0) {
1041
+ config = {};
1042
+ }
1043
+
1044
+ var callbacks = {
1045
+ keyBindingFn: undefined,
1046
+ handleKeyCommand: undefined,
1047
+ handleReturn: undefined,
1048
+ onChange: undefined
1049
+ };
1050
+ var ariaProps = {
1051
+ ariaHasPopup: 'false',
1052
+ ariaExpanded: false,
1053
+ ariaOwneeID: undefined,
1054
+ ariaActiveDescendantID: undefined
1055
+ };
1056
+ var searches = Map();
1057
+ var escapedSearch;
1058
+ var clientRectFunctions = Map();
1059
+ var isOpened = false;
1060
+ var referenceElement;
1061
+ var store = {
1062
+ getEditorState: undefined,
1063
+ setEditorState: undefined,
1064
+ getPortalClientRect: function getPortalClientRect(offsetKey) {
1065
+ return clientRectFunctions.get(offsetKey)();
1066
+ },
1067
+ getAllSearches: function getAllSearches() {
1068
+ return searches;
1069
+ },
1070
+ isEscaped: function isEscaped(offsetKey) {
1071
+ return escapedSearch === offsetKey;
1072
+ },
1073
+ escapeSearch: function escapeSearch(offsetKey) {
1074
+ escapedSearch = offsetKey;
1075
+ },
1076
+ resetEscapedSearch: function resetEscapedSearch() {
1077
+ escapedSearch = undefined;
1078
+ },
1079
+ register: function register(offsetKey) {
1080
+ searches = searches.set(offsetKey, offsetKey);
1081
+ },
1082
+ updatePortalClientRect: function updatePortalClientRect(offsetKey, func) {
1083
+ clientRectFunctions = clientRectFunctions.set(offsetKey, func);
1084
+ },
1085
+ unregister: function unregister(offsetKey) {
1086
+ searches = searches["delete"](offsetKey);
1087
+ clientRectFunctions = clientRectFunctions["delete"](offsetKey);
1088
+ },
1089
+ getIsOpened: function getIsOpened() {
1090
+ return isOpened;
1091
+ },
1092
+ setIsOpened: function setIsOpened(nextIsOpened) {
1093
+ isOpened = nextIsOpened;
1094
+ },
1095
+ getReferenceElement: function getReferenceElement() {
1096
+ return referenceElement;
1097
+ },
1098
+ setReferenceElement: function setReferenceElement(element) {
1099
+ referenceElement = element;
1100
+ }
1101
+ }; // Styles are overwritten instead of merged as merging causes a lot of confusion.
1102
+ //
1103
+ // Why? Because when merging a developer needs to know all of the underlying
1104
+ // styles which needs a deep dive into the code. Merging also makes it prone to
1105
+ // errors when upgrading as basically every styling change would become a major
1106
+ // breaking change. 1px of an increased padding can break a whole layout.
1107
+
1108
+ var _config = config,
1109
+ _config$mentionPrefix = _config.mentionPrefix,
1110
+ mentionPrefix = _config$mentionPrefix === void 0 ? '' : _config$mentionPrefix,
1111
+ _config$theme = _config.theme,
1112
+ theme = _config$theme === void 0 ? defaultTheme : _config$theme,
1113
+ positionSuggestions = _config.positionSuggestions,
1114
+ mentionComponent = _config.mentionComponent,
1115
+ _config$mentionSugges = _config.mentionSuggestionsComponent,
1116
+ MentionSuggestionsComponent = _config$mentionSugges === void 0 ? MentionSuggestions$1 : _config$mentionSugges,
1117
+ _config$entityMutabil = _config.entityMutability,
1118
+ entityMutability = _config$entityMutabil === void 0 ? 'SEGMENTED' : _config$entityMutabil,
1119
+ _config$mentionTrigge = _config.mentionTrigger,
1120
+ mentionTrigger = _config$mentionTrigge === void 0 ? '@' : _config$mentionTrigge,
1121
+ _config$mentionRegExp = _config.mentionRegExp,
1122
+ mentionRegExp = _config$mentionRegExp === void 0 ? defaultRegExp : _config$mentionRegExp,
1123
+ _config$supportWhites = _config.supportWhitespace,
1124
+ supportWhitespace = _config$supportWhites === void 0 ? false : _config$supportWhites,
1125
+ popperOptions = _config.popperOptions;
1126
+ var mentionTriggers = typeof mentionTrigger === 'string' ? [mentionTrigger] : mentionTrigger;
1127
+ var mentionSearchProps = {
1128
+ ariaProps: ariaProps,
1129
+ callbacks: callbacks,
1130
+ theme: theme,
1131
+ store: store,
1132
+ entityMutability: entityMutability,
1133
+ positionSuggestions: positionSuggestions,
1134
+ mentionTriggers: mentionTriggers,
1135
+ mentionPrefix: mentionPrefix,
1136
+ popperOptions: popperOptions
1137
+ };
1138
+
1139
+ var DecoratedMentionSuggestionsComponent = function DecoratedMentionSuggestionsComponent(props) {
1140
+ return /*#__PURE__*/React.createElement(MentionSuggestionsComponent, _extends({}, props, mentionSearchProps));
1141
+ };
1142
+
1143
+ var DecoratedMention = function DecoratedMention(props) {
1144
+ return /*#__PURE__*/React.createElement(Mention, _extends({}, props, {
1145
+ theme: theme,
1146
+ mentionComponent: mentionComponent
1147
+ }));
1148
+ };
1149
+
1150
+ var DecoratedMentionSuggestionsPortal = function DecoratedMentionSuggestionsPortal(props) {
1151
+ return /*#__PURE__*/React.createElement(MentionSuggestionsPortal, _extends({}, props, {
1152
+ store: store
1153
+ }));
1154
+ };
1155
+
1156
+ return {
1157
+ MentionSuggestions: DecoratedMentionSuggestionsComponent,
1158
+ decorators: [{
1159
+ strategy: mentionStrategy(mentionTriggers),
1160
+ component: DecoratedMention
1161
+ }, {
1162
+ strategy: mentionSuggestionsStrategy(mentionTriggers, supportWhitespace, mentionRegExp),
1163
+ component: DecoratedMentionSuggestionsPortal
1164
+ }],
1165
+ getAccessibilityProps: function getAccessibilityProps() {
1166
+ return {
1167
+ role: 'combobox',
1168
+ ariaAutoComplete: 'list',
1169
+ ariaHasPopup: ariaProps.ariaHasPopup,
1170
+ ariaExpanded: ariaProps.ariaExpanded,
1171
+ ariaActiveDescendantID: ariaProps.ariaActiveDescendantID,
1172
+ ariaOwneeID: ariaProps.ariaOwneeID
1173
+ };
1174
+ },
1175
+ initialize: function initialize(_ref) {
1176
+ var getEditorState = _ref.getEditorState,
1177
+ setEditorState = _ref.setEditorState;
1178
+ store.getEditorState = getEditorState;
1179
+ store.setEditorState = setEditorState;
1180
+ },
1181
+ keyBindingFn: function keyBindingFn(keyboardEvent) {
1182
+ return callbacks.keyBindingFn && callbacks.keyBindingFn(keyboardEvent);
1183
+ },
1184
+ handleReturn: function handleReturn(keyboardEvent) {
1185
+ return callbacks.handleReturn && callbacks.handleReturn(keyboardEvent);
1186
+ },
1187
+ onChange: function onChange(editorState) {
1188
+ if (callbacks.onChange) {
1189
+ return callbacks.onChange(editorState);
1190
+ }
1191
+
1192
+ return editorState;
1193
+ }
1194
+ };
1195
+ });
1196
+ var defaultSuggestionsFilter = suggestionsFilter;
1197
+
1198
+ export { MentionSuggestions$1 as MentionSuggestions, Popover, addMention, index as default, defaultSuggestionsFilter, defaultTheme };