Ver Fonte

Merge branch 'color_picker' into main

Falko Schindler há 3 anos atrás
pai
commit
e4c120d434

+ 9 - 0
main.py

@@ -218,6 +218,15 @@ with example(ui.number):
         ui.label('underlying value: ')
         ui.label().bind_text_from(number_input, 'value')
 
+with example(ui.color_input):
+    color_label = ui.label('Change my color!')
+    ui.color_input(label='Color', value='#000000',
+                   on_change=lambda e: color_label.style(f'color:{e.value}'))
+
+with example(ui.color_picker):
+    picker = ui.color_picker(on_pick=lambda e: button.style(f'background-color:{e.color}!important'))
+    button = ui.button(on_click=picker.open).props('icon=colorize')
+
 with example(ui.radio):
     radio = ui.radio([1, 2, 3], value=1).props('inline')
     ui.radio({1: 'A', 2: 'B', 3: 'C'}, value=1).props('inline').bind_value(radio, 'value')

+ 36 - 0
nicegui/elements/color_input.py

@@ -0,0 +1,36 @@
+from typing import Callable, Optional
+
+import justpy as jp
+
+from .string_element import StringElement
+
+
+class ColorInput(StringElement):
+
+    def __init__(self, label: str = None, *,
+                 placeholder: str = None, value: str = '', on_change: Optional[Callable] = None):
+        """Color Input Element
+
+        :param label: displayed label for the color input
+        :param placeholder: text to show if no color is selected
+        :param value: the current color value
+        :param on_change: callback to execute when the input is confirmed by leaving the focus
+        """
+        view = jp.QInput(
+            label=label,
+            placeholder=placeholder,
+            value=value,
+            input=self.handle_change,
+            temp=False,
+        )
+
+        icon_button = jp.parse_html('''
+            <q-icon name="colorize" class="cursor-pointer">
+                <q-popup-proxy transition-show="scale" transition-hide="scale" name="popup">
+                    <q-color name="color_input"/>
+                </q-popup-proxy>
+            </q-icon>''')
+        view.add_scoped_slot('append', icon_button)
+        icon_button.name_dict['color_input'].on('change', self.handle_change)
+
+        super().__init__(view, value=value, on_change=on_change)

+ 34 - 0
nicegui/elements/color_picker.py

@@ -0,0 +1,34 @@
+from typing import Callable, Dict
+
+import justpy as jp
+from nicegui.events import ColorPickEventArguments, handle_event
+
+from .element import Element
+
+
+class ColorPicker(Element):
+
+    def __init__(self, *, on_pick: Callable, value: bool = False):
+        """Color Picker
+
+        :param on_pick: callback to execute when a color is picked
+        :param value: whether the menu is already opened (default: `False`)
+        """
+        view = jp.parse_html('''
+            <q-popup-proxy transition-show="scale" transition-hide="scale" name="popup">
+                <q-color name="color_input"/>
+            </q-popup-proxy>
+            ''')
+
+        def handle_pick(sender, msg: Dict):
+            return handle_event(on_pick, ColorPickEventArguments(sender=self, color=msg.value), update=self.parent_view)
+        view.name_dict['color_input'].on('change', handle_pick)
+        view.name_dict['popup'].value = value
+
+        super().__init__(view)
+
+    def open(self):
+        self.view.name_dict['popup'].value = True
+
+    def close(self):
+        self.view.name_dict['popup'].value = False

+ 2 - 2
nicegui/elements/number.py

@@ -1,4 +1,4 @@
-from typing import Callable, Optional
+from typing import Callable, Dict, Optional
 
 import justpy as jp
 
@@ -29,7 +29,7 @@ class Number(FloatElement):
 
         super().__init__(view, value=value, format=format, on_change=on_change)
 
-    def handle_change(self, msg):
+    def handle_change(self, msg: Dict):
         msg['value'] = float(msg['value'])
 
         return super().handle_change(msg)

+ 1 - 1
nicegui/elements/select.py

@@ -26,7 +26,7 @@ class Select(ChoiceElement):
         else:
             return value
 
-    def handle_change(self, msg):
+    def handle_change(self, msg: Dict):
         msg['label'] = msg['value']['label']
         msg['value'] = msg['value']['value']
         return super().handle_change(msg)

+ 2 - 2
nicegui/elements/value_element.py

@@ -1,4 +1,4 @@
-from typing import Any, Callable, Optional
+from typing import Any, Callable, Dict, Optional
 
 import justpy as jp
 
@@ -23,7 +23,7 @@ class ValueElement(Element):
     def value_to_view(self, value):
         return value
 
-    def handle_change(self, msg):
+    def handle_change(self, msg: Dict):
         self.value = msg['value']
 
     def bind_value_to(self, target_object, target_name, *, forward=lambda x: x):

+ 4 - 0
nicegui/events.py

@@ -22,6 +22,10 @@ class ClickEventArguments(EventArguments):
     pass
 
 
+class ColorPickEventArguments(EventArguments):
+    color: str
+
+
 class MouseEventArguments(EventArguments):
     type: str
     image_x: float

+ 2 - 0
nicegui/ui.py

@@ -8,6 +8,8 @@ class Ui:
     from .elements.card import CardSection as card_section
     from .elements.chart import Chart as chart
     from .elements.checkbox import Checkbox as checkbox
+    from .elements.color_input import ColorInput as color_input
+    from .elements.color_picker import ColorPicker as color_picker
     from .elements.colors import Colors as colors
     from .elements.column import Column as column
     from .elements.custom_example import CustomExample as custom_example