fix: formatted text inside markdown links rendering in wrong color#7232
fix: formatted text inside markdown links rendering in wrong color#7232divyanshu-patil wants to merge 9 commits intoRocketChat:developfrom
Conversation
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (2)
📒 Files selected for processing (1)
📜 Recent review details🧰 Additional context used📓 Path-based instructions (4)**/*.{js,ts,jsx,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{ts,tsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
app/containers/**/*.{ts,tsx}📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (3)📓 Common learnings📚 Learning: 2026-03-15T13:55:42.038ZApplied to files:
📚 Learning: 2026-04-04T21:34:30.268ZApplied to files:
🔇 Additional comments (2)
WalkthroughThe Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ 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. Comment |
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (5)
app/containers/UIKit/__snapshots__/UiKitMessage.test.tsx.snapis excluded by!**/*.snapapp/containers/UIKit/__snapshots__/UiKitModal.test.tsx.snapis excluded by!**/*.snapapp/containers/markdown/__snapshots__/Markdown.test.tsx.snapis excluded by!**/*.snapapp/containers/message/__snapshots__/Message.test.tsx.snapis excluded by!**/*.snapapp/views/RoomView/LoadMore/__snapshots__/LoadMore.test.tsx.snapis 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-configbase 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.plainTextis intentional—it allows parent colors (particularly Link colors) to propagate correctly. ThetextStyleprop passed to theMarkdowncomponent by its caller provides the top-level color throughMarkdownContext, and allPlaincomponent instances are nested within parentTextwrappers (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 standalonePlainusages exist in the codebase.
500932a to
6afef9d
Compare
6afef9d to
abce34f
Compare
There was a problem hiding this comment.
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
⛔ Files ignored due to path filters (3)
app/containers/markdown/__snapshots__/Markdown.test.tsx.snapis excluded by!**/*.snapapp/containers/message/__snapshots__/Message.test.tsx.snapis excluded by!**/*.snapapp/views/RoomView/LoadMore/__snapshots__/LoadMore.test.tsx.snapis 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-configbase 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
colorcorrectly letsPlaininherit color from parent<Text>(e.g.,LinksettingfontInfo), which resolves issue#7035for bold/italic segments inside links. The accompanying comment now documents the rationale per the prior review feedback.
| /** | ||
| * 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`. | ||
| */ |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 | 🟡 MinorAdd a
keyprop to the mapped children.
blockArray.map(...)returns React elements withoutkeys, 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: RenameshowlineThrough→showLineThroughfor camelCase consistency.The prop name concatenates
lineandThroughwith a lowercasel, which breaks camelCase and reads inconsistently next to the sibling propshowUnderline. Rename for readability and to match the rest of the codebase's prop naming conventions. The change propagates toStrike.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.tsxline 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
📒 Files selected for processing (2)
app/containers/markdown/components/inline/Link.tsxapp/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.tsxapp/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.tsxapp/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-configbase including React, React Native, TypeScript, and Jest plugins
Files:
app/containers/markdown/components/inline/Strike.tsxapp/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.tsxapp/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'onshowUnderlinelets a parentLinkpreserve its underline when wrapping aStrike, while standalone strikes keep their original look.'underline line-through'is a validTextStyle['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
coloron theLink's outerTextwhilePlainno longer sets a color means nestedBold/Italic/Plaincorrectly inheritthemes[theme].fontInfo, which is exactly the fix for issue#7035. The conditional ontextDecorationLinealso preserves the underline when aStrikewraps aLink.
a218a64 to
c39323d
Compare
Proposed changes
Remove the hardcoded
color: colors.fontDefaultfrom thePlaincomponent 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 explicitcolorstyle is set.Plainwas hardcodingcolors.fontDefault(black), which broke color inheritance wheneverPlainwas rendered insideBoldorItalic, which in turn were rendered insideLink. 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
[**bold link**](https://rocket.chat)[_italic link_](https://rocket.chat)Screenshots
Types of changes
Checklist
Further comments
The root cause was subtle —
BoldandItalicthemselves do not set a color, so they would have inherited the link blue correctly. However, they delegatePLAIN_TEXTblock rendering to thePlaincomponent, which was explicitly settingcolor: colors.fontDefault, overriding the inherited color from theLinkparent.Removing the hardcoded color from
Plainis safe becausefontDefaultis already the system default text color — no standalone usage ofPlainis affected visually. Color inheritance from any parent<Text>(such asLink) now works as expected.Summary by CodeRabbit
Bug Fixes
Tests