瀏覽代碼

add list and item element

Paula Kammler 1 年之前
父節點
當前提交
719a6b2386
共有 3 個文件被更改,包括 116 次插入0 次删除
  1. 59 0
      nicegui/elements/list.py
  2. 8 0
      nicegui/ui.py
  3. 49 0
      tests/test_list.py

+ 59 - 0
nicegui/elements/list.py

@@ -0,0 +1,59 @@
+from typing import Any, Callable, Optional
+
+from ..element import Element
+from ..events import ClickEventArguments, handle_event
+from .mixins.disableable_element import DisableableElement
+from .mixins.text_element import TextElement
+
+
+class List(Element):
+
+    def __init__(self) -> None:
+        """List
+
+        A list element based on Quasar's `QList <https://quasar.dev/vue-components/list-and-list-items#qlist-api>`_ component.
+        It provides a container for list items.
+        """
+        super().__init__('q-list')
+
+
+class ListItem(DisableableElement):
+
+    def __init__(self, on_click: Optional[Callable[..., Any]] = None) -> None:
+        """List Item
+
+        Creates a list item based on Quasar's `QItem <https://quasar.dev/vue-components/list-and-list-items#qitem-api>`_ component.
+        The item should be placed inside a list element.
+        """
+        super().__init__(tag='q-item')
+
+        if on_click:
+            self._props['clickable'] = True
+            self.on('click', lambda e: handle_event(on_click, ClickEventArguments(sender=self, client=self.client)))
+
+
+class ListItemSection(Element):
+
+    def __init__(self) -> None:
+        """
+        List Item Section
+
+        Creates an item section based on Quasar's `QItemList <https://quasar.dev/vue-components/list-and-list-items#qitemsection-api>`_ component.
+        The section should be placed inside a list item element.
+        """
+
+        super().__init__('q-item-section')
+
+
+class ListItemLabel(TextElement):
+
+    def __init__(self, text: str = '') -> None:
+        """
+        List Item Label
+
+        Creates an item label based on Quasar's `QItemLabel <https://quasar.dev/vue-components/list-and-list-items#qitemlabel-api>`_ component.
+
+        :param text: text to be displayed (default: '')
+        """
+
+        super().__init__(tag='q-item-label', text=text)

+ 8 - 0
nicegui/ui.py

@@ -32,6 +32,9 @@ __all__ = [
     'image',
     'input',
     'interactive_image',
+    'item',
+    'item_label',
+    'item_section',
     'joystick',
     'json_editor',
     'keyboard',
@@ -41,6 +44,7 @@ __all__ = [
     'line_plot',
     'link',
     'link_target',
+    'list',
     'log',
     'markdown',
     'menu',
@@ -148,6 +152,10 @@ from .elements.leaflet import Leaflet as leaflet
 from .elements.line_plot import LinePlot as line_plot
 from .elements.link import Link as link
 from .elements.link import LinkTarget as link_target
+from .elements.list import List as list  # pylint: disable=redefined-builtin
+from .elements.list import ListItem as item
+from .elements.list import ListItemLabel as item_label
+from .elements.list import ListItemSection as item_section
 from .elements.log import Log as log
 from .elements.markdown import Markdown as markdown
 from .elements.menu import Menu as menu

+ 49 - 0
tests/test_list.py

@@ -0,0 +1,49 @@
+from nicegui import ui
+from nicegui.testing import Screen
+
+
+def test_list(screen: Screen):
+    with ui.button('List'):
+        with ui.list():
+            with ui.item():
+                ui.item_label('Test')
+
+    screen.open('/')
+    screen.click('List')
+    screen.should_contain('Test')
+
+
+def test_clicking_items(screen: Screen):
+    label = ui.label()
+    with ui.list():
+        with ui.item(on_click=lambda: label.set_text('Clicked item 1')):
+            ui.item_label('Item 1')
+        with ui.item(on_click=lambda: label.set_text('Clicked item 2')):
+            ui.item_label('Item 2')
+
+    screen.open('/')
+    screen.should_contain('Item 1')
+    screen.should_contain('Item 2')
+
+    screen.click('Item 1')
+    screen.should_contain('Clicked item 1')
+
+
+def test_clicking_nested_sections(screen: Screen):
+    label = ui.label()
+    with ui.list():
+        with ui.item(on_click=lambda: label.set_text('Clicked!')):
+            with ui.item_section().props('avatar'):
+                ui.button('Button').on('click.stop', lambda: label.set_text('Clicked button!'))
+            with ui.item_section():
+                ui.item_label('Item')
+
+    screen.open('/')
+    screen.should_contain('Button')
+    screen.should_contain('Item')
+
+    screen.click('Button')
+    screen.should_contain('Clicked button!')
+
+    screen.click('Item')
+    screen.should_contain('Clicked!')