Skip to content

Tabs widget does not support Rich #5635

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
charles-001 opened this issue Mar 10, 2025 · 6 comments · Fixed by #5657
Closed

Tabs widget does not support Rich #5635

charles-001 opened this issue Mar 10, 2025 · 6 comments · Fixed by #5657

Comments

@charles-001
Copy link

Rich theme (and Rich in general) is not being supported with Tabs widget using v2.0.0. Also, emojis are not working anymore.

I tried to use from_markup, but it isn't working:

def on_mount(self) -> None:
        self.query_one(Tabs).add_tab(Text.from_markup("[special_red]Special Red Again"))

Error:
AttributeError: 'Text' object has no attribute 'translate'

MRE:

from rich.text import Text
from rich.theme import Theme as RichTheme
from textual.app import App, ComposeResult
from textual.widgets import Tabs

NAMES = [
    "[special_red]Special Red",
    "[red]Red",
    "[yellow]Yellow",
    ":skull: Skull",
]


class MREApp(App):

    def __init__(self):
        super().__init__()

        theme = RichTheme(
            {
                "special_red": "#ff5e5e",
            }
        )
        self.console.push_theme(theme)

    def compose(self) -> ComposeResult:
        yield Tabs(*NAMES)


if __name__ == "__main__":
    app = MREApp()
    app.run()
Copy link

We found the following entries in the FAQ which you may find helpful:

Feel free to close this issue if you found an answer in the FAQ. Otherwise, please give us a little time to review.

This is an automated reply, generated by FAQtory

@TomJGooding
Copy link
Contributor

It looks like the problem is a mismatch between the expected types for Tabs and Tab. While Tabs still expects a TextType, the Tab was updated to expect the new ContentType1.

I'm not sure what the correct fix is as it needs a maintainer to confirm the correct update to the types. But here's a workaround in the meantime:

from textual.app import App, ComposeResult
from textual.content import Content
from textual.widgets import Tab, Tabs


class ExampleApp(App):
    def compose(self) -> ComposeResult:
        yield Tabs(
            # workaround for https://github.com/Textualize/textual/issues/5635
            Tab(Content.from_rich_text("[green]Markup & emoji :smiley:"))
        )


if __name__ == "__main__":
    app = ExampleApp()
    app.run()

Footnotes

  1. See the Releases page and the docs for more info about Textual's new Content object.

@charles-001
Copy link
Author

It looks like the problem is a mismatch between the expected types for Tabs and Tab. While Tabs still expects a TextType, the Tab was updated to expect the new ContentType1.

I'm not sure what the correct fix is as it needs a maintainer to confirm the correct update to the types. But here's a workaround in the meantime:

from textual.app import App, ComposeResult
from textual.content import Content
from textual.widgets import Tab, Tabs

class ExampleApp(App):
def compose(self) -> ComposeResult:
yield Tabs(
# workaround for #5635
Tab(Content.from_rich_text("[green]Markup & emoji 😃"))
)

if name == "main":
app = ExampleApp()
app.run()

Footnotes

  1. See the Releases page and the docs for more info about Textual's new Content object.

Hi @TomJGooding - thanks for looking into this. That does work, but still doesn't support Rich Themes :/

@TomJGooding
Copy link
Contributor

TomJGooding commented Mar 11, 2025

There's been some major changes in Textual recently, including its own theming and content system. Since this moves away from rendering with Rich objects, I'm afraid using Rich Themes this way is likely no longer supported (but this really needs a maintainer to confirm).

You might want to explore app-specific variables as a possible alternative. This allows mapping a variable name to a value, which can also then be overridden by a Textual theme.

@charles-001
Copy link
Author

Yeah, I read about that. The one thing as well is emojis are not natively supported using Content. If I want to use 💀, I have to use the Emoji() function. Text from Rich is just a great way to get all the things you want supported in one nice little package.

TomJGooding added a commit to TomJGooding/textual that referenced this issue Mar 11, 2025
Revert the type of the `Tab` label to `TextType`.

Currently there's a mismatch between the expected types for `Tabs` and
`Tab`, which can cause the app to crash. While `Tabs` still expects a
`TextType`, the `Tab` was recently updated to expect a `ContentType`.

Since the tabs documentation is based on using `Text` objects, I think
reverting this changes makes sense, especially given that `Tab` seems to
be the only widget that now exclusively expects `ContentType`.

This might _technically_ be a breaking change, but the current
incompatibility of types means that the tabs were broken anyway.

Fixes Textualize#5635.
Copy link

Don't forget to star the repository!

Follow @textualizeio for Textual updates.

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 a pull request may close this issue.

2 participants