Skip to content

feat(android): EnrichedText#400

Open
exploIF wants to merge 26 commits intomainfrom
@exploif/android-enriched-text
Open

feat(android): EnrichedText#400
exploIF wants to merge 26 commits intomainfrom
@exploif/android-enriched-text

Conversation

@exploIF
Copy link
Copy Markdown
Collaborator

@exploIF exploIF commented Jan 27, 2026

Summary

Implements EnrichedText component which can be used for displaying text created by EnrichedTextInput.
Tackles: #374

Test Plan

Verify that EnrichedText component is rendered properly, styles can be customized and any valid html or raw text is displayed properly

Screenshots / Videos

Screen.Recording.2026-01-27.at.15.01.03.mov

Compatibility

OS Implemented
iOS
Android

exploIF and others added 10 commits January 26, 2026 14:06
…r-android

# Conflicts:
#	android/src/main/java/com/swmansion/enriched/common/parser/EnrichedParser.java
#	android/src/main/java/com/swmansion/enriched/common/spans/EnrichedCheckboxListSpan.kt
#	android/src/main/java/com/swmansion/enriched/textinput/EnrichedTextInputView.kt
#	android/src/main/java/com/swmansion/enriched/textinput/watchers/EnrichedSpanWatcher.kt
…ched-text

# Conflicts:
#	src/index.tsx
#	src/types.ts
#	src/utils/normalizeHtmlStyle.ts
@exploIF exploIF mentioned this pull request Jan 27, 2026
3 tasks
@kacperzolkiewski kacperzolkiewski changed the title [WIP]: feat: android EnrichedText feat(android): EnrichedText Apr 16, 2026
@kacperzolkiewski kacperzolkiewski marked this pull request as ready for review April 16, 2026 06:55
fun setFontWeight(weight: String?) {
val fontWeight = parseFontWeight(weight)

if (fontWeight != fontStyle) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (fontWeight != fontStyle) {
if (fontWeight != this.fontWeight) {

Comment on lines +66 to +68
val text = value ?: return
val style = enrichedStyle ?: return
if (!valueDirty) return
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
val text = value ?: return
val style = enrichedStyle ?: return
if (!valueDirty) return
if (!valueDirty) return
val text = value ?: return
val style = enrichedStyle ?: return

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We do not need to check for text and style if valueDirty == false

Comment on lines +84 to +86
super.setPadding(view, left, top, right, bottom)

view?.setPadding(left, top, right, bottom)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to call setPadding twice with super and view. here?

Comment on lines +113 to +114
val parsed = EnrichedParser.fromHtml(text, enrichedStyle, factory)
return parsed.trimEnd('\n')
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we should put deletion of last newline:.trimEnd('\n') into fromHtml function because everywhere where we are using fromHtml we also delete last newline after parsing.

Comment thread src/EnrichedText.tsx
Comment on lines +108 to +113
focus: () => {
nullthrows(nativeRef.current).focus();
},
blur: () => {
nullthrows(nativeRef.current).blur();
},
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should't we omit those methods? EnrichedText is only renderer so those methods have no effect on it?

Comment thread .maestro/scripts/run-tests.sh
Comment thread .maestro/enrichedText/subflows/capture_or_assert_screenshot.yaml
@pkaramon
Copy link
Copy Markdown
Collaborator

Not sure how hard this would be, but it’d be great if styles were preserved when copying from EnrichedText into EnrichedTextInput.

Screen.Recording.2026-04-16.at.11.58.59.mov

Comment thread .maestro/enrichedText/flows/mention_press.yaml Outdated
Comment thread .maestro/enrichedText/flows/custom_styles_display.yaml
Comment thread src/utils/normalizeHtmlStyle.ts Outdated
Comment thread src/index.tsx Outdated
@kacperzolkiewski
Copy link
Copy Markdown
Collaborator

Not sure how hard this would be, but it’d be great if styles were preserved when copying from EnrichedText into EnrichedTextInput.

Screen.Recording.2026-04-16.at.11.58.59.mov

@pkaramon nice idea, but it will be better to add it in separate PR ;)

Co-authored-by: Piotr Karamon <33125365+pkaramon@users.noreply.github.com>
@pkaramon
Copy link
Copy Markdown
Collaborator

When selectable is set to true clicking on mentions and links does not work.

Screen.Recording.2026-04-16.at.14.41.08.mov

I've asked AI about this and apparently:

TextView only uses one MovementMethod at a time.

  • Links/mentions rely on a link-style method (here: EnrichedTextMovementMethod, based on LinkMovementMethod).
  • selectable={true} maps to setTextIsSelectable(true), which installs the selection movement method (ArrowKeyMovementMethod), replacing the link handler.

@kacperzolkiewski
Copy link
Copy Markdown
Collaborator

When selectable is set to true clicking on mentions and links does not work.

Screen.Recording.2026-04-16.at.14.41.08.mov

I've asked AI about this and apparently:

TextView only uses one MovementMethod at a time.

  • Links/mentions rely on a link-style method (here: EnrichedTextMovementMethod, based on LinkMovementMethod).
  • selectable={true} maps to setTextIsSelectable(true), which installs the selection movement method (ArrowKeyMovementMethod), replacing the link handler.

@pkaramon can you test it right now? I pushed the fix for that

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants