Quellcode durchsuchen

#271 introduce password toggle button for ui.input

Falko Schindler vor 2 Jahren
Ursprung
Commit
3e9960f9d1
2 geänderte Dateien mit 30 neuen und 1 gelöschten Zeilen
  1. 12 1
      nicegui/elements/input.py
  2. 18 0
      tests/test_input.py

+ 12 - 1
nicegui/elements/input.py

@@ -1,5 +1,6 @@
 from typing import Callable, Optional
 from typing import Callable, Optional
 
 
+from .icon import Icon
 from .mixins.value_element import ValueElement
 from .mixins.value_element import ValueElement
 
 
 
 
@@ -10,16 +11,26 @@ class Input(ValueElement):
                  placeholder: Optional[str] = None,
                  placeholder: Optional[str] = None,
                  value: str = '',
                  value: str = '',
                  password: bool = False,
                  password: bool = False,
+                 password_toggle_button: bool = False,
                  on_change: Optional[Callable] = None) -> None:
                  on_change: Optional[Callable] = None) -> None:
         """Text Input
         """Text Input
 
 
         :param label: displayed label for the text input
         :param label: displayed label for the text input
         :param placeholder: text to show if no value is entered
         :param placeholder: text to show if no value is entered
         :param value: the current value of the text input
         :param value: the current value of the text input
-        :param password: whether to hide the input
+        :param password: whether to hide the input (default: False)
+        :param password_toggle_button: whether to show a button to toggle the password visibility (default: False)
         :param on_change: callback to execute when the input is confirmed by leaving the focus
         :param on_change: callback to execute when the input is confirmed by leaving the focus
         """
         """
         super().__init__(tag='q-input', value=value, on_value_change=on_change)
         super().__init__(tag='q-input', value=value, on_value_change=on_change)
         self._props['label'] = label
         self._props['label'] = label
         self._props['placeholder'] = placeholder
         self._props['placeholder'] = placeholder
         self._props['type'] = 'password' if password else 'text'
         self._props['type'] = 'password' if password else 'text'
+
+        if password_toggle_button:
+            with self.add_slot('append'):
+                def toggle_type(_):
+                    is_hidden = self._props.get('type') == 'password'
+                    icon.props(f'name={"visibility" if is_hidden else "visibility_off"}')
+                    self.props(f'type={"text" if is_hidden else "password"}')
+                icon = Icon('visibility_off').classes('cursor-pointer').on('click', toggle_type)

+ 18 - 0
tests/test_input.py

@@ -30,3 +30,21 @@ def test_password(screen: Screen):
 
 
     element.send_keys('789')
     element.send_keys('789')
     assert element.get_attribute('value') == '123456789'
     assert element.get_attribute('value') == '123456789'
+
+
+def test_toggle_button(screen: Screen):
+    ui.input('Your password', value='123456', password=True, password_toggle_button=True)
+
+    screen.open('/')
+    screen.should_contain('Your password')
+    screen.should_contain('visibility_off')
+
+    element = screen.selenium.find_element(By.XPATH, '//*[@aria-label="Your password"]')
+    assert element.get_attribute('type') == 'password'
+    assert element.get_attribute('value') == '123456'
+
+    screen.click('visibility_off')
+    assert element.get_attribute('type') == 'text'
+
+    screen.click('visibility')
+    assert element.get_attribute('type') == 'password'