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 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; // if we are inside iframe, we need to find activeElement within its contentDocument
1437
+ isComposing = false;
1429
1438
 
1430
- var currentDocument = document.activeElement && document.activeElement.contentDocument || document;
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
- if (currentDocument.activeElement !== ev.target) {
1433
- // fix an IE bug (blur from empty input element with placeholder attribute trigger "input" event)
1434
- return;
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 === ev.target) {
891
- var value = _this.props.value || "", config = readConfigFromChildren(_this.props.children), newPlainTextValue = ev.target.value, newValue = applyChangeToValue(value, newPlainTextValue, {
892
- selectionStartBefore: _this.state.selectionStart,
893
- selectionEndBefore: _this.state.selectionEnd,
894
- selectionEndAfter: ev.target.selectionEnd
895
- }, config);
896
- newPlainTextValue = getPlainText(newValue, config);
897
- var selectionStart = ev.target.selectionStart, selectionEnd = ev.target.selectionEnd, setSelectionAfterMentionChange = !1, startOfMention = findStartOfMentionInPlainText(value, config, selectionStart);
898
- void 0 !== startOfMention && _this.state.selectionEnd > startOfMention && (selectionEnd = selectionStart = startOfMention,
899
- setSelectionAfterMentionChange = !0), _this.setState({
900
- selectionStart: selectionStart,
901
- selectionEnd: selectionEnd,
902
- setSelectionAfterMentionChange: setSelectionAfterMentionChange
903
- });
904
- var mentions = getMentions(newValue, config), eventMock = {
905
- target: {
906
- value: newValue
907
- }
908
- };
909
- _this.executeOnChange(eventMock, newValue, newPlainTextValue, mentions);
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; // if we are inside iframe, we need to find activeElement within its contentDocument
1429
+ isComposing = false;
1421
1430
 
1422
- var currentDocument = document.activeElement && document.activeElement.contentDocument || document;
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
- if (currentDocument.activeElement !== ev.target) {
1425
- // fix an IE bug (blur from empty input element with placeholder attribute trigger "input" event)
1426
- return;
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",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-mentions",
3
- "version": "4.2.0",
3
+ "version": "4.3.2",
4
4
  "description": "React mentions input",
5
5
  "main": "dist/react-mentions.cjs.js",
6
6
  "module": "dist/react-mentions.esm.js",