Skip to content

Added Selection widget to Toga web #3402

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

Merged
merged 9 commits into from
May 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changes/3334.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The Web backend now provides Selection widgets.
6 changes: 4 additions & 2 deletions docs/reference/api/widgets/selection.rst
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@ A widget to select a single option from a list of alternatives.
:align: center
:width: 300px

.. group-tab:: Web |no|
.. group-tab:: Web

Not supported
.. figure:: /reference/images/selection-web.png
:align: center
:width: 300px

.. group-tab:: Textual |no|

Expand Down
2 changes: 1 addition & 1 deletion docs/reference/data/widgets_by_platform.csv
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ MultilineTextInput,General Widget,:class:`~toga.MultilineTextInput`,Multi-line T
NumberInput,General Widget,:class:`~toga.NumberInput`,A text input that is limited to numeric input,|y|,|y|,|y|,|y|,|y|,,
PasswordInput,General Widget,:class:`~toga.PasswordInput`,A text input that hides its input,|y|,|y|,|y|,|y|,|y|,|b|,
ProgressBar,General Widget,:class:`~toga.ProgressBar`,Progress Bar,|y|,|y|,|y|,|y|,|y|,|b|,
Selection,General Widget,:class:`~toga.Selection`,A widget to select a single option from a list of alternatives.,|y|,|y|,|y|,|y|,|y|,,
Selection,General Widget,:class:`~toga.Selection`,A widget to select a single option from a list of alternatives.,|y|,|y|,|y|,|y|,|y|,|b|,
Slider,General Widget,:class:`~toga.Slider`,Slider,|y|,|y|,|y|,|y|,|y|,,
Switch,General Widget,:class:`~toga.Switch`,Switch,|y|,|y|,|y|,|y|,|y|,|b|,
Table,General Widget,:class:`~toga.Table`,A widget for displaying columns of tabular data.,|y|,|y|,|y|,,|b|,,
Expand Down
Binary file added docs/reference/images/selection-web.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions web/src/toga_web/factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
from .widgets.passwordinput import PasswordInput
from .widgets.progressbar import ProgressBar
from .widgets.scrollcontainer import ScrollContainer
from .widgets.selection import Selection

# from .widgets.selection import Selection
# from .widgets.slider import Slider
# from .widgets.splitcontainer import SplitContainer
from .widgets.switch import Switch
Expand Down Expand Up @@ -76,7 +76,7 @@ def not_implemented(feature):
"ProgressBar",
"ActivityIndicator",
"ScrollContainer",
# 'Selection',
"Selection",
# 'Slider',
# 'SplitContainer',
"Switch",
Expand Down
43 changes: 43 additions & 0 deletions web/src/toga_web/widgets/selection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from js import CustomEvent

from toga_web.libs import create_proxy

from .base import Widget


class Selection(Widget):

def create(self):
self.native = self._create_native_widget("sl-select")
self.native.addEventListener("sl-change", create_proxy(self.dom_sl_change))

def dom_sl_change(self, event):
self.interface.on_change()

def clear(self):
while self.native.firstElementChild:
self.native.removeChild(self.native.firstElementChild)

def insert(self, index, item):
display_text = self.interface._title_for_item(item)
option = self._create_native_widget("sl-option")
option.value = str(index)
option.textContent = display_text
if self.native.value == "":
self.native.value = option.value
if index >= len(self.native.children):
self.native.appendChild(option)
else:
self.native.insertBefore(option, self.native.children[index])

def get_selected_index(self):
if self.native.value:
return int(self.native.value)
return None

def select_item(self, index, item):
self.native.value = str(index)
self.native.dispatchEvent(CustomEvent.new("sl-change"))

def rehint(self):
pass