Skip to content

Commit 41357fd

Browse files
committed
added two util function for converting select options and values
1 parent e141849 commit 41357fd

File tree

7 files changed

+26
-21
lines changed

7 files changed

+26
-21
lines changed

nicegui/element_filter.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
from .elements.mixins.source_element import SourceElement
1515
from .elements.mixins.text_element import TextElement
1616
from .elements.notification import Notification
17-
from .elements.select import Select
1817
from .elements.tree import Tree
1918

2019
T = TypeVar('T', bound=Element)

nicegui/elements/choice_element.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
JsonPrimitive = Union[str, int, float, bool, None]
1212
JsonValue = Union[
13-
JsonPrimitive,
13+
JsonPrimitive,
1414
list[str], list[int], list[float], list[bool], 'list[JsonValue]',
1515
tuple[str, ...], tuple[int, ...], tuple[float, ...], tuple[bool, ...], 'tuple[JsonValue, ...]',
1616
dict[str, str], dict[str, int], dict[str, float], dict[str, bool], 'dict[str, JsonValue]',

nicegui/elements/radio.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from collections.abc import Iterable
2-
from typing import Any, Optional, Generic, Union, overload
2+
from typing import Any, Generic, Optional, Union, overload
33

44
from ..events import GenericEventArguments, Handler, ValueChangeEventArguments
5-
from .choice_element import ChoiceElement, Option, L, P, to_option
5+
from .choice_element import ChoiceElement, L, Option, P, to_option
66
from .mixins.disableable_element import DisableableElement
77

88

@@ -31,7 +31,7 @@ def _event_args_to_value(self, e: GenericEventArguments[Optional[P]]) -> Any:
3131

3232
def _value_to_model_value(self, value: Optional[P]) -> Optional[P]:
3333
return value if value in self._values else None
34-
34+
3535

3636
@overload
3737
def radio(

nicegui/elements/select.py

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,20 @@
1313
V = TypeVar('V', bound='Union[tuple[Option[Any, Any], ...], Optional[Option[Any, Any]]]')
1414

1515

16+
def _convert_value(value: Union[tuple[T, ...], Optional[T], tuple[P, ...], Optional[P], Optional[Option[P, P]], tuple[Option[P, P], ...]]):
17+
if isinstance(value, tuple) and all(isinstance(v, (str, int, float, bool)) for v in value):
18+
return tuple(to_option(v) for v in value)
19+
if isinstance(value, (str, int, float, bool)):
20+
return to_option(value)
21+
return value
22+
23+
24+
def _convert_options( options: Union[Iterable[T], Iterable[P]]):
25+
if all(isinstance(v, (str, int, float, bool)) for v in options):
26+
return [to_option(v) for v in options]
27+
return options
28+
29+
1630
class Select(
1731
LabelElement,
1832
ValidationElement[V],
@@ -73,14 +87,7 @@ def __init__(self,
7387
self.new_value_to_option: Optional[Callable[[str], Optional[T]]] = new_value_to_option
7488
if self.new_value_mode and self.new_value_to_option is None:
7589
raise ValueError(f"new_value_to_option not passed. You must provide a function for handling new values when new value mode is '{self.new_value_mode}'.")
76-
if isinstance(value, tuple) and all(isinstance(v, (str, int, float, bool)) for v in value):
77-
value = tuple(to_option(v) for v in value)
78-
if isinstance(value, (str, int, float, bool)):
79-
value = to_option(value)
80-
if all(isinstance(v, (str, int, float, bool)) for v in options):
81-
super().__init__(label=label or None, options=[to_option(v) for v in options], value=value, on_change=on_change, validation=validation)
82-
else:
83-
super().__init__(label=label or None, options=options, value=value, on_change=on_change, validation=validation)
90+
super().__init__(label=label or None, options=_convert_options(options), value=_convert_value(value), on_change=on_change, validation=validation)
8491
if new_value_mode is not None:
8592
self._props['new-value-mode'] = new_value_mode
8693
with_input = True
@@ -146,6 +153,7 @@ def _handle_new_value(self, value: str) -> Optional[T]:
146153
self._update_values_and_labels()
147154
return new_option
148155

156+
149157
@overload
150158
def select(
151159
options: Iterable[T], *, label: str = ..., value: tuple[T, ...],
@@ -158,7 +166,6 @@ def select(
158166
) -> Select[tuple[T, ...], T]:
159167
...
160168

161-
162169
@overload
163170
def select(
164171
options: Iterable[T], *, label: str = ..., value: Literal[None] = ...,
@@ -171,7 +178,6 @@ def select(
171178
) -> Select[Optional[T], T]:
172179
...
173180

174-
175181
@overload
176182
def select(
177183
options: Iterable[P], *, label: str = ..., value: tuple[P, ...],

nicegui/testing/user_interaction.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
from nicegui.element import Element
99
from nicegui.elements.mixins.disableable_element import DisableableElement
1010
from nicegui.elements.mixins.value_element import ValueElement
11-
from nicegui.elements.select import Select
1211
from nicegui.elements.radio import Radio
12+
from nicegui.elements.select import Select
1313

1414
if TYPE_CHECKING:
1515
from .user import User

tests/test_binding.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class Model:
3838
selection: Optional[ui.option[str, tuple[int, int]]] = None
3939
data = Model()
4040
options: list[ui.option[str, tuple[int, int]]] = [
41-
ui.option("1,1", (1, 1)), ui.option("2,2", (2, 2)), ui.option("3,3", (3, 3))
41+
ui.option('1,1', (1, 1)), ui.option('2,2', (2, 2)), ui.option('3,3', (3, 3))
4242
]
4343
data.selection = options[0]
4444

@@ -53,14 +53,14 @@ def page():
5353
screen.wait(0.3)
5454
screen.should_contain('2,2')
5555
screen.should_not_contain('1,1')
56-
assert data.selection == ui.option("2,2", (2, 2))
56+
assert data.selection == ui.option('2,2', (2, 2))
5757

5858

5959
def test_ui_select_with_list_of_lists(screen: Screen):
6060
class Model:
6161
selection: Optional[ui.option[str, list[int]]] = None
6262
data = Model()
63-
options = [ui.option("1,1", [1, 1]), ui.option("2,2", [2, 2]), ui.option("3,3", [3, 3])]
63+
options = [ui.option('1,1', [1, 1]), ui.option('2,2', [2, 2]), ui.option('3,3', [3, 3])]
6464
data.selection = options[0]
6565

6666
@ui.page('/')
@@ -74,7 +74,7 @@ def page():
7474
screen.wait(0.3)
7575
screen.should_contain('2,2')
7676
screen.should_not_contain('1,1')
77-
assert data.selection == ui.option("2,2", [2, 2])
77+
assert data.selection == ui.option('2,2', [2, 2])
7878

7979

8080
def test_binding_to_input(screen: Screen):

tests/test_radio.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from nicegui import ui
2-
from nicegui.testing import Screen, User
32
from nicegui.elements.radio import Radio
3+
from nicegui.testing import Screen, User
44

55

66
def test_radio_click(screen: Screen):

0 commit comments

Comments
 (0)