Ver código fonte

re-write ui.timeline; add test and documentation

Falko Schindler 1 ano atrás
pai
commit
756ea00dc8

+ 0 - 31
nicegui/elements/timeline.js

@@ -1,31 +0,0 @@
-export default {
-    template: `
-    <div class="q-px-lg q-py-md">
-      <q-timeline :color="timelinecolor">
-        <q-timeline-entry v-for="item in items" :key="item.id" 
-                            :title="item.title"
-                            :subtitle="item.subtitle"
-                            :icon="item.icon">
-              <div v-if="item.body">
-                {{item.body}}
-              </div>
-            </q-timeline-entry>
-          </q-timeline>
-        </div>`,
-    props: {
-      initialItems: Array,
-      timelinecolor: String,
-    },
-    data() {
-      return {
-        items: []
-      };
-    },
-    
-    mounted() {
-      if (this.initialItems && this.initialItems.length > 0) {
-        this.items = this.initialItems;
-      }
-    },
-    };
-  

+ 63 - 19
nicegui/elements/timeline.py

@@ -1,29 +1,73 @@
-import uuid
+from typing import Literal, Optional
 
 from nicegui.element import Element
 
 
-class Timeline(Element, component='timeline.js'):
+class Timeline(Element):
 
-    def __init__(self, initial_items: list = None, timelinecolor: str = "secondary") -> None:
-        super().__init__()
-        if initial_items:
-            self._props['initialItems'] = initial_items
-            self._props['timelinecolor'] = timelinecolor
+    def __init__(self,
+                 *,
+                 side: Literal['left', 'right'] = 'left',
+                 layout: Literal['dense', 'comfortable', 'loose'] = 'dense',
+                 color: Optional[str] = None,
+                 ) -> None:
+        """Timeline
 
-    """Timeline
+        This element represents `Quasar's QTimeline <https://quasar.dev/vue-components/timeline#qtimeline-api>`_ component.
 
-    :param initialItems: Items of the timeline. Should be an Array of dictionarys and contain the id, title, subtitle, icon, body
-    :param timelinecolor: Color of the Icons. Should be an quasar color
+        :param side: Side ("left" or "right"; default: "left").
+        :param layout: Layout ("dense", "comfortable" or "loose"; default: "dense").
+        :param color: Color of the icons.
+        """
+        super().__init__('q-timeline')
+        self._props['side'] = side
+        self._props['layout'] = layout
+        if color is not None:
+            self._props['color'] = color
 
-    See `here <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio#events>`_
-    for a list of events you can subscribe to using the generic event subscription `on()`.
-    """
 
-    def _generate_id(self):
-        """Generate a unique ID for each timeline item."""
-        return str(uuid.uuid4())
+class TimelineEntry(Element):
 
-# Example Usage:
-# timeline = Timeline()
-# timeline.add_item(heading="Timeline Heading", title="Event Title", subtitle="Date", body="Description")
+    def __init__(self,
+                 body: Optional[str] = None,
+                 *,
+                 side: Literal['left', 'right'] = 'left',
+                 heading: bool = False,
+                 tag: Optional[str] = None,
+                 icon: Optional[str] = None,
+                 avatar: Optional[str] = None,
+                 title: Optional[str] = None,
+                 subtitle: Optional[str] = None,
+                 color: Optional[str] = None,
+                 ) -> None:
+        """Timeline Entry
+
+        This element represents `Quasar's QTimelineEntry <https://quasar.dev/vue-components/timeline#qtimelineentry-api>`_ component.
+
+        :param body: Body text.
+        :param side: Side ("left" or "right"; default: "left").
+        :param heading: Whether the timeline entry is a heading.
+        :param tag: HTML tag name to be used if it is a heading.
+        :param icon: Icon name.
+        :param avatar: Avatar URL.
+        :param title: Title text.
+        :param subtitle: Subtitle text.
+        :param color: Color or the timeline.
+        """
+        super().__init__('q-timeline-entry')
+        if body is not None:
+            self._props['body'] = body
+        self._props['side'] = side
+        self._props['heading'] = heading
+        if tag is not None:
+            self._props['tag'] = tag
+        if color is not None:
+            self._props['color'] = color
+        if icon is not None:
+            self._props['icon'] = icon
+        if avatar is not None:
+            self._props['avatar'] = avatar
+        if title is not None:
+            self._props['title'] = title
+        if subtitle is not None:
+            self._props['subtitle'] = subtitle

+ 4 - 0
nicegui/static/nicegui.css

@@ -93,6 +93,10 @@
   padding: 0.5rem;
   border: 1px solid #8884;
 }
+h6.q-timeline__title {
+  font-size: 1.25rem;
+  font-weight: 500;
+}
 
 #popup {
   position: fixed;

+ 4 - 0
nicegui/ui.py

@@ -67,6 +67,8 @@ __all__ = [
     'tabs',
     'textarea',
     'time',
+    'timeline',
+    'timeline_item',
     'toggle',
     'tooltip',
     'tree',
@@ -160,6 +162,8 @@ from .elements.tabs import TabPanels as tab_panels
 from .elements.tabs import Tabs as tabs
 from .elements.textarea import Textarea as textarea
 from .elements.time import Time as time
+from .elements.timeline import Timeline as timeline
+from .elements.timeline import TimelineEntry as timeline_entry
 from .elements.toggle import Toggle as toggle
 from .elements.tooltip import Tooltip as tooltip
 from .elements.tree import Tree as tree

+ 16 - 0
tests/test_timeline.py

@@ -0,0 +1,16 @@
+from nicegui import ui
+
+from .screen import Screen
+
+
+def test_timeline(screen: Screen):
+    with ui.timeline():
+        ui.timeline_entry('Entry 1', title='Title 1', subtitle='Subtitle 1')
+        with ui.timeline():
+            ui.label('Entry 2')
+
+    screen.open('/')
+    screen.should_contain('Entry 1')
+    screen.should_contain('Title 1')
+    screen.should_contain('Subtitle 1')
+    screen.should_contain('Entry 2')

+ 1 - 0
website/documentation.py

@@ -182,6 +182,7 @@ def create_full() -> None:
     load_demo(ui.splitter)
     load_demo('tabs')
     load_demo(ui.stepper)
+    load_demo(ui.timeline)
     load_demo(ui.carousel)
     load_demo(ui.menu)
 

+ 16 - 0
website/more_documentation/timeline_documentation.py

@@ -0,0 +1,16 @@
+from nicegui import ui
+
+
+def main_demo() -> None:
+    with ui.timeline(side='right'):
+        ui.timeline_entry('Rodja and Falko start working on NiceGUI.',
+                          title='Initial commit',
+                          subtitle='May 07, 2021')
+        ui.timeline_entry('The first PyPI package is released.',
+                          title='Release of 0.1',
+                          subtitle='May 14, 2021')
+        ui.timeline_entry('Large parts are rewritten to remove JustPy '
+                          'and to upgrade to Vue 3 and Quasar 2.',
+                          title='Release of 1.0',
+                          subtitle='December 15, 2022',
+                          icon='rocket')