react-mention-input 1.1.3 → 1.1.5

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.
@@ -95,4 +95,13 @@
95
95
  color: #aaa;
96
96
  pointer-events: none;
97
97
  position: absolute;
98
+ }
99
+
100
+ .link-highlight {
101
+ color: #007bff;
102
+ text-decoration: underline;
103
+ cursor: pointer;
104
+ }
105
+ .link-highlight:hover {
106
+ color: #0056b3;
98
107
  }
@@ -9,8 +9,16 @@ var MentionInput = function (_a) {
9
9
  var inputRef = useRef(null);
10
10
  var suggestionListRef = useRef(null);
11
11
  var caretOffsetRef = useRef(0);
12
- var highlightMentions = function (text) {
13
- return text.replace(/@([^\s]+(?: [^\s]+)?)(?=\s|$)/g, '<span class="mention-highlight">@$1</span>');
12
+ var highlightMentionsAndLinks = function (text) {
13
+ // Regular expression for detecting links
14
+ var linkRegex = /(https?:\/\/[^\s]+)/g;
15
+ // Regular expression for mentions
16
+ var mentionRegex = /@([^\s]+(?: [^\s]+)?)(?=\s|$)/g;
17
+ // First, highlight mentions
18
+ var highlightedText = text.replace(mentionRegex, '<span class="mention-highlight">@$1</span>');
19
+ // Then, highlight links
20
+ highlightedText = highlightedText.replace(linkRegex, '<a href="$1" target="_blank" rel="noopener noreferrer" class="link-highlight">$1</a>');
21
+ return highlightedText;
14
22
  };
15
23
  var restoreCaretPosition = function (node, caretOffset) {
16
24
  var range = document.createRange();
@@ -70,7 +78,7 @@ var MentionInput = function (_a) {
70
78
  setShowSuggestions(false);
71
79
  }
72
80
  var previousHTML = inputRef.current.innerHTML;
73
- var htmlWithHighlights = highlightMentions(plainText);
81
+ var htmlWithHighlights = highlightMentionsAndLinks(plainText); // Updated function
74
82
  if (previousHTML !== htmlWithHighlights) {
75
83
  inputRef.current.innerHTML = htmlWithHighlights;
76
84
  }
@@ -120,7 +128,7 @@ var MentionInput = function (_a) {
120
128
  var newValue = plainText.substring(0, mentionIndex + 1) + user.name + plainText.substring(caretOffset);
121
129
  setInputValue(newValue);
122
130
  inputRef.current.innerText = newValue;
123
- var htmlWithHighlights = highlightMentions(newValue);
131
+ var htmlWithHighlights = highlightMentionsAndLinks(newValue);
124
132
  inputRef.current.innerHTML = htmlWithHighlights;
125
133
  setShowSuggestions(false);
126
134
  var mentionEnd = mentionIndex + user.name.length + 1;
@@ -138,9 +146,15 @@ var MentionInput = function (_a) {
138
146
  }
139
147
  }
140
148
  };
149
+ var handleKeyDown = function (event) {
150
+ if (event.key === "Enter" && !event.shiftKey) {
151
+ event.preventDefault(); // Prevent newline in content-editable
152
+ handleSendMessage(); // Trigger the same function as the Send button
153
+ }
154
+ };
141
155
  return (React.createElement("div", { className: "mention-container ".concat(containerClassName || "") },
142
156
  React.createElement("div", { className: "mention-input-container ".concat(inputContainerClassName || "") },
143
- React.createElement("div", { ref: inputRef, contentEditable: true, suppressContentEditableWarning: true, className: "mention-input ".concat(inputClassName || ""), onInput: handleInputChange }),
157
+ React.createElement("div", { ref: inputRef, contentEditable: true, suppressContentEditableWarning: true, className: "mention-input ".concat(inputClassName || ""), onInput: handleInputChange, onKeyDown: handleKeyDown }),
144
158
  React.createElement("button", { onClick: handleSendMessage, className: "send-button ".concat(sendBtnClassName || "") }, sendButtonIcon || "➤")),
145
159
  renderSuggestions()));
146
160
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-mention-input",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
@@ -95,4 +95,13 @@
95
95
  color: #aaa;
96
96
  pointer-events: none;
97
97
  position: absolute;
98
+ }
99
+
100
+ .link-highlight {
101
+ color: #007bff;
102
+ text-decoration: underline;
103
+ cursor: pointer;
104
+ }
105
+ .link-highlight:hover {
106
+ color: #0056b3;
98
107
  }
@@ -42,11 +42,26 @@ const MentionInput: React.FC<MentionInputProps> = ({
42
42
  const suggestionListRef = useRef<HTMLUListElement>(null);
43
43
  const caretOffsetRef = useRef<number>(0);
44
44
 
45
- const highlightMentions = (text: string): string => {
46
- return text.replace(
47
- /@([^\s]+(?: [^\s]+)?)(?=\s|$)/g,
45
+ const highlightMentionsAndLinks = (text: string): string => {
46
+ // Regular expression for detecting links
47
+ const linkRegex = /(https?:\/\/[^\s]+)/g;
48
+
49
+ // Regular expression for mentions
50
+ const mentionRegex = /@([^\s]+(?: [^\s]+)?)(?=\s|$)/g;
51
+
52
+ // First, highlight mentions
53
+ let highlightedText = text.replace(
54
+ mentionRegex,
48
55
  '<span class="mention-highlight">@$1</span>'
49
56
  );
57
+
58
+ // Then, highlight links
59
+ highlightedText = highlightedText.replace(
60
+ linkRegex,
61
+ '<a href="$1" target="_blank" rel="noopener noreferrer" class="link-highlight">$1</a>'
62
+ );
63
+
64
+ return highlightedText;
50
65
  };
51
66
 
52
67
  const restoreCaretPosition = (node: HTMLElement, caretOffset: number) => {
@@ -82,10 +97,10 @@ const MentionInput: React.FC<MentionInputProps> = ({
82
97
 
83
98
  const handleInputChange = () => {
84
99
  if (!inputRef.current) return;
85
-
100
+
86
101
  const selection = window.getSelection();
87
102
  const range = selection?.getRangeAt(0);
88
-
103
+
89
104
  let newCaretOffset = 0;
90
105
  if (range && inputRef.current.contains(range.startContainer)) {
91
106
  const preCaretRange = range.cloneRange();
@@ -93,31 +108,32 @@ const MentionInput: React.FC<MentionInputProps> = ({
93
108
  preCaretRange.setEnd(range.startContainer, range.startOffset);
94
109
  newCaretOffset = preCaretRange.toString().length;
95
110
  }
96
-
111
+
97
112
  caretOffsetRef.current = newCaretOffset;
98
-
113
+
99
114
  const plainText = inputRef.current.innerText;
100
115
  setInputValue(plainText);
101
-
116
+
102
117
  const mentionMatch = plainText.slice(0, newCaretOffset).match(/@(\S*)$/);
103
118
  if (mentionMatch) {
104
119
  const query = mentionMatch[1].toLowerCase();
105
120
  const filteredUsers = query === "" ? users : users.filter((user) => user.name.toLowerCase().startsWith(query));
106
-
121
+
107
122
  setSuggestions(filteredUsers);
108
123
  setShowSuggestions(filteredUsers.length > 0);
109
124
  } else {
110
125
  setShowSuggestions(false);
111
126
  }
112
-
127
+
113
128
  const previousHTML = inputRef.current.innerHTML;
114
- const htmlWithHighlights = highlightMentions(plainText);
129
+ const htmlWithHighlights = highlightMentionsAndLinks(plainText); // Updated function
115
130
  if (previousHTML !== htmlWithHighlights) {
116
131
  inputRef.current.innerHTML = htmlWithHighlights;
117
132
  }
118
-
133
+
119
134
  restoreCaretPosition(inputRef.current, newCaretOffset);
120
135
  };
136
+
121
137
 
122
138
  const renderSuggestions = () => {
123
139
  if (!showSuggestions || !inputRef.current) return null;
@@ -190,7 +206,7 @@ const MentionInput: React.FC<MentionInputProps> = ({
190
206
  setInputValue(newValue);
191
207
  inputRef.current.innerText = newValue;
192
208
 
193
- const htmlWithHighlights = highlightMentions(newValue);
209
+ const htmlWithHighlights = highlightMentionsAndLinks(newValue);
194
210
  inputRef.current.innerHTML = htmlWithHighlights;
195
211
 
196
212
  setShowSuggestions(false);
@@ -213,6 +229,13 @@ const MentionInput: React.FC<MentionInputProps> = ({
213
229
  }
214
230
  };
215
231
 
232
+ const handleKeyDown = (event: React.KeyboardEvent<HTMLDivElement>) => {
233
+ if (event.key === "Enter" && !event.shiftKey) {
234
+ event.preventDefault(); // Prevent newline in content-editable
235
+ handleSendMessage(); // Trigger the same function as the Send button
236
+ }
237
+ };
238
+
216
239
 
217
240
 
218
241
  return (
@@ -224,6 +247,7 @@ const MentionInput: React.FC<MentionInputProps> = ({
224
247
  suppressContentEditableWarning
225
248
  className={`mention-input ${inputClassName || ""}`}
226
249
  onInput={handleInputChange}
250
+ onKeyDown={handleKeyDown} // Add keydown listener
227
251
  ></div>
228
252
  <button
229
253
  onClick={handleSendMessage}