react-mentions 4.2.0 → 4.3.2
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +2 -2
- package/dist/react-mentions.cjs.dev.js +24 -8
- package/dist/react-mentions.cjs.prod.js +30 -24
- package/dist/react-mentions.esm.js +24 -8
- package/package.json +1 -1
package/README.md
CHANGED
@@ -7,7 +7,7 @@
|
|
7
7
|
|
8
8
|
A React component that let's you mention people in a textarea like you are used to on Facebook or Twitter.
|
9
9
|
|
10
|
-
Used in production at [Signavio](https://signavio.com), [State](https://state.com), [Snips](https://snips.ai), [Swat.io](https://swat.io), [GotDone](https://www.gotdone.me), [Volinspire](https://volinspire.com), [Marvin](https://amazingmarvin.com), [Timely](https://timelyapp.com), [GuideFitter](https://www.guidefitter.com/), [Evite](https://www.evite.com/), [Publer](https://publer.me/), [Kontentino](https://www.kontentino.com/), and [you?](https://github.com/signavio/react-mentions/edit/master/README.md)
|
10
|
+
Used in production at [Signavio](https://signavio.com), [State](https://state.com), [Snips](https://snips.ai), [Swat.io](https://swat.io), [GotDone](https://www.gotdone.me), [Volinspire](https://volinspire.com), [Marvin](https://amazingmarvin.com), [Timely](https://timelyapp.com), [GuideFitter](https://www.guidefitter.com/), [Evite](https://www.evite.com/), [Publer](https://publer.me/), [Kontentino](https://www.kontentino.com/), [Wix.com](https://wix.com), [Highlight](https://highlight.run/) and [you?](https://github.com/signavio/react-mentions/edit/master/README.md)
|
11
11
|
|
12
12
|
## Getting started
|
13
13
|
|
@@ -76,7 +76,7 @@ Each data source is configured using a `Mention` component, which has the follow
|
|
76
76
|
| markup | string | `'@[__display__](__id__)'` | A template string for the markup to use for mentions |
|
77
77
|
| displayTransform | function (id, display) | returns `display` | Accepts a function for customizing the string that is displayed for a mention |
|
78
78
|
| regex | RegExp | automatically derived from `markup` pattern | Allows providing a custom regular expression for parsing your markup and extracting the placeholder interpolations (optional) | |
|
79
|
-
| onAdd | function (id, display) | empty function | Callback invoked when a suggestion has been added (optional) |
|
79
|
+
| onAdd | function (id, display, startPos, endPos) | empty function | Callback invoked when a suggestion has been added (optional) |
|
80
80
|
| appendSpaceOnAdd | boolean | `false` | Append a space when a suggestion has been added (optional) |
|
81
81
|
|
82
82
|
If a function is passed as the `data` prop, that function will be called with the current search query as first, and a callback function as second argument. The callback can be used to provide results asynchronously, e.g., after fetch requests. (It can even be called multiple times to update the list of suggestions.)
|
@@ -629,6 +629,10 @@ var getSubstringIndex = function getSubstringIndex(str, substr, ignoreAccents) {
|
|
629
629
|
return normalizeString(str).indexOf(normalizeString(substr));
|
630
630
|
};
|
631
631
|
|
632
|
+
var isIE = function isIE() {
|
633
|
+
return !!document.documentMode;
|
634
|
+
};
|
635
|
+
|
632
636
|
var isNumber = function isNumber(val) {
|
633
637
|
return typeof val === 'number';
|
634
638
|
};
|
@@ -1060,6 +1064,7 @@ function (_Component) {
|
|
1060
1064
|
containerRef = _this$props.containerRef,
|
1061
1065
|
position = _this$props.position,
|
1062
1066
|
left = _this$props.left,
|
1067
|
+
right = _this$props.right,
|
1063
1068
|
top = _this$props.top; // do not show suggestions until there is some data
|
1064
1069
|
|
1065
1070
|
if (!isOpened) {
|
@@ -1069,6 +1074,7 @@ function (_Component) {
|
|
1069
1074
|
return React__default.createElement("div", _extends({}, useStyles.inline({
|
1070
1075
|
position: position || 'absolute',
|
1071
1076
|
left: left,
|
1077
|
+
right: right,
|
1072
1078
|
top: top
|
1073
1079
|
}, style), {
|
1074
1080
|
onMouseDown: onMouseDown,
|
@@ -1144,6 +1150,7 @@ _defineProperty(SuggestionsOverlay, "propTypes", {
|
|
1144
1150
|
focusIndex: PropTypes.number,
|
1145
1151
|
position: PropTypes.string,
|
1146
1152
|
left: PropTypes.number,
|
1153
|
+
right: PropTypes.number,
|
1147
1154
|
top: PropTypes.number,
|
1148
1155
|
scrollFocusedIntoView: PropTypes.bool,
|
1149
1156
|
isLoading: PropTypes.bool,
|
@@ -1345,13 +1352,15 @@ function (_React$Component) {
|
|
1345
1352
|
var _this$state$suggestio = _this.state.suggestionsPosition,
|
1346
1353
|
position = _this$state$suggestio.position,
|
1347
1354
|
left = _this$state$suggestio.left,
|
1348
|
-
top = _this$state$suggestio.top
|
1355
|
+
top = _this$state$suggestio.top,
|
1356
|
+
right = _this$state$suggestio.right;
|
1349
1357
|
var suggestionsNode = React__default.createElement(SuggestionsOverlay$1, {
|
1350
1358
|
id: _this.uuidSuggestionsOverlay,
|
1351
1359
|
style: _this.props.style('suggestions'),
|
1352
1360
|
position: position,
|
1353
1361
|
left: left,
|
1354
1362
|
top: top,
|
1363
|
+
right: right,
|
1355
1364
|
focusIndex: _this.state.focusIndex,
|
1356
1365
|
scrollFocusedIntoView: _this.state.scrollFocusedIntoView,
|
1357
1366
|
containerRef: _this.setSuggestionsElement,
|
@@ -1425,13 +1434,16 @@ function (_React$Component) {
|
|
1425
1434
|
});
|
1426
1435
|
|
1427
1436
|
_defineProperty(_assertThisInitialized(_this), "handleChange", function (ev) {
|
1428
|
-
isComposing = false;
|
1437
|
+
isComposing = false;
|
1429
1438
|
|
1430
|
-
|
1439
|
+
if (isIE()) {
|
1440
|
+
// if we are inside iframe, we need to find activeElement within its contentDocument
|
1441
|
+
var currentDocument = document.activeElement && document.activeElement.contentDocument || document;
|
1431
1442
|
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1443
|
+
if (currentDocument.activeElement !== ev.target) {
|
1444
|
+
// fix an IE bug (blur from empty input element with placeholder attribute trigger "input" event)
|
1445
|
+
return;
|
1446
|
+
}
|
1435
1447
|
}
|
1436
1448
|
|
1437
1449
|
var value = _this.props.value || '';
|
@@ -1888,7 +1900,7 @@ function (_React$Component) {
|
|
1888
1900
|
_this.executeOnChange(eventMock, newValue, newPlainTextValue, mentions);
|
1889
1901
|
|
1890
1902
|
if (onAdd) {
|
1891
|
-
onAdd(id, display);
|
1903
|
+
onAdd(id, display, start, end);
|
1892
1904
|
} // Make sure the suggestions overlay is closed
|
1893
1905
|
|
1894
1906
|
|
@@ -1995,7 +2007,11 @@ function (_React$Component) {
|
|
1995
2007
|
value: newValue
|
1996
2008
|
})
|
1997
2009
|
};
|
1998
|
-
this.executeOnChange(eventMock, newValue, newPlainTextValue, getMentions(newValue, config));
|
2010
|
+
this.executeOnChange(eventMock, newValue, newPlainTextValue, getMentions(newValue, config)); // Move the cursor position to the end of the pasted data
|
2011
|
+
|
2012
|
+
var startOfMention = findStartOfMentionInPlainText(value, config, selectionStart);
|
2013
|
+
var nextPos = (startOfMention || selectionStart) + getPlainText(pastedMentions || pastedData, config).length;
|
2014
|
+
this.setSelection(nextPos, nextPos);
|
1999
2015
|
}
|
2000
2016
|
}, {
|
2001
2017
|
key: "saveSelectionToClipboard",
|
@@ -405,6 +405,8 @@ var _toConsumableArray = _interopDefault(require("@babel/runtime/helpers/toConsu
|
|
405
405
|
return removeAccents(str).toLowerCase();
|
406
406
|
}, getSubstringIndex = function(str, substr, ignoreAccents) {
|
407
407
|
return ignoreAccents ? normalizeString(str).indexOf(normalizeString(substr)) : str.toLowerCase().indexOf(substr.toLowerCase());
|
408
|
+
}, isIE = function() {
|
409
|
+
return !!document.documentMode;
|
408
410
|
}, isNumber = function(val) {
|
409
411
|
return "number" == typeof val;
|
410
412
|
}, keys = function(obj) {
|
@@ -643,10 +645,11 @@ var SuggestionsOverlay = function(_Component) {
|
|
643
645
|
}, {
|
644
646
|
key: "render",
|
645
647
|
value: function() {
|
646
|
-
var _this$props = this.props, id = _this$props.id, a11ySuggestionsListLabel = _this$props.a11ySuggestionsListLabel, isOpened = _this$props.isOpened, style = _this$props.style, onMouseDown = _this$props.onMouseDown, containerRef = _this$props.containerRef, position = _this$props.position, left = _this$props.left, top = _this$props.top;
|
648
|
+
var _this$props = this.props, id = _this$props.id, a11ySuggestionsListLabel = _this$props.a11ySuggestionsListLabel, isOpened = _this$props.isOpened, style = _this$props.style, onMouseDown = _this$props.onMouseDown, containerRef = _this$props.containerRef, position = _this$props.position, left = _this$props.left, right = _this$props.right, top = _this$props.top;
|
647
649
|
return isOpened ? React__default.createElement("div", _extends({}, useStyles.inline({
|
648
650
|
position: position || "absolute",
|
649
651
|
left: left,
|
652
|
+
right: right,
|
650
653
|
top: top
|
651
654
|
}, style), {
|
652
655
|
onMouseDown: onMouseDown,
|
@@ -708,6 +711,7 @@ _defineProperty(SuggestionsOverlay, "propTypes", {
|
|
708
711
|
focusIndex: PropTypes.number,
|
709
712
|
position: PropTypes.string,
|
710
713
|
left: PropTypes.number,
|
714
|
+
right: PropTypes.number,
|
711
715
|
top: PropTypes.number,
|
712
716
|
scrollFocusedIntoView: PropTypes.bool,
|
713
717
|
isLoading: PropTypes.bool,
|
@@ -844,12 +848,13 @@ var makeTriggerRegex = function(trigger) {
|
|
844
848
|
_this.suggestionsElement = el;
|
845
849
|
}), _defineProperty(_assertThisInitialized(_this), "renderSuggestionsOverlay", function() {
|
846
850
|
if (!isNumber(_this.state.selectionStart)) return null;
|
847
|
-
var _this$state$suggestio = _this.state.suggestionsPosition, position = _this$state$suggestio.position, left = _this$state$suggestio.left, top = _this$state$suggestio.top, suggestionsNode = React__default.createElement(SuggestionsOverlay$1, {
|
851
|
+
var _this$state$suggestio = _this.state.suggestionsPosition, position = _this$state$suggestio.position, left = _this$state$suggestio.left, top = _this$state$suggestio.top, right = _this$state$suggestio.right, suggestionsNode = React__default.createElement(SuggestionsOverlay$1, {
|
848
852
|
id: _this.uuidSuggestionsOverlay,
|
849
853
|
style: _this.props.style("suggestions"),
|
850
854
|
position: position,
|
851
855
|
left: left,
|
852
856
|
top: top,
|
857
|
+
right: right,
|
853
858
|
focusIndex: _this.state.focusIndex,
|
854
859
|
scrollFocusedIntoView: _this.state.scrollFocusedIntoView,
|
855
860
|
containerRef: _this.setSuggestionsElement,
|
@@ -887,27 +892,26 @@ var makeTriggerRegex = function(trigger) {
|
|
887
892
|
var _this$props4, _this$props$valueLink;
|
888
893
|
return _this.props.onChange ? (_this$props4 = _this.props).onChange.apply(_this$props4, [ event ].concat(args)) : _this.props.valueLink ? (_this$props$valueLink = _this.props.valueLink).requestChange.apply(_this$props$valueLink, [ event.target.value ].concat(args)) : void 0;
|
889
894
|
}), _defineProperty(_assertThisInitialized(_this), "handleChange", function(ev) {
|
890
|
-
if (isComposing = !1, (document.activeElement && document.activeElement.contentDocument || document).activeElement
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
897
|
-
|
898
|
-
|
899
|
-
|
900
|
-
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
}
|
895
|
+
if ((isComposing = !1, isIE()) && (document.activeElement && document.activeElement.contentDocument || document).activeElement !== ev.target) return;
|
896
|
+
var value = _this.props.value || "", config = readConfigFromChildren(_this.props.children), newPlainTextValue = ev.target.value, newValue = applyChangeToValue(value, newPlainTextValue, {
|
897
|
+
selectionStartBefore: _this.state.selectionStart,
|
898
|
+
selectionEndBefore: _this.state.selectionEnd,
|
899
|
+
selectionEndAfter: ev.target.selectionEnd
|
900
|
+
}, config);
|
901
|
+
newPlainTextValue = getPlainText(newValue, config);
|
902
|
+
var selectionStart = ev.target.selectionStart, selectionEnd = ev.target.selectionEnd, setSelectionAfterMentionChange = !1, startOfMention = findStartOfMentionInPlainText(value, config, selectionStart);
|
903
|
+
void 0 !== startOfMention && _this.state.selectionEnd > startOfMention && (selectionEnd = selectionStart = startOfMention,
|
904
|
+
setSelectionAfterMentionChange = !0), _this.setState({
|
905
|
+
selectionStart: selectionStart,
|
906
|
+
selectionEnd: selectionEnd,
|
907
|
+
setSelectionAfterMentionChange: setSelectionAfterMentionChange
|
908
|
+
});
|
909
|
+
var mentions = getMentions(newValue, config), eventMock = {
|
910
|
+
target: {
|
911
|
+
value: newValue
|
912
|
+
}
|
913
|
+
};
|
914
|
+
_this.executeOnChange(eventMock, newValue, newPlainTextValue, mentions);
|
911
915
|
}), _defineProperty(_assertThisInitialized(_this), "handleSelect", function(ev) {
|
912
916
|
if (_this.setState({
|
913
917
|
selectionStart: ev.target.selectionStart,
|
@@ -1075,7 +1079,7 @@ var makeTriggerRegex = function(trigger) {
|
|
1075
1079
|
value: newValue
|
1076
1080
|
}
|
1077
1081
|
}, mentions = getMentions(newValue, config), newPlainTextValue = spliceString(plainTextValue, querySequenceStart, querySequenceEnd, displayValue);
|
1078
|
-
_this.executeOnChange(eventMock, newValue, newPlainTextValue, mentions), onAdd && onAdd(id, display),
|
1082
|
+
_this.executeOnChange(eventMock, newValue, newPlainTextValue, mentions), onAdd && onAdd(id, display, start, end),
|
1079
1083
|
_this.clearSuggestions();
|
1080
1084
|
}), _defineProperty(_assertThisInitialized(_this), "isLoading", function() {
|
1081
1085
|
var isLoading = !1;
|
@@ -1134,6 +1138,8 @@ var makeTriggerRegex = function(trigger) {
|
|
1134
1138
|
})
|
1135
1139
|
};
|
1136
1140
|
this.executeOnChange(eventMock, newValue, newPlainTextValue, getMentions(newValue, config));
|
1141
|
+
var nextPos = (findStartOfMentionInPlainText(value, config, selectionStart) || selectionStart) + getPlainText(pastedMentions || pastedData, config).length;
|
1142
|
+
this.setSelection(nextPos, nextPos);
|
1137
1143
|
}
|
1138
1144
|
}
|
1139
1145
|
}, {
|
@@ -621,6 +621,10 @@ var getSubstringIndex = function getSubstringIndex(str, substr, ignoreAccents) {
|
|
621
621
|
return normalizeString(str).indexOf(normalizeString(substr));
|
622
622
|
};
|
623
623
|
|
624
|
+
var isIE = function isIE() {
|
625
|
+
return !!document.documentMode;
|
626
|
+
};
|
627
|
+
|
624
628
|
var isNumber = function isNumber(val) {
|
625
629
|
return typeof val === 'number';
|
626
630
|
};
|
@@ -1052,6 +1056,7 @@ function (_Component) {
|
|
1052
1056
|
containerRef = _this$props.containerRef,
|
1053
1057
|
position = _this$props.position,
|
1054
1058
|
left = _this$props.left,
|
1059
|
+
right = _this$props.right,
|
1055
1060
|
top = _this$props.top; // do not show suggestions until there is some data
|
1056
1061
|
|
1057
1062
|
if (!isOpened) {
|
@@ -1061,6 +1066,7 @@ function (_Component) {
|
|
1061
1066
|
return React.createElement("div", _extends({}, inline({
|
1062
1067
|
position: position || 'absolute',
|
1063
1068
|
left: left,
|
1069
|
+
right: right,
|
1064
1070
|
top: top
|
1065
1071
|
}, style), {
|
1066
1072
|
onMouseDown: onMouseDown,
|
@@ -1136,6 +1142,7 @@ _defineProperty(SuggestionsOverlay, "propTypes", {
|
|
1136
1142
|
focusIndex: PropTypes.number,
|
1137
1143
|
position: PropTypes.string,
|
1138
1144
|
left: PropTypes.number,
|
1145
|
+
right: PropTypes.number,
|
1139
1146
|
top: PropTypes.number,
|
1140
1147
|
scrollFocusedIntoView: PropTypes.bool,
|
1141
1148
|
isLoading: PropTypes.bool,
|
@@ -1337,13 +1344,15 @@ function (_React$Component) {
|
|
1337
1344
|
var _this$state$suggestio = _this.state.suggestionsPosition,
|
1338
1345
|
position = _this$state$suggestio.position,
|
1339
1346
|
left = _this$state$suggestio.left,
|
1340
|
-
top = _this$state$suggestio.top
|
1347
|
+
top = _this$state$suggestio.top,
|
1348
|
+
right = _this$state$suggestio.right;
|
1341
1349
|
var suggestionsNode = React.createElement(SuggestionsOverlay$1, {
|
1342
1350
|
id: _this.uuidSuggestionsOverlay,
|
1343
1351
|
style: _this.props.style('suggestions'),
|
1344
1352
|
position: position,
|
1345
1353
|
left: left,
|
1346
1354
|
top: top,
|
1355
|
+
right: right,
|
1347
1356
|
focusIndex: _this.state.focusIndex,
|
1348
1357
|
scrollFocusedIntoView: _this.state.scrollFocusedIntoView,
|
1349
1358
|
containerRef: _this.setSuggestionsElement,
|
@@ -1417,13 +1426,16 @@ function (_React$Component) {
|
|
1417
1426
|
});
|
1418
1427
|
|
1419
1428
|
_defineProperty(_assertThisInitialized(_this), "handleChange", function (ev) {
|
1420
|
-
isComposing = false;
|
1429
|
+
isComposing = false;
|
1421
1430
|
|
1422
|
-
|
1431
|
+
if (isIE()) {
|
1432
|
+
// if we are inside iframe, we need to find activeElement within its contentDocument
|
1433
|
+
var currentDocument = document.activeElement && document.activeElement.contentDocument || document;
|
1423
1434
|
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1435
|
+
if (currentDocument.activeElement !== ev.target) {
|
1436
|
+
// fix an IE bug (blur from empty input element with placeholder attribute trigger "input" event)
|
1437
|
+
return;
|
1438
|
+
}
|
1427
1439
|
}
|
1428
1440
|
|
1429
1441
|
var value = _this.props.value || '';
|
@@ -1880,7 +1892,7 @@ function (_React$Component) {
|
|
1880
1892
|
_this.executeOnChange(eventMock, newValue, newPlainTextValue, mentions);
|
1881
1893
|
|
1882
1894
|
if (onAdd) {
|
1883
|
-
onAdd(id, display);
|
1895
|
+
onAdd(id, display, start, end);
|
1884
1896
|
} // Make sure the suggestions overlay is closed
|
1885
1897
|
|
1886
1898
|
|
@@ -1987,7 +1999,11 @@ function (_React$Component) {
|
|
1987
1999
|
value: newValue
|
1988
2000
|
})
|
1989
2001
|
};
|
1990
|
-
this.executeOnChange(eventMock, newValue, newPlainTextValue, getMentions(newValue, config));
|
2002
|
+
this.executeOnChange(eventMock, newValue, newPlainTextValue, getMentions(newValue, config)); // Move the cursor position to the end of the pasted data
|
2003
|
+
|
2004
|
+
var startOfMention = findStartOfMentionInPlainText(value, config, selectionStart);
|
2005
|
+
var nextPos = (startOfMention || selectionStart) + getPlainText(pastedMentions || pastedData, config).length;
|
2006
|
+
this.setSelection(nextPos, nextPos);
|
1991
2007
|
}
|
1992
2008
|
}, {
|
1993
2009
|
key: "saveSelectionToClipboard",
|