فهرست منبع

Merge pull request #676 from abulka/splitter

ui.splitter element
Rodja Trappe 2 سال پیش
والد
کامیت
e5f6777fa4
5فایلهای تغییر یافته به همراه99 افزوده شده و 0 حذف شده
  1. 37 0
      nicegui/elements/splitter.py
  2. 1 0
      nicegui/ui.py
  3. 18 0
      tests/test_splitter.py
  4. 1 0
      website/documentation.py
  5. 42 0
      website/more_documentation/splitter_documentation.py

+ 37 - 0
nicegui/elements/splitter.py

@@ -0,0 +1,37 @@
+from typing import Callable, Optional, Tuple
+
+from .mixins.value_element import ValueElement
+
+
+class Splitter(ValueElement):
+    def __init__(self, *,
+                 horizontal: Optional[bool] = False,
+                 reverse: Optional[bool] = False,
+                 limits: Optional[Tuple[float, float]] = (0, 100),
+                 value: Optional[float] = 50,
+                 on_change: Optional[Callable] = None) -> None:
+        """Splitter
+
+        The `ui.splitter` element divides the screen space into resizable sections, 
+        allowing for flexible and responsive layouts in your applications.
+
+        Based on Quasar's Splitter component:
+        `Splitter <https://quasar.dev/vue-components/splitter>`_
+
+        It provides three customizable slots: ``before``, ``after``, and ``separator``, which can be
+        used to embed other elements within the splitter.
+
+        :param horizontal: Whether to split horizontally instead of vertically
+        :param limits: Two numbers representing the minimum and maximum split size of the two panels
+        :param value: Size of the first panel (or second if using reverse)
+        :param reverse: Whether to apply the model size to the second panel instead of the first
+        :param on_change: callback which is invoked when the user releases the splitter
+        """
+        super().__init__(tag='q-splitter', value=value, on_value_change=on_change, throttle=0.05)
+        self._props['horizontal'] = horizontal
+        self._props['limits'] = limits
+        self._props['reverse'] = reverse
+
+        self.before = self.add_slot('before')
+        self.after = self.add_slot('after')
+        self.separator = self.add_slot('separator')

+ 1 - 0
nicegui/ui.py

@@ -46,6 +46,7 @@ from .elements.select import Select as select
 from .elements.separator import Separator as separator
 from .elements.separator import Separator as separator
 from .elements.slider import Slider as slider
 from .elements.slider import Slider as slider
 from .elements.spinner import Spinner as spinner
 from .elements.spinner import Spinner as spinner
+from .elements.splitter import Splitter as splitter
 from .elements.switch import Switch as switch
 from .elements.switch import Switch as switch
 from .elements.table import Table as table
 from .elements.table import Table as table
 from .elements.tabs import Tab as tab
 from .elements.tabs import Tab as tab

+ 18 - 0
tests/test_splitter.py

@@ -0,0 +1,18 @@
+from nicegui import ui
+
+from .screen import Screen
+
+
+def test_splitter(screen: Screen):
+    with ui.splitter() as splitter:
+        with splitter.before:
+            ui.label('Left hand side.')
+        with splitter.after:
+            ui.label('Right hand side.')
+    ui.label().bind_text_from(splitter, 'value')
+
+    screen.open('/')
+    screen.should_contain('Left hand side.')
+    screen.should_contain('Right hand side.')
+    screen.should_contain('50')
+    # TODO: programmatically move splitter

+ 1 - 0
website/documentation.py

@@ -163,6 +163,7 @@ def create_full() -> None:
         ui.button('Clear', on_click=container.clear)
         ui.button('Clear', on_click=container.clear)
 
 
     load_demo(ui.expansion)
     load_demo(ui.expansion)
+    load_demo(ui.splitter)
 
 
     @text_demo('Tabs', '''
     @text_demo('Tabs', '''
         The elements `ui.tabs`, `ui.tab`, `ui.tab_panels`, and `ui.tab_panel` resemble
         The elements `ui.tabs`, `ui.tab`, `ui.tab_panels`, and `ui.tab_panel` resemble

+ 42 - 0
website/more_documentation/splitter_documentation.py

@@ -0,0 +1,42 @@
+from nicegui import ui
+
+from ..documentation_tools import text_demo
+
+
+def main_demo() -> None:
+    with ui.splitter() as splitter:
+        with splitter.before:
+            ui.label('This is some content on the left hand side.')
+        with splitter.after:
+            ui.label('This is some content on the right hand side.')\
+                .classes('ml-2')
+
+
+def more() -> None:
+    @text_demo('Advanced usage', '''
+        This demo shows all the slots and parameters including a tooltip, a custom separator, and a callback.
+    ''')
+    def advanced_usage() -> None:
+        with ui.splitter(horizontal=False, reverse=False, value=60,
+                         on_change=lambda e: ui.notify(e.value)) as splitter:
+            ui.tooltip('This is the default slot.').classes('bg-green')
+            with splitter.before:
+                ui.label('This is the left hand side.')
+            with splitter.after:
+                ui.label('This is the right hand side.') \
+                    .classes('ml-2')
+            with splitter.separator:
+                ui.icon('lightbulb').classes('text-green')
+
+        ui.number('Split value', format='%.1f').bind_value(splitter)
+
+    @text_demo('Image fun', '''
+        This demo shows how to use the splitter to display images side by side.
+    ''')
+    def image_fun() -> None:
+        with ui.splitter().classes('w-72 h-48') \
+                .props('before-class=overflow-hidden after-class=overflow-hidden') as splitter:
+            with splitter.before:
+                ui.image('https://cdn.quasar.dev/img/parallax1.jpg').classes('w-72 absolute-top-left')
+            with splitter.after:
+                ui.image('https://cdn.quasar.dev/img/parallax1-bw.jpg').classes('w-72 absolute-top-right')