@openim/im-composer 1.0.0 → 1.0.1
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/LICENSE +1 -1
- package/README.md +214 -203
- package/dist/index.css +1 -518
- package/dist/index.d.mts +617 -0
- package/dist/index.d.ts +487 -276
- package/dist/index.js +24 -2641
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +32 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +136 -82
- package/CHANGELOG.md +0 -37
- package/dist/index.cjs +0 -2603
- package/dist/index.cjs.map +0 -1
- package/dist/index.css.map +0 -1
- package/dist/index.d.cts +0 -406
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { ReactNode } from 'react';
|
|
3
|
-
import {
|
|
1
|
+
import * as React$1 from 'react';
|
|
2
|
+
import React__default, { MouseEventHandler, ReactNode } from 'react';
|
|
3
|
+
import { Editor, useEditor } from '@tiptap/react';
|
|
4
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
|
+
import { Editor as Editor$1 } from '@tiptap/core';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
|
-
*
|
|
8
|
+
* Represents a file attachment in plain mode
|
|
7
9
|
*/
|
|
8
|
-
|
|
10
|
+
interface Attachment {
|
|
9
11
|
/** Unique identifier generated by the component */
|
|
10
12
|
id: string;
|
|
11
|
-
/** Original File object
|
|
13
|
+
/** Original File object */
|
|
12
14
|
file: File;
|
|
13
15
|
/** File name */
|
|
14
16
|
name: string;
|
|
@@ -16,391 +18,600 @@ type Attachment = {
|
|
|
16
18
|
size: number;
|
|
17
19
|
/** MIME type */
|
|
18
20
|
mime: string;
|
|
19
|
-
/**
|
|
21
|
+
/** File last modified timestamp */
|
|
20
22
|
lastModified?: number;
|
|
21
|
-
/** Preview URL (objectURL)
|
|
23
|
+
/** Preview URL for images (objectURL) */
|
|
22
24
|
previewUrl?: string;
|
|
23
|
-
}
|
|
25
|
+
}
|
|
24
26
|
/**
|
|
25
|
-
*
|
|
27
|
+
* Information about a mention in the message
|
|
26
28
|
*/
|
|
27
|
-
|
|
28
|
-
/** User ID
|
|
29
|
+
interface MentionInfo {
|
|
30
|
+
/** User ID */
|
|
29
31
|
userId: string;
|
|
30
|
-
/** Display name
|
|
32
|
+
/** Display name */
|
|
31
33
|
display: string;
|
|
32
|
-
/** Start index (UTF-16, inclusive) */
|
|
34
|
+
/** Start index in plainText (UTF-16, inclusive) */
|
|
33
35
|
start: number;
|
|
34
|
-
/** End index (UTF-16, exclusive) */
|
|
36
|
+
/** End index in plainText (UTF-16, exclusive) */
|
|
35
37
|
end: number;
|
|
36
|
-
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Member data for mention suggestions
|
|
41
|
+
*/
|
|
42
|
+
interface Member {
|
|
43
|
+
/** Unique user identifier */
|
|
44
|
+
userId: string;
|
|
45
|
+
/** Display name shown in the editor */
|
|
46
|
+
display: string;
|
|
47
|
+
/** Optional avatar URL */
|
|
48
|
+
avatarUrl?: string;
|
|
49
|
+
}
|
|
37
50
|
/**
|
|
38
|
-
*
|
|
51
|
+
* Quoted message information
|
|
39
52
|
*/
|
|
40
|
-
|
|
41
|
-
/**
|
|
53
|
+
interface QuoteInfo {
|
|
54
|
+
/** Quote title, e.g., "Reply to Alice:" */
|
|
42
55
|
title: string;
|
|
43
|
-
/**
|
|
56
|
+
/** Quoted content */
|
|
44
57
|
content: string;
|
|
45
|
-
}
|
|
58
|
+
}
|
|
46
59
|
/**
|
|
47
|
-
*
|
|
60
|
+
* Result from image upload handler
|
|
48
61
|
*/
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
heading3?: string;
|
|
67
|
-
bulletList?: string;
|
|
68
|
-
orderedList?: string;
|
|
69
|
-
quote?: string;
|
|
70
|
-
codeBlock?: string;
|
|
71
|
-
link?: string;
|
|
72
|
-
image?: string;
|
|
73
|
-
};
|
|
74
|
-
};
|
|
62
|
+
interface UploadImageResult {
|
|
63
|
+
/** URL of the uploaded image */
|
|
64
|
+
url: string;
|
|
65
|
+
/** Optional alt text */
|
|
66
|
+
alt?: string;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Progress callback for image upload
|
|
70
|
+
*/
|
|
71
|
+
interface UploadProgressEvent {
|
|
72
|
+
/** Upload progress percentage (0-100) */
|
|
73
|
+
progress: number;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Image upload function type with optional progress callback
|
|
77
|
+
*/
|
|
78
|
+
type UploadImageFn = (file: File, onProgress?: (event: UploadProgressEvent) => void) => Promise<UploadImageResult>;
|
|
75
79
|
/**
|
|
76
80
|
* Payload for plain text mode messages
|
|
77
81
|
*/
|
|
78
|
-
|
|
82
|
+
interface PlainMessagePayload {
|
|
79
83
|
type: 'text';
|
|
80
|
-
/** Plain text with
|
|
84
|
+
/** Plain text with mentions as @userId */
|
|
81
85
|
plainText: string;
|
|
82
|
-
/** List of mentions with positions */
|
|
86
|
+
/** List of mentions with their positions */
|
|
83
87
|
mentions: MentionInfo[];
|
|
84
|
-
/**
|
|
88
|
+
/** List of attached files */
|
|
85
89
|
attachments: Attachment[];
|
|
86
|
-
/**
|
|
90
|
+
/** Quoted message (if any) */
|
|
87
91
|
quote?: QuoteInfo;
|
|
88
|
-
}
|
|
92
|
+
}
|
|
89
93
|
/**
|
|
90
|
-
* Payload for rich text
|
|
94
|
+
* Payload for rich text mode messages (Markdown)
|
|
91
95
|
*/
|
|
92
|
-
|
|
96
|
+
interface MarkdownMessagePayload {
|
|
93
97
|
type: 'markdown';
|
|
94
98
|
/** Markdown content */
|
|
95
99
|
markdown: string;
|
|
96
|
-
}
|
|
100
|
+
}
|
|
97
101
|
/**
|
|
98
102
|
* Union type for all message payloads
|
|
99
103
|
*/
|
|
100
104
|
type MessagePayload = PlainMessagePayload | MarkdownMessagePayload;
|
|
101
105
|
/**
|
|
102
|
-
*
|
|
106
|
+
* Draft state for saving/restoring editor content
|
|
103
107
|
*/
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
|
|
109
|
-
/**
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
interface ComposerDraft {
|
|
109
|
+
/** Editor mode */
|
|
110
|
+
mode?: EditorMode;
|
|
111
|
+
/** Serialized editor state (JSON string from getJSON) - deprecated, use json */
|
|
112
|
+
editorState?: string;
|
|
113
|
+
/** Editor JSON content */
|
|
114
|
+
json?: Record<string, unknown>;
|
|
115
|
+
/** Attachments (plain mode only) */
|
|
116
|
+
attachments?: Attachment[];
|
|
117
|
+
/** Quick restore text for plain mode */
|
|
118
|
+
text?: string;
|
|
119
|
+
/** Quote information (plain mode only) */
|
|
120
|
+
quote?: QuoteInfo;
|
|
121
|
+
}
|
|
112
122
|
/**
|
|
113
|
-
*
|
|
123
|
+
* Locale strings for internationalization
|
|
114
124
|
*/
|
|
115
|
-
|
|
125
|
+
interface IMComposerLocale {
|
|
126
|
+
/** Placeholder text for plain mode */
|
|
127
|
+
placeholderPlain?: string;
|
|
128
|
+
/** Placeholder text for rich mode */
|
|
129
|
+
placeholderRich?: string;
|
|
130
|
+
/** No results found in mention list */
|
|
131
|
+
mentionNoResults?: string;
|
|
132
|
+
/** Loading text for mention list */
|
|
133
|
+
mentionLoading?: string;
|
|
134
|
+
/** Error text for mention list */
|
|
135
|
+
mentionError?: string;
|
|
136
|
+
/** Remove attachment button label */
|
|
137
|
+
removeAttachment?: string;
|
|
138
|
+
/** Remove quote button label */
|
|
139
|
+
removeQuote?: string;
|
|
140
|
+
/** Upload failed message */
|
|
141
|
+
uploadFailed?: string;
|
|
142
|
+
/** Uploading text */
|
|
143
|
+
uploading?: string;
|
|
144
|
+
/** Undo button */
|
|
145
|
+
undo?: string;
|
|
146
|
+
/** Redo button */
|
|
147
|
+
redo?: string;
|
|
148
|
+
/** Heading dropdown */
|
|
149
|
+
heading?: string;
|
|
150
|
+
/** Heading 1 */
|
|
151
|
+
heading1?: string;
|
|
152
|
+
/** Heading 2 */
|
|
153
|
+
heading2?: string;
|
|
154
|
+
/** Heading 3 */
|
|
155
|
+
heading3?: string;
|
|
156
|
+
/** Heading 4 */
|
|
157
|
+
heading4?: string;
|
|
158
|
+
/** Paragraph */
|
|
159
|
+
paragraph?: string;
|
|
160
|
+
/** List dropdown */
|
|
161
|
+
list?: string;
|
|
162
|
+
/** Bullet list */
|
|
163
|
+
bulletList?: string;
|
|
164
|
+
/** Ordered list */
|
|
165
|
+
orderedList?: string;
|
|
166
|
+
/** Task list */
|
|
167
|
+
taskList?: string;
|
|
168
|
+
/** Blockquote button */
|
|
169
|
+
blockquote?: string;
|
|
170
|
+
/** Code block button */
|
|
171
|
+
codeBlock?: string;
|
|
172
|
+
/** Bold button */
|
|
173
|
+
bold?: string;
|
|
174
|
+
/** Italic button */
|
|
175
|
+
italic?: string;
|
|
176
|
+
/** Strikethrough button */
|
|
177
|
+
strike?: string;
|
|
178
|
+
/** Inline code button */
|
|
179
|
+
code?: string;
|
|
180
|
+
/** Underline button */
|
|
181
|
+
underline?: string;
|
|
182
|
+
/** Highlight button */
|
|
183
|
+
highlight?: string;
|
|
184
|
+
/** Remove highlight */
|
|
185
|
+
removeHighlight?: string;
|
|
186
|
+
/** Link button */
|
|
187
|
+
link?: string;
|
|
188
|
+
/** Link input placeholder */
|
|
189
|
+
linkPlaceholder?: string;
|
|
190
|
+
/** Apply link */
|
|
191
|
+
applyLink?: string;
|
|
192
|
+
/** Open link */
|
|
193
|
+
openLink?: string;
|
|
194
|
+
/** Remove link */
|
|
195
|
+
removeLink?: string;
|
|
196
|
+
/** Superscript button */
|
|
197
|
+
superscript?: string;
|
|
198
|
+
/** Subscript button */
|
|
199
|
+
subscript?: string;
|
|
200
|
+
/** Align left button */
|
|
201
|
+
alignLeft?: string;
|
|
202
|
+
/** Align center button */
|
|
203
|
+
alignCenter?: string;
|
|
204
|
+
/** Align right button */
|
|
205
|
+
alignRight?: string;
|
|
206
|
+
/** Align justify button */
|
|
207
|
+
alignJustify?: string;
|
|
208
|
+
/** Insert image button */
|
|
209
|
+
insertImage?: string;
|
|
210
|
+
/** Upload image */
|
|
211
|
+
uploadImage?: string;
|
|
212
|
+
/** Click to upload */
|
|
213
|
+
clickToUpload?: string;
|
|
214
|
+
/** Or drag and drop */
|
|
215
|
+
orDragAndDrop?: string;
|
|
216
|
+
/** Maximum files */
|
|
217
|
+
maxFiles?: string;
|
|
218
|
+
/** Clear all */
|
|
219
|
+
clearAll?: string;
|
|
220
|
+
}
|
|
116
221
|
/**
|
|
117
|
-
*
|
|
222
|
+
* Default English locale
|
|
118
223
|
*/
|
|
119
|
-
|
|
120
|
-
/** URL of the uploaded image (must be https) */
|
|
121
|
-
url: string;
|
|
122
|
-
/** Optional alt text */
|
|
123
|
-
alt?: string;
|
|
124
|
-
};
|
|
224
|
+
declare const defaultLocale: IMComposerLocale;
|
|
125
225
|
/**
|
|
126
|
-
*
|
|
226
|
+
* Send keymap configuration
|
|
127
227
|
*/
|
|
128
|
-
type
|
|
228
|
+
type SendKeymap = 'enter' | 'ctrlEnter' | 'cmdEnter';
|
|
129
229
|
/**
|
|
130
|
-
*
|
|
230
|
+
* Editor mode
|
|
131
231
|
*/
|
|
132
|
-
type
|
|
133
|
-
heading?: boolean;
|
|
134
|
-
bold?: boolean;
|
|
135
|
-
italic?: boolean;
|
|
136
|
-
strike?: boolean;
|
|
137
|
-
codeInline?: boolean;
|
|
138
|
-
codeBlock?: boolean;
|
|
139
|
-
quote?: boolean;
|
|
140
|
-
list?: boolean;
|
|
141
|
-
link?: boolean;
|
|
142
|
-
image?: boolean;
|
|
143
|
-
};
|
|
232
|
+
type EditorMode = 'plain' | 'rich';
|
|
144
233
|
/**
|
|
145
|
-
*
|
|
234
|
+
* Attachment limit exceeded reason
|
|
146
235
|
*/
|
|
147
|
-
type
|
|
236
|
+
type AttachmentLimitReason = 'count' | 'size' | 'mime';
|
|
148
237
|
/**
|
|
149
|
-
*
|
|
238
|
+
* Main component props
|
|
150
239
|
*/
|
|
151
|
-
|
|
240
|
+
interface IMComposerProps {
|
|
152
241
|
/** Controlled mode */
|
|
153
|
-
mode?:
|
|
242
|
+
mode?: EditorMode;
|
|
154
243
|
/** Default mode for uncontrolled usage */
|
|
155
|
-
defaultMode?:
|
|
156
|
-
/**
|
|
244
|
+
defaultMode?: EditorMode;
|
|
245
|
+
/** Called when user triggers send action */
|
|
157
246
|
onSend?: (payload: PlainMessagePayload | MarkdownMessagePayload) => void;
|
|
158
|
-
/**
|
|
247
|
+
/** Called when editor content changes */
|
|
248
|
+
onChange?: () => void;
|
|
249
|
+
/** Context menu handler */
|
|
250
|
+
onContextMenu?: MouseEventHandler<HTMLDivElement>;
|
|
251
|
+
/** Called when quote is removed */
|
|
252
|
+
onQuoteRemoved?: () => void;
|
|
253
|
+
/** Enable @mention feature */
|
|
159
254
|
enableMention?: boolean;
|
|
160
|
-
/** Async
|
|
255
|
+
/** Async provider for mention suggestions */
|
|
161
256
|
mentionProvider?: (query: string) => Promise<Member[]>;
|
|
162
|
-
/** Maximum number of mentions allowed
|
|
257
|
+
/** Maximum number of mentions allowed */
|
|
163
258
|
maxMentions?: number;
|
|
164
|
-
/** Custom render function for mention list items
|
|
259
|
+
/** Custom render function for mention list items */
|
|
165
260
|
renderMentionItem?: (props: {
|
|
166
261
|
member: Member;
|
|
167
262
|
isSelected: boolean;
|
|
168
|
-
}) =>
|
|
169
|
-
/**
|
|
263
|
+
}) => ReactNode;
|
|
264
|
+
/** Mention list placement relative to cursor: 'top' or 'bottom' */
|
|
265
|
+
mentionPlacement?: 'top' | 'bottom';
|
|
266
|
+
/** Enable file attachments */
|
|
170
267
|
enableAttachments?: boolean;
|
|
171
|
-
/**
|
|
268
|
+
/** Attachment preview bar placement */
|
|
172
269
|
attachmentPreviewPlacement?: 'top' | 'bottom';
|
|
173
|
-
/** Maximum number of attachments
|
|
270
|
+
/** Maximum number of attachments */
|
|
174
271
|
maxAttachments?: number;
|
|
175
|
-
/** Allowed MIME types (
|
|
272
|
+
/** Allowed MIME types (supports wildcards like "image/*") */
|
|
176
273
|
allowedMimeTypes?: string[];
|
|
177
274
|
/** Maximum file size in bytes */
|
|
178
275
|
maxFileSize?: number;
|
|
179
|
-
/**
|
|
180
|
-
onAttachmentLimitExceeded?: (reason:
|
|
181
|
-
/**
|
|
276
|
+
/** Called when attachment limit is exceeded */
|
|
277
|
+
onAttachmentLimitExceeded?: (reason: AttachmentLimitReason, file: File) => void;
|
|
278
|
+
/** Called when attachments change */
|
|
182
279
|
onFilesChange?: (attachments: Attachment[]) => void;
|
|
183
|
-
/** Show
|
|
280
|
+
/** Show attachment preview bar */
|
|
184
281
|
showAttachmentPreview?: boolean;
|
|
185
|
-
/** Markdown
|
|
282
|
+
/** Markdown options */
|
|
186
283
|
markdownOptions?: {
|
|
187
|
-
enabledSyntax?:
|
|
284
|
+
enabledSyntax?: string[];
|
|
188
285
|
};
|
|
189
|
-
/** Image upload
|
|
286
|
+
/** Image upload handler with optional progress callback */
|
|
190
287
|
uploadImage?: UploadImageFn;
|
|
191
288
|
/** Keymap configuration */
|
|
192
289
|
keymap?: {
|
|
193
|
-
send?:
|
|
290
|
+
send?: SendKeymap;
|
|
194
291
|
};
|
|
195
|
-
/** Placeholder text */
|
|
292
|
+
/** Placeholder text (string or per-mode object) */
|
|
196
293
|
placeholder?: string | {
|
|
197
294
|
plain?: string;
|
|
198
295
|
rich?: string;
|
|
199
296
|
};
|
|
200
297
|
/** Disable the editor */
|
|
201
298
|
disabled?: boolean;
|
|
202
|
-
/**
|
|
299
|
+
/** Additional CSS class */
|
|
203
300
|
className?: string;
|
|
204
|
-
/**
|
|
205
|
-
onContextMenu?: React.MouseEventHandler<HTMLDivElement>;
|
|
206
|
-
/** Callback when quote is removed (plain mode) */
|
|
207
|
-
onQuoteRemoved?: () => void;
|
|
208
|
-
/** Callback when editor content changes */
|
|
209
|
-
onChange?: () => void;
|
|
210
|
-
/** Locale/i18n configuration */
|
|
301
|
+
/** Locale strings */
|
|
211
302
|
locale?: IMComposerLocale;
|
|
212
|
-
}
|
|
303
|
+
}
|
|
213
304
|
/**
|
|
214
305
|
* Methods exposed via ref
|
|
215
306
|
*/
|
|
216
|
-
|
|
307
|
+
interface IMComposerRef {
|
|
217
308
|
/** Focus the editor */
|
|
218
309
|
focus: () => void;
|
|
219
|
-
/** Clear editor content
|
|
310
|
+
/** Clear the editor content */
|
|
220
311
|
clear: () => void;
|
|
221
|
-
/** Export current payload
|
|
312
|
+
/** Export current content as payload. Returns null if empty or uploading */
|
|
222
313
|
exportPayload: () => PlainMessagePayload | MarkdownMessagePayload | null;
|
|
223
314
|
/** Import markdown content (rich mode only) */
|
|
224
315
|
importMarkdown: (markdown: string) => void;
|
|
225
|
-
/** Get current attachments
|
|
316
|
+
/** Get current attachments */
|
|
226
317
|
getAttachments: () => Attachment[];
|
|
227
|
-
/** Set attachments
|
|
318
|
+
/** Set attachments */
|
|
228
319
|
setAttachments: (attachments: Attachment[]) => void;
|
|
229
|
-
/**
|
|
230
|
-
insertQuote: (title: string, content: string) => void;
|
|
231
|
-
/** Add files to attachments (plain mode) */
|
|
320
|
+
/** Add files to attachments */
|
|
232
321
|
addFiles: (files: FileList | File[]) => void;
|
|
233
|
-
/** Remove
|
|
322
|
+
/** Remove a specific attachment by ID */
|
|
234
323
|
removeAttachment: (id: string) => void;
|
|
235
|
-
/** Clear all attachments
|
|
324
|
+
/** Clear all attachments */
|
|
236
325
|
clearAttachments: () => void;
|
|
237
|
-
/** Insert
|
|
326
|
+
/** Insert or replace a quote */
|
|
327
|
+
insertQuote: (title: string, content: string) => void;
|
|
328
|
+
/** Programmatically insert a mention */
|
|
238
329
|
insertMention: (userId: string, display: string) => void;
|
|
239
|
-
/** Get
|
|
240
|
-
getDraft: () =>
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
};
|
|
245
|
-
/** Set complete draft state (restore from saved draft) */
|
|
246
|
-
setDraft: (draft: {
|
|
247
|
-
editorState: string;
|
|
248
|
-
attachments?: Attachment[];
|
|
249
|
-
}) => void;
|
|
250
|
-
/** Set editor content from plain text and optional mentions (plain mode) */
|
|
330
|
+
/** Get current draft state */
|
|
331
|
+
getDraft: () => ComposerDraft;
|
|
332
|
+
/** Restore from draft state */
|
|
333
|
+
setDraft: (draft: ComposerDraft) => void;
|
|
334
|
+
/** Set text content (with optional mentions for plain mode) */
|
|
251
335
|
setText: (text: string, mentions?: Member[]) => void;
|
|
252
|
-
/** Insert text at cursor
|
|
336
|
+
/** Insert text at cursor */
|
|
253
337
|
insertText: (text: string) => void;
|
|
254
|
-
}
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* @internal Mention suggestion state
|
|
341
|
+
*/
|
|
342
|
+
interface MentionSuggestionState {
|
|
343
|
+
active: boolean;
|
|
344
|
+
query: string;
|
|
345
|
+
items: Member[];
|
|
346
|
+
selectedIndex: number;
|
|
347
|
+
loading: boolean;
|
|
348
|
+
error: boolean;
|
|
349
|
+
/** Command to insert a mention (replaces @ trigger) */
|
|
350
|
+
command: ((member: {
|
|
351
|
+
userId: string;
|
|
352
|
+
display: string;
|
|
353
|
+
}) => void) | null;
|
|
354
|
+
}
|
|
255
355
|
|
|
256
|
-
|
|
356
|
+
/**
|
|
357
|
+
* IM Composer component supporting plain text and rich text modes.
|
|
358
|
+
*/
|
|
359
|
+
declare const IMComposer: React__default.ForwardRefExoticComponent<IMComposerProps & React__default.RefAttributes<IMComposerRef>>;
|
|
257
360
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
isInline(): boolean;
|
|
279
|
-
canInsertTextBefore(): boolean;
|
|
280
|
-
canInsertTextAfter(): boolean;
|
|
281
|
-
decorate(): ReactNode;
|
|
361
|
+
interface RichEditorProps {
|
|
362
|
+
placeholder?: string;
|
|
363
|
+
disabled?: boolean;
|
|
364
|
+
uploadImage?: UploadImageFn;
|
|
365
|
+
onUploadingChange?: (count: number) => void;
|
|
366
|
+
onSend?: () => void;
|
|
367
|
+
onChange?: () => void;
|
|
368
|
+
sendKeymap?: 'enter' | 'ctrlEnter' | 'cmdEnter';
|
|
369
|
+
}
|
|
370
|
+
interface RichEditorRef {
|
|
371
|
+
editor: Editor | null;
|
|
372
|
+
focus: () => void;
|
|
373
|
+
clear: () => void;
|
|
374
|
+
exportPayload: () => MarkdownMessagePayload | null;
|
|
375
|
+
importMarkdown: (markdown: string) => void;
|
|
376
|
+
getDraft: () => ComposerDraft;
|
|
377
|
+
setDraft: (draft: ComposerDraft) => void;
|
|
378
|
+
setText: (text: string) => void;
|
|
379
|
+
insertText: (text: string) => void;
|
|
380
|
+
isUploading: () => boolean;
|
|
282
381
|
}
|
|
283
|
-
declare
|
|
284
|
-
declare function $isMentionNode(node: LexicalNode | null | undefined): node is MentionNode;
|
|
382
|
+
declare const RichEditor: React$1.ForwardRefExoticComponent<RichEditorProps & React$1.RefAttributes<RichEditorRef>>;
|
|
285
383
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
384
|
+
declare function LocaleProvider({ locale, children, }: {
|
|
385
|
+
locale?: IMComposerLocale;
|
|
386
|
+
children: React.ReactNode;
|
|
387
|
+
}): react_jsx_runtime.JSX.Element;
|
|
388
|
+
declare function useLocale(): IMComposerLocale;
|
|
389
|
+
|
|
390
|
+
interface MentionListProps {
|
|
391
|
+
/** List of member suggestions */
|
|
392
|
+
items: Member[];
|
|
393
|
+
/** Currently selected index */
|
|
394
|
+
selectedIndex: number;
|
|
395
|
+
/** Loading state */
|
|
396
|
+
loading: boolean;
|
|
397
|
+
/** Error state */
|
|
398
|
+
error: boolean;
|
|
399
|
+
/** Called when item is clicked */
|
|
400
|
+
onSelect: (member: Member) => void;
|
|
401
|
+
/** Called when mouse enters an item */
|
|
402
|
+
onHover: (index: number) => void;
|
|
403
|
+
/** Custom render function */
|
|
404
|
+
renderItem?: (props: {
|
|
405
|
+
member: Member;
|
|
406
|
+
isSelected: boolean;
|
|
407
|
+
}) => React__default.ReactNode;
|
|
408
|
+
/** Locale strings */
|
|
409
|
+
locale?: {
|
|
410
|
+
noResults?: string;
|
|
411
|
+
loading?: string;
|
|
412
|
+
error?: string;
|
|
413
|
+
};
|
|
311
414
|
}
|
|
312
|
-
|
|
313
|
-
|
|
415
|
+
/**
|
|
416
|
+
* Mention suggestion list component.
|
|
417
|
+
*/
|
|
418
|
+
declare function MentionList({ items, selectedIndex, loading, error, onSelect, onHover, renderItem, locale, }: MentionListProps): react_jsx_runtime.JSX.Element | null;
|
|
314
419
|
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
updateDOM(): boolean;
|
|
325
|
-
exportDOM(): DOMExportOutput;
|
|
326
|
-
static importDOM(): DOMConversionMap | null;
|
|
327
|
-
static importJSON(serializedNode: SerializedEmojiNode): EmojiNode;
|
|
328
|
-
exportJSON(): SerializedEmojiNode;
|
|
329
|
-
getEmoji(): string;
|
|
330
|
-
getTextContent(): string;
|
|
331
|
-
isIsolated(): boolean;
|
|
332
|
-
isInline(): boolean;
|
|
333
|
-
canInsertTextBefore(): boolean;
|
|
334
|
-
canInsertTextAfter(): boolean;
|
|
335
|
-
decorate(): ReactNode;
|
|
420
|
+
interface AttachmentPreviewProps {
|
|
421
|
+
/** List of attachments */
|
|
422
|
+
attachments: Attachment[];
|
|
423
|
+
/** Called when remove button is clicked */
|
|
424
|
+
onRemove: (id: string) => void;
|
|
425
|
+
/** Placement position */
|
|
426
|
+
placement?: 'top' | 'bottom';
|
|
427
|
+
/** Remove button label */
|
|
428
|
+
removeLabel?: string;
|
|
336
429
|
}
|
|
337
|
-
|
|
338
|
-
|
|
430
|
+
/**
|
|
431
|
+
* Attachment preview bar component.
|
|
432
|
+
*/
|
|
433
|
+
declare function AttachmentPreview({ attachments, onRemove, placement, removeLabel, }: AttachmentPreviewProps): react_jsx_runtime.JSX.Element | null;
|
|
339
434
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
static getType(): string;
|
|
348
|
-
static clone(node: QuoteNode): QuoteNode;
|
|
349
|
-
constructor(title: string, content: string, key?: NodeKey);
|
|
350
|
-
createDOM(config: EditorConfig): HTMLElement;
|
|
351
|
-
updateDOM(): boolean;
|
|
352
|
-
exportDOM(): DOMExportOutput;
|
|
353
|
-
static importDOM(): DOMConversionMap | null;
|
|
354
|
-
static importJSON(serializedNode: SerializedQuoteNode): QuoteNode;
|
|
355
|
-
exportJSON(): SerializedQuoteNode;
|
|
356
|
-
getTitle(): string;
|
|
357
|
-
getContent(): string;
|
|
358
|
-
getTextContent(): string;
|
|
359
|
-
isIsolated(): boolean;
|
|
360
|
-
isInline(): boolean;
|
|
361
|
-
decorate(): ReactNode;
|
|
435
|
+
interface QuoteBarProps {
|
|
436
|
+
/** Quote information */
|
|
437
|
+
quote: QuoteInfo;
|
|
438
|
+
/** Called when remove button is clicked */
|
|
439
|
+
onRemove: () => void;
|
|
440
|
+
/** Remove button label */
|
|
441
|
+
removeLabel?: string;
|
|
362
442
|
}
|
|
363
|
-
|
|
364
|
-
|
|
443
|
+
/**
|
|
444
|
+
* Quote message bar component.
|
|
445
|
+
*/
|
|
446
|
+
declare function QuoteBar({ quote, onRemove, removeLabel }: QuoteBarProps): react_jsx_runtime.JSX.Element;
|
|
365
447
|
|
|
366
448
|
interface UseAttachmentsOptions {
|
|
449
|
+
/** Maximum number of attachments */
|
|
367
450
|
maxAttachments?: number;
|
|
451
|
+
/** Maximum file size in bytes */
|
|
368
452
|
maxFileSize?: number;
|
|
453
|
+
/** Allowed MIME types */
|
|
369
454
|
allowedMimeTypes?: string[];
|
|
370
|
-
|
|
455
|
+
/** Called when limit is exceeded */
|
|
456
|
+
onLimitExceeded?: (reason: AttachmentLimitReason, file: File) => void;
|
|
457
|
+
/** Called when attachments change */
|
|
458
|
+
onChange?: (attachments: Attachment[]) => void;
|
|
371
459
|
}
|
|
372
|
-
interface
|
|
460
|
+
interface UseAttachmentsReturn {
|
|
461
|
+
/** Current attachments */
|
|
373
462
|
attachments: Attachment[];
|
|
463
|
+
/** Add files to attachments */
|
|
374
464
|
addFiles: (files: FileList | File[]) => void;
|
|
465
|
+
/** Remove attachment by ID */
|
|
375
466
|
removeAttachment: (id: string) => void;
|
|
467
|
+
/** Clear all attachments */
|
|
376
468
|
clearAttachments: () => void;
|
|
469
|
+
/** Set attachments directly */
|
|
377
470
|
setAttachments: (attachments: Attachment[]) => void;
|
|
471
|
+
/** Get current attachments */
|
|
472
|
+
getAttachments: () => Attachment[];
|
|
378
473
|
}
|
|
379
|
-
|
|
474
|
+
/**
|
|
475
|
+
* Hook for managing file attachments with proper objectURL lifecycle.
|
|
476
|
+
*/
|
|
477
|
+
declare function useAttachments(options?: UseAttachmentsOptions): UseAttachmentsReturn;
|
|
380
478
|
|
|
381
|
-
interface
|
|
382
|
-
/**
|
|
383
|
-
|
|
384
|
-
/**
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
|
|
388
|
-
/**
|
|
389
|
-
|
|
479
|
+
interface UsePlainEditorOptions {
|
|
480
|
+
/** Placeholder text */
|
|
481
|
+
placeholder?: string;
|
|
482
|
+
/** Keymap for send */
|
|
483
|
+
sendKeymap?: SendKeymap;
|
|
484
|
+
/** Called when send is triggered */
|
|
485
|
+
onSend?: () => void;
|
|
486
|
+
/** Enable mention */
|
|
487
|
+
enableMention?: boolean;
|
|
488
|
+
/** Mention provider */
|
|
489
|
+
mentionProvider?: (query: string) => Promise<Member[]>;
|
|
490
|
+
/** Max mentions */
|
|
491
|
+
maxMentions?: number;
|
|
492
|
+
/** Called when mention state changes */
|
|
493
|
+
onMentionStateChange?: (state: MentionSuggestionState) => void;
|
|
494
|
+
/** Called when files are pasted */
|
|
495
|
+
onPasteFiles?: (files: File[]) => void;
|
|
496
|
+
/** Get current uploading state */
|
|
497
|
+
isUploading?: () => boolean;
|
|
498
|
+
/** Disabled state */
|
|
499
|
+
disabled?: boolean;
|
|
500
|
+
/** Called on content change */
|
|
501
|
+
onChange?: () => void;
|
|
502
|
+
/** Called when quote is removed */
|
|
503
|
+
onQuoteRemoved?: () => void;
|
|
390
504
|
}
|
|
391
|
-
interface
|
|
392
|
-
/**
|
|
393
|
-
|
|
394
|
-
/**
|
|
395
|
-
|
|
396
|
-
/**
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
505
|
+
interface UsePlainEditorReturn {
|
|
506
|
+
/** Tiptap editor instance */
|
|
507
|
+
editor: ReturnType<typeof useEditor>;
|
|
508
|
+
/** Check if composing (IME) */
|
|
509
|
+
isComposing: () => boolean;
|
|
510
|
+
/** Check if mention list is open */
|
|
511
|
+
isMentionListOpen: () => boolean;
|
|
512
|
+
/** Export payload */
|
|
513
|
+
exportPayload: (attachments: Attachment[]) => PlainMessagePayload | null;
|
|
514
|
+
/** Get draft */
|
|
515
|
+
getDraft: (attachments: Attachment[]) => ComposerDraft;
|
|
516
|
+
/** Set draft */
|
|
517
|
+
setDraft: (draft: ComposerDraft) => void;
|
|
518
|
+
/** Insert mention programmatically */
|
|
519
|
+
insertMention: (userId: string, display: string) => void;
|
|
520
|
+
/** Insert quote */
|
|
521
|
+
insertQuote: (title: string, content: string) => void;
|
|
522
|
+
/** Remove quote */
|
|
523
|
+
removeQuote: () => void;
|
|
524
|
+
/** Get current quote */
|
|
525
|
+
getQuote: () => QuoteInfo | undefined;
|
|
526
|
+
/** Set text content */
|
|
527
|
+
setText: (text: string) => void;
|
|
528
|
+
/** Insert text at cursor */
|
|
529
|
+
insertText: (text: string) => void;
|
|
530
|
+
/** Clear editor */
|
|
531
|
+
clear: () => void;
|
|
532
|
+
/** Focus editor */
|
|
533
|
+
focus: () => void;
|
|
403
534
|
}
|
|
404
|
-
|
|
535
|
+
/**
|
|
536
|
+
* Hook for managing plain text editor.
|
|
537
|
+
*/
|
|
538
|
+
declare function usePlainEditor(options?: UsePlainEditorOptions): UsePlainEditorReturn;
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* Extract plain text and mention information from the editor.
|
|
542
|
+
* Mention tokens are output as @{userId} followed by a space.
|
|
543
|
+
*
|
|
544
|
+
* @param editor Tiptap editor instance
|
|
545
|
+
* @returns Object containing plainText and mentions array with UTF-16 indices
|
|
546
|
+
*/
|
|
547
|
+
declare function extractPlainTextWithMentions(editor: Editor$1): {
|
|
548
|
+
plainText: string;
|
|
549
|
+
mentions: MentionInfo[];
|
|
550
|
+
};
|
|
551
|
+
/**
|
|
552
|
+
* Check if mention indices are valid and aligned with the plainText.
|
|
553
|
+
*/
|
|
554
|
+
declare function validateMentionIndices(plainText: string, mentions: MentionInfo[]): boolean;
|
|
555
|
+
/**
|
|
556
|
+
* Create a mention info object with calculated indices.
|
|
557
|
+
*/
|
|
558
|
+
declare function createMentionInfo(userId: string, display: string, startIndex: number): MentionInfo;
|
|
559
|
+
|
|
560
|
+
/**
|
|
561
|
+
* Create an Attachment object from a File.
|
|
562
|
+
*/
|
|
563
|
+
declare function createAttachment(file: File): Attachment;
|
|
564
|
+
/**
|
|
565
|
+
* Revoke object URL for an attachment.
|
|
566
|
+
*/
|
|
567
|
+
declare function revokeAttachmentUrl(attachment: Attachment): void;
|
|
568
|
+
/**
|
|
569
|
+
* Revoke all object URLs for a list of attachments.
|
|
570
|
+
*/
|
|
571
|
+
declare function revokeAllAttachmentUrls(attachments: Attachment[]): void;
|
|
572
|
+
/**
|
|
573
|
+
* Validate a file against attachment constraints.
|
|
574
|
+
* Returns the reason for rejection, or null if valid.
|
|
575
|
+
*/
|
|
576
|
+
declare function validateFile(file: File, currentCount: number, options: {
|
|
577
|
+
maxAttachments?: number;
|
|
578
|
+
maxFileSize?: number;
|
|
579
|
+
allowedMimeTypes?: string[];
|
|
580
|
+
}): AttachmentLimitReason | null;
|
|
581
|
+
/**
|
|
582
|
+
* Format file size for display.
|
|
583
|
+
*/
|
|
584
|
+
declare function formatFileSize(bytes: number): string;
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Markdown serializer for Tiptap editor content.
|
|
588
|
+
* Converts the editor document to Markdown string.
|
|
589
|
+
*/
|
|
590
|
+
declare function editorToMarkdown(editor: Editor$1): string;
|
|
591
|
+
/**
|
|
592
|
+
* Parse Markdown to Tiptap-compatible JSON content.
|
|
593
|
+
* This is a simplified parser for the Markdown subset we support.
|
|
594
|
+
*/
|
|
595
|
+
declare function markdownToEditorContent(markdown: string): any;
|
|
596
|
+
|
|
597
|
+
/**
|
|
598
|
+
* Check if a URL has an allowed protocol for links.
|
|
599
|
+
*/
|
|
600
|
+
declare function isAllowedLinkProtocol(url: string): boolean;
|
|
601
|
+
/**
|
|
602
|
+
* Check if a URL has an allowed protocol for images.
|
|
603
|
+
*/
|
|
604
|
+
declare function isAllowedImageProtocol(url: string): boolean;
|
|
605
|
+
/**
|
|
606
|
+
* Sanitize a URL for links.
|
|
607
|
+
* - Adds https:// if no protocol is present
|
|
608
|
+
* - Returns null if protocol is not allowed (including javascript:, vbscript:, etc.)
|
|
609
|
+
*/
|
|
610
|
+
declare function sanitizeLinkUrl(url: string): string | null;
|
|
611
|
+
/**
|
|
612
|
+
* Sanitize a URL for images.
|
|
613
|
+
* Returns null if protocol is not allowed.
|
|
614
|
+
*/
|
|
615
|
+
declare function sanitizeImageUrl(url: string): string | null;
|
|
405
616
|
|
|
406
|
-
export {
|
|
617
|
+
export { type Attachment, type AttachmentLimitReason, AttachmentPreview, type AttachmentPreviewProps, type ComposerDraft, type EditorMode, IMComposer, type IMComposerLocale, type IMComposerProps, type IMComposerRef, LocaleProvider, type MarkdownMessagePayload, type Member, type MentionInfo, MentionList, type MentionListProps, type MessagePayload, type PlainMessagePayload, QuoteBar, type QuoteBarProps, type QuoteInfo, RichEditor, type RichEditorProps, type RichEditorRef, type SendKeymap, type UploadImageFn, type UploadImageResult, type UploadProgressEvent, type UseAttachmentsOptions, type UseAttachmentsReturn, type UsePlainEditorOptions, type UsePlainEditorReturn, createAttachment, createMentionInfo, defaultLocale, editorToMarkdown, extractPlainTextWithMentions, formatFileSize, isAllowedImageProtocol, isAllowedLinkProtocol, markdownToEditorContent, revokeAllAttachmentUrls, revokeAttachmentUrl, sanitizeImageUrl, sanitizeLinkUrl, useAttachments, useLocale, usePlainEditor, validateFile, validateMentionIndices };
|