router.py 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. from typing import Awaitable, Callable, Union
  2. from nicegui import background_tasks, ui
  3. from nicegui.dependencies import register_component
  4. from nicegui.element import Element
  5. register_component('router_frame', __file__, 'router_frame.js')
  6. class Router():
  7. def __init__(self) -> None:
  8. self.routes: dict[str, Callable] = {}
  9. self.content: Element = None
  10. def add(self, path: str):
  11. def decorator(func):
  12. self.routes[path] = func
  13. return func
  14. return decorator
  15. def open(self, target: Union[Callable, Awaitable, str]):
  16. if isinstance(target, str):
  17. path = target
  18. builder = self.routes[target]
  19. else:
  20. path = {v: k for k, v in self.routes.items()}[target]
  21. builder = target
  22. self.content.clear()
  23. async def build():
  24. with self.content:
  25. await ui.run_javascript(f'history.pushState({{page: "{path}"}}, "", "{path}")', respond=False)
  26. await builder()
  27. background_tasks.create(build())
  28. def frame(self):
  29. self.content = ui.element('router_frame').on('open', lambda msg: self.open(msg['args']))
  30. return self.content