Skip to content
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

Add rxui.range #268

Merged
merged 4 commits into from
Nov 10, 2024
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
64 changes: 64 additions & 0 deletions __tests/test_range.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from ex4nicegui.reactive import rxui
from nicegui import ui
from ex4nicegui import to_ref
from .screen import BrowserManager, PageUtils
from typing import Literal


def drap_move(type: Literal["min", "max"], page: PageUtils, offset_x: int):
targets = page.locator(".q-slider__focus-ring")
if type == "min":
target = targets.first
else:
target = targets.last

rect = target.bounding_box()
assert rect
x = rect["x"] + rect["width"] / 2
y = rect["y"] + rect["height"] / 2

page._page.mouse.move(x, y)
page._page.mouse.down()
page._page.mouse.move(x + offset_x, y)
page._page.mouse.up()


def test_min_change(browser: BrowserManager, page_path: str):
r_value = to_ref(
{
"min": 0,
"max": 100,
}
)

@ui.page(page_path)
def _():
rxui.range(min=0, max=100, value=r_value).classes("target")
rxui.label(r_value).classes("label")

page = browser.open(page_path)
label = page.Label(".label")

label.expect_equal_text("{'min': 0, 'max': 100}")
drap_move("min", page, offset_x=100)
label.expect_equal_text("{'min': 8, 'max': 100}")


def test_max_change(browser: BrowserManager, page_path: str):
r_value = to_ref(
{
"min": 0,
"max": 100,
}
)

@ui.page(page_path)
def _():
rxui.range(min=0, max=100, value=r_value).classes("target")
rxui.label(r_value).classes("label")

page = browser.open(page_path)
label = page.Label(".label")

drap_move("max", page, offset_x=-100)
label.expect_equal_text("{'min': 0, 'max': 92}")
3 changes: 3 additions & 0 deletions ex4nicegui/reactive/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@
from .officials.toggle import ToggleBindableUi as toggle
from .officials.avatar import AvatarBindableUi as avatar
from .officials.badge import BadgeBindableUi as badge
from .officials.range import RangeBindableUi as range


from .local_file_picker import local_file_picker
from .UseDraggable.UseDraggable import use_draggable
Expand Down Expand Up @@ -139,4 +141,5 @@
"toggle",
"avatar",
"badge",
"range",
]
45 changes: 45 additions & 0 deletions ex4nicegui/reactive/officials/range.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from typing import Any, Callable, Optional, Dict, cast


from ex4nicegui.utils.signals import (
_TMaybeRef as TMaybeRef,
)

from nicegui import ui
from ex4nicegui.reactive.base import BindableUi, DisableableMixin
from ex4nicegui.reactive.services.reactive_service import ParameterClassifier
from ex4nicegui.reactive.mixins.value_element import ValueElementMixin


class RangeBindableUi(
BindableUi[ui.range],
DisableableMixin,
ValueElementMixin[Dict[str, int]],
):
def __init__(
self,
*,
min: TMaybeRef[float], # pylint: disable=redefined-builtin
max: TMaybeRef[float], # pylint: disable=redefined-builtin
step: TMaybeRef[float] = 1.0,
value: Optional[TMaybeRef[Dict[str, int]]] = None,
on_change: Optional[Callable[..., Any]] = None,
) -> None:
pc = ParameterClassifier(
locals(),
maybeRefs=["min", "max", "step", "value"],
v_model=("value", "on_change"),
events=["on_change"],
)

value_kws = pc.get_values_kws()

element = ui.range(**value_kws)
super().__init__(element) # type: ignore

for key, value in pc.get_bindings().items():
self.bind_prop(key, value) # type: ignore

@property
def value(self):
return cast(Dict[str, int], self.element.value)
Loading