Comments (4)
Diving into the innards with this:
from textual import on
from textual.app import App, ComposeResult
from textual.containers import Horizontal
from textual.reactive import var
from textual.widgets import Button, OptionList, Pretty
from textual.widgets.option_list import Option
class OptionListReAdd(App[None]):
CSS = """
OptionList {
height: 1fr;
}
Horizontal {
height: 2fr;
Pretty {
width: 1fr;
}
}
"""
count: var[int] = var(0)
def compose(self) -> ComposeResult:
yield Button("Add again")
yield OptionList()
with Horizontal():
yield Pretty([], id="options")
yield Pretty([], id="ids")
@on(Button.Pressed)
def readd(self) -> None:
self.count += 1
self.query_one(OptionList).add_option(
Option(f"Option {self.count}", id=str(self.count))
)
self.query_one("#options", Pretty).update(
self.query_one(OptionList)._options
)
self.query_one("#ids", Pretty).update(
self.query_one(OptionList)._option_ids
)
if __name__ == "__main__":
OptionListReAdd().run()
I see this:
it looks like the changes made have introduced some sort of off-by-one error on the index mapping for each ID.
from textual.
It's a bit late in the evening for me to do a PR with confidence, but it looks like the issue is fixed with something like this:
diff --git a/src/textual/widgets/_option_list.py b/src/textual/widgets/_option_list.py
index 59e2adf9..9366f071 100644
--- a/src/textual/widgets/_option_list.py
+++ b/src/textual/widgets/_option_list.py
@@ -596,13 +596,14 @@ class OptionList(ScrollView, can_focus=True):
# Turn any incoming values into valid content for the list.
content = [self._make_content(item) for item in items]
self._duplicate_id_check(content)
+ start = len(self._options)
self._contents.extend(content)
# Pull out the content that is genuine options. Add them to the
# list of options and map option IDs to their new indices.
new_options = [item for item in content if isinstance(item, Option)]
self._options.extend(new_options)
for new_option_index, new_option in enumerate(
- new_options, start=len(self._options)
+ new_options, start=start
):
if new_option.id:
self._option_ids[new_option.id] = new_option_index
The calculation of the new index values for the mapping is currently starting after the new options have been added, when it should go from the last position before they're added (is how it looks to me).
Pinging @rodrigogiraoserrao for a double-check as this does seem to be from b1aaea7
from textual.
A test like this illustrates the issue:
from textual.app import App, ComposeResult
from textual.widgets import OptionList
from textual.widgets.option_list import Option
class OptionListApp(App[None]):
"""Test option list application."""
def compose(self) -> ComposeResult:
yield OptionList()
async def test_get_after_add() -> None:
"""It should be possible to get an option by ID after adding."""
async with OptionListApp().run_test() as pilot:
option_list = pilot.app.query_one(OptionList)
option_list.add_option(Option("0", id="0"))
assert option_list.get_option("0").id == "0"
This will fail.
from textual.
Don't forget to star the repository!
Follow @textualizeio for Textual updates.
from textual.
Related Issues (20)
- Crash when using hot-reloading with new hatch CSS rule HOT 1
- `hatch: <type> <colour-name>` results in parsing error HOT 1
- Crash on pushing screen when a toast is active HOT 7
- Style(bgcolor="$success") results in an exception, same with Text("value", "bgcolor: $success") HOT 3
- Add feature: TCSS property font-size HOT 5
- Header Expansion HOT 6
- Color Palete HOT 1
- `pop_screen()` triggering randomly after hoovering buttons under heavy load HOT 13
- The type of dark attribute of class App might be inaccurate. (Reactive[bool] -> bool) HOT 5
- Broken Links in Reference/Widgets sections HOT 2
- Add tooltips to all input widgets HOT 1
- How to change text background on button click HOT 2
- CancelledError stack trace in terminal after quitting app with Ctrl+C HOT 2
- `on_leave` event being fired by widget in inactive screen
- pageup and pagedown bindings not firing on `main` branch HOT 6
- Memray's test suite deadlocks with Textual 0.65.2 HOT 3
- New default key bindings for DataTable override app-defined bindings HOT 3
- priority binding order is not respected in the Footer HOT 3
- Method to add content to Content Switcher HOT 3
- Memray's test suite fails due to a deadlock with Textual 0.67.1 HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from textual.