From f93aff97fffb3b46f752a3ee8b094a9954547571 Mon Sep 17 00:00:00 2001 From: IvanIhnatsiuk Date: Sat, 8 Nov 2025 13:06:49 +0100 Subject: [PATCH] fix: recalculating layout after changing html styles --- .../enriched/EnrichedTextInputView.kt | 27 +++++++ example/src/App.tsx | 77 ++++++++++++++++++- 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt b/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt index bae67e5..372aa37 100644 --- a/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt +++ b/android/src/main/java/com/swmansion/enriched/EnrichedTextInputView.kt @@ -57,6 +57,12 @@ class EnrichedTextInputView : AppCompatEditText { val mentionHandler: MentionHandler? = MentionHandler(this) var htmlStyle: HtmlStyle = HtmlStyle(this, null) + set(value) { + if (field != value) { + field = value + reapplyTextWithNewStyles() + } + } var spanWatcher: EnrichedSpanWatcher? = null var layoutManager: EnrichedTextInputViewLayoutManager = EnrichedTextInputViewLayoutManager(this) @@ -533,6 +539,27 @@ class EnrichedTextInputView : AppCompatEditText { } } + private fun reapplyTextWithNewStyles() { + val currentText = text + if (currentText != null && currentText.isNotEmpty()) { + runAsATransaction { + val currentHtml = EnrichedParser.toHtml(currentText as Spannable) + val newText = parseText(currentHtml) + + val currentSelectionStart = selectionStart + val currentSelectionEnd = selectionEnd + + setText(newText) + + val newLength = text?.length ?: 0 + val safeStart = currentSelectionStart.coerceIn(0, newLength) + val safeEnd = currentSelectionEnd.coerceIn(0, newLength) + setSelection(safeStart, safeEnd) + layoutManager.invalidateLayout() + } + } + } + override fun onAttachedToWindow() { super.onAttachedToWindow() diff --git a/example/src/App.tsx b/example/src/App.tsx index b5dac0c..fc2568c 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -74,6 +74,8 @@ export default function App() { const [isLinkModalOpen, setIsLinkModalOpen] = useState(false); const [isValueModalOpen, setIsValueModalOpen] = useState(false); const [currentHtml, setCurrentHtml] = useState(''); + const [currentHtmlStyle, setCurrentHtmlStyle] = + useState(htmlStyle); const [selection, setSelection] = useState(); const [stylesState, setStylesState] = useState(DEFAULT_STYLE); @@ -235,6 +237,12 @@ export default function App() { closeChannelMentionPopup(); }; + const handleChangeHtmlStyle = () => { + setCurrentHtmlStyle((style) => + style === htmlStyle ? anotherHtmlStyle : htmlStyle + ); + }; + const handleFocusEvent = () => { console.log('Input focused'); }; @@ -267,7 +275,7 @@ export default function App() { key={key} mentionIndicators={['@', '#']} style={styles.editorInput} - htmlStyle={htmlStyle} + htmlStyle={currentHtmlStyle} placeholder="Type something here..." placeholderTextColor="rgb(0, 26, 114)" selectionColor="deepskyblue" @@ -307,6 +315,11 @@ export default function App() { />