Переглянути джерело

Add function to update browser bar URL (#4382)

Sometimes when you change the state of you application, you also want to
have this reflected in the browser URL bar. That way, users can
bookmark/share that URL and return to the state where they left off. I
could not immediately find this functionality in NiceGUI out of the box.

Simple use case:

``` python
@ui.page('/select/{id}')
def page(id: int):
    select1 = ui.select([1, 2, 3], value=id).on_value_change(
        lambda e: ui.navigate.set_browser_url(f'/select/{e.value}')
    )
    select2 = ui.select({1: 'One', 2: 'Two', 3: 'Three'}).bind_value(select1, 'value')
    ui.link('Link to selected option', f'/select/{id}')
```

---------

Co-authored-by: Timmermans Pieter <pieter.timmermans@jandenul.com>
Co-authored-by: Falko Schindler <falko@zauberzeug.com>
platinops 2 місяців тому
батько
коміт
8e77ddace8

+ 28 - 0
nicegui/functions/navigate.py

@@ -14,6 +14,9 @@ class Navigate:
     *Added in version 2.0.0*
     *Added in version 2.0.0*
     """
     """
 
 
+    def __init__(self) -> None:
+        self.history = History()
+
     def back(self) -> None:
     def back(self) -> None:
         """ui.navigate.back
         """ui.navigate.back
 
 
@@ -66,4 +69,29 @@ class Navigate:
         context.client.open(path, new_tab)
         context.client.open(path, new_tab)
 
 
 
 
+class History:
+
+    def push(self, url: str) -> None:
+        """Push a URL to the browser navigation history.
+
+        See JavaScript's `pushState <https://developer.mozilla.org/en-US/docs/Web/API/History/pushState>`_ for more information.
+
+        *Added in version 2.13.0*
+
+        :param url: relative or absolute URL
+        """
+        run_javascript(f'history.pushState({{}}, "", "{url}");')
+
+    def replace(self, url: str) -> None:
+        """Replace the current URL in the browser history.
+
+        See JavaScript's `replaceState <https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState>`_ for more information.
+
+        *Added in version 2.13.0*
+
+        :param url: relative or absolute URL
+        """
+        run_javascript(f'history.replaceState({{}}, "", "{url}");')
+
+
 navigate = Navigate()
 navigate = Navigate()

+ 1 - 0
nicegui/testing/user_navigate.py

@@ -13,6 +13,7 @@ if TYPE_CHECKING:
 class UserNavigate(Navigate):
 class UserNavigate(Navigate):
 
 
     def __init__(self, user: User) -> None:
     def __init__(self, user: User) -> None:
+        super().__init__()
         self.user = user
         self.user = user
 
 
     def to(self, target: Union[Callable[..., Any], str, Element], new_tab: bool = False) -> None:
     def to(self, target: Union[Callable[..., Any], str, Element], new_tab: bool = False) -> None:

+ 2 - 1
website/documentation/content/doc/api.py

@@ -11,6 +11,7 @@ from typing import Any, Callable, Dict, Optional, Union, overload
 import nicegui
 import nicegui
 from nicegui import app as nicegui_app
 from nicegui import app as nicegui_app
 from nicegui import ui as nicegui_ui
 from nicegui import ui as nicegui_ui
+from nicegui.functions.navigate import Navigate
 from nicegui.elements.markdown import remove_indentation
 from nicegui.elements.markdown import remove_indentation
 
 
 from .page import DocumentationPage
 from .page import DocumentationPage
@@ -69,7 +70,7 @@ def demo(element: type, /,
 
 
 
 
 @overload
 @overload
-def demo(function: Callable, /,
+def demo(function: Union[Callable, Navigate], /,
          tab: Optional[Union[str, Callable]] = None,
          tab: Optional[Union[str, Callable]] = None,
          lazy: bool = True,
          lazy: bool = True,
          ) -> Callable[[Callable], Callable]:
          ) -> Callable[[Callable], Callable]:

+ 15 - 0
website/documentation/content/navigate_documentation.py

@@ -17,3 +17,18 @@ def main_demo() -> None:
 def open_github() -> None:
 def open_github() -> None:
     url = 'https://github.com/zauberzeug/nicegui/'
     url = 'https://github.com/zauberzeug/nicegui/'
     ui.button('Open GitHub', on_click=lambda: ui.navigate.to(url, new_tab=True))
     ui.button('Open GitHub', on_click=lambda: ui.navigate.to(url, new_tab=True))
+
+
+@doc.demo('Push and replace URLs', '''
+    The `history` API allows you to push and replace URLs to the browser history.
+
+    While the `history.push` method pushes a new URL to the history,
+    the `history.replace` method replaces the current URL.
+
+    See `JavaScript's History API <https://developer.mozilla.org/en-US/docs/Web/API/History>`_ for more information.
+
+    *Added in version 2.13.0*
+''')
+def history_demo() -> None:
+    ui.button('Push URL', on_click=lambda: ui.navigate.history.push('/a'))
+    ui.button('Replace URL', on_click=lambda: ui.navigate.history.replace('/b'))