textual icon indicating copy to clipboard operation
textual copied to clipboard

`Widget.loading` can cause widgets to disappear

Open davep opened this issue 2 years ago • 2 comments

This might be a case of Widget.loading needing some more work, or the documentation for the property needing expanding, but right now using the widget loading property can have results that are counter what you'd expect given the documentation:

If set to True this widget will temporarily be replaced with a loading indicator.

This would suggest that a loading indicator would appear in a space the same dimension as the widget it's overlaying. With some widgets, that isn't the case. As a sample:

from textual.app import App, ComposeResult
from textual.widgets import Static, Label, Footer, Button

class Fixed(Label):

    DEFAULT_CSS = """
    Fixed {
        width: 1fr;
        height: 10;
        background: teal;
    }
    """

class LabelLoadingTestApp(App[None]):

    BINDINGS = [
        ("space", "toggle", "Toggle the loading indicator"),
    ]

    def compose(self) -> ComposeResult:
        yield Label()
        yield Label("This is a test")
        yield Static()
        yield Static("This is a test")
        yield Footer()
        yield Button("")
        yield Button("Foo")
        yield Fixed("This is fixed")

    def action_toggle(self) -> None:
        for widget in self.query("Screen > *").results():
            widget.loading = not widget.loading

if __name__ == "__main__":
    LabelLoadingTestApp().run()

without loading, the screen looks like this:

Screenshot 2023-12-29 at 16 30 30

when you toggle on loading, it looks like this:

Screenshot 2023-12-29 at 16 30 34

davep avatar Dec 29 '23 16:12 davep

For anyone who might stumble across this issue, you can workaround this by adding a min width/height to your widgets, for example:

class LabelLoadingTestApp(App[None]):
    CSS = """
    Static, Label {
        min-height: 1;
        min-width: 9;
    }

    Button {
        min-height: 3;
    }
    """

TomJGooding avatar Apr 01 '24 18:04 TomJGooding

The loading indicator works with containers, but when applied to simple widgets it transforms them into containers that don't render because they have no dimensions.

I don't think there is an easy fix for this one. We likely need some additional mechanism to change how a widget is rendered without changing its dimensions.

Worth doing, but not a small job.

Parking for now.

willmcgugan avatar Jul 22 '24 09:07 willmcgugan