diff --git a/CHANGELOG.md b/CHANGELOG.md index 8bbea029..3d603d4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to - ♿(frontend) improve screen reader support in DocShare modal #1628 - 🐛(frontend) fix toolbar not activated when reader #1640 - 🐛(frontend) preserve left panel width on window resize #1588 +- 🐛(frontend) prevent duplicate as first character in title #1595 ## [3.10.0] - 2025-11-18 diff --git a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx index 33905caa..4fdbdad9 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx +++ b/src/frontend/apps/impress/src/features/docs/doc-header/components/DocTitle.tsx @@ -122,11 +122,17 @@ const DocTitleInput = ({ doc }: DocTitleProps) => { if (isTopRoot) { const sanitizedTitle = updateDocTitle(doc, inputText); setTitleDisplay(sanitizedTitle); + return sanitizedTitle; } else { - const sanitizedTitle = updateDocTitle( - doc, - emoji ? `${emoji} ${inputText}` : inputText, - ); + const { emoji: pastedEmoji } = getEmojiAndTitle(inputText); + const textPreservingPastedEmoji = pastedEmoji + ? `\u200B${inputText}` + : inputText; + const finalTitle = emoji + ? `${emoji} ${textPreservingPastedEmoji}` + : textPreservingPastedEmoji; + + const sanitizedTitle = updateDocTitle(doc, finalTitle); const { titleWithoutEmoji: sanitizedTitleWithoutEmoji } = getEmojiAndTitle(sanitizedTitle); diff --git a/src/frontend/apps/impress/src/features/docs/doc-management/utils.ts b/src/frontend/apps/impress/src/features/docs/doc-management/utils.ts index 2d43b68f..c126cc8a 100644 --- a/src/frontend/apps/impress/src/features/docs/doc-management/utils.ts +++ b/src/frontend/apps/impress/src/features/docs/doc-management/utils.ts @@ -26,12 +26,13 @@ export const getEmojiAndTitle = (title: string) => { // Use emoji-regex library for comprehensive emoji detection compatible with ES5 const regex = emojiRegex(); - // Check if the title starts with an emoji - const match = title.match(regex); + // Ignore leading spaces when checking for a leading emoji + const trimmedTitle = title.trimStart(); + const match = trimmedTitle.match(regex); - if (match && title.startsWith(match[0])) { + if (match && trimmedTitle.startsWith(match[0])) { const emoji = match[0]; - const titleWithoutEmoji = title.substring(emoji.length).trim(); + const titleWithoutEmoji = trimmedTitle.substring(emoji.length).trim(); return { emoji, titleWithoutEmoji }; }