text_view: Follow the container's text color so rich text reads in filled bubbles - #3329
Open
Bombatomica64 wants to merge 2 commits into
Open
Bombatomica64 wants to merge 2 commits into
Bombatomica64 wants to merge 2 commits into
Conversation
TextView paints its own text color, so a TextView inside a Filled bubble drew the theme foreground on the primary surface (white on white in dark mode), with primary links and accent code backgrounds equally hidden. BubbleVariant::text_view_style returns a TextViewStyle whose text color matches the bubble; for Filled it also derives link and code colors from the text color. The per-variant text color now lives in one place and is used by both the bubble surface and the style. Closes longbridge#3326 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This was referenced Sep 30, 2026
Contributor
Author
|
I've added before/after screen recordings to the Screenshot section (Android, dark theme, Kit 0.7.0 with and without this diff). Before pr3329-before.mp4After pr3329-after.mp4 |
…::text_view_style Replace the per-variant `BubbleVariant::text_view_style` with inheritance in `TextView`: a view without an explicit style takes the text color its container sets. On a surface inverted from the page, such as a `Filled` bubble, links, muted text, code and table backgrounds, borders and selection are derived from that color too, the dark flag flips, and the installed syntax highlighter is left out. `TextViewDefaults::with_inherit_text_color` turns this on; Component enables it because its Root sets the theme foreground. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3326
Description
TextViewpaints its own text color on its root, so it does not inherit the color aBubblesets on its content. In aFilledbubble, Markdown is drawn in the themeforegroundon theprimarysurface: white on white in dark mode. Links (primary) disappear too, and code backgrounds (accent/muted) are tuned for the page, not for aprimarysurface.The first revision added
BubbleVariant::text_view_style(cx), which callers passed to everyTextViewin a bubble. That repeated the bubble's variant at each call site and would have needed the same method on every other colored container, so the fix now lives inTextViewitself:TextViewwithout an explicit.style()takes the text color its container sets (window.text_style().color, or its own.text_color()).Filled, whoseprimaryfill is dark on a light page and light on a dark one): when the inherited color is more than 0.6 away from the style's foreground in Oklab lightness, links, muted text (block quotes), code and inline-code backgrounds, borders, selection, the table header and body backgrounds are all derived from it. The dark flag flips, so todo checkboxes pick the right icon. The installed syntax highlighter is left out, since its colors are made for the page.TextViewDefaults::with_inherit_text_color(true)enables it. Component turns it on because its Root sets the theme foreground. A Base-only window that sets no root text color would otherwise inherit GPUI's default black.Bubbleneeds no change, since it already sets each variant's text color.Screenshot
Filled, Secondary and Destructive bubbles with a link, inline code, a block quote, a todo list, a fenced code block and a table, in the light and dark themes, read correctly. Before this change, the Filled bubble's text, link and table were invisible in dark mode.
Public API
gpui-base
gpui_base::TextViewDefaults::with_inherit_text_color(self, inherit: bool) -> Self: makes text views without an explicit style follow the text color their container sets, adapting every color on an inverted surface.gpui_base::TextViewDefaults::inherit_text_color(&self) -> bool: whether that is enabled.gpui-component
No items are added. Text views now follow the container's text color by default, because Component installs
with_inherit_text_color(true).How to Test
cargo test -p gpui-base -p gpui-componenttext_color_of_a_matching_surface_only_replaces_the_body_textandtext_color_of_an_inverted_surface_derives_every_color_from_itcover the color derivation in both themes.text_view_follows_the_text_color_of_its_containerchecks that a view under a container withprimary_foregroundtext resolves to that color with a flipped dark flag, and that an explicit.style()still wins.Bubble::new().child(TextView::markdown("reply", text))with links, code, quotes, todos and a table in each variant, and toggle the theme.Checklist
cargo runfor story tests related to the changes.🤖 Generated with Claude Code