Browse Source

Merge pull request #1049 from zauberzeug/number

Introduce min, max and out_of_limits for ui.number
Rodja Trappe 1 year ago
parent
commit
925c687d40
2 changed files with 41 additions and 2 deletions
  1. 27 2
      nicegui/elements/number.py
  2. 14 0
      tests/test_number.py

+ 27 - 2
nicegui/elements/number.py

@@ -58,10 +58,35 @@ class Number(ValidationElement, DisableableElement):
             self._props['suffix'] = suffix
         self.on('blur', self.sanitize)
 
+    @property
+    def min(self) -> float:
+        """The minimum value allowed."""
+        return self._props.get('min', -float('inf'))
+
+    @min.setter
+    def min(self, value: float) -> None:
+        self._props['min'] = value
+        self.sanitize()
+
+    @property
+    def max(self) -> float:
+        """The maximum value allowed."""
+        return self._props.get('max', float('inf'))
+
+    @max.setter
+    def max(self, value: float) -> None:
+        self._props['max'] = value
+        self.sanitize()
+
+    @property
+    def out_of_limits(self) -> bool:
+        """Whether the current value is out of the allowed limits."""
+        return not self.min <= self.value <= self.max
+
     def sanitize(self) -> None:
         value = float(self.value or 0)
-        value = max(value, self._props.get('min', -float('inf')))
-        value = min(value, self._props.get('max', float('inf')))
+        value = max(value, self.min)
+        value = min(value, self.max)
         self.set_value(float(self.format % value) if self.format else value)
 
     def _msg_to_value(self, msg: Dict) -> Any:

+ 14 - 0
tests/test_number.py

@@ -39,3 +39,17 @@ def test_clearable_number(screen: Screen):
     screen.should_contain('value: 42')
     screen.click('cancel')
     screen.should_contain('value: None')
+
+
+def test_out_of_limits(screen: Screen):
+    number = ui.number('Number', min=0, max=10, value=5)
+    ui.label().bind_text_from(number, 'out_of_limits', lambda value: f'out_of_limits: {value}')
+
+    screen.open('/')
+    screen.should_contain('out_of_limits: False')
+
+    number.value = 11
+    screen.should_contain('out_of_limits: True')
+
+    number.max = 15
+    screen.should_contain('out_of_limits: False')