reflex 0.6.8a1__py3-none-any.whl → 0.7.0__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.

Files changed (248) hide show
  1. reflex/.templates/jinja/custom_components/pyproject.toml.jinja2 +1 -1
  2. reflex/.templates/jinja/web/pages/_app.js.jinja2 +7 -7
  3. reflex/.templates/jinja/web/pages/utils.js.jinja2 +3 -3
  4. reflex/.templates/web/components/reflex/radix_themes_color_mode_provider.js +1 -4
  5. reflex/.templates/web/utils/state.js +65 -36
  6. reflex/__init__.py +4 -17
  7. reflex/__init__.pyi +1 -2
  8. reflex/app.py +286 -135
  9. reflex/app_mixins/lifespan.py +9 -9
  10. reflex/app_mixins/middleware.py +6 -6
  11. reflex/app_module_for_backend.py +3 -7
  12. reflex/base.py +7 -7
  13. reflex/compiler/compiler.py +8 -0
  14. reflex/compiler/utils.py +57 -18
  15. reflex/components/base/app_wrap.pyi +16 -16
  16. reflex/components/base/bare.py +1 -1
  17. reflex/components/base/body.pyi +16 -16
  18. reflex/components/base/document.pyi +76 -76
  19. reflex/components/base/error_boundary.py +2 -1
  20. reflex/components/base/error_boundary.pyi +19 -22
  21. reflex/components/base/fragment.pyi +16 -16
  22. reflex/components/base/head.pyi +31 -31
  23. reflex/components/base/link.pyi +31 -31
  24. reflex/components/base/meta.py +2 -2
  25. reflex/components/base/meta.pyi +61 -61
  26. reflex/components/base/script.pyi +19 -19
  27. reflex/components/base/strict_mode.py +10 -0
  28. reflex/components/base/strict_mode.pyi +57 -0
  29. reflex/components/component.py +38 -77
  30. reflex/components/core/banner.py +159 -4
  31. reflex/components/core/banner.pyi +162 -76
  32. reflex/components/core/breakpoints.py +3 -1
  33. reflex/components/core/client_side_routing.py +1 -1
  34. reflex/components/core/client_side_routing.pyi +32 -32
  35. reflex/components/core/clipboard.pyi +17 -20
  36. reflex/components/core/cond.py +9 -10
  37. reflex/components/core/debounce.py +1 -1
  38. reflex/components/core/debounce.pyi +17 -17
  39. reflex/components/core/foreach.py +28 -3
  40. reflex/components/core/html.py +1 -1
  41. reflex/components/core/html.pyi +16 -16
  42. reflex/components/core/match.py +5 -5
  43. reflex/components/core/sticky.py +134 -0
  44. reflex/components/core/sticky.pyi +449 -0
  45. reflex/components/core/upload.py +2 -2
  46. reflex/components/core/upload.pyi +80 -88
  47. reflex/components/datadisplay/code.py +5 -14
  48. reflex/components/datadisplay/code.pyi +31 -31
  49. reflex/components/datadisplay/dataeditor.py +7 -4
  50. reflex/components/datadisplay/dataeditor.pyi +40 -54
  51. reflex/components/datadisplay/logo.py +13 -8
  52. reflex/components/datadisplay/shiki_code_block.py +14 -9
  53. reflex/components/datadisplay/shiki_code_block.pyi +46 -46
  54. reflex/components/dynamic.py +22 -3
  55. reflex/components/el/constants/reflex.py +1 -1
  56. reflex/components/el/element.py +1 -1
  57. reflex/components/el/element.pyi +16 -16
  58. reflex/components/el/elements/base.pyi +16 -16
  59. reflex/components/el/elements/forms.py +4 -4
  60. reflex/components/el/elements/forms.pyi +224 -258
  61. reflex/components/el/elements/inline.pyi +421 -421
  62. reflex/components/el/elements/media.pyi +376 -376
  63. reflex/components/el/elements/metadata.pyi +91 -91
  64. reflex/components/el/elements/other.pyi +106 -106
  65. reflex/components/el/elements/scripts.pyi +46 -46
  66. reflex/components/el/elements/sectioning.pyi +226 -226
  67. reflex/components/el/elements/tables.pyi +151 -151
  68. reflex/components/el/elements/typography.pyi +226 -226
  69. reflex/components/gridjs/datatable.pyi +31 -31
  70. reflex/components/lucide/icon.py +46 -8
  71. reflex/components/lucide/icon.pyi +85 -31
  72. reflex/components/markdown/markdown.py +10 -8
  73. reflex/components/markdown/markdown.pyi +16 -16
  74. reflex/components/moment/moment.py +2 -2
  75. reflex/components/moment/moment.pyi +17 -19
  76. reflex/components/next/base.pyi +16 -16
  77. reflex/components/next/image.py +16 -4
  78. reflex/components/next/image.pyi +22 -20
  79. reflex/components/next/link.py +1 -1
  80. reflex/components/next/link.pyi +16 -16
  81. reflex/components/next/video.pyi +16 -16
  82. reflex/components/plotly/__init__.py +29 -2
  83. reflex/components/plotly/plotly.py +240 -5
  84. reflex/components/plotly/plotly.pyi +799 -44
  85. reflex/components/props.py +3 -3
  86. reflex/components/radix/__init__.pyi +1 -1
  87. reflex/components/radix/primitives/accordion.py +9 -5
  88. reflex/components/radix/primitives/accordion.pyi +110 -108
  89. reflex/components/radix/primitives/base.pyi +31 -31
  90. reflex/components/radix/primitives/drawer.py +5 -2
  91. reflex/components/radix/primitives/drawer.pyi +179 -187
  92. reflex/components/radix/primitives/form.pyi +160 -172
  93. reflex/components/radix/primitives/progress.py +1 -1
  94. reflex/components/radix/primitives/progress.pyi +76 -76
  95. reflex/components/radix/primitives/slider.py +1 -1
  96. reflex/components/radix/primitives/slider.pyi +78 -82
  97. reflex/components/radix/themes/base.pyi +121 -121
  98. reflex/components/radix/themes/color_mode.py +11 -9
  99. reflex/components/radix/themes/color_mode.pyi +47 -49
  100. reflex/components/radix/themes/components/alert_dialog.py +3 -0
  101. reflex/components/radix/themes/components/alert_dialog.pyi +110 -112
  102. reflex/components/radix/themes/components/aspect_ratio.pyi +16 -16
  103. reflex/components/radix/themes/components/avatar.pyi +16 -16
  104. reflex/components/radix/themes/components/badge.pyi +16 -16
  105. reflex/components/radix/themes/components/button.pyi +16 -16
  106. reflex/components/radix/themes/components/callout.pyi +76 -76
  107. reflex/components/radix/themes/components/card.py +1 -1
  108. reflex/components/radix/themes/components/card.pyi +17 -17
  109. reflex/components/radix/themes/components/checkbox.pyi +49 -55
  110. reflex/components/radix/themes/components/checkbox_cards.pyi +31 -31
  111. reflex/components/radix/themes/components/checkbox_group.pyi +31 -31
  112. reflex/components/radix/themes/components/context_menu.py +5 -0
  113. reflex/components/radix/themes/components/context_menu.pyi +149 -155
  114. reflex/components/radix/themes/components/data_list.pyi +61 -61
  115. reflex/components/radix/themes/components/dialog.py +3 -0
  116. reflex/components/radix/themes/components/dialog.pyi +113 -117
  117. reflex/components/radix/themes/components/dropdown_menu.py +5 -0
  118. reflex/components/radix/themes/components/dropdown_menu.pyi +133 -137
  119. reflex/components/radix/themes/components/hover_card.py +3 -0
  120. reflex/components/radix/themes/components/hover_card.pyi +63 -67
  121. reflex/components/radix/themes/components/icon_button.py +2 -2
  122. reflex/components/radix/themes/components/icon_button.pyi +17 -16
  123. reflex/components/radix/themes/components/inset.pyi +16 -16
  124. reflex/components/radix/themes/components/popover.py +3 -0
  125. reflex/components/radix/themes/components/popover.pyi +68 -70
  126. reflex/components/radix/themes/components/progress.pyi +16 -16
  127. reflex/components/radix/themes/components/radio.pyi +16 -16
  128. reflex/components/radix/themes/components/radio_cards.py +2 -0
  129. reflex/components/radix/themes/components/radio_cards.pyi +32 -34
  130. reflex/components/radix/themes/components/radio_group.py +1 -1
  131. reflex/components/radix/themes/components/radio_group.pyi +62 -64
  132. reflex/components/radix/themes/components/scroll_area.pyi +16 -16
  133. reflex/components/radix/themes/components/segmented_control.pyi +32 -35
  134. reflex/components/radix/themes/components/select.py +4 -0
  135. reflex/components/radix/themes/components/select.pyi +145 -157
  136. reflex/components/radix/themes/components/separator.pyi +16 -16
  137. reflex/components/radix/themes/components/skeleton.py +3 -0
  138. reflex/components/radix/themes/components/skeleton.pyi +16 -16
  139. reflex/components/radix/themes/components/slider.pyi +22 -28
  140. reflex/components/radix/themes/components/spinner.pyi +16 -16
  141. reflex/components/radix/themes/components/switch.pyi +17 -19
  142. reflex/components/radix/themes/components/table.pyi +106 -106
  143. reflex/components/radix/themes/components/tabs.py +3 -0
  144. reflex/components/radix/themes/components/tabs.pyi +78 -82
  145. reflex/components/radix/themes/components/text_area.py +12 -0
  146. reflex/components/radix/themes/components/text_area.pyi +21 -33
  147. reflex/components/radix/themes/components/text_field.py +1 -1
  148. reflex/components/radix/themes/components/text_field.pyi +52 -80
  149. reflex/components/radix/themes/components/tooltip.py +6 -1
  150. reflex/components/radix/themes/components/tooltip.pyi +20 -21
  151. reflex/components/radix/themes/layout/__init__.pyi +1 -1
  152. reflex/components/radix/themes/layout/base.pyi +16 -16
  153. reflex/components/radix/themes/layout/box.pyi +16 -16
  154. reflex/components/radix/themes/layout/center.pyi +16 -16
  155. reflex/components/radix/themes/layout/container.pyi +16 -16
  156. reflex/components/radix/themes/layout/flex.pyi +16 -16
  157. reflex/components/radix/themes/layout/grid.pyi +16 -16
  158. reflex/components/radix/themes/layout/list.py +2 -2
  159. reflex/components/radix/themes/layout/list.pyi +76 -76
  160. reflex/components/radix/themes/layout/section.pyi +16 -16
  161. reflex/components/radix/themes/layout/spacer.pyi +16 -16
  162. reflex/components/radix/themes/layout/stack.py +2 -2
  163. reflex/components/radix/themes/layout/stack.pyi +46 -46
  164. reflex/components/radix/themes/typography/blockquote.pyi +16 -16
  165. reflex/components/radix/themes/typography/code.pyi +16 -16
  166. reflex/components/radix/themes/typography/heading.pyi +16 -16
  167. reflex/components/radix/themes/typography/link.py +1 -1
  168. reflex/components/radix/themes/typography/link.pyi +16 -16
  169. reflex/components/radix/themes/typography/text.py +2 -2
  170. reflex/components/radix/themes/typography/text.pyi +106 -106
  171. reflex/components/react_player/audio.pyi +33 -39
  172. reflex/components/react_player/react_player.py +1 -1
  173. reflex/components/react_player/react_player.pyi +32 -38
  174. reflex/components/react_player/video.pyi +33 -39
  175. reflex/components/recharts/__init__.py +2 -0
  176. reflex/components/recharts/__init__.pyi +2 -0
  177. reflex/components/recharts/cartesian.pyi +282 -282
  178. reflex/components/recharts/charts.py +15 -15
  179. reflex/components/recharts/charts.pyi +164 -164
  180. reflex/components/recharts/general.py +19 -4
  181. reflex/components/recharts/general.pyi +132 -81
  182. reflex/components/recharts/polar.py +2 -2
  183. reflex/components/recharts/polar.pyi +55 -55
  184. reflex/components/recharts/recharts.py +4 -4
  185. reflex/components/recharts/recharts.pyi +31 -31
  186. reflex/components/sonner/toast.py +15 -13
  187. reflex/components/sonner/toast.pyi +22 -22
  188. reflex/components/suneditor/editor.py +6 -4
  189. reflex/components/suneditor/editor.pyi +26 -40
  190. reflex/components/tags/iter_tag.py +3 -3
  191. reflex/components/tags/tag.py +25 -3
  192. reflex/config.py +48 -20
  193. reflex/constants/__init__.py +1 -0
  194. reflex/constants/base.py +4 -1
  195. reflex/constants/compiler.py +5 -2
  196. reflex/constants/config.py +8 -1
  197. reflex/constants/installer.py +9 -9
  198. reflex/constants/style.py +1 -1
  199. reflex/custom_components/custom_components.py +18 -10
  200. reflex/event.py +228 -233
  201. reflex/experimental/__init__.py +19 -11
  202. reflex/experimental/client_state.py +53 -28
  203. reflex/experimental/hooks.py +5 -5
  204. reflex/experimental/layout.py +8 -5
  205. reflex/experimental/layout.pyi +79 -83
  206. reflex/experimental/misc.py +3 -3
  207. reflex/istate/wrappers.py +1 -1
  208. reflex/middleware/hydrate_middleware.py +2 -2
  209. reflex/model.py +11 -6
  210. reflex/page.py +5 -5
  211. reflex/reflex.py +104 -26
  212. reflex/route.py +1 -1
  213. reflex/state.py +358 -401
  214. reflex/style.py +27 -3
  215. reflex/testing.py +34 -39
  216. reflex/utils/build.py +6 -2
  217. reflex/utils/codespaces.py +1 -4
  218. reflex/utils/compat.py +6 -5
  219. reflex/utils/console.py +71 -21
  220. reflex/utils/exceptions.py +89 -26
  221. reflex/utils/exec.py +69 -74
  222. reflex/utils/export.py +6 -1
  223. reflex/utils/format.py +8 -40
  224. reflex/utils/imports.py +5 -2
  225. reflex/utils/lazy_loader.py +7 -1
  226. reflex/utils/path_ops.py +74 -14
  227. reflex/utils/prerequisites.py +345 -68
  228. reflex/utils/processes.py +45 -32
  229. reflex/utils/pyi_generator.py +39 -33
  230. reflex/utils/registry.py +4 -4
  231. reflex/utils/serializers.py +1 -1
  232. reflex/utils/telemetry.py +5 -4
  233. reflex/utils/types.py +42 -18
  234. reflex/vars/base.py +695 -330
  235. reflex/vars/datetime.py +6 -7
  236. reflex/vars/dep_tracking.py +344 -0
  237. reflex/vars/function.py +11 -5
  238. reflex/vars/number.py +31 -43
  239. reflex/vars/object.py +74 -64
  240. reflex/vars/sequence.py +79 -67
  241. {reflex-0.6.8a1.dist-info → reflex-0.7.0.dist-info}/METADATA +7 -10
  242. reflex-0.7.0.dist-info/RECORD +401 -0
  243. {reflex-0.6.8a1.dist-info → reflex-0.7.0.dist-info}/WHEEL +1 -1
  244. reflex/experimental/assets.py +0 -37
  245. reflex/proxy.py +0 -119
  246. reflex-0.6.8a1.dist-info/RECORD +0 -398
  247. {reflex-0.6.8a1.dist-info → reflex-0.7.0.dist-info}/LICENSE +0 -0
  248. {reflex-0.6.8a1.dist-info → reflex-0.7.0.dist-info}/entry_points.txt +0 -0
@@ -23,8 +23,6 @@ from typing import (
23
23
  Union,
24
24
  )
25
25
 
26
- from typing_extensions import deprecated
27
-
28
26
  import reflex.state
29
27
  from reflex.base import Base
30
28
  from reflex.compiler.templates import STATEFUL_COMPONENT
@@ -47,11 +45,10 @@ from reflex.event import (
47
45
  EventChain,
48
46
  EventHandler,
49
47
  EventSpec,
50
- EventVar,
51
48
  no_args_event_spec,
52
49
  )
53
50
  from reflex.style import Style, format_as_emotion
54
- from reflex.utils import console, format, imports, types
51
+ from reflex.utils import format, imports, types
55
52
  from reflex.utils.imports import (
56
53
  ImmutableParsedImportDict,
57
54
  ImportDict,
@@ -153,7 +150,7 @@ class BaseComponent(Base, ABC):
153
150
  class ComponentNamespace(SimpleNamespace):
154
151
  """A namespace to manage components with subcomponents."""
155
152
 
156
- def __hash__(self) -> int:
153
+ def __hash__(self) -> int: # pyright: ignore [reportIncompatibleVariableOverride]
157
154
  """Get the hash of the namespace.
158
155
 
159
156
  Returns:
@@ -429,20 +426,22 @@ class Component(BaseComponent, ABC):
429
426
  else:
430
427
  continue
431
428
 
429
+ def determine_key(value: Any):
430
+ # Try to create a var from the value
431
+ key = value if isinstance(value, Var) else LiteralVar.create(value)
432
+
433
+ # Check that the var type is not None.
434
+ if key is None:
435
+ raise TypeError
436
+
437
+ return key
438
+
432
439
  # Check whether the key is a component prop.
433
440
  if types._issubclass(field_type, Var):
434
441
  # Used to store the passed types if var type is a union.
435
442
  passed_types = None
436
443
  try:
437
- # Try to create a var from the value.
438
- if isinstance(value, Var):
439
- kwargs[key] = value
440
- else:
441
- kwargs[key] = LiteralVar.create(value)
442
-
443
- # Check that the var type is not None.
444
- if kwargs[key] is None:
445
- raise TypeError
444
+ kwargs[key] = determine_key(value)
446
445
 
447
446
  expected_type = fields[key].outer_type_.__args__[0]
448
447
  # validate literal fields.
@@ -463,9 +462,7 @@ class Component(BaseComponent, ABC):
463
462
  if types.is_union(passed_type):
464
463
  # We need to check all possible types in the union.
465
464
  passed_types = (
466
- arg
467
- for arg in passed_type.__args__ # type: ignore
468
- if arg is not type(None)
465
+ arg for arg in passed_type.__args__ if arg is not type(None)
469
466
  )
470
467
  if (
471
468
  # If the passed var is a union, check if all possible types are valid.
@@ -492,7 +489,7 @@ class Component(BaseComponent, ABC):
492
489
  # Check if the key is an event trigger.
493
490
  if key in component_specific_triggers:
494
491
  kwargs["event_triggers"][key] = EventChain.create(
495
- value=value, # type: ignore
492
+ value=value,
496
493
  args_spec=component_specific_triggers[key],
497
494
  key=key,
498
495
  )
@@ -545,41 +542,6 @@ class Component(BaseComponent, ABC):
545
542
  # Construct the component.
546
543
  super().__init__(*args, **kwargs)
547
544
 
548
- @deprecated("Use rx.EventChain.create instead.")
549
- def _create_event_chain(
550
- self,
551
- args_spec: types.ArgsSpec | Sequence[types.ArgsSpec],
552
- value: Union[
553
- Var,
554
- EventHandler,
555
- EventSpec,
556
- List[Union[EventHandler, EventSpec, EventVar]],
557
- Callable,
558
- ],
559
- key: Optional[str] = None,
560
- ) -> Union[EventChain, Var]:
561
- """Create an event chain from a variety of input types.
562
-
563
- Args:
564
- args_spec: The args_spec of the event trigger being bound.
565
- value: The value to create the event chain from.
566
- key: The key of the event trigger being bound.
567
-
568
- Returns:
569
- The event chain.
570
- """
571
- console.deprecate(
572
- "Component._create_event_chain",
573
- "Use rx.EventChain.create instead.",
574
- deprecation_version="0.6.8",
575
- removal_version="0.7.0",
576
- )
577
- return EventChain.create(
578
- value=value, # type: ignore
579
- args_spec=args_spec,
580
- key=key,
581
- )
582
-
583
545
  def get_event_triggers(
584
546
  self,
585
547
  ) -> Dict[str, types.ArgsSpec | Sequence[types.ArgsSpec]]:
@@ -614,7 +576,7 @@ class Component(BaseComponent, ABC):
614
576
  annotation = field.annotation
615
577
  if (metadata := getattr(annotation, "__metadata__", None)) is not None:
616
578
  args_spec = metadata[0]
617
- default_triggers[field.name] = args_spec or (no_args_event_spec) # type: ignore
579
+ default_triggers[field.name] = args_spec or (no_args_event_spec)
618
580
  return default_triggers
619
581
 
620
582
  def __repr__(self) -> str:
@@ -661,8 +623,7 @@ class Component(BaseComponent, ABC):
661
623
  if props is None:
662
624
  # Add component props to the tag.
663
625
  props = {
664
- attr[:-1] if attr.endswith("_") else attr: getattr(self, attr)
665
- for attr in self.get_props()
626
+ attr.removesuffix("_"): getattr(self, attr) for attr in self.get_props()
666
627
  }
667
628
 
668
629
  # Add ref to element if `id` is not None.
@@ -740,22 +701,21 @@ class Component(BaseComponent, ABC):
740
701
  # Import here to avoid circular imports.
741
702
  from reflex.components.base.bare import Bare
742
703
  from reflex.components.base.fragment import Fragment
743
- from reflex.utils.exceptions import ComponentTypeError
704
+ from reflex.utils.exceptions import ChildrenTypeError
744
705
 
745
706
  # Filter out None props
746
707
  props = {key: value for key, value in props.items() if value is not None}
747
708
 
748
- def validate_children(children):
709
+ def validate_children(children: tuple | list):
749
710
  for child in children:
750
- if isinstance(child, tuple):
711
+ if isinstance(child, (tuple, list)):
751
712
  validate_children(child)
713
+
752
714
  # Make sure the child is a valid type.
753
- if not types._isinstance(child, ComponentChild):
754
- raise ComponentTypeError(
755
- "Children of Reflex components must be other components, "
756
- "state vars, or primitive Python types. "
757
- f"Got child {child} of type {type(child)}.",
758
- )
715
+ if isinstance(child, dict) or not types._isinstance(
716
+ child, ComponentChild
717
+ ):
718
+ raise ChildrenTypeError(component=cls.__name__, child=child)
759
719
 
760
720
  # Validate all the children.
761
721
  validate_children(children)
@@ -798,7 +758,7 @@ class Component(BaseComponent, ABC):
798
758
 
799
759
  # Walk the MRO to call all `add_style` methods.
800
760
  for base in self._iter_parent_classes_with_method("add_style"):
801
- s = base.add_style(self) # type: ignore
761
+ s = base.add_style(self)
802
762
  if s is not None:
803
763
  styles.append(s)
804
764
 
@@ -890,7 +850,7 @@ class Component(BaseComponent, ABC):
890
850
  else {}
891
851
  )
892
852
 
893
- def render(self) -> Dict:
853
+ def render(self) -> dict:
894
854
  """Render the component.
895
855
 
896
856
  Returns:
@@ -908,7 +868,7 @@ class Component(BaseComponent, ABC):
908
868
  self._replace_prop_names(rendered_dict)
909
869
  return rendered_dict
910
870
 
911
- def _replace_prop_names(self, rendered_dict) -> None:
871
+ def _replace_prop_names(self, rendered_dict: dict) -> None:
912
872
  """Replace the prop names in the render dictionary.
913
873
 
914
874
  Args:
@@ -948,7 +908,7 @@ class Component(BaseComponent, ABC):
948
908
  comp.__name__ for comp in (Fragment, Foreach, Cond, Match)
949
909
  ]
950
910
 
951
- def validate_child(child):
911
+ def validate_child(child: Any):
952
912
  child_name = type(child).__name__
953
913
 
954
914
  # Iterate through the immediate children of fragment
@@ -1711,7 +1671,7 @@ class CustomComponent(Component):
1711
1671
  if base_value is not None and isinstance(value, Component):
1712
1672
  self.component_props[key] = value
1713
1673
  value = base_value._replace(
1714
- merge_var_data=VarData( # type: ignore
1674
+ merge_var_data=VarData(
1715
1675
  imports=value._get_all_imports(),
1716
1676
  hooks=value._get_all_hooks(),
1717
1677
  )
@@ -1744,7 +1704,7 @@ class CustomComponent(Component):
1744
1704
  return hash(self.tag)
1745
1705
 
1746
1706
  @classmethod
1747
- def get_props(cls) -> Set[str]:
1707
+ def get_props(cls) -> Set[str]: # pyright: ignore [reportIncompatibleVariableOverride]
1748
1708
  """Get the props for the component.
1749
1709
 
1750
1710
  Returns:
@@ -1839,7 +1799,7 @@ class CustomComponent(Component):
1839
1799
  include_children=include_children, ignore_ids=ignore_ids
1840
1800
  )
1841
1801
 
1842
- @lru_cache(maxsize=None) # noqa
1802
+ @lru_cache(maxsize=None) # noqa: B019
1843
1803
  def get_component(self) -> Component:
1844
1804
  """Render the component.
1845
1805
 
@@ -1983,7 +1943,7 @@ class StatefulComponent(BaseComponent):
1983
1943
 
1984
1944
  if not should_memoize:
1985
1945
  # Determine if any Vars have associated data.
1986
- for prop_var in component._get_vars():
1946
+ for prop_var in component._get_vars(include_children=True):
1987
1947
  if prop_var._get_all_var_data():
1988
1948
  should_memoize = True
1989
1949
  break
@@ -2366,8 +2326,8 @@ class MemoizationLeaf(Component):
2366
2326
  """
2367
2327
  comp = super().create(*children, **props)
2368
2328
  if comp._get_all_hooks():
2369
- comp._memoization_mode = cls._memoization_mode.copy(
2370
- update={"disposition": MemoizationDisposition.ALWAYS}
2329
+ comp._memoization_mode = dataclasses.replace(
2330
+ comp._memoization_mode, disposition=MemoizationDisposition.ALWAYS
2371
2331
  )
2372
2332
  return comp
2373
2333
 
@@ -2428,7 +2388,7 @@ def render_dict_to_var(tag: dict | Component | str, imported_names: set[str]) ->
2428
2388
  if tag["name"] == "match":
2429
2389
  element = tag["cond"]
2430
2390
 
2431
- conditionals = tag["default"]
2391
+ conditionals = render_dict_to_var(tag["default"], imported_names)
2432
2392
 
2433
2393
  for case in tag["match_cases"][::-1]:
2434
2394
  condition = case[0].to_string() == element.to_string()
@@ -2437,7 +2397,7 @@ def render_dict_to_var(tag: dict | Component | str, imported_names: set[str]) ->
2437
2397
 
2438
2398
  conditionals = ternary_operation(
2439
2399
  condition,
2440
- case[-1],
2400
+ render_dict_to_var(case[-1], imported_names),
2441
2401
  conditionals,
2442
2402
  )
2443
2403
 
@@ -2496,6 +2456,7 @@ def render_dict_to_var(tag: dict | Component | str, imported_names: set[str]) ->
2496
2456
  @dataclasses.dataclass(
2497
2457
  eq=False,
2498
2458
  frozen=True,
2459
+ slots=True,
2499
2460
  )
2500
2461
  class LiteralComponentVar(CachedVarOperation, LiteralVar, ComponentVar):
2501
2462
  """A Var that represents a Component."""
@@ -4,6 +4,7 @@ from __future__ import annotations
4
4
 
5
5
  from typing import Optional
6
6
 
7
+ from reflex import constants
7
8
  from reflex.components.component import Component
8
9
  from reflex.components.core.cond import cond
9
10
  from reflex.components.el.elements.typography import Div
@@ -25,7 +26,7 @@ from reflex.vars.function import FunctionStringVar
25
26
  from reflex.vars.number import BooleanVar
26
27
  from reflex.vars.sequence import LiteralArrayVar
27
28
 
28
- connect_error_var_data: VarData = VarData( # type: ignore
29
+ connect_error_var_data: VarData = VarData(
29
30
  imports=Imports.EVENTS,
30
31
  hooks={Hooks.EVENTS: None},
31
32
  )
@@ -99,14 +100,14 @@ class ConnectionToaster(Toaster):
99
100
  """
100
101
  toast_id = "websocket-error"
101
102
  target_url = WebsocketTargetURL.create()
102
- props = ToastProps( # type: ignore
103
+ props = ToastProps(
103
104
  description=LiteralVar.create(
104
105
  f"Check if server is reachable at {target_url}",
105
106
  ),
106
107
  close_button=True,
107
108
  duration=120000,
108
109
  id=toast_id,
109
- )
110
+ ) # pyright: ignore [reportCallIssue]
110
111
 
111
112
  individual_hooks = [
112
113
  f"const toast_props = {LiteralVar.create(props)!s};",
@@ -116,7 +117,7 @@ class ConnectionToaster(Toaster):
116
117
  _var_data=VarData(
117
118
  imports={
118
119
  "react": ["useEffect", "useState"],
119
- **dict(target_url._get_all_var_data().imports), # type: ignore
120
+ **dict(target_url._get_all_var_data().imports), # pyright: ignore [reportArgumentType, reportOptionalMemberAccess]
120
121
  }
121
122
  ),
122
123
  ).call(
@@ -293,7 +294,161 @@ class ConnectionPulser(Div):
293
294
  )
294
295
 
295
296
 
297
+ class BackendDisabled(Div):
298
+ """A component that displays a message when the backend is disabled."""
299
+
300
+ @classmethod
301
+ def create(cls, **props) -> Component:
302
+ """Create a backend disabled component.
303
+
304
+ Args:
305
+ **props: The properties of the component.
306
+
307
+ Returns:
308
+ The backend disabled component.
309
+ """
310
+ import reflex as rx
311
+
312
+ is_backend_disabled = Var(
313
+ "backendDisabled",
314
+ _var_type=bool,
315
+ _var_data=VarData(
316
+ hooks={
317
+ "const [backendDisabled, setBackendDisabled] = useState(false);": None,
318
+ "useEffect(() => { setBackendDisabled(isBackendDisabled()); }, []);": None,
319
+ },
320
+ imports={
321
+ f"$/{constants.Dirs.STATE_PATH}": [
322
+ ImportVar(tag="isBackendDisabled")
323
+ ],
324
+ },
325
+ ),
326
+ )
327
+
328
+ return super().create(
329
+ rx.cond(
330
+ is_backend_disabled,
331
+ rx.box(
332
+ rx.el.link(
333
+ rel="preconnect",
334
+ href="https://fonts.googleapis.com",
335
+ ),
336
+ rx.el.link(
337
+ rel="preconnect",
338
+ href="https://fonts.gstatic.com",
339
+ crossorigin="",
340
+ ),
341
+ rx.el.link(
342
+ href="https://fonts.googleapis.com/css2?family=Instrument+Sans:ital,wght@0,500;0,600&display=swap",
343
+ rel="stylesheet",
344
+ ),
345
+ rx.box(
346
+ rx.vstack(
347
+ rx.text(
348
+ "This app is paused",
349
+ font_size="1.5rem",
350
+ font_weight="600",
351
+ line_height="1.25rem",
352
+ letter_spacing="-0.0375rem",
353
+ ),
354
+ rx.hstack(
355
+ rx.el.svg(
356
+ rx.el.svg.path(
357
+ d="M6.90816 1.34341C7.61776 1.10786 8.38256 1.10786 9.09216 1.34341C9.7989 1.57799 10.3538 2.13435 10.9112 2.91605C11.4668 3.69515 12.0807 4.78145 12.872 6.18175L12.9031 6.23672C13.6946 7.63721 14.3085 8.72348 14.6911 9.60441C15.0755 10.4896 15.267 11.2539 15.1142 11.9881C14.9604 12.7275 14.5811 13.3997 14.0287 13.9079C13.4776 14.4147 12.7273 14.6286 11.7826 14.7313C10.8432 14.8334 9.6143 14.8334 8.0327 14.8334H7.9677C6.38604 14.8334 5.15719 14.8334 4.21778 14.7313C3.27301 14.6286 2.52269 14.4147 1.97164 13.9079C1.41924 13.3997 1.03995 12.7275 0.88613 11.9881C0.733363 11.2539 0.92483 10.4896 1.30926 9.60441C1.69184 8.72348 2.30573 7.63721 3.09722 6.23671L3.12828 6.18175C3.91964 4.78146 4.53355 3.69515 5.08914 2.91605C5.64658 2.13435 6.20146 1.57799 6.90816 1.34341ZM7.3335 11.3334C7.3335 10.9652 7.63063 10.6667 7.99716 10.6667H8.00316C8.3697 10.6667 8.66683 10.9652 8.66683 11.3334C8.66683 11.7016 8.3697 12.0001 8.00316 12.0001H7.99716C7.63063 12.0001 7.3335 11.7016 7.3335 11.3334ZM7.3335 8.66675C7.3335 9.03495 7.63196 9.33341 8.00016 9.33341C8.36836 9.33341 8.66683 9.03495 8.66683 8.66675V6.00008C8.66683 5.63189 8.36836 5.33341 8.00016 5.33341C7.63196 5.33341 7.3335 5.63189 7.3335 6.00008V8.66675Z",
358
+ fill_rule="evenodd",
359
+ clip_rule="evenodd",
360
+ fill=rx.color("amber", 11),
361
+ ),
362
+ width="16",
363
+ height="16",
364
+ viewBox="0 0 16 16",
365
+ fill="none",
366
+ xmlns="http://www.w3.org/2000/svg",
367
+ margin_top="0.125rem",
368
+ flex_shrink="0",
369
+ ),
370
+ rx.text(
371
+ "If you are the owner of this app, visit ",
372
+ rx.link(
373
+ "Reflex Cloud",
374
+ color=rx.color("amber", 11),
375
+ underline="always",
376
+ _hover={
377
+ "color": rx.color("amber", 11),
378
+ "text_decoration_color": rx.color(
379
+ "amber", 11
380
+ ),
381
+ },
382
+ text_decoration_color=rx.color("amber", 10),
383
+ href="https://cloud.reflex.dev/",
384
+ font_weight="600",
385
+ is_external=True,
386
+ ),
387
+ " for more information on how to resume your app.",
388
+ font_size="0.875rem",
389
+ font_weight="500",
390
+ line_height="1.25rem",
391
+ letter_spacing="-0.01094rem",
392
+ color=rx.color("amber", 11),
393
+ ),
394
+ align="start",
395
+ gap="0.625rem",
396
+ border_radius="0.75rem",
397
+ border_width="1px",
398
+ border_color=rx.color("amber", 5),
399
+ background_color=rx.color("amber", 3),
400
+ padding="0.625rem",
401
+ ),
402
+ rx.link(
403
+ rx.el.button(
404
+ "Resume app",
405
+ color="rgba(252, 252, 253, 1)",
406
+ font_size="0.875rem",
407
+ font_weight="600",
408
+ line_height="1.25rem",
409
+ letter_spacing="-0.01094rem",
410
+ height="2.5rem",
411
+ padding="0rem 0.75rem",
412
+ width="100%",
413
+ border_radius="0.75rem",
414
+ background=f"linear-gradient(180deg, {rx.color('violet', 9)} 0%, {rx.color('violet', 10)} 100%)",
415
+ _hover={
416
+ "background": f"linear-gradient(180deg, {rx.color('violet', 10)} 0%, {rx.color('violet', 10)} 100%)",
417
+ },
418
+ ),
419
+ width="100%",
420
+ underline="none",
421
+ href="https://cloud.reflex.dev/",
422
+ is_external=True,
423
+ ),
424
+ gap="1rem",
425
+ ),
426
+ font_family='"Instrument Sans", "Helvetica", "Arial", sans-serif',
427
+ position="fixed",
428
+ top="50%",
429
+ left="50%",
430
+ transform="translate(-50%, -50%)",
431
+ width="60ch",
432
+ max_width="90vw",
433
+ border_radius="0.75rem",
434
+ border_width="1px",
435
+ border_color=rx.color("slate", 4),
436
+ padding="1.5rem",
437
+ background_color=rx.color("slate", 1),
438
+ box_shadow="0px 2px 5px 0px light-dark(rgba(28, 32, 36, 0.03), rgba(0, 0, 0, 0.00))",
439
+ ),
440
+ position="fixed",
441
+ z_index=9999,
442
+ backdrop_filter="grayscale(1) blur(5px)",
443
+ width="100dvw",
444
+ height="100dvh",
445
+ ),
446
+ )
447
+ )
448
+
449
+
296
450
  connection_banner = ConnectionBanner.create
297
451
  connection_modal = ConnectionModal.create
298
452
  connection_toaster = ConnectionToaster.create
299
453
  connection_pulser = ConnectionPulser.create
454
+ backend_disabled = BackendDisabled.create