Browse Source

#789 add favicons to demo browser tabs

Falko Schindler 2 years ago
parent
commit
65a91e5ac8

+ 36 - 35
website/demo.py

@@ -1,5 +1,5 @@
 import inspect
-from typing import Callable, Optional
+from typing import Callable, Optional, Union
 
 import isort
 
@@ -19,37 +19,32 @@ def remove_prefix(text: str, prefix: str) -> str:
     return text[len(prefix):] if text.startswith(prefix) else text
 
 
-class demo:
-
-    def __init__(self, browser_title: Optional[str] = None) -> None:
-        self.browser_title = browser_title
-
-    def __call__(self, f: Callable) -> Callable:
-        with ui.column().classes('w-full items-stretch gap-8 no-wrap min-[1500px]:flex-row'):
-            code = inspect.getsource(f).split('# END OF DEMO')[0].strip().splitlines()
-            while not code[0].strip().startswith('def') and not code[0].strip().startswith('async def'):
-                del code[0]
+def demo(f: Callable) -> Callable:
+    with ui.column().classes('w-full items-stretch gap-8 no-wrap min-[1500px]:flex-row'):
+        code = inspect.getsource(f).split('# END OF DEMO')[0].strip().splitlines()
+        while not code[0].strip().startswith('def') and not code[0].strip().startswith('async def'):
             del code[0]
-            indentation = len(code[0]) - len(code[0].lstrip())
-            code = [line[indentation:] for line in code]
-            code = ['from nicegui import ui'] + [remove_prefix(line, '# ') for line in code]
-            code = ['' if line == '#' else line for line in code]
-            if not code[-1].startswith('ui.run('):
-                code.append('')
-                code.append('ui.run()')
-            code = isort.code('\n'.join(code), no_sections=True, lines_after_imports=1)
-            with python_window(classes='w-full max-w-[44rem]'):
-                async def copy_code():
-                    await ui.run_javascript('navigator.clipboard.writeText(`' + code + '`)', respond=False)
-                    ui.notify('Copied to clipboard', type='positive', color='primary')
-                ui.markdown(f'````python\n{code}\n````')
-                ui.icon('content_copy', size='xs') \
-                    .classes('absolute right-2 top-10 opacity-10 hover:opacity-80 cursor-pointer') \
-                    .on('click', copy_code)
-            with browser_window(self.browser_title,
-                                classes='w-full max-w-[44rem] min-[1500px]:max-w-[20rem] min-h-[10rem] browser-window'):
-                intersection_observer(on_intersection=f)
-        return f
+        del code[0]
+        indentation = len(code[0]) - len(code[0].lstrip())
+        code = [line[indentation:] for line in code]
+        code = ['from nicegui import ui'] + [remove_prefix(line, '# ') for line in code]
+        code = ['' if line == '#' else line for line in code]
+        if not code[-1].startswith('ui.run('):
+            code.append('')
+            code.append('ui.run()')
+        code = isort.code('\n'.join(code), no_sections=True, lines_after_imports=1)
+        with python_window(classes='w-full max-w-[44rem]'):
+            async def copy_code():
+                await ui.run_javascript('navigator.clipboard.writeText(`' + code + '`)', respond=False)
+                ui.notify('Copied to clipboard', type='positive', color='primary')
+            ui.markdown(f'````python\n{code}\n````')
+            ui.icon('content_copy', size='xs') \
+                .classes('absolute right-2 top-10 opacity-10 hover:opacity-80 cursor-pointer') \
+                .on('click', copy_code)
+        with browser_window(title=getattr(f, 'tab', None),
+                            classes='w-full max-w-[44rem] min-[1500px]:max-w-[20rem] min-h-[10rem] browser-window'):
+            intersection_observer(on_intersection=f)
+    return f
 
 
 def _window_header(bgcolor: str) -> ui.row():
@@ -67,16 +62,22 @@ def _title(title: str) -> None:
     ui.label(title).classes('text-sm text-gray-600 absolute left-1/2 top-[6px]').style('transform: translateX(-50%)')
 
 
-def _tab(name: str, color: str, bgcolor: str) -> None:
+def _tab(content: Union[str, Callable], color: str, bgcolor: str) -> None:
     with ui.row().classes('gap-0'):
         with ui.label().classes(f'w-2 h-[24px] bg-[{color}]'):
             ui.label().classes(f'w-full h-full bg-[{bgcolor}] rounded-br-[6px]')
-        ui.label(name).classes(f'text-sm text-gray-600 px-6 py-1 h-[24px] rounded-t-[6px] bg-[{color}]')
+        with ui.row().classes(f'text-sm text-gray-600 px-4 py-1 h-[24px] rounded-t-[6px] bg-[{color}] items-center gap-2'):
+            if callable(content):
+                content()
+            else:
+                ui.image('/favicon/favicon.ico').classes('w-4 h-4')
+                ui.label(content)
         with ui.label().classes(f'w-2 h-[24px] bg-[{color}]'):
             ui.label().classes(f'w-full h-full bg-[{bgcolor}] rounded-bl-[6px]')
 
 
-def window(color: str, bgcolor: str, *, title: str = '', tab: str = '', classes: str = '') -> ui.column:
+def window(color: str, bgcolor: str, *,
+           title: str = '', tab: Union[str, Callable] = '', classes: str = '') -> ui.column:
     with ui.card().classes(f'no-wrap bg-[{color}] rounded-xl p-0 gap-0 {classes}') \
             .style('box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1)'):
         with _window_header(bgcolor):
@@ -96,5 +97,5 @@ def bash_window(*, classes: str = '') -> ui.card:
     return window(BASH_COLOR, BASH_BGCOLOR, title='bash', classes=classes).classes('p-2 bash-window')
 
 
-def browser_window(title: Optional[str] = None, *, classes: str = '') -> ui.card:
+def browser_window(title: Optional[Union[str, Callable]] = None, *, classes: str = '') -> ui.card:
     return window(BROWSER_COLOR, BROWSER_BGCOLOR, tab=title or 'NiceGUI', classes=classes).classes('p-4 browser-window')

+ 1 - 1
website/documentation.py

@@ -645,7 +645,7 @@ def create_full() -> None:
         Pick any parameter as it is defined by the internally used [pywebview module](https://pywebview.flowrl.com/guide/api.html) 
         for the `webview.create_window` and `webview.start` functions.
         Note that these keyword arguments will take precedence over the parameters defined in ui.run.
-    ''')
+    ''', tab=lambda: ui.label('NiceGUI'))
     def native_mode_demo():
         from nicegui import app
 

+ 6 - 5
website/documentation_tools.py

@@ -65,15 +65,17 @@ def render_docstring(doc: str, with_params: bool = True) -> ui.html:
 
 class text_demo:
 
-    def __init__(self, title: str, explanation: str) -> None:
+    def __init__(self, title: str, explanation: str, tab: Optional[Union[str, Callable]] = None) -> None:
         self.title = title
         self.explanation = explanation
         self.make_menu_entry = True
+        self.tab = tab
 
     def __call__(self, f: Callable) -> Callable:
         subheading(self.title, make_menu_entry=self.make_menu_entry)
         ui.markdown(self.explanation).classes('bold-links arrow-links')
-        return demo()(f)
+        f.tab = self.tab
+        return demo(f)
 
 
 class intro_demo(text_demo):
@@ -85,9 +87,8 @@ class intro_demo(text_demo):
 
 class element_demo:
 
-    def __init__(self, element_class: Union[Callable, type], browser_title: Optional[str] = None) -> None:
+    def __init__(self, element_class: Union[Callable, type]) -> None:
         self.element_class = element_class
-        self.browser_title = browser_title
 
     def __call__(self, f: Callable, *, more_link: Optional[str] = None) -> Callable:
         doc = self.element_class.__doc__ or self.element_class.__init__.__doc__
@@ -95,7 +96,7 @@ class element_demo:
         with ui.column().classes('w-full mb-8 gap-2'):
             subheading(title, more_link=more_link)
             render_docstring(documentation, with_params=more_link is None)
-            return demo(browser_title=self.browser_title)(f)
+            return demo(f)
 
 
 def load_demo(api: Union[type, Callable]) -> None:

File diff suppressed because it is too large
+ 11 - 4
website/more_documentation/run_documentation.py


Some files were not shown because too many files changed in this diff