@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.
Files changed (64) hide show
  1. package/dist/assets/bin.svg +1 -0
  2. package/dist/assets/format_blockquote.svg +3 -0
  3. package/dist/assets/format_bold.svg +5 -0
  4. package/dist/assets/format_code.svg +3 -0
  5. package/dist/assets/format_code_block.svg +5 -0
  6. package/dist/assets/format_italic.svg +3 -0
  7. package/dist/assets/format_link.svg +3 -0
  8. package/dist/assets/format_ordered_list.svg +5 -0
  9. package/dist/assets/format_strikethrough.svg +5 -0
  10. package/dist/assets/format_toggle.svg +1 -0
  11. package/dist/assets/format_underline.svg +5 -0
  12. package/dist/assets/format_unordered_list.svg +5 -0
  13. package/dist/assets/pause_circle.svg +1 -0
  14. package/dist/assets/warning-small.svg +0 -0
  15. package/dist/index.d.ts +360 -6
  16. package/dist/index.js +1 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/styles/CometChatCompactMessageComposer.css +1111 -0
  19. package/dist/styles/CometChatConversations.css +37 -1
  20. package/dist/styles/CometChatDocumentBubble.css +0 -1
  21. package/dist/styles/CometChatFormattingToolbar.css +257 -0
  22. package/dist/styles/CometChatLinkDialog.css +191 -0
  23. package/dist/styles/CometChatLinkPopover.css +128 -0
  24. package/dist/styles/CometChatMarkdownFormatter.css +141 -0
  25. package/dist/styles/CometChatMediaRecorder.css +73 -1
  26. package/dist/styles/CometChatMessageComposer.css +210 -3
  27. package/dist/styles/CometChatMessagePreview.css +10 -0
  28. package/dist/styles/CometChatSearch.css +11 -0
  29. package/dist/styles/CometChatTextBubble.css +267 -3
  30. package/dist/styles/LinkPreview.css +1 -1
  31. package/dist/styles/components/CometChatCompactMessageComposer.css +1111 -0
  32. package/dist/styles/components/CometChatConversations.css +37 -1
  33. package/dist/styles/components/CometChatDocumentBubble.css +0 -1
  34. package/dist/styles/components/CometChatFormattingToolbar.css +257 -0
  35. package/dist/styles/components/CometChatLinkDialog.css +191 -0
  36. package/dist/styles/components/CometChatLinkPopover.css +128 -0
  37. package/dist/styles/components/CometChatMarkdownFormatter.css +141 -0
  38. package/dist/styles/components/CometChatMediaRecorder.css +73 -1
  39. package/dist/styles/components/CometChatMessageComposer.css +210 -3
  40. package/dist/styles/components/CometChatMessagePreview.css +10 -0
  41. package/dist/styles/components/CometChatSearch.css +11 -0
  42. package/dist/styles/components/CometChatTextBubble.css +267 -3
  43. package/dist/styles/components/LinkPreview.css +1 -1
  44. package/dist/styles/components/index.css +6 -5
  45. package/dist/styles/css-variables.css +1 -0
  46. package/dist/styles/index.css +6 -5
  47. package/dist/types/CometChatUIKit/CometChatUIKitUtility.d.ts +13 -0
  48. package/dist/types/components/CometChatCompactMessageComposer/CometChatCompactMessageComposer.d.ts +247 -0
  49. package/dist/types/components/CometChatFormattingToolbar/CometChatFormattingToolbar.d.ts +29 -0
  50. package/dist/types/components/CometChatLinkDialog/CometChatLinkDialog.d.ts +22 -0
  51. package/dist/types/components/CometChatLinkPopover/CometChatLinkPopover.d.ts +24 -0
  52. package/dist/types/components/CometChatLinkPopover/index.d.ts +1 -0
  53. package/dist/types/components/useRichTextComposer/useRichTextComposer.d.ts +138 -0
  54. package/dist/types/formatters/CometChatFormatters/CometChatMarkdownFormatter/CometChatMarkdownFormatter.d.ts +109 -0
  55. package/dist/types/formatters/CometChatFormatters/CometChatRichTextFormatter.d.ts +32 -0
  56. package/dist/types/formatters/CometChatFormatters/CometChatUrlsFormatter/CometChatUrlsFormatter.d.ts +9 -3
  57. package/dist/types/formatters/index.d.ts +2 -0
  58. package/dist/types/index.d.ts +1 -0
  59. package/dist/types/utils/EmojiShortcodeUtils.d.ts +11 -0
  60. package/dist/types/utils/HtmlToMarkdown.d.ts +52 -0
  61. package/dist/types/utils/MarkdownPatternDetector.d.ts +108 -0
  62. package/dist/types/utils/RichTextFormatting.d.ts +143 -0
  63. package/dist/types/utils/util.d.ts +1 -1
  64. 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
+ }
@@ -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';
@@ -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;