@cometchat/chat-uikit-react 6.3.13 → 6.4.0
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/dist/assets/bin.svg +1 -0
- package/dist/assets/format_blockquote.svg +3 -0
- package/dist/assets/format_bold.svg +5 -0
- package/dist/assets/format_code.svg +3 -0
- package/dist/assets/format_code_block.svg +5 -0
- package/dist/assets/format_italic.svg +3 -0
- package/dist/assets/format_link.svg +3 -0
- package/dist/assets/format_ordered_list.svg +5 -0
- package/dist/assets/format_strikethrough.svg +5 -0
- package/dist/assets/format_toggle.svg +1 -0
- package/dist/assets/format_underline.svg +5 -0
- package/dist/assets/format_unordered_list.svg +5 -0
- package/dist/assets/pause_circle.svg +1 -0
- package/dist/assets/warning-small.svg +0 -0
- package/dist/index.d.ts +360 -6
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/styles/CometChatCompactMessageComposer.css +1111 -0
- package/dist/styles/CometChatConversations.css +37 -1
- package/dist/styles/CometChatDocumentBubble.css +0 -1
- package/dist/styles/CometChatFormattingToolbar.css +257 -0
- package/dist/styles/CometChatLinkDialog.css +191 -0
- package/dist/styles/CometChatLinkPopover.css +128 -0
- package/dist/styles/CometChatMarkdownFormatter.css +141 -0
- package/dist/styles/CometChatMediaRecorder.css +73 -1
- package/dist/styles/CometChatMessageComposer.css +210 -3
- package/dist/styles/CometChatMessagePreview.css +10 -0
- package/dist/styles/CometChatSearch.css +11 -0
- package/dist/styles/CometChatTextBubble.css +267 -3
- package/dist/styles/LinkPreview.css +1 -1
- package/dist/styles/components/CometChatCompactMessageComposer.css +1111 -0
- package/dist/styles/components/CometChatConversations.css +37 -1
- package/dist/styles/components/CometChatDocumentBubble.css +0 -1
- package/dist/styles/components/CometChatFormattingToolbar.css +257 -0
- package/dist/styles/components/CometChatLinkDialog.css +191 -0
- package/dist/styles/components/CometChatLinkPopover.css +128 -0
- package/dist/styles/components/CometChatMarkdownFormatter.css +141 -0
- package/dist/styles/components/CometChatMediaRecorder.css +73 -1
- package/dist/styles/components/CometChatMessageComposer.css +210 -3
- package/dist/styles/components/CometChatMessagePreview.css +10 -0
- package/dist/styles/components/CometChatSearch.css +11 -0
- package/dist/styles/components/CometChatTextBubble.css +267 -3
- package/dist/styles/components/LinkPreview.css +1 -1
- package/dist/styles/components/index.css +6 -5
- package/dist/styles/css-variables.css +1 -0
- package/dist/styles/index.css +6 -5
- package/dist/types/CometChatUIKit/CometChatUIKitUtility.d.ts +13 -0
- package/dist/types/components/CometChatCompactMessageComposer/CometChatCompactMessageComposer.d.ts +247 -0
- package/dist/types/components/CometChatFormattingToolbar/CometChatFormattingToolbar.d.ts +29 -0
- package/dist/types/components/CometChatLinkDialog/CometChatLinkDialog.d.ts +22 -0
- package/dist/types/components/CometChatLinkPopover/CometChatLinkPopover.d.ts +24 -0
- package/dist/types/components/CometChatLinkPopover/index.d.ts +1 -0
- package/dist/types/components/useRichTextComposer/useRichTextComposer.d.ts +138 -0
- package/dist/types/formatters/CometChatFormatters/CometChatMarkdownFormatter/CometChatMarkdownFormatter.d.ts +109 -0
- package/dist/types/formatters/CometChatFormatters/CometChatRichTextFormatter.d.ts +32 -0
- package/dist/types/formatters/CometChatFormatters/CometChatUrlsFormatter/CometChatUrlsFormatter.d.ts +9 -3
- package/dist/types/formatters/index.d.ts +2 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/utils/EmojiShortcodeUtils.d.ts +11 -0
- package/dist/types/utils/HtmlToMarkdown.d.ts +52 -0
- package/dist/types/utils/MarkdownPatternDetector.d.ts +108 -0
- package/dist/types/utils/RichTextFormatting.d.ts +143 -0
- package/dist/types/utils/util.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface LinkDialogProps {
|
|
2
|
+
/** The initial URL value */
|
|
3
|
+
initialUrl?: string;
|
|
4
|
+
/** The initial display text value */
|
|
5
|
+
initialText?: string;
|
|
6
|
+
/** Whether to show the text input field (hide when text is already selected) */
|
|
7
|
+
showTextInput?: boolean;
|
|
8
|
+
/** Whether this is edit mode (changes title and button text) */
|
|
9
|
+
isEditMode?: boolean;
|
|
10
|
+
/** When true, focus the Link field on mount instead of the Text field */
|
|
11
|
+
focusLinkField?: boolean;
|
|
12
|
+
/** Callback when the link is submitted */
|
|
13
|
+
onSubmit: (url: string, displayText?: string) => void;
|
|
14
|
+
/** Callback when the dialog is cancelled */
|
|
15
|
+
onCancel: () => void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* CometChatLinkDialog - A dialog for adding/editing hyperlinks
|
|
19
|
+
* Shows URL input and optional display text input
|
|
20
|
+
*/
|
|
21
|
+
export declare function CometChatLinkDialog(props: LinkDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
interface LinkPopoverProps {
|
|
3
|
+
/** The link text displayed */
|
|
4
|
+
linkText: string;
|
|
5
|
+
/** The URL of the link */
|
|
6
|
+
linkUrl: string;
|
|
7
|
+
/** Position of the popover */
|
|
8
|
+
position: {
|
|
9
|
+
top: number;
|
|
10
|
+
left: number;
|
|
11
|
+
};
|
|
12
|
+
/** Callback when Edit button is clicked */
|
|
13
|
+
onEdit: () => void;
|
|
14
|
+
/** Callback when Remove button is clicked */
|
|
15
|
+
onRemove: () => void;
|
|
16
|
+
/** Callback when popover should close */
|
|
17
|
+
onClose: () => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* CometChatLinkPopover - A popover that appears when clicking on a link
|
|
21
|
+
* Shows link text, URL (clickable), and Edit/Remove buttons
|
|
22
|
+
*/
|
|
23
|
+
declare const CometChatLinkPopover: React.FC<LinkPopoverProps>;
|
|
24
|
+
export { CometChatLinkPopover };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CometChatLinkPopover } from "./CometChatLinkPopover";
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { FormatType } from "../../utils/RichTextFormatting";
|
|
2
|
+
import { CometChatTextFormatter } from "../../formatters/CometChatFormatters/CometChatTextFormatter";
|
|
3
|
+
/**
|
|
4
|
+
* Configuration for the useRichTextComposer hook
|
|
5
|
+
*/
|
|
6
|
+
export interface RichTextComposerConfig {
|
|
7
|
+
enableRichTextEditor: boolean;
|
|
8
|
+
hideRichTextFormattingOptions: boolean;
|
|
9
|
+
showToolbarOnSelection: boolean;
|
|
10
|
+
getCurrentDocument: () => Document;
|
|
11
|
+
getCurrentWindow: () => Window;
|
|
12
|
+
getCurrentInput: () => Element | null | undefined;
|
|
13
|
+
composerContainerClass: string;
|
|
14
|
+
errorHandler: (error: unknown, context: string) => void;
|
|
15
|
+
setTextFormatters: React.Dispatch<React.SetStateAction<CometChatTextFormatter[]>>;
|
|
16
|
+
}
|
|
17
|
+
export interface LinkPopoverData {
|
|
18
|
+
linkText: string;
|
|
19
|
+
linkUrl: string;
|
|
20
|
+
linkElement: HTMLAnchorElement | null;
|
|
21
|
+
position: {
|
|
22
|
+
top: number;
|
|
23
|
+
left: number;
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export interface LinkEditData {
|
|
27
|
+
url: string;
|
|
28
|
+
text: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* State for undoing markdown conversions
|
|
32
|
+
*/
|
|
33
|
+
export interface MarkdownUndoState {
|
|
34
|
+
originalHtml: string;
|
|
35
|
+
cursorPosition: number;
|
|
36
|
+
timestamp: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Shared hook that encapsulates all rich text formatting logic
|
|
40
|
+
* used by both CometChatMessageComposer and CometChatCompactMessageComposer.
|
|
41
|
+
*/
|
|
42
|
+
export declare function useRichTextComposer(config: RichTextComposerConfig): {
|
|
43
|
+
isFixedToolbarVisible: boolean;
|
|
44
|
+
setIsFixedToolbarVisible: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
45
|
+
isFloatingToolbarVisible: boolean;
|
|
46
|
+
setIsFloatingToolbarVisible: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
47
|
+
floatingToolbarPosition: {
|
|
48
|
+
top: number;
|
|
49
|
+
left: number;
|
|
50
|
+
} | null;
|
|
51
|
+
activeFormats: FormatType[];
|
|
52
|
+
setActiveFormats: import("react").Dispatch<import("react").SetStateAction<FormatType[]>>;
|
|
53
|
+
showLinkInput: boolean;
|
|
54
|
+
showLinkPopover: boolean;
|
|
55
|
+
linkPopoverData: LinkPopoverData | null;
|
|
56
|
+
isLinkEditMode: boolean;
|
|
57
|
+
linkEditData: LinkEditData | null;
|
|
58
|
+
linkDialogSelectedText: string;
|
|
59
|
+
linkDialogSelectedTextRef: import("react").MutableRefObject<string>;
|
|
60
|
+
richTextFormatter: {
|
|
61
|
+
getSelection: () => Selection | null;
|
|
62
|
+
saveSelection: () => Range | null;
|
|
63
|
+
restoreSelection: (range: Range | null) => void;
|
|
64
|
+
hasSelection: () => boolean;
|
|
65
|
+
getSelectedText: (savedRange?: Range | null) => string;
|
|
66
|
+
isFormatted: (formatType: FormatType, containerElement: HTMLElement) => boolean;
|
|
67
|
+
isFormattingModeActive: () => boolean;
|
|
68
|
+
getActiveFormats: (containerElement: HTMLElement) => FormatType[];
|
|
69
|
+
getActiveFormattingModes: () => FormatType[];
|
|
70
|
+
findFormattingAncestor: () => HTMLElement | null;
|
|
71
|
+
applyFormat: () => void;
|
|
72
|
+
removeFormat: () => void;
|
|
73
|
+
toggleFormat: (formatType: FormatType, containerElement: HTMLElement) => void;
|
|
74
|
+
toggleFormattingMode: () => void;
|
|
75
|
+
toggleBold: (containerElement: HTMLElement) => void;
|
|
76
|
+
toggleItalic: (containerElement: HTMLElement) => void;
|
|
77
|
+
toggleUnderline: (containerElement: HTMLElement) => void;
|
|
78
|
+
toggleStrikethrough: (containerElement: HTMLElement) => void;
|
|
79
|
+
insertLink: (url: string, displayText: string | undefined, containerElement: HTMLElement) => void;
|
|
80
|
+
updateLink: (url: string, displayText: string | undefined, containerElement: HTMLElement) => void;
|
|
81
|
+
removeLink: (containerElement: HTMLElement) => void;
|
|
82
|
+
isInsideLink: (containerElement: HTMLElement) => boolean;
|
|
83
|
+
toggleOrderedList: (containerElement: HTMLElement) => void;
|
|
84
|
+
toggleUnorderedList: (containerElement: HTMLElement) => void;
|
|
85
|
+
fixOrderedListContinuation: (containerElement: HTMLElement) => void;
|
|
86
|
+
isInsideList: (listType: "orderedList" | "unorderedList", containerElement: HTMLElement) => HTMLElement | null;
|
|
87
|
+
isInsideAnyList: (containerElement: HTMLElement) => HTMLElement | null;
|
|
88
|
+
getCurrentListItem: (containerElement: HTMLElement) => HTMLLIElement | null;
|
|
89
|
+
isCurrentListItemEmpty: (containerElement: HTMLElement) => boolean;
|
|
90
|
+
isCursorAtListItemStart: (containerElement: HTMLElement) => boolean;
|
|
91
|
+
handleListBackspace: (containerElement: HTMLElement) => boolean;
|
|
92
|
+
handleListEnter: (containerElement: HTMLElement) => boolean;
|
|
93
|
+
handleListTab: (containerElement: HTMLElement, shiftKey: boolean) => boolean;
|
|
94
|
+
handleCodeBlockEnter: (containerElement: HTMLElement) => boolean;
|
|
95
|
+
handleCodeBlockBackspace: (containerElement: HTMLElement) => boolean;
|
|
96
|
+
handleAutoListTrigger: (containerElement: HTMLElement) => "orderedList" | "unorderedList" | null;
|
|
97
|
+
applyListInlineStyles: (containerElement: HTMLElement) => void;
|
|
98
|
+
toggleBlockquote: (containerElement: HTMLElement) => void;
|
|
99
|
+
isInsideBlockquote: (containerElement: HTMLElement) => HTMLElement | null;
|
|
100
|
+
toggleCodeInline: (containerElement: HTMLElement) => void;
|
|
101
|
+
toggleCodeBlock: (containerElement: HTMLElement) => void;
|
|
102
|
+
isInsideCodeInline: (containerElement: HTMLElement) => HTMLElement | null;
|
|
103
|
+
isInsideCodeBlock: (containerElement: HTMLElement) => HTMLElement | null;
|
|
104
|
+
handleInlineCodePreservation: (containerElement: HTMLElement, wasInsideInlineCode: boolean) => void;
|
|
105
|
+
clearFormattingModes: () => void;
|
|
106
|
+
resetFontContext: (containerElement?: HTMLElement) => void;
|
|
107
|
+
handleKeyboardShortcut: (event: KeyboardEvent, containerElement: HTMLElement) => boolean;
|
|
108
|
+
handleArrowKeyInCode: (event: KeyboardEvent, containerElement: HTMLElement) => boolean;
|
|
109
|
+
getPlainText: (htmlContent: string) => string;
|
|
110
|
+
normalizeHtml: (htmlContent: string) => string;
|
|
111
|
+
trimRichTextWhitespace: (html: string | null | undefined) => string;
|
|
112
|
+
handleMarkdownShortcuts: (containerElement: HTMLElement, onBeforeConversion?: () => void) => boolean;
|
|
113
|
+
clearPendingFormats: () => void;
|
|
114
|
+
getPendingFormats: () => FormatType[];
|
|
115
|
+
getTextOffsetAtCursor: (containerElement: HTMLElement) => number;
|
|
116
|
+
setCursorByTextOffset: (containerElement: HTMLElement, offset: number) => void;
|
|
117
|
+
convertMarkdownToFormat: (containerElement: HTMLElement, startOffset: number, endOffset: number, contentStart: number, contentEnd: number, formatType: FormatType, linkUrl?: string) => void;
|
|
118
|
+
positionCursorAfterFormat: (containerElement: HTMLElement, formattedNode: Node) => void;
|
|
119
|
+
applyMarkdownConversion: (containerElement: HTMLElement, match: {
|
|
120
|
+
startOffset: number;
|
|
121
|
+
endOffset: number;
|
|
122
|
+
contentStart: number;
|
|
123
|
+
contentEnd: number;
|
|
124
|
+
linkUrl?: string;
|
|
125
|
+
}, formatType: FormatType) => void;
|
|
126
|
+
} | null;
|
|
127
|
+
handleLinkClick: () => void;
|
|
128
|
+
handleLinkSubmit: (url: string, displayText?: string) => void;
|
|
129
|
+
handleLinkCancel: () => void;
|
|
130
|
+
handleInputClick: (event: React.MouseEvent) => void;
|
|
131
|
+
handleLinkPopoverEdit: () => void;
|
|
132
|
+
handleLinkPopoverRemove: () => void;
|
|
133
|
+
handleLinkPopoverClose: () => void;
|
|
134
|
+
handleFormatApplied: () => void;
|
|
135
|
+
handleFormattingKeyDown: (event: KeyboardEvent, contenteditable: Element) => boolean;
|
|
136
|
+
saveMarkdownUndoState: () => void;
|
|
137
|
+
handleMarkdownUndo: () => boolean;
|
|
138
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { CometChatTextFormatter } from "../CometChatTextFormatter";
|
|
2
|
+
import { MentionsTargetElement } from "../../../Enums/Enums";
|
|
3
|
+
/**
|
|
4
|
+
* CometChatMarkdownFormatter
|
|
5
|
+
*
|
|
6
|
+
* Handles bidirectional conversion between HTML and markdown:
|
|
7
|
+
*
|
|
8
|
+
* BUBBLE SIDE (getFormattedText): Markdown → HTML for display
|
|
9
|
+
* - **bold** → <b>bold</b>
|
|
10
|
+
* - _italic_ → <i>italic</i>
|
|
11
|
+
* - <u>underline</u> → <u>underline</u> (pass-through)
|
|
12
|
+
* - ~~strikethrough~~ → <s>strikethrough</s>
|
|
13
|
+
* - `inline code` → <code>inline code</code>
|
|
14
|
+
* - ```code block``` → <pre><code>code block</code></pre>
|
|
15
|
+
* - > blockquote → <blockquote>blockquote</blockquote>
|
|
16
|
+
* - [text](url) → <a href="url">text</a>
|
|
17
|
+
*
|
|
18
|
+
* COMPOSER SIDE (getOriginalText): HTML → Markdown for storage
|
|
19
|
+
* - <b>bold</b> → **bold**
|
|
20
|
+
* - <i>italic</i> → _italic_
|
|
21
|
+
* - <u>underline</u> → <u>underline</u>
|
|
22
|
+
* - <s>strikethrough</s> → ~~strikethrough~~
|
|
23
|
+
* - <code>code</code> → `code`
|
|
24
|
+
* - <pre><code>code</code></pre> → ```code```
|
|
25
|
+
* - <blockquote>text</blockquote> → > text
|
|
26
|
+
* - <a href="url">text</a> → [text](url)
|
|
27
|
+
*/
|
|
28
|
+
export declare class CometChatMarkdownFormatter extends CometChatTextFormatter {
|
|
29
|
+
constructor();
|
|
30
|
+
/**
|
|
31
|
+
* BUBBLE SIDE: Convert markdown syntax to styled HTML for display
|
|
32
|
+
*/
|
|
33
|
+
getFormattedText(inputText: string, params?: {
|
|
34
|
+
mentionsTargetElement?: MentionsTargetElement;
|
|
35
|
+
}): string;
|
|
36
|
+
/**
|
|
37
|
+
* COMPOSER SIDE: Pass through unchanged.
|
|
38
|
+
* HTML→Markdown conversion is handled exclusively by CometChatRichTextFormatter
|
|
39
|
+
* (via HtmlToMarkdown.ts). Running a second conversion here would double-process
|
|
40
|
+
* the text and corrupt mention spans before CometChatMentionsFormatter can replace
|
|
41
|
+
* them with <@uid:xxx> tokens.
|
|
42
|
+
*/
|
|
43
|
+
getOriginalText(inputText: string | null | undefined): string;
|
|
44
|
+
/**
|
|
45
|
+
* Format code blocks: ```code``` → <pre><code>code</code></pre>
|
|
46
|
+
*/
|
|
47
|
+
private formatCodeBlocks;
|
|
48
|
+
/**
|
|
49
|
+
* Apply a formatting function only to text segments outside of code blocks.
|
|
50
|
+
* Unlike formatOutsideCode, this does NOT split on inline <code> tags or mention placeholders.
|
|
51
|
+
* Used for blockquote processing which runs before inline code conversion.
|
|
52
|
+
*/
|
|
53
|
+
private formatOutsideCodeBlocks;
|
|
54
|
+
/**
|
|
55
|
+
* Apply a formatting function only to text segments outside of code blocks and inline code.
|
|
56
|
+
* Splits the text by <pre><code>...</code></pre> and <code>...</code> segments,
|
|
57
|
+
* applies the formatter only to non-code parts, then reassembles.
|
|
58
|
+
*/
|
|
59
|
+
private formatOutsideCode;
|
|
60
|
+
/**
|
|
61
|
+
* Format inline code: `code` → <code>code</code>
|
|
62
|
+
*/
|
|
63
|
+
private formatInlineCode;
|
|
64
|
+
/**
|
|
65
|
+
* Format bold: **text** → <b>text</b>
|
|
66
|
+
*/
|
|
67
|
+
private formatBold;
|
|
68
|
+
/**
|
|
69
|
+
* Format italic: _text_ → <i>text</i>
|
|
70
|
+
*/
|
|
71
|
+
private formatItalic;
|
|
72
|
+
/**
|
|
73
|
+
* Format underline: <u>text</u> → <u>text</u>
|
|
74
|
+
* The markdown syntax uses HTML-style <u> tags directly.
|
|
75
|
+
* Also supports legacy ++text++ and __text__ for backward compatibility.
|
|
76
|
+
*/
|
|
77
|
+
private formatUnderline;
|
|
78
|
+
/**
|
|
79
|
+
* Format strikethrough: ~~text~~ → <s>text</s>
|
|
80
|
+
*/
|
|
81
|
+
private formatStrikethrough;
|
|
82
|
+
/**
|
|
83
|
+
* Format links: [text](url) → <a href="url">text</a>
|
|
84
|
+
*/
|
|
85
|
+
private formatLinks;
|
|
86
|
+
/**
|
|
87
|
+
* Format blockquotes: > text → <blockquote>text</blockquote>
|
|
88
|
+
*/
|
|
89
|
+
private formatBlockquotes;
|
|
90
|
+
/**
|
|
91
|
+
* Format ordered lists: 1. item → <li>item</li>
|
|
92
|
+
*/
|
|
93
|
+
/**
|
|
94
|
+
* Format ordered lists: consecutive "N. item" lines → <ol><li>item</li></ol>
|
|
95
|
+
*/
|
|
96
|
+
private formatOrderedLists;
|
|
97
|
+
/**
|
|
98
|
+
* Format unordered lists: • item or - item → <li>item</li>
|
|
99
|
+
*/
|
|
100
|
+
/**
|
|
101
|
+
* Format unordered lists: consecutive "• item" or "- item" lines → <ul><li>item</li></ul>
|
|
102
|
+
*/
|
|
103
|
+
private formatUnorderedLists;
|
|
104
|
+
/**
|
|
105
|
+
* Register click handlers for links
|
|
106
|
+
*/
|
|
107
|
+
registerEventListeners(span: Element, classList: DOMTokenList): Element;
|
|
108
|
+
stripMarkdownForConversation(text: string): string;
|
|
109
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { CometChatTextFormatter } from "./CometChatTextFormatter";
|
|
2
|
+
import { MentionsTargetElement } from "../../Enums/Enums";
|
|
3
|
+
/**
|
|
4
|
+
* CometChatRichTextFormatter
|
|
5
|
+
*
|
|
6
|
+
* Handles rich text formatting for CometChat messages.
|
|
7
|
+
* - COMPOSER SIDE: Converts HTML from contenteditable to markdown for storage
|
|
8
|
+
* - BUBBLE SIDE: Passes through text as-is (markdown rendering handled by CometChatMarkdownFormatter)
|
|
9
|
+
*/
|
|
10
|
+
export declare class CometChatRichTextFormatter extends CometChatTextFormatter {
|
|
11
|
+
constructor();
|
|
12
|
+
/**
|
|
13
|
+
* BUBBLE SIDE: Pass through text as-is
|
|
14
|
+
* The CometChatMarkdownFormatter handles converting markdown to HTML for display
|
|
15
|
+
*/
|
|
16
|
+
getFormattedText(inputText: string, _params?: {
|
|
17
|
+
mentionsTargetElement?: MentionsTargetElement;
|
|
18
|
+
}): string;
|
|
19
|
+
/**
|
|
20
|
+
* COMPOSER SIDE: Convert HTML from contenteditable to markdown
|
|
21
|
+
* This is called before sending the message to convert the rich HTML to markdown format
|
|
22
|
+
*/
|
|
23
|
+
getOriginalText(inputText: string | null | undefined): string;
|
|
24
|
+
/**
|
|
25
|
+
* Check if the input contains HTML tags that need conversion
|
|
26
|
+
*/
|
|
27
|
+
private containsHtmlTags;
|
|
28
|
+
/**
|
|
29
|
+
* Register click handlers for links in bubbles
|
|
30
|
+
*/
|
|
31
|
+
registerEventListeners(span: Element, _classList: DOMTokenList): Element;
|
|
32
|
+
}
|
package/dist/types/formatters/CometChatFormatters/CometChatUrlsFormatter/CometChatUrlsFormatter.d.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { CometChatTextFormatter } from "../CometChatTextFormatter";
|
|
2
2
|
/**
|
|
3
3
|
* Class that handles the text formatting for URLs in CometChat.
|
|
4
|
-
* CometChatUrlsFormatter is a child class of CometChatTextFormatter.
|
|
5
|
-
* It extends the functionality of text formatting to specifically handle URLs.
|
|
6
|
-
* It is used in extension decorators like link preview, message translation, and dataSource utils.
|
|
7
4
|
*/
|
|
8
5
|
export declare class CometChatUrlsFormatter extends CometChatTextFormatter {
|
|
9
6
|
constructor(regexPatterns: Array<RegExp>);
|
|
7
|
+
onKeyUp(event: KeyboardEvent): void;
|
|
8
|
+
/**
|
|
9
|
+
* DOM-based URL linkification for message bubbles.
|
|
10
|
+
* Walks ALL text nodes and wraps URLs in clickable spans.
|
|
11
|
+
* Never breaks HTML structure. URLs inside code blocks become clickable.
|
|
12
|
+
* Only skips text inside <a> tags.
|
|
13
|
+
*/
|
|
10
14
|
protected onRegexMatch(inputText?: string | null): string;
|
|
11
15
|
registerEventListeners(element: HTMLElement, classList: DOMTokenList): HTMLElement;
|
|
16
|
+
formatComposerContent(_element: HTMLElement): void;
|
|
17
|
+
getOriginalText(inputText: string | null | undefined): string;
|
|
12
18
|
}
|
|
@@ -2,3 +2,5 @@ export { CometChatTextFormatter } from './CometChatFormatters/CometChatTextForma
|
|
|
2
2
|
export { CometChatUrlsFormatter } from './CometChatFormatters/CometChatUrlsFormatter/CometChatUrlsFormatter';
|
|
3
3
|
export { CometChatMentionsFormatter } from './CometChatFormatters/CometChatMentionsFormatter/CometChatMentionsFormatter';
|
|
4
4
|
export { CometChatTextHighlightFormatter } from './CometChatFormatters/CometChatTextHighlightFormatter/CometChatTextHighlightFormatter';
|
|
5
|
+
export { CometChatRichTextFormatter } from './CometChatFormatters/CometChatRichTextFormatter';
|
|
6
|
+
export { CometChatMarkdownFormatter } from './CometChatFormatters/CometChatMarkdownFormatter/CometChatMarkdownFormatter';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ export { CometChatGroupMembers } from './components/CometChatGroupMembers/CometC
|
|
|
37
37
|
export { CometChatGroups } from './components/CometChatGroups/CometChatGroups';
|
|
38
38
|
export { CometChatMessageBubble } from './components/BaseComponents/CometChatMessageBubble/CometChatMessageBubble';
|
|
39
39
|
export { CometChatMessageComposer } from './components/CometChatMessageComposer/CometChatMessageComposer';
|
|
40
|
+
export { CometChatCompactMessageComposer } from './components/CometChatCompactMessageComposer/CometChatCompactMessageComposer';
|
|
40
41
|
export { CometChatMessageHeader } from './components/CometChatMessageHeader/CometChatMessageHeader';
|
|
41
42
|
export { CometChatMessageList } from './components/CometChatMessageList/CometChatMessageList';
|
|
42
43
|
export { CometChatUsers } from './components/CometChatUsers/CometChatUsers';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replaces all unicode emoji characters in a string with their :shortcode: equivalents.
|
|
3
|
+
* Handles multi-codepoint emoji (ZWJ sequences, variation selectors, skin tones).
|
|
4
|
+
* Unknown emoji characters (not in emojis.ts) pass through unchanged.
|
|
5
|
+
*/
|
|
6
|
+
export declare function emojiToShortcode(text: string): string;
|
|
7
|
+
/**
|
|
8
|
+
* Replaces all :shortcode: patterns in a string with their unicode emoji characters.
|
|
9
|
+
* Unknown shortcodes pass through unchanged.
|
|
10
|
+
*/
|
|
11
|
+
export declare function shortcodeToEmoji(text: string): string;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML to Markdown Converter
|
|
3
|
+
*
|
|
4
|
+
* Converts rich text HTML from the message composer to markdown
|
|
5
|
+
* for storage and transmission.
|
|
6
|
+
*
|
|
7
|
+
* Conversion rules:
|
|
8
|
+
* - <b>, <strong> → **text**
|
|
9
|
+
* - <i>, <em> → _text_
|
|
10
|
+
* - <s>, <strike>, <del> → ~~text~~
|
|
11
|
+
* - <u> → <u>text</u> (HTML-style underline)
|
|
12
|
+
* - <code> (not in pre) → `text`
|
|
13
|
+
* - <pre><code> → ```text```
|
|
14
|
+
* - <blockquote> → > text
|
|
15
|
+
* - <a href="url">text</a> → [text](url)
|
|
16
|
+
* - <ol><li> → 1. text
|
|
17
|
+
* - <ul><li> → • text
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
* Convert HTML string to markdown
|
|
21
|
+
*/
|
|
22
|
+
export declare function htmlToMarkdown(html: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Remove escape backslashes from markdown text before sending.
|
|
25
|
+
* Preserves literal markdown characters that were escaped by the user.
|
|
26
|
+
*
|
|
27
|
+
* Rules:
|
|
28
|
+
* - Single backslash before markdown character: remove backslash, keep character
|
|
29
|
+
* - Even number of backslashes: keep half of them (they escape each other)
|
|
30
|
+
* - Odd number of backslashes: keep (n-1)/2 backslashes, last one escapes the markdown char
|
|
31
|
+
*
|
|
32
|
+
* Examples:
|
|
33
|
+
* - \* → *
|
|
34
|
+
* - \\* → \*
|
|
35
|
+
* - \\\* → \*
|
|
36
|
+
* - \\\\* → \\*
|
|
37
|
+
*
|
|
38
|
+
* @param text - Markdown text that may contain escape sequences
|
|
39
|
+
* @returns Text with escape backslashes removed
|
|
40
|
+
*/
|
|
41
|
+
export declare function removeEscapeBackslashes(text: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* Clean up markdown output
|
|
44
|
+
* - Remove excessive newlines
|
|
45
|
+
* - Trim whitespace
|
|
46
|
+
*/
|
|
47
|
+
export declare function cleanMarkdown(markdown: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* Convert HTML to clean markdown
|
|
50
|
+
* Removes escape backslashes before sending (Requirement 12.2)
|
|
51
|
+
*/
|
|
52
|
+
export declare function convertHtmlToMarkdown(html: string): string;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MarkdownPatternDetector - Utility for detecting and validating markdown syntax patterns
|
|
3
|
+
* in contenteditable elements for automatic conversion to rich text formatting.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Represents a markdown pattern definition
|
|
7
|
+
*/
|
|
8
|
+
export interface MarkdownPattern {
|
|
9
|
+
type: 'bold' | 'italic' | 'underline' | 'strikethrough' | 'codeInline' | 'codeBlock' | 'link';
|
|
10
|
+
openDelimiter: string;
|
|
11
|
+
closeDelimiter: string;
|
|
12
|
+
priority: number;
|
|
13
|
+
/** If true, use custom detection logic instead of standard delimiter matching */
|
|
14
|
+
customDetection?: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Represents a detected markdown pattern match
|
|
18
|
+
*/
|
|
19
|
+
export interface PatternMatch {
|
|
20
|
+
pattern: MarkdownPattern;
|
|
21
|
+
startOffset: number;
|
|
22
|
+
endOffset: number;
|
|
23
|
+
contentStart: number;
|
|
24
|
+
contentEnd: number;
|
|
25
|
+
content: string;
|
|
26
|
+
linkUrl?: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Context information for pattern detection
|
|
30
|
+
*/
|
|
31
|
+
export interface DetectionContext {
|
|
32
|
+
text: string;
|
|
33
|
+
cursorOffset: number;
|
|
34
|
+
triggerChar: string;
|
|
35
|
+
scopeStart: number;
|
|
36
|
+
scopeEnd: number;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Supported markdown patterns ordered by priority (highest first)
|
|
40
|
+
*/
|
|
41
|
+
export declare const MARKDOWN_PATTERNS: MarkdownPattern[];
|
|
42
|
+
/**
|
|
43
|
+
* Map of trigger characters to their associated patterns for efficient lookup
|
|
44
|
+
*/
|
|
45
|
+
export declare const TRIGGER_CHARS: Record<string, MarkdownPattern[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Detects markdown patterns in text at cursor position
|
|
48
|
+
*
|
|
49
|
+
* @param context - Detection context with text, cursor position, and scope boundaries
|
|
50
|
+
* @returns PatternMatch if valid pattern found, null otherwise
|
|
51
|
+
*/
|
|
52
|
+
export declare function detectMarkdownPattern(context: DetectionContext): PatternMatch | null;
|
|
53
|
+
/**
|
|
54
|
+
* Validates that a pattern match is properly formed
|
|
55
|
+
*
|
|
56
|
+
* @param match - Pattern match to validate
|
|
57
|
+
* @param context - Detection context
|
|
58
|
+
* @returns true if pattern is valid, false otherwise
|
|
59
|
+
*/
|
|
60
|
+
export declare function validatePattern(match: PatternMatch, context: DetectionContext): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Checks if a position in text is within an escape sequence
|
|
63
|
+
*
|
|
64
|
+
* @param text - Full text content
|
|
65
|
+
* @param position - Position to check
|
|
66
|
+
* @returns true if position is escaped, false otherwise
|
|
67
|
+
*/
|
|
68
|
+
export declare function isEscaped(text: string, position: number): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Finds scope boundaries (paragraph/block element) for pattern matching
|
|
71
|
+
*
|
|
72
|
+
* @param element - Container element
|
|
73
|
+
* @param cursorNode - Current cursor node
|
|
74
|
+
* @param cursorOffset - Current cursor offset
|
|
75
|
+
* @returns Object with start and end offsets of the scope
|
|
76
|
+
*/
|
|
77
|
+
export declare function findScopeBoundaries(element: HTMLElement, cursorNode: Node, cursorOffset: number): {
|
|
78
|
+
start: number;
|
|
79
|
+
end: number;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Checks if the cursor is currently inside a mention element.
|
|
83
|
+
* Mention elements use `<span class="cometchat-mentions">`.
|
|
84
|
+
*
|
|
85
|
+
* @param cursorNode - The DOM node where the cursor is positioned
|
|
86
|
+
* @param containerElement - The contenteditable container element
|
|
87
|
+
* @returns true if cursor is inside a mention span, false otherwise
|
|
88
|
+
*/
|
|
89
|
+
export declare function isCursorInsideMention(cursorNode: Node, containerElement: HTMLElement): boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Checks if the cursor is currently inside a link (anchor) element.
|
|
92
|
+
*
|
|
93
|
+
* @param cursorNode - The DOM node where the cursor is positioned
|
|
94
|
+
* @param containerElement - The contenteditable container element
|
|
95
|
+
* @returns true if cursor is inside an <a> element, false otherwise
|
|
96
|
+
*/
|
|
97
|
+
export declare function isCursorInsideLink(cursorNode: Node, containerElement: HTMLElement): boolean;
|
|
98
|
+
/**
|
|
99
|
+
* Checks if a pattern match spans across a mention or link element boundary.
|
|
100
|
+
* This prevents markdown patterns from being matched when the opening delimiter
|
|
101
|
+
* is outside a mention/link and the closing delimiter is inside (or vice versa).
|
|
102
|
+
*
|
|
103
|
+
* @param containerElement - The contenteditable container element
|
|
104
|
+
* @param startOffset - Text offset of the pattern start (opening delimiter)
|
|
105
|
+
* @param endOffset - Text offset of the pattern end (closing delimiter)
|
|
106
|
+
* @returns true if the pattern crosses a mention or link boundary, false otherwise
|
|
107
|
+
*/
|
|
108
|
+
export declare function patternCrossesMentionOrLink(containerElement: HTMLElement, startOffset: number, endOffset: number): boolean;
|