react-mention-input 1.1.14 → 1.1.16

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/demo.tsx ADDED
@@ -0,0 +1,98 @@
1
+ import React, { useState } from 'react';
2
+ import { MentionInput, ShowMessageCard } from './src';
3
+
4
+ const Demo: React.FC = () => {
5
+ const [messages, setMessages] = useState<any[]>([
6
+ {
7
+ id: 1,
8
+ name: 'John Doe',
9
+ date: '2 hours ago',
10
+ comment: 'Updated the status to Draft. Need <span class="mention-highlight">@team-leads</span> review before proceeding. <span class="hashtag-highlight">#urgent</span> <span class="hashtag-highlight">#review</span>',
11
+ itemName: '26may_item001 (A)',
12
+ },
13
+ {
14
+ id: 2,
15
+ name: 'Mike Johnson',
16
+ date: '1 day ago',
17
+ comment: 'Revision A completed successfully. Ready for next phase. <span class="hashtag-highlight">#milestone</span>',
18
+ itemName: '26may_item001 (A)',
19
+ }
20
+ ]);
21
+
22
+ // Sample users for mentions
23
+ const users = [
24
+ { id: 1, name: 'John Doe' },
25
+ { id: 2, name: 'Jane Smith' },
26
+ { id: 3, name: 'Mike Johnson' },
27
+ { id: 4, name: 'Sarah Wilson' },
28
+ ];
29
+
30
+ const handleSendMessage = (messageData: {
31
+ messageText: string;
32
+ messageHTML: string;
33
+ userSelectListWithIds: { id: number; name: string }[];
34
+ userSelectListName: string[];
35
+ tags: string[];
36
+ images?: File[];
37
+ imageUrl?: string | null;
38
+ }) => {
39
+ console.log('Message Data:', messageData);
40
+ console.log('Extracted Tags:', messageData.tags);
41
+
42
+ // Create a new message for display
43
+ const newMessage = {
44
+ id: Date.now(),
45
+ name: 'You',
46
+ date: new Date().toLocaleTimeString(),
47
+ comment: messageData.messageHTML,
48
+ imageUrl: messageData.imageUrl,
49
+ tags: messageData.tags,
50
+ mentions: messageData.userSelectListName,
51
+ itemName: 'new_item001 (A)', // You can customize this or make it dynamic
52
+ };
53
+
54
+ setMessages([...messages, newMessage]);
55
+ };
56
+
57
+ return (
58
+ <div style={{ maxWidth: '600px', margin: '20px auto', padding: '20px' }}>
59
+ <h1>React Mention Input with Hashtag Support</h1>
60
+
61
+ <div style={{ marginBottom: '20px' }}>
62
+ <h3>Features:</h3>
63
+ <ul>
64
+ <li>Type <strong>@</strong> to mention users (e.g., @John Doe)</li>
65
+ <li>Type <strong>#</strong> to create hashtags (e.g., #urgent #review #milestone)</li>
66
+ <li>Links are automatically detected and highlighted</li>
67
+ <li>Hashtags are extracted and returned in the tags array</li>
68
+ </ul>
69
+ </div>
70
+
71
+ <div style={{ marginBottom: '20px' }}>
72
+ <MentionInput
73
+ users={users}
74
+ placeholder="Type a message with @mentions and #hashtags..."
75
+ onSendMessage={handleSendMessage}
76
+ suggestionPosition="bottom"
77
+ />
78
+ </div>
79
+
80
+ <div>
81
+ <h3>Messages:</h3>
82
+ <ShowMessageCard data={messages} />
83
+ </div>
84
+
85
+ <div style={{ marginTop: '20px', padding: '15px', backgroundColor: '#f5f5f5', borderRadius: '8px' }}>
86
+ <h4>Example Usage:</h4>
87
+ <p>Try typing these examples:</p>
88
+ <ul>
89
+ <li>"Project update complete. Ready for @John Doe review #milestone #completed"</li>
90
+ <li>"Need urgent help with deployment @Jane Smith @Mike Johnson #urgent #deployment #help"</li>
91
+ <li>"Meeting scheduled for tomorrow #meeting #planning"</li>
92
+ </ul>
93
+ </div>
94
+ </div>
95
+ );
96
+ };
97
+
98
+ export default Demo;
@@ -193,6 +193,14 @@
193
193
  font-weight: 500;
194
194
  }
195
195
 
196
+ .hashtag-highlight {
197
+ background-color: rgba(255, 165, 0, 0.1);
198
+ color: #FF8C00;
199
+ border-radius: 4px;
200
+ padding: 1px 4px;
201
+ font-weight: 500;
202
+ }
203
+
196
204
  .link-highlight {
197
205
  color: #2684FF;
198
206
  text-decoration: none;
@@ -13,6 +13,8 @@ interface MentionInputProps {
13
13
  sendBtnClassName?: string;
14
14
  suggestionListClassName?: string;
15
15
  suggestionItemClassName?: string;
16
+ attachedImageContainerClassName?: string;
17
+ attachedImageContainerStyle?: React.CSSProperties;
16
18
  imgClassName?: string;
17
19
  imgStyle?: React.CSSProperties;
18
20
  sendButtonIcon?: ReactNode;
@@ -39,7 +39,7 @@ import ReactDOM from "react-dom";
39
39
  import "./MentionInput.css";
40
40
  var MentionInput = function (_a) {
41
41
  var _b, _c;
42
- var users = _a.users, _d = _a.placeholder, placeholder = _d === void 0 ? "Type a message... (or drag & drop an image)" : _d, containerClassName = _a.containerClassName, inputContainerClassName = _a.inputContainerClassName, inputClassName = _a.inputClassName, sendBtnClassName = _a.sendBtnClassName, suggestionListClassName = _a.suggestionListClassName, suggestionItemClassName = _a.suggestionItemClassName, imgClassName = _a.imgClassName, imgStyle = _a.imgStyle, sendButtonIcon = _a.sendButtonIcon, attachmentButtonIcon = _a.attachmentButtonIcon, onSendMessage = _a.onSendMessage, _e = _a.suggestionPosition, suggestionPosition = _e === void 0 ? 'bottom' : _e, onImageUpload = _a.onImageUpload;
42
+ var users = _a.users, _d = _a.placeholder, placeholder = _d === void 0 ? "Type a message... (or drag & drop an image)" : _d, containerClassName = _a.containerClassName, inputContainerClassName = _a.inputContainerClassName, inputClassName = _a.inputClassName, sendBtnClassName = _a.sendBtnClassName, suggestionListClassName = _a.suggestionListClassName, suggestionItemClassName = _a.suggestionItemClassName, imgClassName = _a.imgClassName, imgStyle = _a.imgStyle, attachedImageContainerClassName = _a.attachedImageContainerClassName, attachedImageContainerStyle = _a.attachedImageContainerStyle, sendButtonIcon = _a.sendButtonIcon, attachmentButtonIcon = _a.attachmentButtonIcon, onSendMessage = _a.onSendMessage, _e = _a.suggestionPosition, suggestionPosition = _e === void 0 ? 'bottom' : _e, onImageUpload = _a.onImageUpload;
43
43
  var _f = useState(""), inputValue = _f[0], setInputValue = _f[1]; // Plain text
44
44
  var _g = useState([]), suggestions = _g[0], setSuggestions = _g[1];
45
45
  var _h = useState(false), showSuggestions = _h[0], setShowSuggestions = _h[1];
@@ -338,7 +338,7 @@ var MentionInput = function (_a) {
338
338
  };
339
339
  console.log(inputValue, (_b = inputRef.current) === null || _b === void 0 ? void 0 : _b.innerText.trim(), "inputValue====");
340
340
  return (React.createElement("div", { className: "mention-container ".concat(containerClassName || "") },
341
- imageUrl && selectedImage && (React.createElement("div", { className: "image-preview-card" },
341
+ imageUrl && selectedImage && (React.createElement("div", { className: "image-preview-card ".concat(attachedImageContainerClassName || ""), style: attachedImageContainerStyle },
342
342
  React.createElement("img", { src: imageUrl, alt: "Preview", className: imgClassName || "", style: imgStyle }),
343
343
  React.createElement("button", { onClick: removeImage, className: "remove-image-btn", "aria-label": "Remove image" }, "\u00D7"))),
344
344
  React.createElement("div", { className: "mention-input-container ".concat(inputContainerClassName || "", " ").concat(isDraggingOver ? 'dragging-over' : ''), onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDragEnd: function () { return setIsDraggingOver(false); }, onDrop: handleDrop },
@@ -21,9 +21,25 @@
21
21
  .message-card-header {
22
22
  display: flex;
23
23
  align-items: center;
24
+ justify-content: space-between;
24
25
  margin-bottom: 8px; /* Space between header and body */
25
26
  }
26
27
 
28
+ .message-card-header-left {
29
+ display: flex;
30
+ align-items: center;
31
+ }
32
+
33
+ .message-card-item-name {
34
+ font-size: 14px;
35
+ color: #666;
36
+ font-weight: 500;
37
+ background-color: #f5f5f5;
38
+ padding: 4px 8px;
39
+ border-radius: 6px;
40
+ border: 1px solid #e0e0e0;
41
+ }
42
+
27
43
  .message-card-img,
28
44
  .message-card-initials {
29
45
  width: 48px;
@@ -72,4 +88,40 @@
72
88
  color: #007bff;
73
89
  padding: 2px 4px;
74
90
  border-radius: 4px;
91
+ }
92
+
93
+ .hashtag-highlight {
94
+ background-color: rgba(255, 165, 0, 0.15);
95
+ color: #FF8C00;
96
+ padding: 2px 4px;
97
+ border-radius: 4px;
98
+ font-weight: 500;
99
+ }
100
+
101
+ /* Tag chips styling */
102
+ .message-card-tags {
103
+ display: flex;
104
+ flex-wrap: wrap;
105
+ gap: 8px;
106
+ margin-top: 12px;
107
+ }
108
+
109
+ .tag-chip {
110
+ padding: 6px 12px;
111
+ border-radius: 16px;
112
+ font-size: 12px;
113
+ font-weight: 500;
114
+ border: none;
115
+ display: inline-block;
116
+ white-space: nowrap;
117
+ }
118
+
119
+ .hashtag-chip {
120
+ background-color: #D4A574;
121
+ color: #FFFFFF;
122
+ }
123
+
124
+ .mention-chip {
125
+ background-color: #2684FF;
126
+ color: #FFFFFF;
75
127
  }
@@ -30,6 +30,8 @@ interface ShowMessageCardProps {
30
30
  commentStyle?: CSSProperties;
31
31
  attachedImageClassName?: string;
32
32
  attachedImageStyle?: CSSProperties;
33
+ attachedImageContainerClassName?: string;
34
+ attachedImageContainerStyle?: CSSProperties;
33
35
  renderItem?: (element: MessageCardProps) => ReactNode;
34
36
  }
35
37
  export declare const ShowMessageCard: React.FC<ShowMessageCardProps>;
@@ -13,7 +13,7 @@ import React, { useState } from "react";
13
13
  import "./ShowMessageCard.css";
14
14
  export var ShowMessageCard = function (_a) {
15
15
  var data = _a.data, _b = _a.nameKey, nameKey = _b === void 0 ? "name" : _b, _c = _a.dateKey, dateKey = _c === void 0 ? "date" : _c, _d = _a.commentKey, commentKey = _d === void 0 ? "comment" : _d, _e = _a.imgSrcKey, imgSrcKey = _e === void 0 ? "imgSrc" : _e, _f = _a.imageUrlKey, imageUrlKey = _f === void 0 ? "imageUrl" : _f, // Default key for attached image
16
- containerClassName = _a.containerClassName, containerStyle = _a.containerStyle, cardClassName = _a.cardClassName, cardStyle = _a.cardStyle, headerClassName = _a.headerClassName, headerStyle = _a.headerStyle, imgClassName = _a.imgClassName, imgStyle = _a.imgStyle, infoClassName = _a.infoClassName, infoStyle = _a.infoStyle, nameClassName = _a.nameClassName, nameStyle = _a.nameStyle, dateClassName = _a.dateClassName, dateStyle = _a.dateStyle, bodyClassName = _a.bodyClassName, bodyStyle = _a.bodyStyle, commentClassName = _a.commentClassName, commentStyle = _a.commentStyle, attachedImageClassName = _a.attachedImageClassName, attachedImageStyle = _a.attachedImageStyle, renderItem = _a.renderItem;
16
+ containerClassName = _a.containerClassName, containerStyle = _a.containerStyle, cardClassName = _a.cardClassName, cardStyle = _a.cardStyle, headerClassName = _a.headerClassName, headerStyle = _a.headerStyle, imgClassName = _a.imgClassName, imgStyle = _a.imgStyle, infoClassName = _a.infoClassName, infoStyle = _a.infoStyle, nameClassName = _a.nameClassName, nameStyle = _a.nameStyle, dateClassName = _a.dateClassName, dateStyle = _a.dateStyle, bodyClassName = _a.bodyClassName, bodyStyle = _a.bodyStyle, commentClassName = _a.commentClassName, commentStyle = _a.commentStyle, attachedImageClassName = _a.attachedImageClassName, attachedImageStyle = _a.attachedImageStyle, attachedImageContainerClassName = _a.attachedImageContainerClassName, attachedImageContainerStyle = _a.attachedImageContainerStyle, renderItem = _a.renderItem;
17
17
  // State to manage initials for images that fail to load
18
18
  var _g = useState({}), initialsState = _g[0], setInitialsState = _g[1];
19
19
  // Handle image load failure
@@ -46,7 +46,7 @@ export var ShowMessageCard = function (_a) {
46
46
  React.createElement("p", { className: "message-card-date ".concat(dateClassName || ""), style: dateStyle }, item[dateKey]))),
47
47
  React.createElement("div", { className: "message-card-body ".concat(bodyClassName || ""), style: bodyStyle },
48
48
  React.createElement("p", { className: "message-card-comment ".concat(commentClassName || ""), style: commentStyle, dangerouslySetInnerHTML: { __html: item[commentKey] } }),
49
- (item === null || item === void 0 ? void 0 : item[imageUrlKey]) && (React.createElement("div", { className: "message-card-attached-image-container" },
49
+ (item === null || item === void 0 ? void 0 : item[imageUrlKey]) && (React.createElement("div", { className: "message-card-attached-image-container ".concat(attachedImageContainerClassName || ""), style: attachedImageContainerStyle },
50
50
  React.createElement("img", { src: item[imageUrlKey], alt: "Attached", className: "message-card-attached-image ".concat(attachedImageClassName || ""), style: attachedImageStyle }))))));
51
51
  })));
52
52
  };
package/dist/demo.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const Demo: React.FC;
3
+ export default Demo;
package/dist/demo.js ADDED
@@ -0,0 +1,80 @@
1
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
2
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
3
+ if (ar || !(i in from)) {
4
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
5
+ ar[i] = from[i];
6
+ }
7
+ }
8
+ return to.concat(ar || Array.prototype.slice.call(from));
9
+ };
10
+ import React, { useState } from 'react';
11
+ import { MentionInput, ShowMessageCard } from './src';
12
+ var Demo = function () {
13
+ var _a = useState([
14
+ {
15
+ id: 1,
16
+ name: 'John Doe',
17
+ date: '2 hours ago',
18
+ comment: 'Updated the status to Draft. Need <span class="mention-highlight">@team-leads</span> review before proceeding. <span class="hashtag-highlight">#urgent</span> <span class="hashtag-highlight">#review</span>',
19
+ itemName: '26may_item001 (A)',
20
+ },
21
+ {
22
+ id: 2,
23
+ name: 'Mike Johnson',
24
+ date: '1 day ago',
25
+ comment: 'Revision A completed successfully. Ready for next phase. <span class="hashtag-highlight">#milestone</span>',
26
+ itemName: '26may_item001 (A)',
27
+ }
28
+ ]), messages = _a[0], setMessages = _a[1];
29
+ // Sample users for mentions
30
+ var users = [
31
+ { id: 1, name: 'John Doe' },
32
+ { id: 2, name: 'Jane Smith' },
33
+ { id: 3, name: 'Mike Johnson' },
34
+ { id: 4, name: 'Sarah Wilson' },
35
+ ];
36
+ var handleSendMessage = function (messageData) {
37
+ console.log('Message Data:', messageData);
38
+ console.log('Extracted Tags:', messageData.tags);
39
+ // Create a new message for display
40
+ var newMessage = {
41
+ id: Date.now(),
42
+ name: 'You',
43
+ date: new Date().toLocaleTimeString(),
44
+ comment: messageData.messageHTML,
45
+ imageUrl: messageData.imageUrl,
46
+ tags: messageData.tags,
47
+ mentions: messageData.userSelectListName,
48
+ itemName: 'new_item001 (A)', // You can customize this or make it dynamic
49
+ };
50
+ setMessages(__spreadArray(__spreadArray([], messages, true), [newMessage], false));
51
+ };
52
+ return (React.createElement("div", { style: { maxWidth: '600px', margin: '20px auto', padding: '20px' } },
53
+ React.createElement("h1", null, "React Mention Input with Hashtag Support"),
54
+ React.createElement("div", { style: { marginBottom: '20px' } },
55
+ React.createElement("h3", null, "Features:"),
56
+ React.createElement("ul", null,
57
+ React.createElement("li", null,
58
+ "Type ",
59
+ React.createElement("strong", null, "@"),
60
+ " to mention users (e.g., @John Doe)"),
61
+ React.createElement("li", null,
62
+ "Type ",
63
+ React.createElement("strong", null, "#"),
64
+ " to create hashtags (e.g., #urgent #review #milestone)"),
65
+ React.createElement("li", null, "Links are automatically detected and highlighted"),
66
+ React.createElement("li", null, "Hashtags are extracted and returned in the tags array"))),
67
+ React.createElement("div", { style: { marginBottom: '20px' } },
68
+ React.createElement(MentionInput, { users: users, placeholder: "Type a message with @mentions and #hashtags...", onSendMessage: handleSendMessage, suggestionPosition: "bottom" })),
69
+ React.createElement("div", null,
70
+ React.createElement("h3", null, "Messages:"),
71
+ React.createElement(ShowMessageCard, { data: messages })),
72
+ React.createElement("div", { style: { marginTop: '20px', padding: '15px', backgroundColor: '#f5f5f5', borderRadius: '8px' } },
73
+ React.createElement("h4", null, "Example Usage:"),
74
+ React.createElement("p", null, "Try typing these examples:"),
75
+ React.createElement("ul", null,
76
+ React.createElement("li", null, "\"Project update complete. Ready for @John Doe review #milestone #completed\""),
77
+ React.createElement("li", null, "\"Need urgent help with deployment @Jane Smith @Mike Johnson #urgent #deployment #help\""),
78
+ React.createElement("li", null, "\"Meeting scheduled for tomorrow #meeting #planning\"")))));
79
+ };
80
+ export default Demo;
package/dist/main.d.ts ADDED
@@ -0,0 +1 @@
1
+ export {};
package/dist/main.js ADDED
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom/client';
3
+ import Demo from './demo';
4
+ ReactDOM.createRoot(document.getElementById('root')).render(React.createElement(React.StrictMode, null,
5
+ React.createElement(Demo, null)));
@@ -0,0 +1,38 @@
1
+ import React, { ReactNode } from "react";
2
+ import "./MentionInput.css";
3
+ interface User {
4
+ id: number;
5
+ name: string;
6
+ }
7
+ interface MentionInputProps {
8
+ users: User[];
9
+ placeholder?: string;
10
+ containerClassName?: string;
11
+ inputContainerClassName?: string;
12
+ inputClassName?: string;
13
+ sendBtnClassName?: string;
14
+ suggestionListClassName?: string;
15
+ suggestionItemClassName?: string;
16
+ attachedImageContainerClassName?: string;
17
+ attachedImageContainerStyle?: React.CSSProperties;
18
+ imgClassName?: string;
19
+ imgStyle?: React.CSSProperties;
20
+ sendButtonIcon?: ReactNode;
21
+ attachmentButtonIcon?: ReactNode;
22
+ onSendMessage?: (obj: {
23
+ messageText: string;
24
+ messageHTML: string;
25
+ userSelectListWithIds: {
26
+ id: number;
27
+ name: string;
28
+ }[];
29
+ userSelectListName: string[];
30
+ tags: string[];
31
+ images?: File[];
32
+ imageUrl?: string | null;
33
+ }) => void;
34
+ suggestionPosition?: 'top' | 'bottom' | 'left' | 'right';
35
+ onImageUpload?: (file: File) => Promise<string>;
36
+ }
37
+ declare const MentionInput: React.FC<MentionInputProps>;
38
+ export default MentionInput;