`Widget.loading` can cause widgets to disappear
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:
when you toggle on loading, it looks like this:
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;
}
"""
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.