Skip to content

fix: formatted text inside markdown links rendering in wrong color#7232

Open
divyanshu-patil wants to merge 9 commits intoRocketChat:developfrom
divyanshu-patil:fix/markdown-link
Open

fix: formatted text inside markdown links rendering in wrong color#7232
divyanshu-patil wants to merge 9 commits intoRocketChat:developfrom
divyanshu-patil:fix/markdown-link

Conversation

@divyanshu-patil
Copy link
Copy Markdown

@divyanshu-patil divyanshu-patil commented Apr 23, 2026

Proposed changes

Remove the hardcoded color: colors.fontDefault from the Plain component so that it inherits color from its parent <Text> chain instead of overriding it.

In React Native, nested <Text> components inherit color from their parent unless an explicit color style is set. Plain was hardcoding colors.fontDefault (black), which broke color inheritance whenever Plain was rendered inside Bold or Italic, which in turn were rendered inside Link. This caused bold and italic text within links to appear black instead of the expected link blue.

Issue(s)

closes #7035

How to test or reproduce

  1. Open any chat with a markdown link that contains bold or italic text, e.g.:
    • [**bold link**](https://rocket.chat)
    • [_italic link_](https://rocket.chat)
  2. Before fix: the bold/italic portions appear black instead of the link color
  3. After fix: the entire link text (including bold/italic parts) renders in the correct link color

Screenshots

Before After
image image
image image
image image

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Improvement (non-breaking change which improves a current function)
  • New feature (non-breaking change which adds functionality)
  • Documentation update (if none of the other choices apply)

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
  • I have added necessary documentation (if applicable)
  • Any dependent changes have been merged and published in downstream modules

Further comments

The root cause was subtle — Bold and Italic themselves do not set a color, so they would have inherited the link blue correctly. However, they delegate PLAIN_TEXT block rendering to the Plain component, which was explicitly setting color: colors.fontDefault, overriding the inherited color from the Link parent.

Removing the hardcoded color from Plain is safe because fontDefault is already the system default text color — no standalone usage of Plain is affected visually. Color inheritance from any parent <Text> (such as Link) now works as expected.

Summary by CodeRabbit

  • Bug Fixes

    • Updated markdown plain text rendering to use inherited color styling from parent components instead of explicit application.
  • Tests

    • Added test cases for markdown emphasis markers within links and text style variations.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 23, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3e7e97cc-6624-4a2b-a3fd-30e8995d07c4

📥 Commits

Reviewing files that changed from the base of the PR and between a218a64 and bb9136c.

⛔ Files ignored due to path filters (2)
  • app/containers/markdown/__snapshots__/Markdown.test.tsx.snap is excluded by !**/*.snap
  • app/containers/message/__snapshots__/Message.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (1)
  • app/containers/markdown/Markdown.stories.tsx
📜 Recent review details
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use descriptive names for functions, variables, and classes that clearly convey their purpose
Write comments that explain the 'why' behind code decisions, not the 'what'
Keep functions small and focused on a single responsibility
Use const by default, let when reassignment is needed, and avoid var
Prefer async/await over .then() chains for handling asynchronous operations
Use explicit error handling with try/catch blocks for async operations
Avoid deeply nested code; refactor complex logic into helper functions

Files:

  • app/containers/markdown/Markdown.stories.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript for type safety; add explicit type annotations to function parameters and return types
Prefer interfaces over type aliases for defining object shapes in TypeScript
Use enums for sets of related constants rather than magic strings or numbers

**/*.{ts,tsx}: Use TypeScript with strict mode enabled and baseUrl set to app/ for module imports
Support iOS 13.4+ and Android 6.0+ as minimum target platforms

Files:

  • app/containers/markdown/Markdown.stories.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Use tabs for indentation with single quotes, 130 character line width, no trailing commas, and avoid arrow function parentheses when possible
Use ESLint with @rocket.chat/eslint-config base including React, React Native, TypeScript, and Jest plugins

Files:

  • app/containers/markdown/Markdown.stories.tsx
app/containers/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Create reusable UI components in app/containers/ directory

Files:

  • app/containers/markdown/Markdown.stories.tsx
🧠 Learnings (3)
📓 Common learnings
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6911
File: app/containers/markdown/Markdown.stories.tsx:104-104
Timestamp: 2026-03-15T13:55:47.880Z
Learning: In Rocket.Chat React Native's markdown parser, italic delimiters must have a space between the underscore and an `@` or `#` mention sigil for the mention to be parsed correctly. Using `_mention_` (no space) causes the mention to fall through as plain text; the correct form is `_ mention _`. This applies to story files like `app/containers/markdown/Markdown.stories.tsx` and any test/content strings that test italic-wrapped mentions.
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6808
File: app/containers/MessageComposer/components/ComposerInput.tsx:337-341
Timestamp: 2026-04-04T21:34:30.268Z
Learning: In Rocket.Chat React Native, the markdown composer's autocomplete insertion (ComposerInput.tsx onAutocompleteItemSelected) does NOT need to add a space between an underscore italic delimiter `_` and a `@` or `#` mention sigil. The web platform (using the same rocket.chat/message-parser) does not add such a space either, so parity with web is the correct behavior. The previous learning about "space between `_` and mention sigil" applies only to test/story file content strings, not to the composer's runtime autocomplete behavior.
📚 Learning: 2026-03-15T13:55:42.038Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6911
File: app/containers/markdown/Markdown.stories.tsx:104-104
Timestamp: 2026-03-15T13:55:42.038Z
Learning: In Rocket.Chat React Native, the markdown parser requires a space between the underscore wrapping italic text and a mention sigil (_ mention _ instead of _mention_). Ensure stories and tests that include italic-wrapped mentions follow this form to guarantee proper parsing. Specifically, for files like app/containers/markdown/Markdown.stories.tsx, and any test/content strings that exercise italic-mentions, use the pattern _ mention _ (with spaces) to prevent the mention from being treated as plain text. Validate any test strings or story content accordingly.

Applied to files:

  • app/containers/markdown/Markdown.stories.tsx
📚 Learning: 2026-04-04T21:34:30.268Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6808
File: app/containers/MessageComposer/components/ComposerInput.tsx:337-341
Timestamp: 2026-04-04T21:34:30.268Z
Learning: In Rocket.Chat React Native, the markdown composer's autocomplete insertion (ComposerInput.tsx onAutocompleteItemSelected) does NOT need to add a space between an underscore italic delimiter `_` and a `@` or `#` mention sigil. The web platform (using the same rocket.chat/message-parser) does not add such a space either, so parity with web is the correct behavior. The previous learning about "space between `_` and mention sigil" applies only to test/story file content strings, not to the composer's runtime autocomplete behavior.

Applied to files:

  • app/containers/markdown/Markdown.stories.tsx
🔇 Additional comments (2)
app/containers/markdown/Markdown.stories.tsx (2)

118-118: LGTM — good visual coverage for the link-color inheritance fix.

This story case ([*Bold* _italic_ ~strike~ Plain](https://rocket.chat) …) directly exercises the scenario from issue #7035: bold/italic/strike plus plain segments inside a link should all inherit the Link's fontInfo color after the Plain component stopped hardcoding colors.fontDefault. Also nicely validates that the trailing "and the text continues with default style" snaps back to the default color outside the link.


188-188: LGTM — covers the textStyle + link interaction.

Combined with the textStyle prop, this case verifies two things at once: (1) formatted segments inside the link inherit the link color rather than reverting to fontDefault, and (2) the trailing plain text still receives the caller-provided textStyle (red, size 10) without interference from the link. Good complement to the Links story at line 118.


Walkthrough

The Plain markdown component was refactored to remove explicit text color styling, allowing nested formatted text (bold, italic, strikethrough) within links to inherit the parent link color instead of being overridden. Storybook test cases were added to validate this behavior.

Changes

Cohort / File(s) Summary
Color Inheritance Fix
app/containers/markdown/components/Plain.tsx
Removed useTheme hook and explicit colors.fontDefault color styling. The Text element now relies on inherited color from parent components, with a comment explaining that explicit color would interfere with nested styled text in links.
Test Coverage
app/containers/markdown/Markdown.stories.tsx
Added two new Storybook test cases in Links and TextStyle cohorts to validate that emphasis markers (*...*, _..._, ~...~) inside link text are parsed correctly and that nested formatted text inherits the appropriate link and text styles.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: removing hardcoded color from Plain component to fix formatted text color inheritance in markdown links.
Linked Issues check ✅ Passed The PR directly addresses issue #7035 by removing the hardcoded color style that prevented nested formatted text from inheriting link colors, achieving the expected behavior.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the markdown link color inheritance issue: Plain.tsx removes hardcoded color, and Markdown.stories.tsx adds test cases validating the fix.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/containers/markdown/components/Plain.tsx`:
- Around line 12-18: Add a short inline comment in the Plain component (function
Plain) above the <Text> return explaining that we intentionally do NOT set a
color on styles.plainText and rely on React Native Text color inheritance (and
any MarkdownContext-provided textStyle) to avoid breaking nested color
semantics; mention this prevents reintroducing explicit color that caused bugs
and points maintainers to MarkdownContext/textStyle as the place to change color
if needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fa1e3bf0-ec5d-4da9-990b-46f6b8367c63

📥 Commits

Reviewing files that changed from the base of the PR and between 7643f53 and 3d74b65.

⛔ Files ignored due to path filters (5)
  • app/containers/UIKit/__snapshots__/UiKitMessage.test.tsx.snap is excluded by !**/*.snap
  • app/containers/UIKit/__snapshots__/UiKitModal.test.tsx.snap is excluded by !**/*.snap
  • app/containers/markdown/__snapshots__/Markdown.test.tsx.snap is excluded by !**/*.snap
  • app/containers/message/__snapshots__/Message.test.tsx.snap is excluded by !**/*.snap
  • app/views/RoomView/LoadMore/__snapshots__/LoadMore.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (1)
  • app/containers/markdown/components/Plain.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use descriptive names for functions, variables, and classes that clearly convey their purpose
Write comments that explain the 'why' behind code decisions, not the 'what'
Keep functions small and focused on a single responsibility
Use const by default, let when reassignment is needed, and avoid var
Prefer async/await over .then() chains for handling asynchronous operations
Use explicit error handling with try/catch blocks for async operations
Avoid deeply nested code; refactor complex logic into helper functions

Files:

  • app/containers/markdown/components/Plain.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript for type safety; add explicit type annotations to function parameters and return types
Prefer interfaces over type aliases for defining object shapes in TypeScript
Use enums for sets of related constants rather than magic strings or numbers

**/*.{ts,tsx}: Use TypeScript with strict mode enabled and baseUrl set to app/ for module imports
Support iOS 13.4+ and Android 6.0+ as minimum target platforms

Files:

  • app/containers/markdown/components/Plain.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Use tabs for indentation with single quotes, 130 character line width, no trailing commas, and avoid arrow function parentheses when possible
Use ESLint with @rocket.chat/eslint-config base including React, React Native, TypeScript, and Jest plugins

Files:

  • app/containers/markdown/components/Plain.tsx
app/containers/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Create reusable UI components in app/containers/ directory

Files:

  • app/containers/markdown/components/Plain.tsx
🧠 Learnings (4)
📓 Common learnings
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6911
File: app/containers/markdown/Markdown.stories.tsx:104-104
Timestamp: 2026-03-15T13:55:47.880Z
Learning: In Rocket.Chat React Native's markdown parser, italic delimiters must have a space between the underscore and an `@` or `#` mention sigil for the mention to be parsed correctly. Using `_mention_` (no space) causes the mention to fall through as plain text; the correct form is `_ mention _`. This applies to story files like `app/containers/markdown/Markdown.stories.tsx` and any test/content strings that test italic-wrapped mentions.
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6808
File: app/containers/MessageComposer/components/ComposerInput.tsx:337-341
Timestamp: 2026-04-04T21:34:30.268Z
Learning: In Rocket.Chat React Native, the markdown composer's autocomplete insertion (ComposerInput.tsx onAutocompleteItemSelected) does NOT need to add a space between an underscore italic delimiter `_` and a `@` or `#` mention sigil. The web platform (using the same rocket.chat/message-parser) does not add such a space either, so parity with web is the correct behavior. The previous learning about "space between `_` and mention sigil" applies only to test/story file content strings, not to the composer's runtime autocomplete behavior.
📚 Learning: 2026-04-22T22:57:58.545Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.ReactNative PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-22T22:57:58.545Z
Learning: Applies to app/theme.tsx : Define theming context in app/theme.tsx

Applied to files:

  • app/containers/markdown/components/Plain.tsx
📚 Learning: 2026-03-15T13:55:47.880Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6911
File: app/containers/markdown/Markdown.stories.tsx:104-104
Timestamp: 2026-03-15T13:55:47.880Z
Learning: In Rocket.Chat React Native's markdown parser, italic delimiters must have a space between the underscore and an `@` or `#` mention sigil for the mention to be parsed correctly. Using `_mention_` (no space) causes the mention to fall through as plain text; the correct form is `_ mention _`. This applies to story files like `app/containers/markdown/Markdown.stories.tsx` and any test/content strings that test italic-wrapped mentions.

Applied to files:

  • app/containers/markdown/components/Plain.tsx
📚 Learning: 2026-03-10T15:21:45.098Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7046
File: app/containers/InAppNotification/NotifierComponent.stories.tsx:46-75
Timestamp: 2026-03-10T15:21:45.098Z
Learning: In `app/containers/InAppNotification/NotifierComponent.tsx` (React Native, Rocket.Chat), `NotifierComponent` is exported as a Redux-connected component via `connect(mapStateToProps)`. The `isMasterDetail` prop is automatically injected from `state.app.isMasterDetail` and does not need to be passed explicitly at call sites or in Storybook stories that use the default (connected) export.

Applied to files:

  • app/containers/markdown/components/Plain.tsx
🔇 Additional comments (1)
app/containers/markdown/components/Plain.tsx (1)

15-15: Plain component color inheritance is by design and safe.

The missing color property in styles.plainText is intentional—it allows parent colors (particularly Link colors) to propagate correctly. The textStyle prop passed to the Markdown component by its caller provides the top-level color through MarkdownContext, and all Plain component instances are nested within parent Text wrappers (Bold, Italic, Strike, Emoji, Inline) that inherit from this context. Text will default to the system color if no explicit color is provided in the inheritance chain, which is standard React Native behavior. No standalone Plain usages exist in the codebase.

Comment thread app/containers/markdown/components/Plain.tsx
@divyanshu-patil divyanshu-patil marked this pull request as draft April 24, 2026 03:23
@divyanshu-patil divyanshu-patil marked this pull request as ready for review April 24, 2026 04:18
@divyanshu-patil divyanshu-patil changed the title fix: remove explicitly setting text color in markdown fix: Markdown color inside link is not correct Apr 24, 2026
@divyanshu-patil divyanshu-patil changed the title fix: Markdown color inside link is not correct fix: formatted text inside markdown links rendering in wrong color Apr 24, 2026
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/containers/markdown/components/Plain.tsx`:
- Around line 15-19: The comment in Plain.tsx has a casing/grammar nit: change
"setting a explicit text color..." to "Setting an explicit text color..." inside
the comment block above the component (the doc comment near the Plain component
/ file header) so the sentence starts with a capital letter and uses "an" before
"explicit"; update that comment text accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fa2ad680-ed61-4952-8ae5-07fe228c44a4

📥 Commits

Reviewing files that changed from the base of the PR and between cb5d753 and abce34f.

⛔ Files ignored due to path filters (3)
  • app/containers/markdown/__snapshots__/Markdown.test.tsx.snap is excluded by !**/*.snap
  • app/containers/message/__snapshots__/Message.test.tsx.snap is excluded by !**/*.snap
  • app/views/RoomView/LoadMore/__snapshots__/LoadMore.test.tsx.snap is excluded by !**/*.snap
📒 Files selected for processing (1)
  • app/containers/markdown/components/Plain.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use descriptive names for functions, variables, and classes that clearly convey their purpose
Write comments that explain the 'why' behind code decisions, not the 'what'
Keep functions small and focused on a single responsibility
Use const by default, let when reassignment is needed, and avoid var
Prefer async/await over .then() chains for handling asynchronous operations
Use explicit error handling with try/catch blocks for async operations
Avoid deeply nested code; refactor complex logic into helper functions

Files:

  • app/containers/markdown/components/Plain.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript for type safety; add explicit type annotations to function parameters and return types
Prefer interfaces over type aliases for defining object shapes in TypeScript
Use enums for sets of related constants rather than magic strings or numbers

**/*.{ts,tsx}: Use TypeScript with strict mode enabled and baseUrl set to app/ for module imports
Support iOS 13.4+ and Android 6.0+ as minimum target platforms

Files:

  • app/containers/markdown/components/Plain.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Use tabs for indentation with single quotes, 130 character line width, no trailing commas, and avoid arrow function parentheses when possible
Use ESLint with @rocket.chat/eslint-config base including React, React Native, TypeScript, and Jest plugins

Files:

  • app/containers/markdown/components/Plain.tsx
app/containers/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Create reusable UI components in app/containers/ directory

Files:

  • app/containers/markdown/components/Plain.tsx
🧠 Learnings (6)
📓 Common learnings
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6808
File: app/containers/MessageComposer/components/ComposerInput.tsx:337-341
Timestamp: 2026-04-04T21:34:30.268Z
Learning: In Rocket.Chat React Native, the markdown composer's autocomplete insertion (ComposerInput.tsx onAutocompleteItemSelected) does NOT need to add a space between an underscore italic delimiter `_` and a `@` or `#` mention sigil. The web platform (using the same rocket.chat/message-parser) does not add such a space either, so parity with web is the correct behavior. The previous learning about "space between `_` and mention sigil" applies only to test/story file content strings, not to the composer's runtime autocomplete behavior.
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6911
File: app/containers/markdown/Markdown.stories.tsx:104-104
Timestamp: 2026-03-15T13:55:47.880Z
Learning: In Rocket.Chat React Native's markdown parser, italic delimiters must have a space between the underscore and an `@` or `#` mention sigil for the mention to be parsed correctly. Using `_mention_` (no space) causes the mention to fall through as plain text; the correct form is `_ mention _`. This applies to story files like `app/containers/markdown/Markdown.stories.tsx` and any test/content strings that test italic-wrapped mentions.
📚 Learning: 2026-04-22T22:57:58.545Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.ReactNative PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-04-22T22:57:58.545Z
Learning: Applies to app/theme.tsx : Define theming context in app/theme.tsx

Applied to files:

  • app/containers/markdown/components/Plain.tsx
📚 Learning: 2026-04-04T21:34:30.268Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6808
File: app/containers/MessageComposer/components/ComposerInput.tsx:337-341
Timestamp: 2026-04-04T21:34:30.268Z
Learning: In Rocket.Chat React Native, the markdown composer's autocomplete insertion (ComposerInput.tsx onAutocompleteItemSelected) does NOT need to add a space between an underscore italic delimiter `_` and a `@` or `#` mention sigil. The web platform (using the same rocket.chat/message-parser) does not add such a space either, so parity with web is the correct behavior. The previous learning about "space between `_` and mention sigil" applies only to test/story file content strings, not to the composer's runtime autocomplete behavior.

Applied to files:

  • app/containers/markdown/components/Plain.tsx
📚 Learning: 2026-04-07T17:49:25.836Z
Learnt from: CR
Repo: RocketChat/Rocket.Chat.ReactNative PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-07T17:49:25.836Z
Learning: Applies to **/*.{js,ts,jsx,tsx} : Write comments that explain the 'why' behind code decisions, not the 'what'

Applied to files:

  • app/containers/markdown/components/Plain.tsx
📚 Learning: 2026-03-15T13:55:47.880Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6911
File: app/containers/markdown/Markdown.stories.tsx:104-104
Timestamp: 2026-03-15T13:55:47.880Z
Learning: In Rocket.Chat React Native's markdown parser, italic delimiters must have a space between the underscore and an `@` or `#` mention sigil for the mention to be parsed correctly. Using `_mention_` (no space) causes the mention to fall through as plain text; the correct form is `_ mention _`. This applies to story files like `app/containers/markdown/Markdown.stories.tsx` and any test/content strings that test italic-wrapped mentions.

Applied to files:

  • app/containers/markdown/components/Plain.tsx
📚 Learning: 2026-03-10T15:21:45.098Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 7046
File: app/containers/InAppNotification/NotifierComponent.stories.tsx:46-75
Timestamp: 2026-03-10T15:21:45.098Z
Learning: In `app/containers/InAppNotification/NotifierComponent.tsx` (React Native, Rocket.Chat), `NotifierComponent` is exported as a Redux-connected component via `connect(mapStateToProps)`. The `isMasterDetail` prop is automatically injected from `state.app.isMasterDetail` and does not need to be passed explicitly at call sites or in Storybook stories that use the default (connected) export.

Applied to files:

  • app/containers/markdown/components/Plain.tsx
🔇 Additional comments (1)
app/containers/markdown/components/Plain.tsx (1)

12-24: LGTM on the inheritance fix.

Removing the explicit color correctly lets Plain inherit color from parent <Text> (e.g., Link setting fontInfo), which resolves issue #7035 for bold/italic segments inside links. The accompanying comment now documents the rationale per the prior review feedback.

Comment on lines +15 to +19
/**
* Note: Don't set color here — React Native automatically inherits it from the closest parent Text.
* setting a explicit text color would break bold/italic text inside links, which need to inherit the link's color.
* See issue `#7035`.
*/
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Minor grammar/casing nit in the new comment.

"setting a explicit" should be "Setting an explicit" (capitalize sentence start, use "an" before a vowel sound).

✏️ Proposed fix
 		/**
 		 * Note: Don't set color here — React Native automatically inherits it from the closest parent Text.
-		 * setting a explicit text color would break bold/italic text inside links, which need to inherit the link's color.
+		 * Setting an explicit text color would break bold/italic text inside links, which need to inherit the link's color.
 		 * See issue `#7035`.
 		 */
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/containers/markdown/components/Plain.tsx` around lines 15 - 19, The
comment in Plain.tsx has a casing/grammar nit: change "setting a explicit text
color..." to "Setting an explicit text color..." inside the comment block above
the component (the doc comment near the Plain component / file header) so the
sentence starts with a capital letter and uses "an" before "explicit"; update
that comment text accordingly.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
app/containers/markdown/components/inline/Link.tsx (1)

60-76: ⚠️ Potential issue | 🟡 Minor

Add a key prop to the mapped children.

blockArray.map(...) returns React elements without keys, which will trigger React's list-key warning. Using the index is fine here since the label array is stable in order.

🛠️ Proposed fix
-			{(block => {
-				const blockArray = Array.isArray(block) ? block : [block];
-				return blockArray.map(blockInArray => {
-					switch (blockInArray.type) {
-						case 'PLAIN_TEXT':
-							return blockInArray.value;
-						case 'STRIKE':
-							return <Strike value={blockInArray.value} showUnderline />;
-						case 'ITALIC':
-							return <Italic value={blockInArray.value} />;
-						case 'BOLD':
-							return <Bold value={blockInArray.value} />;
-						default:
-							return null;
-					}
-				});
-			})(label)}
+			{(block => {
+				const blockArray = Array.isArray(block) ? block : [block];
+				return blockArray.map((blockInArray, index) => {
+					switch (blockInArray.type) {
+						case 'PLAIN_TEXT':
+							return blockInArray.value;
+						case 'STRIKE':
+							return <Strike key={index} value={blockInArray.value} showUnderline />;
+						case 'ITALIC':
+							return <Italic key={index} value={blockInArray.value} />;
+						case 'BOLD':
+							return <Bold key={index} value={blockInArray.value} />;
+						default:
+							return null;
+					}
+				});
+			})(label)}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/containers/markdown/components/inline/Link.tsx` around lines 60 - 76, The
mapped children returned by the IIFE using blockArray.map are missing React
keys; update the map callback in the inline Link component (the blockArray =>
blockArray.map block that renders PLAIN_TEXT, Strike, Italic, Bold) to pass a
key prop (using the map index is acceptable) to each returned element/string so
React list-key warnings are eliminated; ensure keys are applied to the JSX
elements returned for 'STRIKE', 'ITALIC', 'BOLD' and also to the plain text
return (wrap in a fragment or string with a key) while keeping the existing
switch logic and the same component names (Strike, Italic, Bold).
🧹 Nitpick comments (1)
app/containers/markdown/components/inline/Link.tsx (1)

18-21: Rename showlineThroughshowLineThrough for camelCase consistency.

The prop name concatenates line and Through with a lowercase l, which breaks camelCase and reads inconsistently next to the sibling prop showUnderline. Rename for readability and to match the rest of the codebase's prop naming conventions. The change propagates to Strike.tsx (line 20) where it is forwarded.

As per coding guidelines: "Use descriptive names for functions, variables, and classes that clearly convey their purpose."

🛠️ Proposed fix (Link.tsx)
 interface ILinkProps {
 	value: LinkProps['value'];
-	showlineThrough?: boolean;
+	showLineThrough?: boolean;
 }

-const Link = ({ value, showlineThrough }: ILinkProps) => {
+const Link = ({ value, showLineThrough }: ILinkProps) => {
 	...
-				{ color: themes[theme].fontInfo, textDecorationLine: showlineThrough ? 'underline line-through' : 'underline' }
+				{ color: themes[theme].fontInfo, textDecorationLine: showLineThrough ? 'underline line-through' : 'underline' }

And in Strike.tsx line 20:

-						return <Link showlineThrough value={block.value} />;
+						return <Link showLineThrough value={block.value} />;

Also applies to: 67-67

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/containers/markdown/components/inline/Link.tsx` around lines 18 - 21,
Rename the prop showlineThrough to showLineThrough across the Link component and
its prop interface (ILinkProps) to follow camelCase; update the Link functional
component signature and all usages/forwards (including where Link forwards it to
Strike.tsx) to use showLineThrough, and update any references at the other call
site(s) around line 67 so types and props remain consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/containers/markdown/components/inline/Strike.tsx`:
- Around line 17-32: The mapped children inside value.map in the Strike
component are missing React keys; update the switch return paths for Link,
Plain, Bold, Italic (and the MENTION_CHANNEL Plain) to include a key prop (using
the map index as a fallback) so each element returned from value.map has a
stable unique key and eliminates the React key warning.

---

Outside diff comments:
In `@app/containers/markdown/components/inline/Link.tsx`:
- Around line 60-76: The mapped children returned by the IIFE using
blockArray.map are missing React keys; update the map callback in the inline
Link component (the blockArray => blockArray.map block that renders PLAIN_TEXT,
Strike, Italic, Bold) to pass a key prop (using the map index is acceptable) to
each returned element/string so React list-key warnings are eliminated; ensure
keys are applied to the JSX elements returned for 'STRIKE', 'ITALIC', 'BOLD' and
also to the plain text return (wrap in a fragment or string with a key) while
keeping the existing switch logic and the same component names (Strike, Italic,
Bold).

---

Nitpick comments:
In `@app/containers/markdown/components/inline/Link.tsx`:
- Around line 18-21: Rename the prop showlineThrough to showLineThrough across
the Link component and its prop interface (ILinkProps) to follow camelCase;
update the Link functional component signature and all usages/forwards
(including where Link forwards it to Strike.tsx) to use showLineThrough, and
update any references at the other call site(s) around line 67 so types and
props remain consistent.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 4d76be40-ace8-4eae-873d-4c8ae6c7f1a4

📥 Commits

Reviewing files that changed from the base of the PR and between abce34f and a218a64.

📒 Files selected for processing (2)
  • app/containers/markdown/components/inline/Link.tsx
  • app/containers/markdown/components/inline/Strike.tsx
📜 Review details
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{js,ts,jsx,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{js,ts,jsx,tsx}: Use descriptive names for functions, variables, and classes that clearly convey their purpose
Write comments that explain the 'why' behind code decisions, not the 'what'
Keep functions small and focused on a single responsibility
Use const by default, let when reassignment is needed, and avoid var
Prefer async/await over .then() chains for handling asynchronous operations
Use explicit error handling with try/catch blocks for async operations
Avoid deeply nested code; refactor complex logic into helper functions

Files:

  • app/containers/markdown/components/inline/Strike.tsx
  • app/containers/markdown/components/inline/Link.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use TypeScript for type safety; add explicit type annotations to function parameters and return types
Prefer interfaces over type aliases for defining object shapes in TypeScript
Use enums for sets of related constants rather than magic strings or numbers

**/*.{ts,tsx}: Use TypeScript with strict mode enabled and baseUrl set to app/ for module imports
Support iOS 13.4+ and Android 6.0+ as minimum target platforms

Files:

  • app/containers/markdown/components/inline/Strike.tsx
  • app/containers/markdown/components/inline/Link.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx,js,jsx}: Use tabs for indentation with single quotes, 130 character line width, no trailing commas, and avoid arrow function parentheses when possible
Use ESLint with @rocket.chat/eslint-config base including React, React Native, TypeScript, and Jest plugins

Files:

  • app/containers/markdown/components/inline/Strike.tsx
  • app/containers/markdown/components/inline/Link.tsx
app/containers/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Create reusable UI components in app/containers/ directory

Files:

  • app/containers/markdown/components/inline/Strike.tsx
  • app/containers/markdown/components/inline/Link.tsx
🧠 Learnings (3)
📓 Common learnings
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6911
File: app/containers/markdown/Markdown.stories.tsx:104-104
Timestamp: 2026-03-15T13:55:47.880Z
Learning: In Rocket.Chat React Native's markdown parser, italic delimiters must have a space between the underscore and an `@` or `#` mention sigil for the mention to be parsed correctly. Using `_mention_` (no space) causes the mention to fall through as plain text; the correct form is `_ mention _`. This applies to story files like `app/containers/markdown/Markdown.stories.tsx` and any test/content strings that test italic-wrapped mentions.
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6808
File: app/containers/MessageComposer/components/ComposerInput.tsx:337-341
Timestamp: 2026-04-04T21:34:30.268Z
Learning: In Rocket.Chat React Native, the markdown composer's autocomplete insertion (ComposerInput.tsx onAutocompleteItemSelected) does NOT need to add a space between an underscore italic delimiter `_` and a `@` or `#` mention sigil. The web platform (using the same rocket.chat/message-parser) does not add such a space either, so parity with web is the correct behavior. The previous learning about "space between `_` and mention sigil" applies only to test/story file content strings, not to the composer's runtime autocomplete behavior.
📚 Learning: 2026-03-15T13:55:47.880Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6911
File: app/containers/markdown/Markdown.stories.tsx:104-104
Timestamp: 2026-03-15T13:55:47.880Z
Learning: In Rocket.Chat React Native's markdown parser, italic delimiters must have a space between the underscore and an `@` or `#` mention sigil for the mention to be parsed correctly. Using `_mention_` (no space) causes the mention to fall through as plain text; the correct form is `_ mention _`. This applies to story files like `app/containers/markdown/Markdown.stories.tsx` and any test/content strings that test italic-wrapped mentions.

Applied to files:

  • app/containers/markdown/components/inline/Strike.tsx
📚 Learning: 2026-04-04T21:34:30.268Z
Learnt from: Rohit3523
Repo: RocketChat/Rocket.Chat.ReactNative PR: 6808
File: app/containers/MessageComposer/components/ComposerInput.tsx:337-341
Timestamp: 2026-04-04T21:34:30.268Z
Learning: In Rocket.Chat React Native, the markdown composer's autocomplete insertion (ComposerInput.tsx onAutocompleteItemSelected) does NOT need to add a space between an underscore italic delimiter `_` and a `@` or `#` mention sigil. The web platform (using the same rocket.chat/message-parser) does not add such a space either, so parity with web is the correct behavior. The previous learning about "space between `_` and mention sigil" applies only to test/story file content strings, not to the composer's runtime autocomplete behavior.

Applied to files:

  • app/containers/markdown/components/inline/Strike.tsx
🔇 Additional comments (2)
app/containers/markdown/components/inline/Strike.tsx (1)

13-14: LGTM — decoration toggle is correctly scoped.

Gating 'underline line-through' vs 'line-through' on showUnderline lets a parent Link preserve its underline when wrapping a Strike, while standalone strikes keep their original look. 'underline line-through' is a valid TextStyle['textDecorationLine'] value in React Native 0.81.

app/containers/markdown/components/inline/Link.tsx (1)

51-57: LGTM — link color + decoration now flows correctly.

Keeping color on the Link's outer Text while Plain no longer sets a color means nested Bold/Italic/Plain correctly inherit themes[theme].fontInfo, which is exactly the fix for issue #7035. The conditional on textDecorationLine also preserves the underline when a Strike wraps a Link.

Comment thread app/containers/markdown/components/inline/Strike.tsx Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Formatted link text color is wrong

1 participant