react-mention-input 1.0.18 → 1.0.19

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.
@@ -42,23 +42,21 @@
42
42
  justify-content: center;
43
43
  }
44
44
 
45
+
46
+
45
47
  .suggestion-list {
46
- position: absolute;
47
- top: 100%;
48
- left: 0;
49
- right: 0;
50
- background-color: #fff;
51
- border: 1px solid #ddd;
52
- border-radius: 4px;
53
- list-style: none;
54
- margin: 4px 0;
55
- padding: 0;
56
48
  max-height: 150px;
57
49
  overflow-y: auto;
58
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
59
- z-index: 1;
50
+ background: #fff;
51
+ border: 1px solid #ddd;
52
+ border-radius: 4px;
53
+ z-index: 1000;
54
+ width: auto;
55
+ white-space: nowrap;
56
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
60
57
  }
61
58
 
59
+
62
60
  .suggestion-item {
63
61
  padding: 8px 12px;
64
62
  cursor: pointer;
@@ -69,3 +67,17 @@
69
67
  .suggestion-item:hover {
70
68
  background-color: #f5f5f5;
71
69
  }
70
+
71
+
72
+ .mention-highlight {
73
+ background-color: #e0f7fa;
74
+ color: #007bff;
75
+ padding: 2px 4px;
76
+ border-radius: 4px;
77
+ }
78
+
79
+ .mention-input .placeholder {
80
+ color: #aaa;
81
+ pointer-events: none;
82
+ position: absolute;
83
+ }
@@ -1,5 +1,5 @@
1
- import React, { ReactNode } from 'react';
2
- import './MentionInput.css';
1
+ import React, { ReactNode } from "react";
2
+ import "./MentionInput.css";
3
3
  interface User {
4
4
  id: number;
5
5
  name: string;
@@ -1,48 +1,147 @@
1
- import React, { useState } from 'react';
2
- import './MentionInput.css'; // Import the SCSS file
1
+ import React, { useState, useRef } from "react";
2
+ import ReactDOM from "react-dom";
3
+ import "./MentionInput.css";
3
4
  var MentionInput = function (_a) {
4
- var users = _a.users, placeholder = _a.placeholder, containerClassName = _a.containerClassName, inputContainerClassName = _a.inputContainerClassName, inputClassName = _a.inputClassName, sendBtnClassName = _a.sendBtnClassName, suggestionListClassName = _a.suggestionListClassName, suggestionItemClassName = _a.suggestionItemClassName, sendButtonIcon = _a.sendButtonIcon, onSendMessage = _a.onSendMessage;
5
- var _b = useState(''), inputValue = _b[0], setInputValue = _b[1];
6
- var _c = useState([]), suggestions = _c[0], setSuggestions = _c[1];
7
- var _d = useState(false), showSuggestions = _d[0], setShowSuggestions = _d[1];
8
- var handleInputChange = function (e) {
9
- var value = e.target.value;
10
- setInputValue(value);
11
- var mentionMatch = value.match(/@(\w*)$/);
5
+ var users = _a.users, _b = _a.placeholder, placeholder = _b === void 0 ? "Type a message..." : _b, containerClassName = _a.containerClassName, inputContainerClassName = _a.inputContainerClassName, inputClassName = _a.inputClassName, sendBtnClassName = _a.sendBtnClassName, suggestionListClassName = _a.suggestionListClassName, suggestionItemClassName = _a.suggestionItemClassName, sendButtonIcon = _a.sendButtonIcon, onSendMessage = _a.onSendMessage;
6
+ var _c = useState(""), inputValue = _c[0], setInputValue = _c[1]; // Plain text
7
+ var _d = useState([]), suggestions = _d[0], setSuggestions = _d[1];
8
+ var _e = useState(false), showSuggestions = _e[0], setShowSuggestions = _e[1];
9
+ var _f = useState('bottom'), tooltipPosition = _f[0], setTooltipPosition = _f[1];
10
+ var inputRef = useRef(null);
11
+ var suggestionListRef = useRef(null);
12
+ var caretOffsetRef = useRef(0);
13
+ var highlightMentions = function (text) {
14
+ return text.replace(/@([^\s]+(?: [^\s]+)?)(?=\s|$)/g, // Match @ followed by one or two words, ending with a space or end of string
15
+ '<span class="mention-highlight">@$1</span>');
16
+ };
17
+ var restoreCaretPosition = function (node, caretOffset) {
18
+ var range = document.createRange();
19
+ var sel = window.getSelection();
20
+ var charCount = 0;
21
+ var findCaret = function (currentNode) {
22
+ var _a;
23
+ for (var _i = 0, _b = Array.from(currentNode.childNodes); _i < _b.length; _i++) {
24
+ var child = _b[_i];
25
+ if (child.nodeType === Node.TEXT_NODE) {
26
+ var textLength = ((_a = child.textContent) === null || _a === void 0 ? void 0 : _a.length) || 0;
27
+ if (charCount + textLength >= caretOffset) {
28
+ range.setStart(child, caretOffset - charCount);
29
+ range.collapse(true);
30
+ return true;
31
+ }
32
+ else {
33
+ charCount += textLength;
34
+ }
35
+ }
36
+ else if (child.nodeType === Node.ELEMENT_NODE) {
37
+ if (findCaret(child))
38
+ return true;
39
+ }
40
+ }
41
+ return false;
42
+ };
43
+ findCaret(node);
44
+ if (sel) {
45
+ sel.removeAllRanges();
46
+ sel.addRange(range);
47
+ }
48
+ };
49
+ var handleInputChange = function () {
50
+ if (!inputRef.current)
51
+ return;
52
+ var selection = window.getSelection();
53
+ var range = selection === null || selection === void 0 ? void 0 : selection.getRangeAt(0);
54
+ var newCaretOffset = 0;
55
+ if (range && inputRef.current.contains(range.startContainer)) {
56
+ var preCaretRange = range.cloneRange();
57
+ preCaretRange.selectNodeContents(inputRef.current);
58
+ preCaretRange.setEnd(range.startContainer, range.startOffset);
59
+ newCaretOffset = preCaretRange.toString().length; // Calculate caret offset
60
+ }
61
+ caretOffsetRef.current = newCaretOffset; // Update ref directly
62
+ var plainText = inputRef.current.innerText;
63
+ setInputValue(plainText);
64
+ // Handle mentions and suggestions
65
+ var mentionMatch = plainText.slice(0, newCaretOffset).match(/@(\S*)$/);
12
66
  if (mentionMatch) {
13
67
  var query_1 = mentionMatch[1].toLowerCase();
14
- var filteredUsers = users.filter(function (user) {
15
- return user.name.toLowerCase().startsWith(query_1);
16
- });
68
+ var filteredUsers = query_1 === "" ? users : users.filter(function (user) { return user.name.toLowerCase().startsWith(query_1); });
17
69
  setSuggestions(filteredUsers);
18
- setShowSuggestions(true);
70
+ setShowSuggestions(filteredUsers.length > 0);
19
71
  }
20
72
  else {
21
73
  setShowSuggestions(false);
22
74
  }
75
+ var previousHTML = inputRef.current.innerHTML;
76
+ var htmlWithHighlights = highlightMentions(plainText);
77
+ if (previousHTML !== htmlWithHighlights) {
78
+ inputRef.current.innerHTML = htmlWithHighlights;
79
+ }
80
+ restoreCaretPosition(inputRef.current, newCaretOffset);
23
81
  };
24
82
  var handleSuggestionClick = function (user) {
25
- var mentionIndex = inputValue.lastIndexOf('@');
26
- var newValue = "".concat(inputValue.substring(0, mentionIndex + 1)).concat(user.name, " ");
83
+ if (!inputRef.current)
84
+ return;
85
+ var plainText = inputValue; // Current input value
86
+ var caretOffset = caretOffsetRef.current; // Use ref value for caret offset
87
+ var mentionMatch = plainText.slice(0, caretOffset).match(/@(\S*)$/);
88
+ if (!mentionMatch)
89
+ return;
90
+ var mentionIndex = plainText.slice(0, caretOffset).lastIndexOf("@");
91
+ var newValue = plainText.substring(0, mentionIndex + 1) + user.name + plainText.substring(caretOffset);
27
92
  setInputValue(newValue);
93
+ inputRef.current.innerText = newValue;
94
+ var htmlWithHighlights = highlightMentions(newValue);
95
+ inputRef.current.innerHTML = htmlWithHighlights;
28
96
  setShowSuggestions(false);
97
+ var mentionEnd = mentionIndex + user.name.length + 1;
98
+ restoreCaretPosition(inputRef.current, mentionEnd);
29
99
  };
30
100
  var handleSendMessage = function () {
31
101
  if (inputValue.trim() && onSendMessage) {
32
102
  onSendMessage(inputValue.trim());
33
- setInputValue(''); // Clear input after sending
103
+ setInputValue("");
104
+ setShowSuggestions(false);
105
+ if (inputRef.current)
106
+ inputRef.current.innerText = "";
34
107
  }
35
108
  };
36
- var handleKeyPress = function (e) {
37
- if (e.key === 'Enter') {
38
- e.preventDefault();
39
- handleSendMessage();
109
+ var renderSuggestions = function () {
110
+ if (!showSuggestions || !inputRef.current)
111
+ return null;
112
+ var inputRect = inputRef.current.getBoundingClientRect();
113
+ var styles = {
114
+ position: 'absolute',
115
+ zIndex: 1000
116
+ };
117
+ // Adjust position based on calculated tooltip position
118
+ switch (tooltipPosition) {
119
+ case 'top':
120
+ styles.left = "".concat(inputRect.left, "px");
121
+ styles.top = "".concat(inputRect.top - 150, "px");
122
+ break;
123
+ case 'bottom':
124
+ styles.left = "".concat(inputRect.left, "px");
125
+ styles.top = "".concat(inputRect.bottom, "px");
126
+ break;
127
+ case 'left':
128
+ styles.left = "".concat(inputRect.left - 150, "px");
129
+ styles.top = "".concat(inputRect.top, "px");
130
+ break;
131
+ case 'right':
132
+ styles.left = "".concat(inputRect.right, "px");
133
+ styles.top = "".concat(inputRect.top, "px");
134
+ break;
135
+ default:
136
+ break;
40
137
  }
138
+ return ReactDOM.createPortal(React.createElement("ul", { className: "suggestion-list ".concat(suggestionListClassName || ''), ref: suggestionListRef, style: styles }, suggestions.map(function (user) { return (React.createElement("li", { key: user.id, onClick: function () { return handleSuggestionClick(user); }, className: "suggestion-item ".concat(suggestionItemClassName || ''), role: "option", tabIndex: 0, "aria-selected": "false" }, user.name)); })), document.body // Render in portal
139
+ );
41
140
  };
42
- return (React.createElement("div", { className: "mention-container ".concat(containerClassName || '') },
43
- React.createElement("div", { className: "mention-input-container ".concat(inputContainerClassName || '') },
44
- React.createElement("input", { type: "text", value: inputValue, onChange: handleInputChange, onKeyPress: handleKeyPress, placeholder: placeholder || 'Type a message...', className: "mention-input ".concat(inputClassName || '') }),
45
- React.createElement("button", { onClick: handleSendMessage, className: "send-button ".concat(sendBtnClassName || '') }, sendButtonIcon ? (typeof sendButtonIcon === 'string' ? (React.createElement("img", { src: sendButtonIcon, alt: "Send Icon", style: { width: '20px', height: '20px' } })) : (sendButtonIcon)) : ('➤'))),
46
- showSuggestions && (React.createElement("ul", { className: "suggestion-list ".concat(suggestionListClassName || '') }, suggestions.map(function (user) { return (React.createElement("li", { key: user.id, onClick: function () { return handleSuggestionClick(user); }, className: "suggestion-item ".concat(suggestionItemClassName || '') }, user.name)); })))));
141
+ return (React.createElement("div", { className: "mention-container ".concat(containerClassName || "") },
142
+ 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 }),
144
+ React.createElement("button", { onClick: handleSendMessage, className: "send-button ".concat(sendBtnClassName || "") }, sendButtonIcon || "")),
145
+ renderSuggestions()));
47
146
  };
48
147
  export default MentionInput;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-mention-input",
3
- "version": "1.0.18",
3
+ "version": "1.0.19",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "scripts": {
@@ -42,23 +42,21 @@
42
42
  justify-content: center;
43
43
  }
44
44
 
45
+
46
+
45
47
  .suggestion-list {
46
- position: absolute;
47
- top: 100%;
48
- left: 0;
49
- right: 0;
50
- background-color: #fff;
51
- border: 1px solid #ddd;
52
- border-radius: 4px;
53
- list-style: none;
54
- margin: 4px 0;
55
- padding: 0;
56
48
  max-height: 150px;
57
49
  overflow-y: auto;
58
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
59
- z-index: 1;
50
+ background: #fff;
51
+ border: 1px solid #ddd;
52
+ border-radius: 4px;
53
+ z-index: 1000;
54
+ width: auto;
55
+ white-space: nowrap;
56
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
60
57
  }
61
58
 
59
+
62
60
  .suggestion-item {
63
61
  padding: 8px 12px;
64
62
  cursor: pointer;
@@ -69,3 +67,17 @@
69
67
  .suggestion-item:hover {
70
68
  background-color: #f5f5f5;
71
69
  }
70
+
71
+
72
+ .mention-highlight {
73
+ background-color: #e0f7fa;
74
+ color: #007bff;
75
+ padding: 2px 4px;
76
+ border-radius: 4px;
77
+ }
78
+
79
+ .mention-input .placeholder {
80
+ color: #aaa;
81
+ pointer-events: none;
82
+ position: absolute;
83
+ }
@@ -1,9 +1,10 @@
1
- import React, { useState, ChangeEvent, KeyboardEvent, ReactNode } from 'react';
2
- import './MentionInput.css'; // Import the SCSS file
1
+ import React, { useState, useRef, useEffect, ReactNode } from "react";
2
+ import ReactDOM from "react-dom";
3
+ import "./MentionInput.css";
3
4
 
4
5
  interface User {
5
6
  id: number;
6
- name: string;
7
+ name: string; // Full name, e.g., "John Heart"
7
8
  }
8
9
 
9
10
  interface MentionInputProps {
@@ -19,9 +20,9 @@ interface MentionInputProps {
19
20
  onSendMessage?: (message: string) => void;
20
21
  }
21
22
 
22
- const MentionInput: React.FC<MentionInputProps> = ({
23
+ const MentionInput: React.FC<MentionInputProps> = ({
23
24
  users,
24
- placeholder,
25
+ placeholder = "Type a message...",
25
26
  containerClassName,
26
27
  inputContainerClassName,
27
28
  inputClassName,
@@ -31,92 +32,204 @@ interface MentionInputProps {
31
32
  sendButtonIcon,
32
33
  onSendMessage,
33
34
  }) => {
34
- const [inputValue, setInputValue] = useState<string>('');
35
+ const [inputValue, setInputValue] = useState<string>(""); // Plain text
35
36
  const [suggestions, setSuggestions] = useState<User[]>([]);
36
37
  const [showSuggestions, setShowSuggestions] = useState<boolean>(false);
38
+ const [tooltipPosition, setTooltipPosition] = useState<'top' | 'bottom' | 'left' | 'right'>(
39
+ 'bottom'
40
+ );
41
+
42
+ const inputRef = useRef<HTMLDivElement>(null);
43
+ const suggestionListRef = useRef<HTMLUListElement>(null);
44
+ const caretOffsetRef = useRef<number>(0);
45
+
46
+
47
+ const highlightMentions = (text: string): string => {
48
+ return text.replace(
49
+ /@([^\s]+(?: [^\s]+)?)(?=\s|$)/g, // Match @ followed by one or two words, ending with a space or end of string
50
+ '<span class="mention-highlight">@$1</span>'
51
+ );
52
+ };
53
+
54
+ const restoreCaretPosition = (node: HTMLElement, caretOffset: number) => {
55
+ const range = document.createRange();
56
+ const sel = window.getSelection();
57
+ let charCount = 0;
37
58
 
38
- const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
39
- const value = e.target.value;
40
- setInputValue(value);
59
+ const findCaret = (currentNode: Node) => {
60
+ for (const child of Array.from(currentNode.childNodes)) {
61
+ if (child.nodeType === Node.TEXT_NODE) {
62
+ const textLength = child.textContent?.length || 0;
63
+ if (charCount + textLength >= caretOffset) {
64
+ range.setStart(child, caretOffset - charCount);
65
+ range.collapse(true);
66
+ return true;
67
+ } else {
68
+ charCount += textLength;
69
+ }
70
+ } else if (child.nodeType === Node.ELEMENT_NODE) {
71
+ if (findCaret(child)) return true;
72
+ }
73
+ }
74
+ return false;
75
+ };
41
76
 
42
- const mentionMatch = value.match(/@(\w*)$/);
77
+ findCaret(node);
78
+
79
+ if (sel) {
80
+ sel.removeAllRanges();
81
+ sel.addRange(range);
82
+ }
83
+ };
84
+
85
+ const handleInputChange = () => {
86
+ if (!inputRef.current) return;
87
+
88
+ const selection = window.getSelection();
89
+ const range = selection?.getRangeAt(0);
90
+
91
+ let newCaretOffset = 0;
92
+ if (range && inputRef.current.contains(range.startContainer)) {
93
+ const preCaretRange = range.cloneRange();
94
+ preCaretRange.selectNodeContents(inputRef.current);
95
+ preCaretRange.setEnd(range.startContainer, range.startOffset);
96
+ newCaretOffset = preCaretRange.toString().length; // Calculate caret offset
97
+ }
98
+
99
+ caretOffsetRef.current = newCaretOffset; // Update ref directly
100
+
101
+ const plainText = inputRef.current.innerText;
102
+ setInputValue(plainText);
103
+
104
+ // Handle mentions and suggestions
105
+ const mentionMatch = plainText.slice(0, newCaretOffset).match(/@(\S*)$/);
43
106
  if (mentionMatch) {
44
107
  const query = mentionMatch[1].toLowerCase();
45
- const filteredUsers = users.filter((user) =>
46
- user.name.toLowerCase().startsWith(query)
47
- );
108
+ const filteredUsers = query === "" ? users : users.filter((user) => user.name.toLowerCase().startsWith(query));
109
+
48
110
  setSuggestions(filteredUsers);
49
- setShowSuggestions(true);
111
+ setShowSuggestions(filteredUsers.length > 0);
50
112
  } else {
51
113
  setShowSuggestions(false);
52
114
  }
115
+
116
+ const previousHTML = inputRef.current.innerHTML;
117
+ const htmlWithHighlights = highlightMentions(plainText);
118
+ if (previousHTML !== htmlWithHighlights) {
119
+ inputRef.current.innerHTML = htmlWithHighlights;
120
+ }
121
+
122
+ restoreCaretPosition(inputRef.current, newCaretOffset);
53
123
  };
54
124
 
55
125
  const handleSuggestionClick = (user: User) => {
56
- const mentionIndex = inputValue.lastIndexOf('@');
57
- const newValue = `${inputValue.substring(0, mentionIndex + 1)}${user.name} `;
126
+ if (!inputRef.current) return;
127
+
128
+ const plainText = inputValue; // Current input value
129
+ const caretOffset = caretOffsetRef.current; // Use ref value for caret offset
130
+ const mentionMatch = plainText.slice(0, caretOffset).match(/@(\S*)$/);
131
+
132
+ if (!mentionMatch) return;
133
+
134
+ const mentionIndex = plainText.slice(0, caretOffset).lastIndexOf("@");
135
+
136
+ const newValue =
137
+ plainText.substring(0, mentionIndex + 1) + user.name + plainText.substring(caretOffset);
138
+
58
139
  setInputValue(newValue);
140
+ inputRef.current.innerText = newValue;
141
+
142
+ const htmlWithHighlights = highlightMentions(newValue);
143
+ inputRef.current.innerHTML = htmlWithHighlights;
144
+
59
145
  setShowSuggestions(false);
146
+
147
+ const mentionEnd = mentionIndex + user.name.length + 1;
148
+ restoreCaretPosition(inputRef.current, mentionEnd);
60
149
  };
61
-
62
150
  const handleSendMessage = () => {
63
151
  if (inputValue.trim() && onSendMessage) {
64
152
  onSendMessage(inputValue.trim());
65
- setInputValue(''); // Clear input after sending
153
+ setInputValue("");
154
+ setShowSuggestions(false);
155
+ if (inputRef.current) inputRef.current.innerText = "";
66
156
  }
67
157
  };
68
158
 
69
- const handleKeyPress = (e: KeyboardEvent<HTMLInputElement>) => {
70
- if (e.key === 'Enter') {
71
- e.preventDefault();
72
- handleSendMessage();
159
+ const renderSuggestions = () => {
160
+ if (!showSuggestions || !inputRef.current) return null;
161
+
162
+ const inputRect = inputRef.current.getBoundingClientRect();
163
+ const styles: React.CSSProperties = {
164
+ position: 'absolute',
165
+ zIndex: 1000
166
+ };
167
+
168
+ // Adjust position based on calculated tooltip position
169
+ switch (tooltipPosition) {
170
+ case 'top':
171
+ styles.left = `${inputRect.left}px`;
172
+ styles.top = `${inputRect.top - 150}px`;
173
+ break;
174
+ case 'bottom':
175
+ styles.left = `${inputRect.left}px`;
176
+ styles.top = `${inputRect.bottom}px`;
177
+ break;
178
+ case 'left':
179
+ styles.left = `${inputRect.left - 150}px`;
180
+ styles.top = `${inputRect.top}px`;
181
+ break;
182
+ case 'right':
183
+ styles.left = `${inputRect.right}px`;
184
+ styles.top = `${inputRect.top}px`;
185
+ break;
186
+ default:
187
+ break;
73
188
  }
74
- };
75
189
 
76
- return (
77
- <div className={`mention-container ${containerClassName || ''}`}>
78
-
79
- <div className={`mention-input-container ${inputContainerClassName || ''}`}>
80
- <input
81
- type="text"
82
- value={inputValue}
83
- onChange={handleInputChange}
84
- onKeyPress={handleKeyPress}
85
- placeholder={placeholder || 'Type a message...'}
86
- className={`mention-input ${inputClassName || ''}`}
87
- />
88
- <button
89
- onClick={handleSendMessage}
90
- className={`send-button ${sendBtnClassName || ''}`}
190
+ return ReactDOM.createPortal(
191
+ <ul
192
+ className={`suggestion-list ${suggestionListClassName || ''}`}
193
+ ref={suggestionListRef}
194
+ style={styles}
91
195
  >
92
- {sendButtonIcon ? (
93
- typeof sendButtonIcon === 'string' ? (
94
- <img src={sendButtonIcon} alt="Send Icon" style={{ width: '20px', height: '20px' }} />
95
- ) : (
96
- sendButtonIcon
97
- )
98
- ) : (
99
- '➤'
100
- )}
101
- </button>
196
+ {suggestions.map((user) => (
197
+ <li
198
+ key={user.id}
199
+ onClick={() => handleSuggestionClick(user)}
200
+ className={`suggestion-item ${suggestionItemClassName || ''}`}
201
+ role="option"
202
+ tabIndex={0}
203
+ aria-selected="false"
204
+ >
205
+ {user.name}
206
+ </li>
207
+ ))}
208
+ </ul>,
209
+ document.body // Render in portal
210
+ );
211
+ };
102
212
 
213
+ return (
214
+ <div className={`mention-container ${containerClassName || ""}`}>
215
+ <div className={`mention-input-container ${inputContainerClassName || ""}`}>
216
+ <div
217
+ ref={inputRef}
218
+ contentEditable
219
+ suppressContentEditableWarning
220
+ className={`mention-input ${inputClassName || ""}`}
221
+ onInput={handleInputChange}
222
+ ></div>
223
+ <button
224
+ onClick={handleSendMessage}
225
+ className={`send-button ${sendBtnClassName || ""}`}
226
+ >
227
+ {sendButtonIcon || "➤"}
228
+ </button>
103
229
  </div>
104
- {showSuggestions && (
105
- <ul className={`suggestion-list ${suggestionListClassName || ''}`}>
106
- {suggestions.map((user) => (
107
- <li
108
- key={user.id}
109
- onClick={() => handleSuggestionClick(user)}
110
- className={`suggestion-item ${suggestionItemClassName || ''}`}
111
- >
112
- {user.name}
113
- </li>
114
- ))}
115
- </ul>
116
- )}
230
+ {renderSuggestions()}
117
231
  </div>
118
232
  );
119
233
  };
120
234
 
121
-
122
- export default MentionInput
235
+ export default MentionInput;