Selaa lähdekoodia

Merge branch 'main' into feature/anchorlinks

# Conflicts:
#	main.py
Falko Schindler 3 vuotta sitten
vanhempi
säilyke
bf4380a0d7
5 muutettua tiedostoa jossa 39 lisäystä ja 8 poistoa
  1. 14 7
      main.py
  2. 5 1
      nicegui/elements/button.py
  3. 17 0
      nicegui/elements/open.py
  4. 2 0
      nicegui/events.py
  5. 1 0
      nicegui/ui.py

+ 14 - 7
main.py

@@ -3,11 +3,10 @@ from nicegui import ui
 from contextlib import contextmanager
 import inspect
 import sys
-from typing import Union
+from typing import Callable, Union
 import docutils.core
 import re
 import asyncio
-from nicegui.elements.element import Element
 from nicegui.elements.html import Html
 from nicegui.elements.markdown import Markdown
 from nicegui.events import KeyEventArguments
@@ -17,7 +16,7 @@ from nicegui.globals import page_stack
 page_stack[0].head_html += docutils.core.publish_parts('', writer_name='html')['stylesheet']
 
 @contextmanager
-def example(content: Union[Element, str]):
+def example(content: Union[Callable, type, str]):
     callFrame = inspect.currentframe().f_back.f_back
     begin = callFrame.f_lineno
 
@@ -27,7 +26,7 @@ def example(content: Union[Element, str]):
         if not match:
             return
 
-        headline_id = re.sub('[^(a-z)(A-Z)(0-9)._-]', '', match.groups()[0].strip())
+        headline_id = re.sub('[^(a-z)(A-Z)(0-9)-]', '_', match.groups()[0].strip())
         if not headline_id:
             return
 
@@ -41,7 +40,8 @@ def example(content: Union[Element, str]):
         if isinstance(content, str):
             add_html_anchor(ui.markdown(content).classes('mr-8 w-4/12'))
         else:
-            html = docutils.core.publish_parts(content.__init__.__doc__, writer_name='html')['html_body']
+            doc = content.__doc__ or content.__init__.__doc__
+            html = docutils.core.publish_parts(doc, writer_name='html')['html_body']
             html = html.replace('<p>', '<h3>', 1)
             html = html.replace('</p>', '</h3>', 1)
             html = Markdown.apply_tailwind(html)
@@ -284,7 +284,7 @@ design = '''### Styling
 NiceGUI uses the [Quasar Framework](https://quasar.dev/) and hence has its full design power.
 Each NiceGUI element provides a `props` method whose content is passed [to the Quasar component](https://justpy.io/quasar_tutorial/introduction/#props-of-quasar-components):
 Have a look at [the Quasar documentation](https://quasar.dev/vue-components/button#design) for all styling props.
-You can also apply [Tailwind](https://tailwindcss.com/) utility classes with the `classes` method. 
+You can also apply [Tailwind](https://tailwindcss.com/) utility classes with the `classes` method.
 
 If you really need to apply CSS, you can use the `styles` method. Here the delimiter is `;` instead of a blank space.
 
@@ -397,7 +397,7 @@ with example(ui.page):
 
 add_route = """### Route
 
-Add a new route by calling `ui.add_route` with a starlette route including a path and a function to be called. 
+Add a new route by calling `ui.add_route` with a starlette route including a path and a function to be called.
 Routed paths must start with a `'/'`.
 """
 with example(add_route):
@@ -447,4 +447,11 @@ with example(ui.keyboard):
     ui.label('Key events can be caught globally by using the keyboard element.')
     ui.checkbox('Track key events').bind_value_to(keyboard, 'active')
 
+with example(ui.open):
+    with ui.page('/yet_another_page') as other:
+        ui.label('Welcome to yet another page')
+        ui.button('RETURN', on_click=lambda e: ui.open('/', e.socket))
+
+    ui.button('REDIRECT', on_click=lambda e: ui.open('/yet_another_page', e.socket))
+
 ui.run(port=8080)

+ 5 - 1
nicegui/elements/button.py

@@ -25,7 +25,11 @@ class Button(Element):
         self.text = text
         self.bind_text_to(self.view, 'label')
 
-        view.on('click', lambda *_: handle_event(on_click, ClickEventArguments(sender=self), update=self.parent_view))
+        def process_event(view, event):
+            socket = event.get('websocket')
+            handle_event(on_click, ClickEventArguments(sender=self, socket=socket), update=self.parent_view)
+
+        view.on('click', process_event)
 
     def set_text(self, text: str):
         self.text = text

+ 17 - 0
nicegui/elements/open.py

@@ -0,0 +1,17 @@
+from starlette.websockets import WebSocket
+from ..task_logger import create_task
+
+
+def open(self, path: str, socket: WebSocket):
+    """
+    Open
+
+    Can be used to programmatically trigger redirects for a specific client.
+
+    :param path: string that is a relative url path or an absolute url
+    :param socket: WebSocket defining the target client
+    """
+    create_task(open_async(path, socket))
+
+async def open_async(path: str, socket: WebSocket):
+    await socket.send_json({'type': 'page_update', 'page_options': {'redirect': path}})

+ 2 - 0
nicegui/events.py

@@ -4,6 +4,7 @@ from justpy.htmlcomponents import HTMLBaseComponent
 from pydantic import BaseModel
 import traceback
 from typing import Any, Awaitable, Callable, List, Optional, Union
+from starlette.websockets import WebSocket
 
 from .elements.element import Element
 from .task_logger import create_task
@@ -12,6 +13,7 @@ class EventArguments(BaseModel):
     class Config:
         arbitrary_types_allowed = True
     sender: Element
+    socket: Optional[WebSocket]
 
 class ClickEventArguments(EventArguments):
     pass

+ 1 - 0
nicegui/ui.py

@@ -20,6 +20,7 @@ class Ui:
     from .elements.menu_separator import MenuSeparator as menu_separator
     from .elements.notify import Notify as notify
     from .elements.number import Number as number
+    from .elements.open import open, open_async
     from .elements.page import Page as page
     from .elements.radio import Radio as radio
     from .elements.scene import Scene as scene