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