reflex 0.7.6a1__py3-none-any.whl → 0.7.7a2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of reflex might be problematic. Click here for more details.

@@ -948,6 +948,15 @@ export const isTrue = (val) => {
948
948
  return Boolean(val);
949
949
  };
950
950
 
951
+ /***
952
+ * Check if a value is not null or undefined.
953
+ * @param val The value to check.
954
+ * @returns True if the value is not null or undefined, false otherwise.
955
+ */
956
+ export const isNotNullOrUndefined = (val) => {
957
+ return val ?? undefined !== undefined;
958
+ };
959
+
951
960
  /**
952
961
  * Get the value from a ref.
953
962
  * @param ref The ref to get the value from.
reflex/app.py CHANGED
@@ -293,6 +293,7 @@ class UnevaluatedPage:
293
293
  image: str
294
294
  on_load: EventType[()] | None
295
295
  meta: list[dict[str, str]]
296
+ context: dict[str, Any] | None
296
297
 
297
298
 
298
299
  @dataclasses.dataclass()
@@ -681,6 +682,7 @@ class App(MiddlewareMixin, LifespanMixin):
681
682
  image: str = constants.DefaultPage.IMAGE,
682
683
  on_load: EventType[()] | None = None,
683
684
  meta: list[dict[str, str]] = constants.DefaultPage.META_LIST,
685
+ context: dict[str, Any] | None = None,
684
686
  ):
685
687
  """Add a page to the app.
686
688
 
@@ -695,6 +697,7 @@ class App(MiddlewareMixin, LifespanMixin):
695
697
  image: The image to display on the page.
696
698
  on_load: The event handler(s) that will be called each time the page load.
697
699
  meta: The metadata of the page.
700
+ context: Values passed to page for custom page-specific logic.
698
701
 
699
702
  Raises:
700
703
  PageValueError: When the component is not set for a non-404 page.
@@ -762,6 +765,7 @@ class App(MiddlewareMixin, LifespanMixin):
762
765
  image=image,
763
766
  on_load=on_load,
764
767
  meta=meta,
768
+ context=context,
765
769
  )
766
770
 
767
771
  def _compile_page(self, route: str, save_page: bool = True):
@@ -933,6 +937,9 @@ class App(MiddlewareMixin, LifespanMixin):
933
937
  and i != ""
934
938
  and any(tag.install for tag in tags)
935
939
  }
940
+ pinned = {i.rpartition("@")[0] for i in page_imports if "@" in i}
941
+ page_imports = {i for i in page_imports if i not in pinned}
942
+
936
943
  frontend_packages = get_config().frontend_packages
937
944
  _frontend_packages = []
938
945
  for package in frontend_packages:
@@ -30,6 +30,7 @@ from typing import (
30
30
  )
31
31
 
32
32
  import pydantic.v1
33
+ from rich.markup import escape
33
34
 
34
35
  import reflex.state
35
36
  from reflex.base import Base
@@ -217,7 +218,7 @@ def satisfies_type_hint(obj: Any, type_hint: Any) -> bool:
217
218
  console.deprecate(
218
219
  "implicit-none-for-component-fields",
219
220
  reason="Passing Vars with possible None values to component fields not explicitly marked as Optional is deprecated. "
220
- + f"Passed {obj!s} of type {type(obj) if not isinstance(obj, Var) else obj._var_type} to {type_hint}.",
221
+ + f"Passed {obj!s} of type {escape(str(type(obj) if not isinstance(obj, Var) else obj._var_type))} to {escape(str(type_hint))}.",
221
222
  deprecation_version="0.7.2",
222
223
  removal_version="0.8.0",
223
224
  )
@@ -13,14 +13,17 @@ from reflex.constants import Dirs, EventTriggers
13
13
  from reflex.event import (
14
14
  EventChain,
15
15
  EventHandler,
16
+ checked_input_event,
17
+ float_input_event,
16
18
  input_event,
19
+ int_input_event,
17
20
  key_event,
18
21
  prevent_default,
19
22
  )
20
23
  from reflex.utils.imports import ImportDict
21
- from reflex.utils.types import is_optional
22
24
  from reflex.vars import VarData
23
25
  from reflex.vars.base import LiteralVar, Var
26
+ from reflex.vars.number import ternary_operation
24
27
 
25
28
  from .base import BaseHTML
26
29
 
@@ -294,8 +297,8 @@ HTMLInputTypeAttribute = Literal[
294
297
  ]
295
298
 
296
299
 
297
- class Input(BaseHTML):
298
- """Display the input element."""
300
+ class BaseInput(BaseHTML):
301
+ """A base class for input elements."""
299
302
 
300
303
  tag = "input"
301
304
 
@@ -392,6 +395,42 @@ class Input(BaseHTML):
392
395
  # Value of the input
393
396
  value: Var[str | int | float]
394
397
 
398
+ # Fired when a key is pressed down
399
+ on_key_down: EventHandler[key_event]
400
+
401
+ # Fired when a key is released
402
+ on_key_up: EventHandler[key_event]
403
+
404
+
405
+ class CheckboxInput(BaseInput):
406
+ """Display the input element."""
407
+
408
+ # Fired when the input value changes
409
+ on_change: EventHandler[checked_input_event]
410
+
411
+ # Fired when the input gains focus
412
+ on_focus: EventHandler[checked_input_event]
413
+
414
+ # Fired when the input loses focus
415
+ on_blur: EventHandler[checked_input_event]
416
+
417
+
418
+ class ValueNumberInput(BaseInput):
419
+ """Display the input element."""
420
+
421
+ # Fired when the input value changes
422
+ on_change: EventHandler[float_input_event, int_input_event, input_event]
423
+
424
+ # Fired when the input gains focus
425
+ on_focus: EventHandler[float_input_event, int_input_event, input_event]
426
+
427
+ # Fired when the input loses focus
428
+ on_blur: EventHandler[float_input_event, int_input_event, input_event]
429
+
430
+
431
+ class Input(BaseInput):
432
+ """Display the input element."""
433
+
395
434
  # Fired when the input value changes
396
435
  on_change: EventHandler[input_event]
397
436
 
@@ -401,12 +440,6 @@ class Input(BaseHTML):
401
440
  # Fired when the input loses focus
402
441
  on_blur: EventHandler[input_event]
403
442
 
404
- # Fired when a key is pressed down
405
- on_key_down: EventHandler[key_event]
406
-
407
- # Fired when a key is released
408
- on_key_up: EventHandler[key_event]
409
-
410
443
  @classmethod
411
444
  def create(cls, *children, **props):
412
445
  """Create an Input component.
@@ -418,20 +451,26 @@ class Input(BaseHTML):
418
451
  Returns:
419
452
  The component.
420
453
  """
421
- from reflex.vars.number import ternary_operation
422
-
423
454
  value = props.get("value")
424
455
 
425
456
  # React expects an empty string(instead of null) for controlled inputs.
426
- if value is not None and is_optional(
427
- (value_var := Var.create(value))._var_type
428
- ):
457
+ if value is not None:
458
+ value_var = Var.create(value)
429
459
  props["value"] = ternary_operation(
430
- (value_var != Var.create(None))
431
- & (value_var != Var(_js_expr="undefined")),
432
- value,
433
- Var.create(""),
460
+ value_var.is_not_none(), value_var, Var.create("")
434
461
  )
462
+
463
+ if cls is Input:
464
+ input_type = props.get("type")
465
+
466
+ if input_type == "checkbox":
467
+ # Checkbox inputs should use the CheckboxInput class
468
+ return CheckboxInput.create(*children, **props)
469
+
470
+ if input_type == "number" or input_type == "range":
471
+ # Number inputs should use the ValueNumberInput class
472
+ return ValueNumberInput.create(*children, **props)
473
+
435
474
  return super().create(*children, **props)
436
475
 
437
476