-
Hi All, I have been using textual for the past few days and I really enjoy it and am excited to design applications with it for my day-to-day use. In learning the package I have run into a question (two included here technically) that I can't seem to find any information on. (Keep in mind I am definitely not a master programmer as I have mostly worked with scripting to this point) I've taken the package demo code and reduced it in order to reproduce the issue I am running into in an easily identifiable manner: When the Select widget is clicked on by the user it scrolls the parent container to center Select widget on the screen -- and I can't find out how to disable that behavior. The Select widget should have space on screen to display without scrolling, but no matter where the Select widget is, it scrolls to center it on screen rather that offset by the parent container's sizing I also had a secondary related question for the Select widget such as how to make it lose focus when the click is anywhere else on the screen - if you open it then use a quick access link you'll see that it stays opened at the bottom of the screen until a choice is made. The code: The Python code [yourchoice].pyfrom __future__ import annotations
from rich.console import RenderableType
from textual.app import App, ComposeResult
from textual.binding import Binding
from textual.containers import Container, ScrollableContainer
from textual.widgets import Button, Footer, Header, Select, Static, TextLog, Placeholder, Markdown
__ISSUE_MD__ = """
## Question #1 -- How do I make selecting the option list _NOT_ scroll the parent container
This issue is that even when the Select widget has space on screen to display, it still scrolls which mis-aligns
the parent container on the screen.
I am trying to find a way to keep the section aligned while still having the drop-down expand if needed
to a certain degree, maybe _X_ items long or a max-height value
## Question #2 - What's the best way for the Select widget to _lose_ focus when the user clicks elsewhere?
Example:
If you open the dropdown then click a quick-access link on the left the dropdown menu doesn't naturally close
What's the ideal way to close the list when _anything_ else is clicked?
(I am assuming by overriding the on_click function and checking for focus somehow)
"""
WELCOME_MD = """
## Textual Layout Issue / Question
**Hello**! Textual is amazing and I'm having so much fun learning it!
There are _so_ _many_ potential projects I can use it for!
"""
WIDGETS_MD = """
Textual widgets are _amazingly_ powerful interactive components.
I've been working on building my own -> That's where I found this and couldn't figure it
out
"""
class Welcome(Container):
def compose(self) -> ComposeResult:
yield Markdown(WELCOME_MD)
yield Button("Start", variant="success")
def on_button_pressed(self, event: Button.Pressed) -> None:
self.app.add_note("[b magenta]Start!")
self.app.query_one(".location-first").scroll_visible(duration=0.5, top=True)
class Title(Static):
pass
class Body(ScrollableContainer):
pass
class QuickAccess(Container):
pass
class AboveFold(Container):
pass
class Section(Container):
pass
class SectionTitle(Static):
pass
class Column(Container):
pass
class TextContent(Static):
pass
class LocationLink(Static):
def __init__(self, label: str, reveal: str) -> None:
super().__init__(label)
self.reveal = reveal
def on_click(self) -> None:
self.app.query_one(self.reveal).scroll_visible(top=True, duration=0.5)
self.app.add_note(f"Scrolling to [b]{self.reveal}[/b]")
class DemoApp(App[None]):
CSS_PATH = "demo.css"
TITLE = "Question - Is this a bug?"
BINDINGS = [
("f1", "app.toggle_class('TextLog', '-hidden')", "Notes"),
Binding("ctrl+c,ctrl+q", "app.quit", "Quit", show=True),
]
# Overloaded the __init__ section so that we could enable watching the CSS file
def __init__(self):
super().__init__(watch_css=True)
# I lef the note section in for debugging, but wasn't sure what exactly to log while modifying the CSS
def add_note(self, renderable: RenderableType) -> None:
self.query_one(TextLog).write(renderable)
def compose(self) -> ComposeResult:
yield Container(
Header(show_clock=False),
TextLog(classes="-hidden", wrap=False, highlight=True, markup=True),
Body(
QuickAccess(
LocationLink("Home", ".location-top"),
LocationLink("Bugged Section", ".location-widgets"),
),
AboveFold(Welcome(), classes="location-top"),
Column(
Section(
SectionTitle("Example Section Title"),
Markdown(WIDGETS_MD),
Placeholder("-- Example space of n+ other widgets and their children --"),
Select([("Example Selectable Option", 1)],
prompt="Please choose an option.. (And watch it scroll)"),
Markdown(__ISSUE_MD__, id="issue-markdown"),
id="bugged-section"
),
classes="location-widgets location-first",
)
)
)
yield Footer()
def on_mount(self) -> None:
self.add_note("?? Question ?? is running")
self.query_one("Welcome Button", Button).focus()
app = DemoApp()
if __name__ == "__main__":
app.run() The reduced CSS code: demo.css* {transition: background 500ms in_out_cubic, color 500ms in_out_cubic;}
Screen {
layers: base overlay notes notifications;
overflow: hidden;
}
Body {
height: 100%;
overflow-y: scroll;
width: 100%;
background: $surface;
}
AboveFold {
width: 100%;
height: 100%;
align: center middle;
}
Welcome {
background: $boost;
height: auto;
max-width: 100;
min-width: 40;
border: wide $primary;
padding: 1 2;
margin: 1 2;
box-sizing: border-box;
}
Welcome Button {
width: 100%;
margin-top: 1;
}
Column {
height: auto;
min-height: 100vh;
align: center top;
overflow: hidden;
}
Screen>Container {
height: 100%;
overflow: hidden;
}
TextLog {
background: $surface;
color: $text;
height: 50vh;
dock: bottom;
layer: notes;
border-top: hkey $primary;
offset-y: 0;
transition: offset 400ms in_out_cubic;
padding: 0 1 1 1;
}
TextLog:focus {
offset: 0 0 !important;
}
TextLog.-hidden {
offset-y: 100%;
}
Section {
height: auto;
min-width: 40;
margin: 1 2 4 2;
}
SectionTitle {
padding: 1 2;
background: $boost;
text-align: center;
text-style: bold;
}
QuickAccess {
width: 30;
dock: left;
}
LocationLink {
margin: 1 0 0 1;
height: 1;
padding: 1 2;
background: $boost;
color: $text;
box-sizing: content-box;
content-align: center middle;
}
LocationLink:hover {
background: $accent;
color: $text;
text-style: bold;
}
Message {
margin: 0 1;
}
Tree {
margin: 1 0;
}
Window>Static {
width: auto;
}
#issue-markdown {
margin: 4 4 4 4;
dock: bottom;
}
#bugged-section {
/* --
Here we set the height to be below the center and this demonstrates the issue:
Action: [ User focuses the Select object ]
Result:
The entire parent container scrolls when it has space on screen already and should not need to
*/
height: auto;
border: red;
}
Placeholder {
/* -- This placeholder is meant to simulate other widgets of a collective X height -- */
margin: 1 1 1 1;
height: 10vh;
}
Select {
/* Nothing done in this section - I've tried various fixes with no luck */
} I have been looking for a while to see if I could find references to this or similar issues, but I didn't have any luck or was not putting two and two together. If anyone is aware of other discussions related to this issue please point me towards them! Thank you in advance for any insights you can provide! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
Just to update this: it was turned into issue #2958 and the main report here should hopefully be addressed by #3009. |
Beta Was this translation helpful? Give feedback.
Just to update this: it was turned into issue #2958 and the main report here should hopefully be addressed by #3009.